Skip to content

Commit f13ca5a

Browse files
committed
fix(TubeFilter): Compute number of points and normals based on capping
Also fixed missing index parameter from setTuple causing error.
1 parent bd704a7 commit f13ca5a

File tree

4 files changed

+97
-51
lines changed

4 files changed

+97
-51
lines changed

Sources/Common/DataModel/DataSetAttributes/FieldData.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ function vtkFieldData(publicAPI, model) {
8686
if (((fromId < 1) && (toId < 1)) || !destArr) {
8787
publicAPI.addArray(arr);
8888
} else if ((idx >= fromId) && ((toId > -1) || (idx < toId))) {
89-
destArr.setTuple(arr.getTuple(idx));
89+
destArr.setTuple(idx, arr.getTuple(idx));
9090
}
9191
}
9292
});
Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,54 @@
11
<table>
22
<tr>
3-
<td>Number of Points</td>
3+
<td>Tubing</td>
4+
<td colspan="3">
5+
<input class='tubing' type="checkbox" checked />
6+
</td>
7+
</tr>
8+
<tr>
9+
<td>Number of Sides</td>
410
<td>
5-
<input class='numberOfPoints' type="range" min="1" max="500" step="1" value="25" />
11+
<form name='numberOfSidesForm'>
12+
<input class='numberOfSides' id="numberOfSidesInputId" type="range"
13+
min="3" max="100" step="1" value="50"
14+
oninput="numberOfSidesOutputId.value = numberOfSidesInputId.value"/>
15+
<output id="numberOfSidesOutputId">50</output>
16+
</form>
617
</td>
718
</tr>
819
<tr>
920
<td>Radius</td>
1021
<td>
11-
<input class='radius' type="range" min="0.1" max="0.5" step=".01" value="0.25" />
22+
<form name='radiusForm'>
23+
<input class='radius' id="radiusInputId" type="range"
24+
min="0.01" max="1.0" step=".01" value="0.1"
25+
oninput="radiusOutputId.value = radiusInputId.value"/>
26+
<output id="radiusOutputId">0.1</output>
27+
</form>
28+
</td>
29+
</tr>
30+
<tr>
31+
<td>Vary Radius</td>
32+
<td>
33+
<select class="varyRadius">
34+
<option value="VARY_RADIUS_OFF">VARY_RADIUS_OFF</option>
35+
<option value="VARY_RADIUS_BY_SCALAR">VARY_RADIUS_BY_SCALAR</option>
36+
<option value="VARY_RADIUS_BY_VECTOR">VARY_RADIUS_BY_VECTOR</option>
37+
<option value="VARY_RADIUS_BY_ABSOLUTE_SCALAR">VARY_RADIUS_BY_ABSOLUTE_SCALAR</option>
38+
</select>
39+
</td>
40+
</tr>
41+
<tr>
42+
<td>Capping</td>
43+
<td colspan="3">
44+
<input class='capping' type="checkbox" />
45+
</td>
46+
</tr>
47+
<tr>
48+
<td>OnRatio</td>
49+
<td>
50+
<input class='onRatio' id="onRatioInputId" type="number"
51+
min="1" max="4.0" step="1" value="1"/>
1252
</td>
1353
</tr>
1454
</table>

Sources/Filters/General/TubeFilter/example/index.js

Lines changed: 49 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import 'vtk.js/Sources/favicon';
22

