Skip to content

Commit ed26d23

Browse files
authored
Merge pull request #4431 from plotly/fix4427-streamtube-string-coords
Handle streamtube coordinates in string format and handle different data orders in isosurface and volume
2 parents e778644 + c82da07 commit ed26d23

15 files changed

+1276
-164
lines changed

src/traces/isosurface/calc.js

+22-5
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,39 @@
99
'use strict';
1010

1111
var colorscaleCalc = require('../../components/colorscale/calc');
12+
var processGrid = require('../streamtube/calc').processGrid;
13+
var filter = require('../streamtube/calc').filter;
1214

1315
module.exports = function calc(gd, trace) {
14-
trace._len = Math.min(trace.x.length, trace.y.length, trace.z.length, trace.value.length);
16+
trace._len = Math.min(
17+
trace.x.length,
18+
trace.y.length,
19+
trace.z.length,
20+
trace.value.length
21+
);
22+
23+
trace._x = filter(trace.x, trace._len);
24+
trace._y = filter(trace.y, trace._len);
25+
trace._z = filter(trace.z, trace._len);
26+
trace._value = filter(trace.value, trace._len);
27+
28+
var grid = processGrid(trace);
29+
trace._gridFill = grid.fill;
30+
trace._Xs = grid.Xs;
31+
trace._Ys = grid.Ys;
32+
trace._Zs = grid.Zs;
33+
trace._len = grid.len;
1534

1635
var min = Infinity;
1736
var max = -Infinity;
18-
var len = trace.value.length;
19-
for(var i = 0; i < len; i++) {
20-
var v = trace.value[i];
37+
for(var i = 0; i < trace._len; i++) {
38+
var v = trace._value[i];
2139
min = Math.min(min, v);
2240
max = Math.max(max, v);
2341
}
2442

2543
trace._minValues = min;
2644
trace._maxValues = max;
27-
2845
trace._vMin = (trace.isomin === undefined || trace.isomin === null) ? min : trace.isomin;
2946
trace._vMax = (trace.isomax === undefined || trace.isomin === null) ? max : trace.isomax;
3047

src/traces/isosurface/convert.js

+53-43
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,11 @@
99
'use strict';
1010

1111
var createMesh = require('gl-mesh3d');
12-
13-
var Lib = require('../../lib');
14-
1512
var parseColorScale = require('../../lib/gl_format_color').parseColorScale;
1613
var str2RgbaArray = require('../../lib/str2rgbarray');
1714
var extractOpts = require('../../components/colorscale').extractOpts;
1815
var zip3 = require('../../plots/gl3d/zip3');
1916

20-
function distinctVals(col) {
21-
return Lib.distinctVals(col).vals;
22-
}
23-
2417
var findNearestOnAxis = function(w, arr) {
2518
for(var q = arr.length - 1; q > 0; q--) {
2619
var min = Math.min(arr[q], arr[q - 1]);
@@ -53,9 +46,9 @@ proto.handlePick = function(selection) {
5346
if(selection.object === this.mesh) {
5447
var rawId = selection.data.index;
5548

56-
var x = this.data._x[rawId];
57-
var y = this.data._y[rawId];
58-
var z = this.data._z[rawId];
49+
var x = this.data._meshX[rawId];
50+
var y = this.data._meshY[rawId];
51+
var z = this.data._meshZ[rawId];
5952

6053
var height = this.data._Ys.length;
6154
var depth = this.data._Zs.length;
@@ -67,10 +60,10 @@ proto.handlePick = function(selection) {
6760
var selectIndex = selection.index = k + depth * j + depth * height * i;
6861

6962
selection.traceCoordinate = [
70-
this.data._x[selectIndex],
71-
this.data._y[selectIndex],
72-
this.data._z[selectIndex],
73-
this.data.value[selectIndex]
63+
this.data._meshX[selectIndex],
64+
this.data._meshY[selectIndex],
65+
this.data._meshZ[selectIndex],
66+
this.data._value[selectIndex]
7467
];
7568

7669
var text = this.data.hovertext || this.data.text;
@@ -98,11 +91,11 @@ proto.update = function(data) {
9891
}
9992

10093
var positions = zip3(
101-
toDataCoords(layout.xaxis, data._x, scene.dataScale[0], data.xcalendar),
102-
toDataCoords(layout.yaxis, data._y, scene.dataScale[1], data.ycalendar),
103-
toDataCoords(layout.zaxis, data._z, scene.dataScale[2], data.zcalendar));
94+
toDataCoords(layout.xaxis, data._meshX, scene.dataScale[0], data.xcalendar),
95+
toDataCoords(layout.yaxis, data._meshY, scene.dataScale[1], data.ycalendar),
96+
toDataCoords(layout.zaxis, data._meshZ, scene.dataScale[2], data.zcalendar));
10497

105-
var cells = zip3(data._i, data._j, data._k);
98+
var cells = zip3(data._meshI, data._meshJ, data._meshK);
10699

107100
var config = {
108101
positions: positions,
@@ -123,7 +116,7 @@ proto.update = function(data) {
123116
};
124117

125118
var cOpts = extractOpts(data);
126-
config.vertexIntensity = data._intensity;
119+
config.vertexIntensity = data._meshIntensity;
127120
config.vertexIntensityBounds = [cOpts.min, cOpts.max];
128121
config.colormap = parseColorScale(data);
129122

@@ -136,10 +129,12 @@ proto.dispose = function() {
136129
this.mesh.dispose();
137130
};
138131

132+
var GRID_TYPES = ['xyz', 'xzy', 'yxz', 'yzx', 'zxy', 'zyx'];
133+
139134
function generateIsoMeshes(data) {
140-
data._i = [];
141-
data._j = [];
142-
data._k = [];
135+
data._meshI = [];
136+
data._meshJ = [];
137+
data._meshK = [];
143138

144139
var showSurface = data.surface.show;
145140
var showSpaceframe = data.spaceframe.show;
@@ -154,17 +149,32 @@ function generateIsoMeshes(data) {
154149
var numVertices;
155150
var beginVertextLength;
156151

157-
var Xs = distinctVals(data.x.slice(0, data._len));
158-
var Ys = distinctVals(data.y.slice(0, data._len));
159-
var Zs = distinctVals(data.z.slice(0, data._len));
152+
var Xs = data._Xs;
153+
var Ys = data._Ys;
154+
var Zs = data._Zs;
160155

161156
var width = Xs.length;
162157
var height = Ys.length;
163158
var depth = Zs.length;
164159

165-
function getIndex(i, j, k) {
166-
return k + depth * j + depth * height * i;
167-
}
160+
var filled = GRID_TYPES.indexOf(data._gridFill.replace(/-/g, '').replace(/\+/g, ''));
161+
162+
var getIndex = function(i, j, k) {
163+
switch(filled) {
164+
case 5: // 'zyx'
165+
return k + depth * j + depth * height * i;
166+
case 4: // 'zxy'
167+
return k + depth * i + depth * width * j;
168+
case 3: // 'yzx'
169+
return j + height * k + height * depth * i;
170+
case 2: // 'yxz'
171+
return j + height * i + height * width * k;
172+
case 1: // 'xzy'
173+
return i + width * k + width * depth * j;
174+
default: // case 0: // 'xyz'
175+
return i + width * j + width * height * k;
176+
}
177+
};
168178

169179
var minValues = data._minValues;
170180
var maxValues = data._maxValues;
@@ -218,9 +228,9 @@ function generateIsoMeshes(data) {
218228
}
219229

220230
function addFace(a, b, c) {
221-
data._i.push(a);
222-
data._j.push(b);
223-
data._k.push(c);
231+
data._meshI.push(a);
232+
data._meshJ.push(b);
233+
data._meshK.push(c);
224234
numFaces++;
225235

226236
return numFaces - 1;
@@ -379,10 +389,10 @@ function generateIsoMeshes(data) {
379389
var index = indecies[q];
380390
xyzv.push(
381391
[
382-
data.x[index],
383-
data.y[index],
384-
data.z[index],
385-
data.value[index]
392+
data._x[index],
393+
data._y[index],
394+
data._z[index],
395+
data._value[index]
386396
]
387397
);
388398
}
@@ -870,10 +880,10 @@ function generateIsoMeshes(data) {
870880
for(var k = 0; k < depth; k++) {
871881
var index = getIndex(i, j, k);
872882
addVertex(
873-
data.x[index],
874-
data.y[index],
875-
data.z[index],
876-
data.value[index]
883+
data._x[index],
884+
data._y[index],
885+
data._z[index],
886+
data._value[index]
877887
);
878888
}
879889
}
@@ -1011,10 +1021,10 @@ function generateIsoMeshes(data) {
10111021
emptyVertices();
10121022
}
10131023

1014-
data._x = allXs;
1015-
data._y = allYs;
1016-
data._z = allZs;
1017-
data._intensity = allVs;
1024+
data._meshX = allXs;
1025+
data._meshY = allYs;
1026+
data._meshZ = allZs;
1027+
data._meshIntensity = allVs;
10181028

10191029
data._Xs = Xs;
10201030
data._Ys = Ys;

0 commit comments

Comments
 (0)