Skip to content

Commit

Permalink
docs(polydatanormals): add example for vtkPolyDataNormals
Browse files Browse the repository at this point in the history
There is a rendering crash when no point nor cell normals are available
  • Loading branch information
finetjul authored and floryst committed Sep 20, 2023
1 parent 602c9e8 commit 017f450
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 3 deletions.
14 changes: 14 additions & 0 deletions Sources/Filters/Core/PolyDataNormals/example/controlPanel.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<table>
<tr>
<td>Compute point normals</td>
<td>
<input class="computePointNormals" type="checkbox" checked />
</td>
</tr>
<tr>
<td>Compute cell normals</td>
<td>
<input class="computeCellNormals" type="checkbox" />
</td>
</tr>
</table>
112 changes: 112 additions & 0 deletions Sources/Filters/Core/PolyDataNormals/example/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import '@kitware/vtk.js/favicon';

// Load the rendering pieces we want to use (for both WebGL and WebGPU)
import '@kitware/vtk.js/Rendering/Profiles/Geometry';
import '@kitware/vtk.js/Rendering/Profiles/Glyph';

import vtkFullScreenRenderWindow from '@kitware/vtk.js/Rendering/Misc/FullScreenRenderWindow';

import vtkActor from '@kitware/vtk.js/Rendering/Core/Actor';
import vtkArrowSource from '@kitware/vtk.js/Filters/Sources/ArrowSource';
import vtkCubeSource from '@kitware/vtk.js/Filters/Sources/CubeSource';
import vtkLookupTable from '@kitware/vtk.js/Common/Core/LookupTable';
import vtkGlyph3DMapper from '@kitware/vtk.js/Rendering/Core/Glyph3DMapper';
import vtkMapper from '@kitware/vtk.js/Rendering/Core/Mapper';
import vtkPolyDataNormals from '@kitware/vtk.js/Filters/Core/PolyDataNormals';

import controlPanel from './controlPanel.html';

const { ColorMode, ScalarMode } = vtkMapper;

// ----------------------------------------------------------------------------
// Standard rendering code setup
// ----------------------------------------------------------------------------

const fullScreenRenderer = vtkFullScreenRenderWindow.newInstance({
background: [0.9, 0.9, 0.9],
});
const renderer = fullScreenRenderer.getRenderer();
const renderWindow = fullScreenRenderer.getRenderWindow();

// ----------------------------------------------------------------------------
// Example code
// ----------------------------------------------------------------------------

const lookupTable = vtkLookupTable.newInstance({ hueRange: [0.666, 0] });

const source = vtkCubeSource.newInstance();
const inputPolyData = source.getOutputData();
inputPolyData.getPointData().setNormals(null);

const mapper = vtkMapper.newInstance({
interpolateScalarsBeforeMapping: true,
colorMode: ColorMode.DEFAULT,
scalarMode: ScalarMode.DEFAULT,
useLookupTableScalarRange: true,
lookupTable,
});
const actor = vtkActor.newInstance();
actor.getProperty().setEdgeVisibility(true);

const polyDataNormals = vtkPolyDataNormals.newInstance();

// The generated 'z' array will become the default scalars, so the plane mapper will color by 'z':
polyDataNormals.setInputData(inputPolyData);

mapper.setInputConnection(polyDataNormals.getOutputPort());
actor.setMapper(mapper);

renderer.addActor(actor);

const arrowSource = vtkArrowSource.newInstance();

const glyphMapper = vtkGlyph3DMapper.newInstance();
glyphMapper.setInputConnection(polyDataNormals.getOutputPort());
glyphMapper.setSourceConnection(arrowSource.getOutputPort());
glyphMapper.setOrientationModeToDirection();
glyphMapper.setOrientationArray('Normals');
glyphMapper.setScaleModeToScaleByMagnitude();
glyphMapper.setScaleArray('Normals');
glyphMapper.setScaleFactor(0.1);

