Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import test from 'tape';
import testUtils from 'vtk.js/Sources/Testing/testUtils';

import 'vtk.js/Sources/Rendering/Misc/RenderingAPIs';
import vtkActor from 'vtk.js/Sources/Rendering/Core/Actor';
import vtkCellArray from 'vtk.js/Sources/Common/Core/CellArray';
import vtkGlyph3DMapper from 'vtk.js/Sources/Rendering/Core/Glyph3DMapper';
import vtkPolyData from 'vtk.js/Sources/Common/DataModel/PolyData';
import vtkRenderWindow from 'vtk.js/Sources/Rendering/Core/RenderWindow';
import vtkRenderer from 'vtk.js/Sources/Rendering/Core/Renderer';

function makePolyDataFromPoints(coords) {
const polyData = vtkPolyData.newInstance();
polyData.getPoints().setData(Float32Array.from(coords), 3);
return polyData;
}

function updatePoints(polyData, coords) {
polyData.getPoints().setData(Float32Array.from(coords), 3);
polyData.getPoints().modified();
polyData.modified();
}

function makeLineGlyphSource() {
const source = makePolyDataFromPoints([-0.5, 0, 0, 0.5, 0, 0]);
source.setLines(
vtkCellArray.newInstance({
values: new Uint32Array([2, 0, 1]),
})
);
return source;
}

function getActivePrimitiveCABOs(openGLRenderWindow, mapper) {
const openGLMapper = openGLRenderWindow.getViewNodeFor(mapper);
const primitives = openGLMapper.getReferenceByName('primitives');
return primitives
.map((primitive) => primitive.getCABO())
.filter((cabo) => cabo.getElementCount() > 0);
}

test.onlyIfWebGL(
'Test vtkGlyph3DMapper clears source VBO shift/scale after shifted glyph centers',
(t) => {
const gc = testUtils.createGarbageCollector(t);

const container = document.querySelector('body');
const renderWindowContainer = gc.registerDOMElement(
document.createElement('div')
);
container.appendChild(renderWindowContainer);

const renderWindow = gc.registerResource(vtkRenderWindow.newInstance());
const renderer = gc.registerResource(vtkRenderer.newInstance());
renderWindow.addRenderer(renderer);

const centers = gc.registerResource(
makePolyDataFromPoints([10000000, 0, 0, 10000001, 0, 0])
);
const source = gc.registerResource(makeLineGlyphSource());
const mapper = gc.registerResource(vtkGlyph3DMapper.newInstance());
const actor = gc.registerResource(vtkActor.newInstance());

mapper.setInputData(centers, 0);
mapper.setInputData(source, 1);
mapper.setScalarVisibility(false);

actor.setMapper(mapper);
renderer.addActor(actor);

const openGLRenderWindow = gc.registerResource(
renderWindow.newAPISpecificView()
);
openGLRenderWindow.setContainer(renderWindowContainer);
renderWindow.addView(openGLRenderWindow);
openGLRenderWindow.setSize(1, 1);

renderWindow.render();

const shiftedCABOs = getActivePrimitiveCABOs(openGLRenderWindow, mapper);
t.ok(shiftedCABOs.length > 0, 'glyph source VBOs were built');
t.ok(
shiftedCABOs.some((cabo) => cabo.getCoordShiftAndScaleEnabled()),
'far glyph centers enable shift/scale on source VBOs'
);

updatePoints(centers, [-0.5, 0, 0, 0.5, 0, 0]);
renderWindow.render();

const unshiftedCABOs = getActivePrimitiveCABOs(openGLRenderWindow, mapper);
t.ok(
unshiftedCABOs.every((cabo) => !cabo.getCoordShiftAndScaleEnabled()),
'source VBO shift/scale is cleared once glyph centers no longer use it'
);

gc.releaseResources();
}
);
18 changes: 10 additions & 8 deletions Sources/Rendering/OpenGL/Glyph3DMapper/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -754,14 +754,16 @@ function vtkOpenGLGlyph3DMapper(publicAPI, model) {

superClass.buildBufferObjects(ren, actor);

// apply shift + scale to primitives AFTER vtkOpenGLPolyDataMapper.buildBufferObjects
// so that the Glyph3DMapper gets the last say in the shift + scale
if (useShiftAndScale) {
for (let i = primTypes.Start; i < primTypes.End; i++) {
model.primitives[i]
.getCABO()
.setCoordShiftAndScale(coordShift, coordScale);
}
// Apply shift + scale to primitives AFTER vtkOpenGLPolyDataMapper.buildBufferObjects
// so that the Glyph3DMapper gets the last say in the shift + scale. Clear
// the previous frame's transform when the current glyph centers no longer
// need it; otherwise glyphs keep rendering with stale source-VBO scaling.
const sourceCoordShift = useShiftAndScale ? coordShift : null;
const sourceCoordScale = useShiftAndScale ? coordScale : null;
for (let i = primTypes.Start; i < primTypes.End; i++) {
model.primitives[i]
.getCABO()
.setCoordShiftAndScale(sourceCoordShift, sourceCoordScale);
}
};
}
Expand Down
Loading