Skip to content

Commit 436c0d9

Browse files
committed
now can interpolate for slices on locations between two axis points
1 parent 94b4f5e commit 436c0d9

File tree

3 files changed

+143
-35
lines changed

3 files changed

+143
-35
lines changed

src/traces/isosurface/attributes.js

+2-5
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,9 @@ function makeSliceAttr(axLetter) {
3333
dflt: [],
3434
role: 'info',
3535
description: [
36-
'Specifies the location(s) of slices on the axis [0, n].',
36+
'Specifies the location(s) of slices on the axis.',
3737
'When not locations specified slices would be created for',
38-
'all (0, n) i.e. except start and end caps. Please note that',
39-
'if a location do not match the point on the', axLetter, 'axis,',
40-
'the slicing plane would simply be located on the closest',
41-
'point on the axis (does not interpolate on the axis).'
38+
'all points of the axis', axLetter, 'except start and end.'
4239
].join(' ')
4340
},
4441
fill: {

src/traces/isosurface/convert.js

+140-29
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,17 @@ function findNearestOnAxis(w, arr) {
3030
for(var q = arr.length - 1; q > 0; q--) {
3131
var min = Math.min(arr[q], arr[q - 1]);
3232
var max = Math.max(arr[q], arr[q - 1]);
33-
if(w <= max && w > min) return q;
33+
if(max > min && min < w && w <= max) {
34+
return {
35+
id: q,
36+
distRatio: (max - w) / (max - min)
37+
};
38+
}
3439
}
35-
return 0;
40+
return {
41+
id: 0,
42+
distRatio: 0
43+
};
3644
}
3745

3846
proto.handlePick = function(selection) {
@@ -44,9 +52,9 @@ proto.handlePick = function(selection) {
4452
var y = this.data.y[rawId];
4553
var z = this.data.z[rawId];
4654

47-
var i = findNearestOnAxis(x, this.data._Xs);
48-
var j = findNearestOnAxis(y, this.data._Ys);
49-
var k = findNearestOnAxis(z, this.data._Zs);
55+
var i = findNearestOnAxis(x, this.data._Xs).id;
56+
var j = findNearestOnAxis(y, this.data._Ys).id;
57+
var k = findNearestOnAxis(z, this.data._Zs).id;
5058

5159
var width = this.data._Xs.length;
5260
var height = this.data._Ys.length;
@@ -615,14 +623,55 @@ function generateIsosurfaceMesh(data) {
615623
}
616624

617625
function begin2dCell(style, p00, p01, p10, p11, min, max, isEven) {
626+
// used to create caps and/or slices on exact axis points
618627
if(isEven) {
619628
addRect(style, p00, p01, p11, p10, min, max);
620629
} else {
621630
addRect(style, p01, p11, p10, p00, min, max);
622631
}
623632
}
624633

634+
function beginSection(style, i, j, k, min, max, distRatios) {
635+
// used to create slices between axis points
636+
637+
var A, B, C, D;
638+
639+
var makeSection = function() {
640+
tryCreateTri(style, [A, B, C], [-1, -1, -1], min, max);
641+
tryCreateTri(style, [C, D, A], [-1, -1, -1], min, max);
642+
};
643+
644+
var rX = distRatios[0];
645+
var rY = distRatios[1];
646+
var rZ = distRatios[2];
647+
648+
if(rX) {
649+
A = getBetween(getXYZV([getIndex(i, j - 0, k - 0)])[0], getXYZV([getIndex(i + 1, j - 0, k - 0)])[0], rX);
650+
B = getBetween(getXYZV([getIndex(i, j - 0, k - 1)])[0], getXYZV([getIndex(i + 1, j - 0, k - 1)])[0], rX);
651+
C = getBetween(getXYZV([getIndex(i, j - 1, k - 1)])[0], getXYZV([getIndex(i + 1, j - 1, k - 1)])[0], rX);
652+
D = getBetween(getXYZV([getIndex(i, j - 1, k - 0)])[0], getXYZV([getIndex(i + 1, j - 1, k - 0)])[0], rX);
653+
makeSection();
654+
}
655+
656+
if(rY) {
657+
A = getBetween(getXYZV([getIndex(i - 0, j, k - 0)])[0], getXYZV([getIndex(i - 0, j + 1, k - 0)])[0], rY);
658+
B = getBetween(getXYZV([getIndex(i - 0, j, k - 1)])[0], getXYZV([getIndex(i - 0, j + 1, k - 1)])[0], rY);
659+
C = getBetween(getXYZV([getIndex(i - 1, j, k - 1)])[0], getXYZV([getIndex(i - 1, j + 1, k - 1)])[0], rY);
660+
D = getBetween(getXYZV([getIndex(i - 1, j, k - 0)])[0], getXYZV([getIndex(i - 1, j + 1, k - 0)])[0], rY);
661+
makeSection();
662+
}
663+
664+
if(rZ) {
665+
A = getBetween(getXYZV([getIndex(i - 0, j - 0, k)])[0], getXYZV([getIndex(i - 0, j - 0, k + 1)])[0], rZ);
666+
B = getBetween(getXYZV([getIndex(i - 0, j - 1, k)])[0], getXYZV([getIndex(i - 0, j - 1, k + 1)])[0], rZ);
667+
C = getBetween(getXYZV([getIndex(i - 1, j - 1, k)])[0], getXYZV([getIndex(i - 1, j - 1, k + 1)])[0], rZ);
668+
D = getBetween(getXYZV([getIndex(i - 1, j - 0, k)])[0], getXYZV([getIndex(i - 1, j - 0, k + 1)])[0], rZ);
669+
makeSection();
670+
}
671+
}
672+
625673
function begin3dCell(style, p000, p001, p010, p011, p100, p101, p110, p111, min, max, isEven) {
674+
// used to create spaceframe and/or iso-surfaces
626675
var cellStyle = style;
627676
if(isEven) {
628677
if(drawingSurface && styleIncludes(style, 'check2')) cellStyle = null;
@@ -634,7 +683,8 @@ function generateIsosurfaceMesh(data) {
634683
}
635684

636685
function draw2dX(style, items, min, max) {
637-
items.forEach(function(i) {
686+
for(var q = 0; q < items.length; q++) {
687+
var i = items[q];
638688
for(var k = 1; k < depth; k++) {
639689
for(var j = 1; j < height; j++) {
640690
begin2dCell(style,
@@ -648,11 +698,12 @@ function generateIsosurfaceMesh(data) {
648698
);
649699
}
650700
}
651-
});
701+
}
652702
}
653703

654704
function draw2dY(style, items, min, max) {
655-
items.forEach(function(j) {
705+
for(var q = 0; q < items.length; q++) {
706+
var j = items[q];
656707
for(var i = 1; i < width; i++) {
657708
for(var k = 1; k < depth; k++) {
658709
begin2dCell(style,
@@ -666,11 +717,12 @@ function generateIsosurfaceMesh(data) {
666717
);
667718
}
668719
}
669-
});
720+
}
670721
}
671722

672723
function draw2dZ(style, items, min, max) {
673-
items.forEach(function(k) {
724+
for(var q = 0; q < items.length; q++) {
725+
var k = items[q];
674726
for(var j = 1; j < height; j++) {
675727
for(var i = 1; i < width; i++) {
676728
begin2dCell(style,
@@ -684,7 +736,7 @@ function generateIsosurfaceMesh(data) {
684736
);
685737
}
686738
}
687-
});
739+
}
688740
}
689741

690742
function draw3d(style, min, max) {
@@ -721,6 +773,39 @@ function generateIsosurfaceMesh(data) {
721773
drawingSurface = false;
722774
}
723775

776+
function drawSectionX(style, items, min, max, distRatios) {
777+
for(var q = 0; q < items.length; q++) {
778+
var i = items[q];
779+
for(var k = 1; k < depth; k++) {
780+
for(var j = 1; j < height; j++) {
781+
beginSection(style, i, j, k, min, max, distRatios[q]);
782+
}
783+
}
784+
}
785+
}
786+
787+
function drawSectionY(style, items, min, max, distRatios) {
788+
for(var q = 0; q < items.length; q++) {
789+
var j = items[q];
790+
for(var i = 1; i < width; i++) {
791+
for(var k = 1; k < depth; k++) {
792+
beginSection(style, i, j, k, min, max, distRatios[q]);
793+
}
794+
}
795+
}
796+
}
797+
798+
function drawSectionZ(style, items, min, max, distRatios) {
799+
for(var q = 0; q < items.length; q++) {
800+
var k = items[q];
801+
for(var j = 1; j < height; j++) {
802+
for(var i = 1; i < width; i++) {
803+
beginSection(style, i, j, k, min, max, distRatios[q]);
804+
}
805+
}
806+
}
807+
}
808+
724809
function createRange(a, b) {
725810
var range = [];
726811
for(var q = a; q < b; q++) {
@@ -739,7 +824,7 @@ function generateIsosurfaceMesh(data) {
739824
}
740825
}
741826

742-
function voidMain() {
827+
function drawAll() {
743828

744829
emptyVertices();
745830

@@ -793,33 +878,59 @@ function generateIsosurfaceMesh(data) {
793878
if(slice.show && slice.fill) {
794879
setFill(slice.fill);
795880

796-
var indices = [];
881+
var exactIndices = [];
882+
var ceilIndices = [];
883+
var distRatios = [];
797884
if(slice.locations.length) {
798885
for(var q = 0; q < slice.locations.length; q++) {
799-
indices.push(
800-
findNearestOnAxis(
801-
slice.locations[q],
802-
(e === 'x') ? Xs :
803-
(e === 'y') ? Ys : Zs
804-
)
886+
887+
var near = findNearestOnAxis(
888+
slice.locations[q],
889+
(e === 'x') ? Xs :
890+
(e === 'y') ? Ys : Zs
805891
);
892+
893+
if(near.distRatio === 0) {
894+
exactIndices.push(near.id);
895+
} else {
896+
ceilIndices.push(near.id);
897+
if(e === 'x') {
898+
distRatios.push([near.distRatio, 0, 0]);
899+
} else if(e === 'y') {
900+
distRatios.push([0, near.distRatio, 0]);
901+
} else {
902+
distRatios.push([0, 0, near.distRatio]);
903+
}
904+
}
806905
}
807906
} else {
808907
if(e === 'x') {
809-
indices = createRange(1, width - 1);
908+
exactIndices = createRange(1, width - 1);
810909
} else if(e === 'y') {
811-
indices = createRange(1, height - 1);
910+
exactIndices = createRange(1, height - 1);
812911
} else {
813-
indices = createRange(1, depth - 1);
912+
exactIndices = createRange(1, depth - 1);
814913
}
815914
}
816915

817-
if(e === 'x') {
818-
draw2dX(activeStyle, indices, activeMin, activeMax);
819-
} else if(e === 'y') {
820-
draw2dY(activeStyle, indices, activeMin, activeMax);
821-
} else {
822-
draw2dZ(activeStyle, indices, activeMin, activeMax);
916+
if(ceilIndices.length > 0) {
917+
if(e === 'x') {
918+
drawSectionX(activeStyle, ceilIndices, activeMin, activeMax, distRatios);
919+
} else if(e === 'y') {
920+
drawSectionY(activeStyle, ceilIndices, activeMin, activeMax, distRatios);
921+
} else {
922+
drawSectionZ(activeStyle, ceilIndices, activeMin, activeMax, distRatios);
923+
}
924+
}
925+
926+
if(exactIndices.length > 0) {
927+
if(e === 'x') {
928+
draw2dX(activeStyle, exactIndices, activeMin, activeMax);
929+
} else if(e === 'y') {
930+
draw2dY(activeStyle, exactIndices, activeMin, activeMax);
931+
} else {
932+
draw2dZ(activeStyle, exactIndices, activeMin, activeMax);
933+
}
823934
}
824935
}
825936

@@ -853,7 +964,7 @@ function generateIsosurfaceMesh(data) {
853964
data.intensity = allVs;
854965
}
855966

856-
voidMain();
967+
drawAll();
857968

858969
return data;
859970
}

test/image/mocks/gl3d_isosurface_log-axis_slices_surface-fill.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
"spaceframe": { "show": false },
88
"slices": {
99
"x": { "show": true, "fill": 1, "locations": [-0.9, -0.6, 0] },
10-
"y": { "show": false },
10+
"y": { "show": true, "fill": 1, "locations": [-0.9, -0.6, 0] },
1111
"z": { "show": true, "fill": 1 }
1212
},
1313
"caps": {

0 commit comments

Comments
 (0)