3-
import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
3+
import Constants from 'vtk.js/Sources/Filters/General/TubeFilter/Constants';
44
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
5-
// import vtkPointSource from 'vtk.js/Sources/Filters/Sources/PointSource';
6-
// import vtkOutlineFilter from 'vtk.js/Sources/Filters/General/OutlineFilter';
5+
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
6+
import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
77
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
88
import vtkMath from 'vtk.js/Sources/Common/Core/Math';
9-
import vtkTubeFilter from 'vtk.js/Sources/Filters/General/TubeFilter';
109
import vtkPoints from 'vtk.js/Sources/Common/Core/Points';
1110
import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData';
12-
import { VtkPointPrecision } from 'vtk.js/Sources/Filters/General/Constants';
11+
import vtkTubeFilter from 'vtk.js/Sources/Filters/General/TubeFilter';
1312
import { VtkDataTypes } from 'vtk.js/Sources/Common/Core/DataArray/Constants';
13+
import { VtkPointPrecision } from 'vtk.js/Sources/Filters/General/Constants';
1414

1515
import controlPanel from './controlPanel.html';
1616

17+
const { VtkVaryRadius } = Constants;
18+
1719
// ----------------------------------------------------------------------------
1820
// Standard rendering code setup
1921
// ----------------------------------------------------------------------------
@@ -43,8 +45,8 @@ function addRepresentation(name, filter, props = {}) {
4345
global[`${name}Mapper`] = mapper;
4446
}
4547

46-
vtkMath.randomSeed(1);
47-
const numSegments = 2;
48+
vtkMath.randomSeed(15222);
49+
const numSegments = 3;
4850