const glyphActor = vtkActor.newInstance();
glyphActor.setMapper(glyphMapper);
renderer.addActor(glyphActor);

renderer.resetCamera();
renderWindow.render();

// ----------------------------------------------------------------------------
// UI control handling
// ----------------------------------------------------------------------------

fullScreenRenderer.addController(controlPanel);

// Checkbox
document
.querySelector('.computePointNormals')
.addEventListener('change', (e) => {
polyDataNormals.setComputePointNormals(!!e.target.checked);
renderWindow.render();
});

document
.querySelector('.computeCellNormals')
.addEventListener('change', (e) => {
polyDataNormals.setComputeCellNormals(!!e.target.checked);
renderWindow.render();
});

// -----------------------------------------------------------
// Make some variables global so that you can inspect and
// modify objects in your browser's developer console:
// -----------------------------------------------------------

global.mapper = mapper;
global.actor = actor;
global.source = source;
global.renderer = renderer;
global.renderWindow = renderWindow;
global.lookupTable = lookupTable;
global.polyDataNormals = polyDataNormals;
global.glyphMapper = glyphMapper;
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ test('Test vtkPolyDataNormals passData', (t) => {
t.end();
});

test.only('Test vtkPolyDataNormals normals', (t) => {
test('Test vtkPolyDataNormals normals', (t) => {
const cube = vtkCubeSource.newInstance();
const input = cube.getOutputData();
const pointNormalsData = input.getPointData().getNormals().getData();
Expand Down
15 changes: 14 additions & 1 deletion Sources/Rendering/Core/Glyph3DMapper/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Bounds } from "../../../types";
import { Bounds, Nullable, vtkPipelineConnection } from "../../../types";
import vtkMapper, { IMapperInitialValues } from "../Mapper";
import { OrientationModes, ScaleModes } from "./Constants";

Expand Down Expand Up @@ -87,6 +87,12 @@ export interface vtkGlyph3DMapper extends vtkMapper {
*/
getPrimitiveCount(): IPrimitiveCount;

/**
* Sets the name of the array to use as orientation.
* @param {String} arrayName Name of the array
*/
setOrientationArray(arrayName: Nullable<string>): boolean;

/**
* Orientation mode indicates if the OrientationArray provides the direction
* vector for the orientation or the rotations around each axes.
Expand Down Expand Up @@ -138,6 +144,13 @@ export interface vtkGlyph3DMapper extends vtkMapper {
* Set scale to `SCALE_BY_CONSTANT`
*/
setScaleModeToScaleByConstant(): boolean;

/**
* Convenient method to set the source glyph connection
* @param {vtkPipelineConnection} outputPort The output port of the glyph source.
*/
setSourceConnection(outputPort: vtkPipelineConnection): void;

}

/**
Expand Down
5 changes: 4 additions & 1 deletion Sources/Rendering/Core/Glyph3DMapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ function vtkGlyph3DMapper(publicAPI, model) {
model.normalArray = new Float32Array(9 * numPts);
const nbuff = model.normalArray.buffer;
const tuple = [];
const orientation = [];
for (let i = 0; i < numPts; ++i) {
const z = new Float32Array(mbuff, i * 64, 16);
trans[0] = pts[i * 3];
Expand All @@ -142,7 +143,6 @@ function vtkGlyph3DMapper(publicAPI, model) {
mat4.translate(z, identity, trans);

if (oArray) {
const orientation = [];
oArray.getTuple(i, orientation);
switch (model.orientationMode) {
case OrientationModes.MATRIX: {
Expand Down Expand Up @@ -299,6 +299,9 @@ function vtkGlyph3DMapper(publicAPI, model) {
};
return pcount;
};

publicAPI.setSourceConnection = (outputPort) =>
publicAPI.setInputConnection(outputPort, 1);
}

// ----------------------------------------------------------------------------
Expand Down

0 comments on commit 017f450

Please sign in to comment.