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
36 changes: 36 additions & 0 deletions Sources/Rendering/OpenGL/Profiles/profileHintManifest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { registerProfileHints } from 'vtk.js/Sources/Rendering/SceneGraph/ViewNodeFactory/profileHints';

registerProfileHints(
[
'vtkActor',
'vtkActor2D',
'vtkCamera',
'vtkCubeAxesActor',
'vtkMapper',
'vtkMapper2D',
'vtkPixelSpaceCallbackMapper',
'vtkRenderWindow',
'vtkRenderer',
'vtkScalarBarActor',
'vtkSkybox',
'vtkTexture',
],
'Geometry'
);

registerProfileHints(
[
'vtkAbstractImageMapper',
'vtkImageCPRMapper',
'vtkImageMapper',
'vtkImageResliceMapper',
'vtkImageSlice',
'vtkVolume',
'vtkVolumeMapper',
],
'Volume'
);

registerProfileHints(['vtkGlyph3DMapper'], 'Glyph');
registerProfileHints(['vtkSphereMapper', 'vtkStickMapper'], 'Molecule');
registerProfileHints(['vtkSurfaceLICMapper'], 'LIC');
47 changes: 46 additions & 1 deletion Sources/Rendering/SceneGraph/ViewNodeFactory/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,45 @@
import macro from 'vtk.js/Sources/macros';
import { getProfileForClass, getSuggestedProfile } from './profileHints';
import 'vtk.js/Sources/Rendering/OpenGL/Profiles/profileHintManifest';
import 'vtk.js/Sources/Rendering/WebGPU/Profiles/profileHintManifest';

const { vtkOnceErrorMacro } = macro;

function listClassHierarchy(dataObject) {
const classNames = [];
let depth = 0;
let className = dataObject.getClassName(depth++);
while (className) {
classNames.push(className);
className = dataObject.getClassName(depth++);
}
return classNames;
}

function buildMissingImplementationMessage(factoryName, classNames) {
const classList = classNames.join(' → ');
const suggestedClass = getSuggestedProfile(classNames);
const suggestedProfile = suggestedClass && getProfileForClass(suggestedClass);

if (suggestedProfile) {
return [
`No ${factoryName} implementation found for ${classNames[0]}.`,
`Class hierarchy: ${classList}.`,
'This usually means the rendering profile import is missing.',
`Try importing '@kitware/vtk.js/Rendering/Profiles/${suggestedProfile}' or 'vtk.js/Sources/Rendering/Profiles/${suggestedProfile}'.`,
"You can also use the full profile imports '@kitware/vtk.js/Rendering/Profiles/All' or 'vtk.js/Sources/Rendering/Profiles/All'.",
].join('\n');
}

return [
`No ${factoryName} implementation found for ${classNames[0]}.`,
`Class hierarchy: ${classList}.`,
'If this is a built-in renderable, a rendering profile import may be missing.',
"Try importing '@kitware/vtk.js/Rendering/Profiles/All' or 'vtk.js/Sources/Rendering/Profiles/All',",
'or import the specific rendering profile needed by this renderable.',
'If this is a custom renderable, register a matching override with the view node factory.',
].join('\n');
}

// ----------------------------------------------------------------------------
// vtkViewNodeFactory methods
Expand All @@ -18,8 +59,9 @@ function vtkViewNodeFactory(publicAPI, model) {
return null;
}

const classNames = listClassHierarchy(dataObject);
let cpt = 0;
let className = dataObject.getClassName(cpt++);
let className = classNames[cpt++];
let isObject = false;
const keys = Object.keys(model.overrides);
while (className && !isObject) {
Expand All @@ -31,6 +73,9 @@ function vtkViewNodeFactory(publicAPI, model) {
}

if (!isObject) {
vtkOnceErrorMacro(
buildMissingImplementationMessage(publicAPI.getClassName(), classNames)
);
return null;
}
const vn = model.overrides[className]();
Expand Down
26 changes: 26 additions & 0 deletions Sources/Rendering/SceneGraph/ViewNodeFactory/profileHints.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const PROFILE_HINTS = Object.create(null);

export function registerProfileHint(className, profile) {
PROFILE_HINTS[className] = profile;
}

export function registerProfileHints(classNames, profile) {
classNames.forEach((className) => {
registerProfileHint(className, profile);
});
}

export function getSuggestedProfile(classNames) {
return classNames.find((className) => PROFILE_HINTS[className]);
}

export function getProfileForClass(className) {
return PROFILE_HINTS[className];
}

export default {
registerProfileHint,
registerProfileHints,
getSuggestedProfile,
getProfileForClass,
};
26 changes: 26 additions & 0 deletions Sources/Rendering/WebGPU/Profiles/profileHintManifest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { registerProfileHints } from 'vtk.js/Sources/Rendering/SceneGraph/ViewNodeFactory/profileHints';

registerProfileHints(
[
'vtkActor',
'vtkActor2D',
'vtkCamera',
'vtkCubeAxesActor',
'vtkMapper',
'vtkMapper2D',
'vtkPixelSpaceCallbackMapper',
'vtkRenderWindow',
'vtkRenderer',
'vtkScalarBarActor',
'vtkTexture',
],
'Geometry'
);

registerProfileHints(
['vtkImageMapper', 'vtkImageSlice', 'vtkVolume'],
'Volume'
);
registerProfileHints(['vtkGlyph3DMapper'], 'Glyph');
registerProfileHints(['vtkSphereMapper', 'vtkStickMapper'], 'Molecule');
registerProfileHints(['vtkSurfaceLICMapper'], 'LIC');
Loading