Skip to content

Commit

Permalink
fix(TubeFilter): Compute number of points and normals based on capping
Browse files Browse the repository at this point in the history
Also fixed missing index parameter from setTuple causing error.
  • Loading branch information
sankhesh committed Jan 23, 2018
1 parent bd704a7 commit f13ca5a
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 51 deletions.
2 changes: 1 addition & 1 deletion Sources/Common/DataModel/DataSetAttributes/FieldData.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function vtkFieldData(publicAPI, model) {
if (((fromId < 1) && (toId < 1)) || !destArr) {
publicAPI.addArray(arr);
} else if ((idx >= fromId) && ((toId > -1) || (idx < toId))) {
destArr.setTuple(arr.getTuple(idx));
destArr.setTuple(idx, arr.getTuple(idx));
}
}
});
Expand Down
46 changes: 43 additions & 3 deletions Sources/Filters/General/TubeFilter/example/controlPanel.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,54 @@
<table>
<tr>
<td>Number of Points</td>
<td>Tubing</td>
<td colspan="3">
<input class='tubing' type="checkbox" checked />
</td>
</tr>
<tr>
<td>Number of Sides</td>
<td>
<input class='numberOfPoints' type="range" min="1" max="500" step="1" value="25" />
<form name='numberOfSidesForm'>
<input class='numberOfSides' id="numberOfSidesInputId" type="range"
min="3" max="100" step="1" value="50"
oninput="numberOfSidesOutputId.value = numberOfSidesInputId.value"/>
<output id="numberOfSidesOutputId">50</output>
</form>
</td>
</tr>
<tr>
<td>Radius</td>
<td>
<input class='radius' type="range" min="0.1" max="0.5" step=".01" value="0.25" />
<form name='radiusForm'>
<input class='radius' id="radiusInputId" type="range"
min="0.01" max="1.0" step=".01" value="0.1"
oninput="radiusOutputId.value = radiusInputId.value"/>
<output id="radiusOutputId">0.1</output>
</form>
</td>
</tr>
<tr>
<td>Vary Radius</td>
<td>
<select class="varyRadius">
<option value="VARY_RADIUS_OFF">VARY_RADIUS_OFF</option>
<option value="VARY_RADIUS_BY_SCALAR">VARY_RADIUS_BY_SCALAR</option>
<option value="VARY_RADIUS_BY_VECTOR">VARY_RADIUS_BY_VECTOR</option>
<option value="VARY_RADIUS_BY_ABSOLUTE_SCALAR">VARY_RADIUS_BY_ABSOLUTE_SCALAR</option>
</select>
</td>
</tr>
<tr>
<td>Capping</td>
<td colspan="3">
<input class='capping' type="checkbox" />
</td>
</tr>
<tr>
<td>OnRatio</td>
<td>
<input class='onRatio' id="onRatioInputId" type="number"
min="1" max="4.0" step="1" value="1"/>
</td>
</tr>
</table>
76 changes: 49 additions & 27 deletions Sources/Filters/General/TubeFilter/example/index.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import 'vtk.js/Sources/favicon';

import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
import Constants from 'vtk.js/Sources/Filters/General/TubeFilter/Constants';
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
// import vtkPointSource from 'vtk.js/Sources/Filters/Sources/PointSource';
// import vtkOutlineFilter from 'vtk.js/Sources/Filters/General/OutlineFilter';
import vtkDataArray from 'vtk.js/Sources/Common/Core/DataArray';
import vtkFullScreenRenderWindow from 'vtk.js/Sources/Rendering/Misc/FullScreenRenderWindow';
import vtkMapper from 'vtk.js/Sources/Rendering/Core/Mapper';
import vtkMath from 'vtk.js/Sources/Common/Core/Math';
import vtkTubeFilter from 'vtk.js/Sources/Filters/General/TubeFilter';
import vtkPoints from 'vtk.js/Sources/Common/Core/Points';
import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData';
import { VtkPointPrecision } from 'vtk.js/Sources/Filters/General/Constants';
import vtkTubeFilter from 'vtk.js/Sources/Filters/General/TubeFilter';
import { VtkDataTypes } from 'vtk.js/Sources/Common/Core/DataArray/Constants';
import { VtkPointPrecision } from 'vtk.js/Sources/Filters/General/Constants';

import controlPanel from './controlPanel.html';

const { VtkVaryRadius } = Constants;

