Skip to content

Commit 017f450

Browse files
finetjulfloryst
authored andcommitted
docs(polydatanormals): add example for vtkPolyDataNormals
There is a rendering crash when no point nor cell normals are available
1 parent 602c9e8 commit 017f450

File tree

5 files changed

+145
-3
lines changed

5 files changed

+145
-3
lines changed
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<table>
2+
<tr>
3+
<td>Compute point normals</td>
4+
<td>
5+
<input class="computePointNormals" type="checkbox" checked />
6+
</td>
7+
</tr>
8+
<tr>
9+
<td>Compute cell normals</td>
10+
<td>
11+
<input class="computeCellNormals" type="checkbox" />
12+
</td>
13+
</tr>
14+
</table>
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import '@kitware/vtk.js/favicon';
2+
3+
// Load the rendering pieces we want to use (for both WebGL and WebGPU)
4+
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
5+
import '@kitware/vtk.js/Rendering/Profiles/Glyph';
6+
7+
import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';
8+
9+
import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
10+
import vtkArrowSource from '@kitware/vtk.js/Filters/Sources/ArrowSource';
11+
import vtkCubeSource from '@kitware/vtk.js/Filters/Sources/CubeSource';
12+
import vtkLookupTable from '@kitware/vtk.js/Common/Core/LookupTable';
13+
import vtkGlyph3DMapper from '@kitware/vtk.js/Rendering/Core/Glyph3DMapper';
14+
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
15+
import vtkPolyDataNormals from '@kitware/vtk.js/Filters/Core/PolyDataNormals';
16+
17+
import controlPanel from './controlPanel.html';
18+
19+
const { ColorMode, ScalarMode } = vtkMapper;
20+
21+
// ----------------------------------------------------------------------------
22+
// Standard rendering code setup
23+
// ----------------------------------------------------------------------------
24+
25+
const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
26+
background: [0.9, 0.9, 0.9],
27+
});
28+
const renderer = fullScreenRenderer.getRenderer();
29+
const renderWindow = fullScreenRenderer.getRenderWindow();
30+
31+
// ----------------------------------------------------------------------------
32+
// Example code
33+
// ----------------------------------------------------------------------------
34+
35+
const lookupTable = vtkLookupTable.newInstance({ hueRange: [0.666, 0] });
36+
37+
const source = vtkCubeSource.newInstance();
38+
const inputPolyData = source.getOutputData();
39+
inputPolyData.getPointData().setNormals(null);
40+
41+
const mapper = vtkMapper.newInstance({
42+
interpolateScalarsBeforeMapping: true,
43+
colorMode: ColorMode.DEFAULT,
44+
scalarMode: ScalarMode.DEFAULT,
45+
useLookupTableScalarRange: true,
46+
lookupTable,
47+
});
48+
const actor = vtkActor.newInstance();
49+
actor.getProperty().setEdgeVisibility(true);
50+
51+
const polyDataNormals = vtkPolyDataNormals.newInstance();
52+
53+
// The generated 'z' array will become the default scalars, so the plane mapper will color by 'z':
54+
polyDataNormals.setInputData(inputPolyData);
55+
56+
mapper.setInputConnection(polyDataNormals.getOutputPort());
57+
actor.setMapper(mapper);
58+
59+
renderer.addActor(actor);
60+
61+
const arrowSource = vtkArrowSource.newInstance();
62+
63+
const glyphMapper = vtkGlyph3DMapper.newInstance();
64+
glyphMapper.setInputConnection(polyDataNormals.getOutputPort());
65+
glyphMapper.setSourceConnection(arrowSource.getOutputPort());
66+
glyphMapper.setOrientationModeToDirection();
67+
glyphMapper.setOrientationArray('Normals');
68+
glyphMapper.setScaleModeToScaleByMagnitude();
69+
glyphMapper.setScaleArray('Normals');
70+
glyphMapper.setScaleFactor(0.1);
71+
72+
const glyphActor = vtkActor.newInstance();
73+
glyphActor.setMapper(glyphMapper);
74+
renderer.addActor(glyphActor);
75+
76+
renderer.resetCamera();
77+
renderWindow.render();
78+
79+
// ----------------------------------------------------------------------------
80+
// UI control handling
81+
// ----------------------------------------------------------------------------
82+
83+
fullScreenRenderer.addController(controlPanel);
84+
85+
// Checkbox
86+
document
87+
.querySelector('.computePointNormals')
88+
.addEventListener('change', (e) => {
89+
polyDataNormals.setComputePointNormals(!!e.target.checked);
90+
renderWindow.render();
91+
});
92+
93+
document
94+
.querySelector('.computeCellNormals')
95+
.addEventListener('change', (e) => {
96+
polyDataNormals.setComputeCellNormals(!!e.target.checked);
97+
renderWindow.render();
98+
});
99+
100+
// -----------------------------------------------------------
101+
// Make some variables global so that you can inspect and
102+
// modify objects in your browser's developer console:
103+
// -----------------------------------------------------------
104+
105+
global.mapper = mapper;
106+
global.actor = actor;
107+
global.source = source;
108+
global.renderer = renderer;
109+
global.renderWindow = renderWindow;
110+
global.lookupTable = lookupTable;
111+
global.polyDataNormals = polyDataNormals;
112+
global.glyphMapper = glyphMapper;

