Skip to content

Commit 1306292

Browse files
committed
feat(Rendering): report missing view node profile imports
fixes #3343
1 parent 9d00695 commit 1306292

File tree

4 files changed

+132
-1
lines changed

4 files changed

+132
-1
lines changed
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { registerProfileHints } from 'vtk.js/Sources/Rendering/SceneGraph/ViewNodeFactory/profileHints';
2+
3+
registerProfileHints(
4+
[
5+
'vtkActor',
6+
'vtkActor2D',
7+
'vtkCamera',
8+
'vtkCubeAxesActor',
9+
'vtkMapper',
10+
'vtkMapper2D',
11+
'vtkPixelSpaceCallbackMapper',
12+
'vtkRenderWindow',
13+
'vtkRenderer',
14+
'vtkScalarBarActor',
15+
'vtkSkybox',
16+
'vtkTexture',
17+
],
18+
'Geometry'
19+
);
20+
21+
registerProfileHints(
22+
[
23+
'vtkAbstractImageMapper',
24+
'vtkImageCPRMapper',
25+
'vtkImageMapper',
26+
'vtkImageResliceMapper',
27+
'vtkImageSlice',
28+
'vtkVolume',
29+
'vtkVolumeMapper',
30+
],
31+
'Volume'
32+
);
33+
34+
registerProfileHints(['vtkGlyph3DMapper'], 'Glyph');
35+
registerProfileHints(['vtkSphereMapper', 'vtkStickMapper'], 'Molecule');
36+
registerProfileHints(['vtkSurfaceLICMapper'], 'LIC');

Sources/Rendering/SceneGraph/ViewNodeFactory/index.js

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,46 @@
11
import macro from 'vtk.js/Sources/macros';
2+
import { getProfileForClass, getSuggestedProfile } from './profileHints';
3+
import 'vtk.js/Sources/Rendering/OpenGL/Profiles/profileHintManifest';
4+
import 'vtk.js/Sources/Rendering/WebGPU/Profiles/profileHintManifest';
5+
6+
const { vtkOnceErrorMacro } = macro;
7+
8+
function listClassHierarchy(dataObject) {
9+
const classNames = [];
10+
let depth = 0;
11+
let className = dataObject.getClassName(depth++);
12+
while (className) {
13+
classNames.push(className);
14+
className = dataObject.getClassName(depth++);
15+
}
16+
return classNames;
17+
}
18+
19+
function buildMissingImplementationMessage(factoryName, classNames) {
20+
const classList = classNames.join(' → ');
21+
const suggestedClass = getSuggestedProfile(classNames);
22+
const suggestedProfile =
23+
suggestedClass && getProfileForClass(suggestedClass);
24+
25+
if (suggestedProfile) {
26+
return [
27+
`No ${factoryName} implementation found for ${classNames[0]}.`,
28+
`Class hierarchy: ${classList}.`,
29+
'This usually means the rendering profile import is missing.',
30+
`Try importing '@kitware/vtk.js/Rendering/Profiles/${suggestedProfile}' or 'vtk.js/Sources/Rendering/Profiles/${suggestedProfile}'.`,
31+
"You can also use the full profile imports '@kitware/vtk.js/Rendering/Profiles/All' or 'vtk.js/Sources/Rendering/Profiles/All'.",
32+
].join('\n');
33+
}
34+
35+
return [
36+
`No ${factoryName} implementation found for ${classNames[0]}.`,
37+
`Class hierarchy: ${classList}.`,
38+
'If this is a built-in renderable, a rendering profile import may be missing.',
39+
"Try importing '@kitware/vtk.js/Rendering/Profiles/All' or 'vtk.js/Sources/Rendering/Profiles/All',",
40+
'or import the specific rendering profile needed by this renderable.',
41+
'If this is a custom renderable, register a matching override with the view node factory.',
42+
].join('\n');
43+
}
244

345
// ----------------------------------------------------------------------------
446
// vtkViewNodeFactory methods
@@ -18,8 +60,9 @@ function vtkViewNodeFactory(publicAPI, model) {
1860
return null;
1961
}
2062

63+
const classNames = listClassHierarchy(dataObject);
2164
let cpt = 0;
22-
let className = dataObject.getClassName(cpt++);
65+
let className = classNames[cpt++];
2366
let isObject = false;
2467
const keys = Object.keys(model.overrides);
2568
while (className && !isObject) {
@@ -31,6 +74,9 @@ function vtkViewNodeFactory(publicAPI, model) {
3174
}
3275

3376
if (!isObject) {
77+
vtkOnceErrorMacro(
78+
buildMissingImplementationMessage(publicAPI.getClassName(), classNames)
79+
);
3480
return null;
3581
}
3682
const vn = model.overrides[className]();
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const PROFILE_HINTS = Object.create(null);
2+
3+
export function registerProfileHint(className, profile) {
4+
PROFILE_HINTS[className] = profile;
5+
}
6+
7+
export function registerProfileHints(classNames, profile) {
8+
classNames.forEach((className) => {
9+
registerProfileHint(className, profile);
10+
});
11+
}
12+
13+
export function getSuggestedProfile(classNames) {
14+
return classNames.find((className) => PROFILE_HINTS[className]);
15+
}
16+
17+
export function getProfileForClass(className) {
18+
return PROFILE_HINTS[className];
19+
}
20+
21+
export default {
22+
registerProfileHint,
23+
registerProfileHints,
24+
getSuggestedProfile,
25+
getProfileForClass,
26+
};
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { registerProfileHints } from 'vtk.js/Sources/Rendering/SceneGraph/ViewNodeFactory/profileHints';
2+
3+
registerProfileHints(
4+
[
5+
'vtkActor',
6+
'vtkActor2D',
7+
'vtkCamera',
8+
'vtkCubeAxesActor',
9+
'vtkMapper',
10+
'vtkMapper2D',
11+
'vtkPixelSpaceCallbackMapper',
12+
'vtkRenderWindow',
13+
'vtkRenderer',
14+
'vtkScalarBarActor',
15+
'vtkTexture',
16+
],
17+
'Geometry'
18+
);
19+
20+
registerProfileHints(['vtkImageMapper', 'vtkImageSlice', 'vtkVolume'], 'Volume');
21+
registerProfileHints(['vtkGlyph3DMapper'], 'Glyph');
22+
registerProfileHints(['vtkSphereMapper', 'vtkStickMapper'], 'Molecule');
23+
registerProfileHints(['vtkSurfaceLICMapper'], 'LIC');

0 commit comments

Comments
 (0)