4951
function initializePolyData(dType) {
5052
let pointType = VtkDataTypes.FLOAT;
@@ -56,43 +58,45 @@ function initializePolyData(dType) {
5658
const polyData = vtkPolyData.newInstance();
5759
const points = vtkPoints.newInstance({ dataType: pointType });
5860
points.setNumberOfPoints(numSegments + 1);
59-
// const pointData = points.getData();
61+
const pointData = new Float32Array(3 * (numSegments + 1));
6062
const verts = new Uint32Array(2 * (numSegments + 1));
6163
const lines = new Uint32Array(numSegments + 2);
6264
lines[0] = numSegments + 1;
65+
const scalarsData = new Float32Array(numSegments + 1);
66+
const scalars = vtkDataArray.newInstance(
67+
{ name: 'Scalars', values: scalarsData });
6368

64-
const pointData = [0, 0, 0, -0.13, -0.51, 0, -0.41, -0.48, 0];
65-
points.setData(pointData);
6669
for (let i = 0; i < (numSegments + 1); ++i) {
67-
// for (let j = 0; j < 3; ++j) {
68-
// pointData[(3 * i) + j] = Math.random();
69-
// }
70+
for (let j = 0; j < 3; ++j) {
71+
pointData[(3 * i) + j] = vtkMath.random();
72+
}
73+
scalarsData[i] = i * 0.1;
7074
verts[i] = 1;
7175
verts[i + 1] = i;
7276
lines[i + 1] = i;
7377
}
7478

79+
points.setData(pointData);
7580
polyData.setPoints(points);
76-
// polyData.getVerts().setData(verts);
81+
polyData.getVerts().setData(verts);
7782
polyData.getLines().setData(lines);
83+
polyData.getPointData().setScalars(scalars);
7884
return polyData;
7985
}
8086

8187
// ----------------------------------------------------------------------------
8288

8389

84-
// const pointSource = vtkPointSource.newInstance({ numberOfPoints: 25, radius: 0.25 });
8590
const polyData = initializePolyData(VtkPointPrecision.DOUBLE);
8691
const tubeFilter = vtkTubeFilter.newInstance();
87-
tubeFilter.setCapping(true);
88-
tubeFilter.setNumberOfSides(30);
89-
tubeFilter.setRadius(0.083);
90-
tubeFilter.setRadiusFactor(10);
92+
tubeFilter.setCapping(false);
93+
tubeFilter.setNumberOfSides(50);
94+
tubeFilter.setRadius(0.1);
9195

9296
tubeFilter.setInputData(polyData);
97+
tubeFilter.setInputArrayToProcess(0, 'Scalars', 'PointData', 'Scalars');
9398

9499
addRepresentation('polyData', polyData, {});
95-
// addRepresentation('pointSource', pointSource, { pointSize: 5 });
96100
addRepresentation('tubeFilter', tubeFilter, {});
97101

98102
renderer.resetCamera();
@@ -104,13 +108,31 @@ renderWindow.render();
104108

105109
fullScreenRenderer.addController(controlPanel);
106110

107-
// ['numberOfPoints', 'radius'].forEach((propertyName) => {
108-
// document.querySelector(`.${propertyName}`).addEventListener('input', (e) => {
109-
// const value = Number(e.target.value);
110-
// pointSource.set({ [propertyName]: value });
111-
// renderWindow.render();
112-
// });
113-
// });
111+
['numberOfSides', 'radius', 'onRatio'].forEach((propertyName) => {
112+
document.querySelector(`.${propertyName}`).addEventListener('input', (e) => {
113+
const value = Number(e.target.value);
114+
tubeFilter.set({ [propertyName]: value });
115+
renderWindow.render();
116+
});
117+
});
118+
119+
document.querySelector('.varyRadius').addEventListener('change', (e) => {
120+
const value = e.target.value;
121+
tubeFilter.set({ varyRadius: VtkVaryRadius[value] });
122+
renderWindow.render();
123+
});
124+
125+
document.querySelector('.capping').addEventListener('change', (e) => {
126+
const capping = !!(e.target.checked);
127+
tubeFilter.set({ capping });
128+
renderWindow.render();
129+
});
130+
131+
document.querySelector('.tubing').addEventListener('change', (e) => {
132+
const tubing = !!(e.target.checked);
133+
global.tubeFilterActor.setVisibility(tubing);
134+
renderWindow.render();
135+
});
114136

115137
// // ----- Console play ground -----
116138
// global.pointSource = pointSource;

Sources/Filters/General/TubeFilter/index.js

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -215,25 +215,18 @@ function vtkTubeFilter(publicAPI, model) {
215215
sPrev[i] = sNext[i];
216216
startCapNorm[i] = -sPrev[i];
217217
}
218-
console.log(`First Point: ${p}`);
219-
console.log(`startCapNorm: ${startCapNorm}`);
220218
vtkMath.normalize(startCapNorm);
221-
console.log(`startCapNorm: ${startCapNorm}`);
222219
} else if (j === (npts - 1)) {
223220
for (let i = 0; i < 3; ++i) {
224221
sPrev[i] = sNext[i];
225222
p[i] = pNext[i];
226223
endCapNorm[i] = sNext[i];
227224
}
228-
console.log(`Third Point: ${p}`);
229-
console.log(`endCapNorm: ${endCapNorm}`);
230225
vtkMath.normalize(endCapNorm);
231-
console.log(`endCapNorm: ${endCapNorm}`);
232226
} else {
233227
for (let i = 0; i < 3; ++i) {
234228
p[i] = pNext[i];
235229
}
236-
console.log(`Second Point: ${p}`);
237230
pNext = inPts.slice(3 * pts[j + 1], 3 * (pts[j + 1] + 1));
238231
for (let i = 0; i < 3; ++i) {
239232
sPrev[i] = sNext[i];
@@ -249,10 +242,8 @@ function vtkTubeFilter(publicAPI, model) {
249242
for (let i = 0; i < 3; ++i) {
250243
s[i] = (sPrev[i] + sNext[i]) / 2.0; // average vector
251244
}
252-
console.log(`Average Vector: ${s}`);
253245

254246
n = inNormals.slice(3 * pts[j], 3 * (pts[j] + 1));
255-
console.log(`Normal for point ${pts[j]}: ${n}`);
256247
// if s is zero then just use sPrev cross n
257248
if (vtkMath.normalize(s) === 0.0) {
258249
vtkMath.cross(sPrev, n, s);
@@ -293,14 +284,12 @@ function vtkTubeFilter(publicAPI, model) {
293284
// create points around line
294285
if (model.sidesShareVertices) {
295286
for (let k = 0; k < model.numberOfSides; ++k) {
296-
console.log(`Point ${ptId}`);
297287
for (let i = 0; i < 3; ++i) {
298288
normal[i] = (w[i] * Math.cos(k * theta)) + (nP[i] * Math.sin(k * theta));
299289
s[i] = p[i] + (model.radius * sFactor * normal[i]);
300290
newPts[(3 * ptId) + i] = s[i];
301291
newNormals[(3 * ptId) + i] = normal[i];
302292
}
303-
console.log(`${s}`);
304293
outPD.passData(pd, pts[j], ptId);
305294
ptId++;
306295
} // for each side
@@ -330,7 +319,6 @@ function vtkTubeFilter(publicAPI, model) {
330319
} // else separate vertices
331320
} // for all points in the polyline
332321

333-
console.log(`NewNormals size: ${newNormals.length}`);
334322
// Produce end points for cap. They are placed at tail end of points.
335323
if (model.capping) {
336324
let numCapSides = model.numberOfSides;
@@ -347,11 +335,9 @@ function vtkTubeFilter(publicAPI, model) {
347335
newPts[(3 * ptId) + i] = s[i];
348336
newNormals[(3 * ptId) + i] = startCapNorm[i];
349337
}
350-
console.log(`Start cap Id: ${ptId} : ${startCapNorm}`);
351338
outPD.passData(pd, pts[0], ptId);
352339
ptId++;
353340
}
354-
console.log(`NewNormals size: ${newNormals.length}`);
355341

356342
// the end cap
357343
let endOffset = offset + ((npts - 1) * model.numberOfSides);
@@ -364,7 +350,6 @@ function vtkTubeFilter(publicAPI, model) {
364350
newPts[(3 * ptId) + i] = s[i];
365351
newNormals[(3 * ptId) + i] = endCapNorm[i];
366352
}
367-
console.log(`end cap Id: ${ptId} : ${endCapNorm}`);
368353
outPD.passData(pd, pts[npts - 1], ptId);
369354
ptId++;
370355
}
@@ -578,7 +563,10 @@ function vtkTubeFilter(publicAPI, model) {
578563
return;
579564
}
580565

581-
const numNewPts = numPts * model.numberOfSides;
566+
let numNewPts = numPts * model.numberOfSides;
567+
if (model.capping) {
568+
numNewPts = (numPts + 2) * model.numberOfSides;
569+
}
582570
let pointType = inPts.getDataType();
583571
if (model.outputPointsPrecision === VtkPointPrecision.SINGLE) {
584572
pointType = VtkDataTypes.FLOAT;
@@ -587,7 +575,6 @@ function vtkTubeFilter(publicAPI, model) {
587575
}
588576
const newPts = vtkPoints.newInstance(
589577
{ dataType: pointType, size: (numNewPts * 3), numberOfComponents: 3 });
590-
// const newPtsData = newPts.getData();
591578
let numNormals = 3 * numNewPts;
592579
if (model.capping) {
593580
numNormals = 3 * (numNewPts + (2 * model.numberOfSides));
@@ -633,7 +620,6 @@ function vtkTubeFilter(publicAPI, model) {
633620
maxSpeed = inVectors.getMaxNorm();
634621
}
635622

636-
// const numNewCells = (numLines * model.numberOfSides) + 2;
637623
const outCD = output.getCellData();
638624
outCD.copyNormalsOff();
639625
outCD.passData(input.getCellData());
@@ -696,8 +682,6 @@ function vtkTubeFilter(publicAPI, model) {
696682
output.setStrips(newStrips);
697683
output.setPointData(outPD);
698684
outPD.setNormals(newNormals);
699-
const s = JSON.stringify(output.getState());
700-
console.log(`${s}`);
701685
outData[0] = output;
702686
};
703687
}

0 commit comments

Comments
 (0)