// ----------------------------------------------------------------------------
// Standard rendering code setup
// ----------------------------------------------------------------------------
Expand Down Expand Up @@ -43,8 +45,8 @@ function addRepresentation(name, filter, props = {}) {
global[`${name}Mapper`] = mapper;
}

vtkMath.randomSeed(1);
const numSegments = 2;
vtkMath.randomSeed(15222);
const numSegments = 3;

function initializePolyData(dType) {
let pointType = VtkDataTypes.FLOAT;
Expand All @@ -56,43 +58,45 @@ function initializePolyData(dType) {
const polyData = vtkPolyData.newInstance();
const points = vtkPoints.newInstance({ dataType: pointType });
points.setNumberOfPoints(numSegments + 1);
// const pointData = points.getData();
const pointData = new Float32Array(3 * (numSegments + 1));
const verts = new Uint32Array(2 * (numSegments + 1));
const lines = new Uint32Array(numSegments + 2);
lines[0] = numSegments + 1;
const scalarsData = new Float32Array(numSegments + 1);
const scalars = vtkDataArray.newInstance(
{ name: 'Scalars', values: scalarsData });

const pointData = [0, 0, 0, -0.13, -0.51, 0, -0.41, -0.48, 0];
points.setData(pointData);
for (let i = 0; i < (numSegments + 1); ++i) {
// for (let j = 0; j < 3; ++j) {
// pointData[(3 * i) + j] = Math.random();
// }
for (let j = 0; j < 3; ++j) {
pointData[(3 * i) + j] = vtkMath.random();
}
scalarsData[i] = i * 0.1;
verts[i] = 1;
verts[i + 1] = i;
lines[i + 1] = i;
}

points.setData(pointData);
polyData.setPoints(points);
// polyData.getVerts().setData(verts);
polyData.getVerts().setData(verts);
polyData.getLines().setData(lines);
polyData.getPointData().setScalars(scalars);
return polyData;
}

// ----------------------------------------------------------------------------


// const pointSource = vtkPointSource.newInstance({ numberOfPoints: 25, radius: 0.25 });
const polyData = initializePolyData(VtkPointPrecision.DOUBLE);
const tubeFilter = vtkTubeFilter.newInstance();
tubeFilter.setCapping(true);
tubeFilter.setNumberOfSides(30);
tubeFilter.setRadius(0.083);
tubeFilter.setRadiusFactor(10);
tubeFilter.setCapping(false);
tubeFilter.setNumberOfSides(50);
tubeFilter.setRadius(0.1);

tubeFilter.setInputData(polyData);
tubeFilter.setInputArrayToProcess(0, 'Scalars', 'PointData', 'Scalars');

addRepresentation('polyData', polyData, {});
// addRepresentation('pointSource', pointSource, { pointSize: 5 });
addRepresentation('tubeFilter', tubeFilter, {});

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

fullScreenRenderer.addController(controlPanel);

// ['numberOfPoints', 'radius'].forEach((propertyName) => {
// document.querySelector(`.${propertyName}`).addEventListener('input', (e) => {
// const value = Number(e.target.value);
// pointSource.set({ [propertyName]: value });
// renderWindow.render();
// });
// });
['numberOfSides', 'radius', 'onRatio'].forEach((propertyName) => {
document.querySelector(`.${propertyName}`).addEventListener('input', (e) => {
const value = Number(e.target.value);
tubeFilter.set({ [propertyName]: value });
renderWindow.render();
});
});

document.querySelector('.varyRadius').addEventListener('change', (e) => {
const value = e.target.value;
tubeFilter.set({ varyRadius: VtkVaryRadius[value] });
renderWindow.render();
});

document.querySelector('.capping').addEventListener('change', (e) => {
const capping = !!(e.target.checked);
tubeFilter.set({ capping });
renderWindow.render();
});

document.querySelector('.tubing').addEventListener('change', (e) => {
const tubing = !!(e.target.checked);
global.tubeFilterActor.setVisibility(tubing);
renderWindow.render();
});

// // ----- Console play ground -----
// global.pointSource = pointSource;
Expand Down
24 changes: 4 additions & 20 deletions Sources/Filters/General/TubeFilter/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -215,25 +215,18 @@ function vtkTubeFilter(publicAPI, model) {
sPrev[i] = sNext[i];
startCapNorm[i] = -sPrev[i];
}
console.log(`First Point: ${p}`);
console.log(`startCapNorm: ${startCapNorm}`);
vtkMath.normalize(startCapNorm);
console.log(`startCapNorm: ${startCapNorm}`);
} else if (j === (npts - 1)) {
for (let i = 0; i < 3; ++i) {
sPrev[i] = sNext[i];
p[i] = pNext[i];
endCapNorm[i] = sNext[i];
}
console.log(`Third Point: ${p}`);
console.log(`endCapNorm: ${endCapNorm}`);
vtkMath.normalize(endCapNorm);
console.log(`endCapNorm: ${endCapNorm}`);
} else {
for (let i = 0; i < 3; ++i) {
p[i] = pNext[i];
}
console.log(`Second Point: ${p}`);
pNext = inPts.slice(3 * pts[j + 1], 3 * (pts[j + 1] + 1));
for (let i = 0; i < 3; ++i) {
sPrev[i] = sNext[i];
Expand All @@ -249,10 +242,8 @@ function vtkTubeFilter(publicAPI, model) {
for (let i = 0; i < 3; ++i) {
s[i] = (sPrev[i] + sNext[i]) / 2.0; // average vector
}
console.log(`Average Vector: ${s}`);

n = inNormals.slice(3 * pts[j], 3 * (pts[j] + 1));
console.log(`Normal for point ${pts[j]}: ${n}`);
// if s is zero then just use sPrev cross n
if (vtkMath.normalize(s) === 0.0) {
vtkMath.cross(sPrev, n, s);
Expand Down Expand Up @@ -293,14 +284,12 @@ function vtkTubeFilter(publicAPI, model) {
// create points around line
if (model.sidesShareVertices) {
for (let k = 0; k < model.numberOfSides; ++k) {
console.log(`Point ${ptId}`);
for (let i = 0; i < 3; ++i) {
normal[i] = (w[i] * Math.cos(k * theta)) + (nP[i] * Math.sin(k * theta));
s[i] = p[i] + (model.radius * sFactor * normal[i]);
newPts[(3 * ptId) + i] = s[i];
newNormals[(3 * ptId) + i] = normal[i];
}
console.log(`${s}`);
outPD.passData(pd, pts[j], ptId);
ptId++;
} // for each side
Expand Down Expand Up @@ -330,7 +319,6 @@ function vtkTubeFilter(publicAPI, model) {
} // else separate vertices
} // for all points in the polyline

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

// the end cap
let endOffset = offset + ((npts - 1) * model.numberOfSides);
Expand All @@ -364,7 +350,6 @@ function vtkTubeFilter(publicAPI, model) {
newPts[(3 * ptId) + i] = s[i];
newNormals[(3 * ptId) + i] = endCapNorm[i];
}
console.log(`end cap Id: ${ptId} : ${endCapNorm}`);
outPD.passData(pd, pts[npts - 1], ptId);
ptId++;
}
Expand Down Expand Up @@ -578,7 +563,10 @@ function vtkTubeFilter(publicAPI, model) {
return;
}

const numNewPts = numPts * model.numberOfSides;
let numNewPts = numPts * model.numberOfSides;
if (model.capping) {
numNewPts = (numPts + 2) * model.numberOfSides;
}
let pointType = inPts.getDataType();
if (model.outputPointsPrecision === VtkPointPrecision.SINGLE) {
pointType = VtkDataTypes.FLOAT;
Expand All @@ -587,7 +575,6 @@ function vtkTubeFilter(publicAPI, model) {
}
const newPts = vtkPoints.newInstance(
{ dataType: pointType, size: (numNewPts * 3), numberOfComponents: 3 });
// const newPtsData = newPts.getData();
let numNormals = 3 * numNewPts;
if (model.capping) {
numNormals = 3 * (numNewPts + (2 * model.numberOfSides));
Expand Down Expand Up @@ -633,7 +620,6 @@ function vtkTubeFilter(publicAPI, model) {
maxSpeed = inVectors.getMaxNorm();
}

// const numNewCells = (numLines * model.numberOfSides) + 2;
const outCD = output.getCellData();
outCD.copyNormalsOff();
outCD.passData(input.getCellData());
Expand Down Expand Up @@ -696,8 +682,6 @@ function vtkTubeFilter(publicAPI, model) {
output.setStrips(newStrips);
output.setPointData(outPD);
outPD.setNormals(newNormals);
const s = JSON.stringify(output.getState());
console.log(`${s}`);
outData[0] = output;
};
}
Expand Down

0 comments on commit f13ca5a

Please sign in to comment.