Sources/Filters/Core/PolyDataNormals/test/testPolyDataNormals.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ test('Test vtkPolyDataNormals passData', (t) => {
2929
t.end();
3030
});
3131

32-
test.only('Test vtkPolyDataNormals normals', (t) => {
32+
test('Test vtkPolyDataNormals normals', (t) => {
3333
const cube = vtkCubeSource.newInstance();
3434
const input = cube.getOutputData();
3535
const pointNormalsData = input.getPointData().getNormals().getData();

Sources/Rendering/Core/Glyph3DMapper/index.d.ts

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Bounds } from "../../../types";
1+
import { Bounds, Nullable, vtkPipelineConnection } from "../../../types";
22
import vtkMapper, { IMapperInitialValues } from "../Mapper";
33
import { OrientationModes, ScaleModes } from "./Constants";
44

@@ -87,6 +87,12 @@ export interface vtkGlyph3DMapper extends vtkMapper {
8787
*/
8888
getPrimitiveCount(): IPrimitiveCount;
8989

90+
/**
91+
* Sets the name of the array to use as orientation.
92+
* @param {String} arrayName Name of the array
93+
*/
94+
setOrientationArray(arrayName: Nullable<string>): boolean;
95+
9096
/**
9197
* Orientation mode indicates if the OrientationArray provides the direction
9298
* vector for the orientation or the rotations around each axes.
@@ -138,6 +144,13 @@ export interface vtkGlyph3DMapper extends vtkMapper {
138144
* Set scale to `SCALE_BY_CONSTANT`
139145
*/
140146
setScaleModeToScaleByConstant(): boolean;
147+
148+
/**
149+
* Convenient method to set the source glyph connection
150+
* @param {vtkPipelineConnection} outputPort The output port of the glyph source.
151+
*/
152+
setSourceConnection(outputPort: vtkPipelineConnection): void;
153+
141154
}
142155

143156
/**

Sources/Rendering/Core/Glyph3DMapper/index.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ function vtkGlyph3DMapper(publicAPI, model) {
134134
model.normalArray = new Float32Array(9 * numPts);
135135
const nbuff = model.normalArray.buffer;
136136
const tuple = [];
137+
const orientation = [];
137138
for (let i = 0; i < numPts; ++i) {
138139
const z = new Float32Array(mbuff, i * 64, 16);
139140
trans[0] = pts[i * 3];
@@ -142,7 +143,6 @@ function vtkGlyph3DMapper(publicAPI, model) {
142143
mat4.translate(z, identity, trans);
143144

144145
if (oArray) {
145-
const orientation = [];
146146
oArray.getTuple(i, orientation);
147147
switch (model.orientationMode) {
148148
case OrientationModes.MATRIX: {
@@ -299,6 +299,9 @@ function vtkGlyph3DMapper(publicAPI, model) {
299299
};
300300
return pcount;
301301
};
302+
303+
publicAPI.setSourceConnection = (outputPort) =>
304+
publicAPI.setInputConnection(outputPort, 1);
302305
}
303306

304307
// ----------------------------------------------------------------------------

0 commit comments

Comments
 (0)