@geode/opengeodeweb-front 10.34.0-rc.8 → 10.34.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{server → .build/server}/utils/app_config.js +10 -9
- package/{server → .build/server}/utils/cleanup.js +31 -17
- package/{server → .build/server}/utils/cloud.js +1 -4
- package/{server → .build/server}/utils/microservices.js +21 -9
- package/{server → .build/server}/utils/path.js +4 -4
- package/{server → .build/server}/utils/scripts.js +9 -9
- package/.build/server/utils/server_config.js +51 -0
- package/.build/server/utils/stream.js +6 -0
- package/{server → .build/server}/utils/ws_client.js +18 -3
- package/{shared → .build/shared}/scripts.js +10 -10
- package/.build/shared/utils/call_raw.js +31 -0
- package/{shared → .build/shared}/utils/call_schema.js +2 -2
- package/.build/shared/utils/fetch_raw.js +52 -0
- package/{shared → .build/shared}/utils/fetch_schema.js +2 -2
- package/{shared → .build/shared}/utils/file.js +3 -1
- package/{shared → .build/shared}/utils/response_handlers/load.js +10 -7
- package/{shared → .build/shared}/utils/validate_schema.js +1 -1
- package/app/components/ActionButton.vue +6 -6
- package/app/components/CameraManager/List.vue +5 -5
- package/app/components/CameraManager/Saver.vue +3 -5
- package/app/components/CameraManager.vue +6 -4
- package/app/components/CameraOrientation.vue +12 -12
- package/app/components/ClippingPlaneCard.vue +4 -2
- package/app/components/ClippingPlanes.vue +8 -8
- package/app/components/CrsSelector.vue +9 -10
- package/app/components/DeleteDialog.vue +4 -2
- package/app/components/DragAndDrop.vue +10 -12
- package/app/components/DragAndDropInternal/DragAndDropInline.vue +4 -2
- package/app/components/ExtensionSelector.vue +4 -4
- package/app/components/FeedBack/ErrorBanner.vue +3 -1
- package/app/components/FeedBack/Snackers.vue +4 -3
- package/app/components/FileSelector.vue +10 -8
- package/app/components/FileUploader.vue +11 -11
- package/app/components/GlassCard.vue +1 -1
- package/app/components/HybridRenderingView.vue +7 -5
- package/app/components/HybridViewerTooltip.vue +7 -7
- package/app/components/Launcher.vue +1 -1
- package/app/components/Loading/EcoMessages.vue +9 -3
- package/app/components/Loading.vue +2 -2
- package/app/components/MissingFilesSelector.vue +12 -10
- package/app/components/ObjectSelector.vue +10 -9
- package/app/components/PackagesVersions.vue +6 -5
- package/app/components/Recaptcha.vue +3 -3
- package/app/components/RemoteRenderingView.vue +6 -7
- package/app/components/Ruler.vue +3 -3
- package/app/components/Screenshot.vue +6 -6
- package/app/components/SearchBar.vue +4 -2
- package/app/components/ShrinkFilter.vue +7 -7
- package/app/components/Step.vue +6 -5
- package/app/components/Stepper.vue +4 -3
- package/app/components/ToolPanel.vue +6 -3
- package/app/components/ViewToolbar.vue +25 -28
- package/app/components/Viewer/ContextMenu/CenterButton.vue +7 -5
- package/app/components/Viewer/ContextMenu/CircularItems.vue +3 -3
- package/app/components/Viewer/ContextMenu/ContextMenu.vue +22 -19
- package/app/components/Viewer/ContextMenu/ContextMenuItem.vue +10 -8
- package/app/components/Viewer/ContextMenu/InfoCard.vue +11 -12
- package/app/components/Viewer/EdgedCurve/SpecificEdgesOptions.vue +13 -17
- package/app/components/Viewer/Generic/Mesh/CellsOptions.vue +11 -15
- package/app/components/Viewer/Generic/Mesh/EdgesOptions.vue +12 -16
- package/app/components/Viewer/Generic/Mesh/PointsOptions.vue +8 -12
- package/app/components/Viewer/Generic/Mesh/PolygonsOptions.vue +11 -15
- package/app/components/Viewer/Generic/Mesh/PolyhedraOptions.vue +11 -15
- package/app/components/Viewer/Generic/Model/BlocksOptions.vue +67 -38
- package/app/components/Viewer/Generic/Model/CornersOptions.vue +53 -23
- package/app/components/Viewer/Generic/Model/EdgesOptions.vue +1 -3
- package/app/components/Viewer/Generic/Model/LinesOptions.vue +67 -38
- package/app/components/Viewer/Generic/Model/ModelStyleCard.vue +31 -15
- package/app/components/Viewer/Generic/Model/ModelStyleOptions.vue +2 -3
- package/app/components/Viewer/Generic/Model/PointsOptions.vue +6 -6
- package/app/components/Viewer/Generic/Model/SurfacesOptions.vue +69 -38
- package/app/components/Viewer/ObjectTree/Base/CommonTreeView.vue +64 -46
- package/app/components/Viewer/ObjectTree/Base/Controls.vue +5 -5
- package/app/components/Viewer/ObjectTree/Base/ItemLabel.vue +13 -9
- package/app/components/Viewer/ObjectTree/Base/StickyHeader.vue +5 -5
- package/app/components/Viewer/ObjectTree/Base/TreeRow.vue +10 -10
- package/app/components/Viewer/ObjectTree/Box.vue +6 -4
- package/app/components/Viewer/ObjectTree/Layout.vue +23 -21
- package/app/components/Viewer/ObjectTree/Views/GlobalObjects.vue +14 -14
- package/app/components/Viewer/ObjectTree/Views/{ModelCollections.vue → ModelTree.vue} +59 -24
- package/app/components/Viewer/Options/AttributeColorBar.vue +4 -2
- package/app/components/Viewer/Options/AttributeRangeSelector.vue +4 -2
- package/app/components/Viewer/Options/AttributeSelector.vue +7 -9
- package/app/components/Viewer/Options/ColorMapList.vue +15 -13
- package/app/components/Viewer/Options/ColorMapPicker.vue +4 -4
- package/app/components/Viewer/Options/ColorPicker.vue +223 -41
- package/app/components/Viewer/Options/ColoringTypeSelector.vue +16 -16
- package/app/components/Viewer/Options/ColormapQuickPicker.vue +7 -5
- package/app/components/Viewer/Options/OptionsSection.vue +1 -1
- package/app/components/Viewer/Options/TextureItem.vue +8 -6
- package/app/components/Viewer/Options/TexturesSelector.vue +1 -1
- package/app/components/Viewer/OverlappingObjectsPicker.vue +8 -9
- package/app/components/Viewer/PointSet/SpecificPointsOptions.vue +2 -6
- package/app/components/Viewer/Solid/SpecificPolyhedraOptions.vue +12 -16
- package/app/components/Viewer/Surface/PolygonsOptions.vue +12 -16
- package/app/components/Viewer/Ui.vue +2 -2
- package/app/components/Wrapper.vue +1 -4
- package/app/components/ZScaling.vue +5 -3
- package/app/components/csv-preview/CsvPreviewer.vue +38 -37
- package/app/components/csv-preview/CsvSettings.vue +6 -4
- package/app/components/csv-preview/CsvTable.vue +1 -1
- package/app/composables/batch_style.ts +5 -6
- package/app/composables/clipping_planes_widget.ts +73 -181
- package/app/composables/clipping_planes_widget_entries.ts +189 -0
- package/app/composables/copy_to_clipboard.ts +7 -0
- package/app/composables/global_attribute_style.ts +163 -83
- package/app/composables/hover_highlight.ts +46 -14
- package/app/composables/model_collections.ts +26 -13
- package/app/composables/model_components.ts +26 -13
- package/app/composables/project_manager.ts +76 -19
- package/app/composables/responsive_middle_truncate.ts +13 -13
- package/app/composables/stepper_tree.ts +34 -11
- package/app/composables/tree_filter.ts +66 -44
- package/app/composables/tree_keyboard_nav.ts +25 -11
- package/app/composables/tree_scroll.ts +44 -14
- package/app/composables/use_adaptive_styles.ts +66 -23
- package/app/composables/use_overlapping_picker.ts +66 -16
- package/app/composables/use_quick_colormap.ts +16 -5
- package/app/composables/virtual_tree.ts +75 -43
- package/app/composables/vtk_implicit_plane_widget.d.ts +2 -0
- package/app/plugins/auto_store_register.ts +2 -7
- package/app/plugins/click_outside_ignore_snackbars.client.ts +39 -0
- package/app/stores/app.ts +57 -192
- package/app/stores/app_helpers/extension.ts +179 -0
- package/app/stores/back.ts +37 -21
- package/app/stores/camera_manager.ts +22 -20
- package/app/stores/cloud.ts +17 -13
- package/app/stores/data.ts +88 -47
- package/app/stores/data_helpers/collections.ts +36 -38
- package/app/stores/data_helpers/mesh.ts +45 -36
- package/app/stores/data_style.ts +50 -28
- package/app/stores/feedback.ts +6 -6
- package/app/stores/hybrid_viewer.ts +41 -52
- package/app/stores/infra.ts +39 -37
- package/app/stores/menu.ts +23 -14
- package/app/stores/treeview.ts +72 -42
- package/app/stores/viewer.ts +39 -27
- package/app/utils/attributes.ts +3 -3
- package/app/utils/clipping_planes.ts +111 -14
- package/app/utils/color_picker.ts +57 -0
- package/app/utils/colormap.ts +58 -35
- package/app/utils/default_styles/index.ts +2 -2
- package/app/utils/default_styles/meshes.ts +107 -13
- package/app/utils/default_styles/models.ts +83 -14
- package/app/utils/extension.ts +47 -20
- package/app/utils/import_workflow.ts +21 -13
- package/app/utils/name_cleaner.ts +1 -1
- package/app/utils/string.ts +1 -1
- package/app/utils/treeview.ts +2 -2
- package/internal/database/base_database.ts +7 -3
- package/internal/database/database.ts +36 -26
- package/internal/database/extended_database.ts +1 -1
- package/internal/stores/data_style/mesh/cells/cell.ts +70 -34
- package/internal/stores/data_style/mesh/cells/color.ts +12 -6
- package/internal/stores/data_style/mesh/cells/common.ts +18 -8
- package/internal/stores/data_style/mesh/cells/index.ts +122 -42
- package/internal/stores/data_style/mesh/cells/textures.ts +12 -6
- package/internal/stores/data_style/mesh/cells/vertex.ts +75 -34
- package/internal/stores/data_style/mesh/cells/visibility.ts +15 -4
- package/internal/stores/data_style/mesh/edges/color.ts +12 -6
- package/internal/stores/data_style/mesh/edges/common.ts +14 -6
- package/internal/stores/data_style/mesh/edges/edge.ts +71 -39
- package/internal/stores/data_style/mesh/edges/index.ts +117 -42
- package/internal/stores/data_style/mesh/edges/vertex.ts +76 -39
- package/internal/stores/data_style/mesh/edges/visibility.ts +15 -4
- package/internal/stores/data_style/mesh/edges/width.ts +12 -4
- package/internal/stores/data_style/mesh/index.ts +30 -11
- package/internal/stores/data_style/mesh/points/color.ts +12 -6
- package/internal/stores/data_style/mesh/points/common.ts +21 -8
- package/internal/stores/data_style/mesh/points/index.ts +101 -50
- package/internal/stores/data_style/mesh/points/size.ts +12 -4
- package/internal/stores/data_style/mesh/points/vertex.ts +75 -34
- package/internal/stores/data_style/mesh/points/visibility.ts +17 -7
- package/internal/stores/data_style/mesh/polygons/color.ts +12 -6
- package/internal/stores/data_style/mesh/polygons/common.ts +23 -6
- package/internal/stores/data_style/mesh/polygons/index.ts +130 -70
- package/internal/stores/data_style/mesh/polygons/polygon.ts +77 -43
- package/internal/stores/data_style/mesh/polygons/textures.ts +12 -6
- package/internal/stores/data_style/mesh/polygons/vertex.ts +79 -39
- package/internal/stores/data_style/mesh/polygons/visibility.ts +16 -6
- package/internal/stores/data_style/mesh/polyhedra/color.ts +12 -6
- package/internal/stores/data_style/mesh/polyhedra/common.ts +14 -6
- package/internal/stores/data_style/mesh/polyhedra/index.ts +115 -56
- package/internal/stores/data_style/mesh/polyhedra/polyhedron.ts +80 -39
- package/internal/stores/data_style/mesh/polyhedra/vertex.ts +79 -39
- package/internal/stores/data_style/mesh/polyhedra/visibility.ts +16 -6
- package/internal/stores/data_style/model/blocks/color.ts +43 -13
- package/internal/stores/data_style/model/blocks/common.ts +21 -6
- package/internal/stores/data_style/model/blocks/index.ts +89 -59
- package/internal/stores/data_style/model/blocks/polyhedron.ts +101 -44
- package/internal/stores/data_style/model/blocks/vertex.ts +107 -42
- package/internal/stores/data_style/model/blocks/visibility.ts +17 -4
- package/internal/stores/data_style/model/color.ts +171 -83
- package/internal/stores/data_style/model/common.ts +70 -21
- package/internal/stores/data_style/model/corners/color.ts +43 -11
- package/internal/stores/data_style/model/corners/common.ts +25 -6
- package/internal/stores/data_style/model/corners/index.ts +66 -41
- package/internal/stores/data_style/model/corners/vertex.ts +105 -74
- package/internal/stores/data_style/model/corners/visibility.ts +19 -4
- package/internal/stores/data_style/model/edges/common.ts +12 -4
- package/internal/stores/data_style/model/edges/index.ts +2 -1
- package/internal/stores/data_style/model/edges/visibility.ts +24 -7
- package/internal/stores/data_style/model/index.ts +24 -11
- package/internal/stores/data_style/model/lines/color.ts +41 -11
- package/internal/stores/data_style/model/lines/common.ts +17 -6
- package/internal/stores/data_style/model/lines/edge.ts +105 -42
- package/internal/stores/data_style/model/lines/index.ts +86 -59
- package/internal/stores/data_style/model/lines/vertex.ts +105 -42
- package/internal/stores/data_style/model/lines/visibility.ts +17 -4
- package/internal/stores/data_style/model/points/common.ts +8 -4
- package/internal/stores/data_style/model/points/index.ts +10 -3
- package/internal/stores/data_style/model/points/size.ts +12 -4
- package/internal/stores/data_style/model/points/visibility.ts +16 -6
- package/internal/stores/data_style/model/selection.ts +80 -58
- package/internal/stores/data_style/model/surfaces/color.ts +41 -11
- package/internal/stores/data_style/model/surfaces/common.ts +23 -6
- package/internal/stores/data_style/model/surfaces/index.ts +89 -59
- package/internal/stores/data_style/model/surfaces/polygon.ts +107 -67
- package/internal/stores/data_style/model/surfaces/vertex.ts +111 -67
- package/internal/stores/data_style/model/surfaces/visibility.ts +18 -5
- package/internal/stores/data_style/model/visibility.ts +82 -20
- package/internal/stores/data_style/state.ts +77 -65
- package/internal/stores/hybrid_viewer/brightness.ts +49 -31
- package/internal/stores/hybrid_viewer/camera.ts +191 -177
- package/internal/stores/hybrid_viewer/camera_animation.ts +11 -10
- package/internal/stores/hybrid_viewer/core.ts +64 -0
- package/internal/stores/hybrid_viewer/filters.ts +10 -16
- package/internal/stores/hybrid_viewer/highlight.ts +91 -130
- package/internal/stores/hybrid_viewer/ruler.ts +24 -15
- package/internal/stores/hybrid_viewer/scene.ts +96 -117
- package/internal/stores/hybrid_viewer/viewport.ts +74 -65
- package/internal/stores/hybrid_viewer/vtk_types.ts +13 -29
- package/internal/utils/api_fetch.ts +54 -23
- package/internal/utils/upload_file.ts +74 -53
- package/internal/utils/viewer_call.ts +22 -13
- package/internal/utils/ws_client.ts +24 -13
- package/nuxt.config.ts +58 -1
- package/package.json +20 -8
- package/server/api/cloud/extensions/run.post.ts +6 -10
- package/server/api/local/app/project_folder_path.post.ts +4 -4
- package/server/api/local/app/run_back.post.ts +5 -7
- package/server/api/local/app/run_viewer.post.ts +5 -7
- package/server/api/local/extensions/kill.post.ts +4 -3
- package/server/api/local/extensions/run.post.ts +7 -10
- package/server/api/local/extensions/upload.put.ts +44 -54
- package/server/api/microservice/app/get_is_app_ready.get.ts +4 -5
- package/server/api/microservice/app/set_app_base_url.post.ts +5 -6
- package/server/api/microservice/app/set_back_base_url.post.ts +5 -6
- package/server/api/microservice/app/set_is_app_ready.post.ts +5 -6
- package/server/api/microservice/app/set_viewer_base_url.post.ts +5 -6
- package/server/api/microservice/extensions/download.post.ts +5 -4
- package/server/api/serverless/run_cloud.post.ts +53 -11
- package/server/utils/app_config.ts +29 -22
- package/server/utils/cleanup.ts +60 -30
- package/server/utils/cloud.ts +9 -8
- package/server/utils/extension.ts +23 -9
- package/server/utils/microservices.ts +33 -24
- package/server/utils/path.ts +4 -4
- package/server/utils/scripts.ts +26 -23
- package/server/utils/server.ts +2 -2
- package/server/utils/server_config.ts +41 -27
- package/server/utils/stream.ts +6 -0
- package/server/utils/ws_client.ts +42 -8
- package/shared/scripts.ts +15 -10
- package/shared/utils/call_raw.ts +23 -16
- package/shared/utils/call_schema.ts +5 -8
- package/shared/utils/fetch_raw.ts +87 -47
- package/shared/utils/fetch_schema.ts +6 -9
- package/shared/utils/file.ts +8 -2
- package/shared/utils/response_handlers/load.ts +26 -11
- package/shared/utils/types.ts +9 -9
- package/shared/utils/validate_schema.ts +1 -1
- package/app/components/Viewer/ObjectTree/Views/ModelComponents.vue +0 -276
- package/server/types/vendor.d.ts +0 -64
- package/server/utils/server_config.js +0 -43
- package/shared/utils/call_raw.js +0 -30
- package/shared/utils/fetch_raw.js +0 -40
- /package/{opengeodeweb_front_schemas.js → .build/opengeodeweb_front_schemas.js} +0 -0
- /package/{server → .build/server}/utils/server.js +0 -0
- /package/{shared → .build/shared}/app_mode.js +0 -0
- /package/{shared → .build/shared}/utils/parse_boolean.js +0 -0
- /package/{shared → .build/shared}/utils/types.js +0 -0
|
@@ -1,58 +1,38 @@
|
|
|
1
|
-
// Not auto-fixable (eslint's sort-imports core rule has no autofixer) and this file's import order doesn't match its syntax-kind-then-alphabetical requirement - left as-is rather than manually reordered across the codebase for a purely cosmetic rule.
|
|
2
|
-
// oxlint-disable eslint/sort-imports
|
|
3
1
|
import {
|
|
4
|
-
AXIS_SCALE,
|
|
5
2
|
CHANGE_THRESHOLD,
|
|
6
|
-
|
|
7
|
-
|
|
3
|
+
type MainCameraOptions,
|
|
4
|
+
type SceneBoundsInfo,
|
|
5
|
+
alignCameraToMainCamera,
|
|
8
6
|
computeSceneBoundsInfo,
|
|
9
|
-
|
|
10
|
-
hasPlaneChanged,
|
|
7
|
+
resolveActiveActors,
|
|
11
8
|
} from "@ogw_front/utils/clipping_planes";
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
import type vtkActor from "@kitware/vtk.js/Rendering/Core/Actor";
|
|
21
|
-
import type { vtkCamera } from "@kitware/vtk.js/Rendering/Core/Camera";
|
|
9
|
+
import {
|
|
10
|
+
type ClippingPlane,
|
|
11
|
+
useWidgetEntryManager,
|
|
12
|
+
} from "@ogw_front/composables/clipping_planes_widget_entries";
|
|
13
|
+
import {
|
|
14
|
+
type vtkWidgetManager as WidgetManagerInstance,
|
|
15
|
+
newInstance as vtkWidgetManager,
|
|
16
|
+
} from "@kitware/vtk.js/Widgets/Core/WidgetManager";
|
|
22
17
|
import type { vtkGenericRenderWindow as GenericRenderWindowInstance } from "@ogw_internal/stores/hybrid_viewer/vtk_types";
|
|
23
18
|
import type { useHybridViewerStore } from "@ogw_front/stores/hybrid_viewer";
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
origin?: number[];
|
|
27
|
-
normal: number[];
|
|
28
|
-
}
|
|
19
|
+
import type { vtkCamera } from "@kitware/vtk.js/Rendering/Core/Camera";
|
|
20
|
+
import { newInstance as vtkGenericRenderWindow } from "@kitware/vtk.js/Rendering/Misc/GenericRenderWindow";
|
|
29
21
|
|
|
30
22
|
interface DataItemLike {
|
|
31
23
|
id: string;
|
|
32
24
|
}
|
|
33
25
|
|
|
34
|
-
// Vtk.js's plane-widget factory/handle/state objects (from ImplicitPlaneWidget, which ships no type declarations) are kept as `any` here - deep vtk.js widget internals with no typed surface to build on.
|
|
35
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
36
|
-
type PlaneWidget = any;
|
|
37
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
38
|
-
type WidgetHandle = any;
|
|
39
|
-
|
|
40
|
-
interface WidgetEntry {
|
|
41
|
-
planeWidget: PlaneWidget;
|
|
42
|
-
widgetHandle: WidgetHandle;
|
|
43
|
-
subscription: { unsubscribe: () => void };
|
|
44
|
-
}
|
|
45
|
-
|
|
46
26
|
interface ClippingPlanesWidgetParams {
|
|
47
27
|
planes: Ref<ClippingPlane[]>;
|
|
48
28
|
targetAllVisible: Ref<boolean>;
|
|
49
29
|
selectedDatasetIds: Ref<string[]>;
|
|
50
30
|
allItems: Ref<DataItemLike[]>;
|
|
51
31
|
hybridViewerStore: ReturnType<typeof useHybridViewerStore>;
|
|
52
|
-
debouncedApply: (...args: unknown[]) => void;
|
|
32
|
+
debouncedApply: (...args: readonly unknown[]) => void;
|
|
53
33
|
}
|
|
54
34
|
|
|
55
|
-
// oxlint-disable-next-line max-params max-lines-per-function
|
|
35
|
+
// oxlint-disable-next-line max-params max-lines-per-function typescript/prefer-readonly-parameter-types -- Ref-backed params are inherently mutable through .value.
|
|
56
36
|
function useClippingPlanesWidget({
|
|
57
37
|
planes,
|
|
58
38
|
targetAllVisible,
|
|
@@ -60,118 +40,48 @@ function useClippingPlanesWidget({
|
|
|
60
40
|
allItems,
|
|
61
41
|
hybridViewerStore,
|
|
62
42
|
debouncedApply,
|
|
63
|
-
}: ClippingPlanesWidgetParams) {
|
|
43
|
+
}: ClippingPlanesWidgetParams): {
|
|
44
|
+
getSceneCenter: typeof getSceneCenter;
|
|
45
|
+
syncWidgets: typeof syncWidgets;
|
|
46
|
+
syncLocalCamera: typeof syncLocalCamera;
|
|
47
|
+
cleanupLocalWidget: typeof cleanupLocalWidget;
|
|
48
|
+
initLocalWidget: typeof initLocalWidget;
|
|
49
|
+
updateWidgetPlacement: typeof updateWidgetPlacement;
|
|
50
|
+
isFromWidget: typeof isFromWidget;
|
|
51
|
+
setFromWidget: typeof setFromWidget;
|
|
52
|
+
} {
|
|
64
53
|
let localRenderWindow: GenericRenderWindowInstance | undefined = undefined;
|
|
65
54
|
let widgetManager: WidgetManagerInstance | undefined = undefined;
|
|
66
|
-
let widgetEntries: WidgetEntry[] = [];
|
|
67
|
-
let fromWidget = false;
|
|
68
55
|
let maxDistance = 0;
|
|
69
56
|
let isLimitingCameraZoom = false;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
return targeted;
|
|
82
|
-
}
|
|
83
|
-
return Object.values(hybridViewerStore.hybridDb)
|
|
84
|
-
.map((entry) => entry && entry.actor)
|
|
85
|
-
.filter((actor): actor is vtkActor => Boolean(actor));
|
|
86
|
-
}
|
|
87
|
-
function getSceneBoundsInfo() {
|
|
88
|
-
return computeSceneBoundsInfo(resolveActiveActors());
|
|
57
|
+
const widgetEntryManager = useWidgetEntryManager({ planes, debouncedApply });
|
|
58
|
+
|
|
59
|
+
function getSceneBoundsInfo(): SceneBoundsInfo {
|
|
60
|
+
return computeSceneBoundsInfo(
|
|
61
|
+
resolveActiveActors(
|
|
62
|
+
targetAllVisible.value,
|
|
63
|
+
allItems.value,
|
|
64
|
+
selectedDatasetIds.value,
|
|
65
|
+
hybridViewerStore.hybridDb,
|
|
66
|
+
),
|
|
67
|
+
);
|
|
89
68
|
}
|
|
90
|
-
function getSceneCenter(): number[] {
|
|
69
|
+
function getSceneCenter(): readonly number[] {
|
|
91
70
|
return getSceneBoundsInfo().center;
|
|
92
71
|
}
|
|
93
|
-
|
|
94
|
-
planeWidget: PlaneWidget,
|
|
95
|
-
widgetHandle: WidgetHandle,
|
|
96
|
-
planeIndex: number,
|
|
97
|
-
): WidgetEntry {
|
|
98
|
-
const widgetState = planeWidget.getWidgetState();
|
|
99
|
-
const plane = planes.value[planeIndex];
|
|
100
|
-
if (plane?.origin) {
|
|
101
|
-
widgetState.setOrigin(plane.origin);
|
|
102
|
-
}
|
|
103
|
-
if (plane) {
|
|
104
|
-
widgetState.setNormal(plane.normal);
|
|
105
|
-
}
|
|
106
|
-
const subscription = widgetState.onModified(() => {
|
|
107
|
-
if (fromWidget) {
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
|
-
const origin: number[] = widgetState.getOrigin().map((val: number) => Number(val.toFixed(4)));
|
|
111
|
-
const normal: number[] = widgetState.getNormal().map((val: number) => Number(val.toFixed(4)));
|
|
112
|
-
const currentPlane = planes.value[planeIndex];
|
|
113
|
-
if (
|
|
114
|
-
!currentPlane ||
|
|
115
|
-
!hasPlaneChanged(origin, normal, currentPlane.origin, currentPlane.normal)
|
|
116
|
-
) {
|
|
117
|
-
return;
|
|
118
|
-
}
|
|
119
|
-
fromWidget = true;
|
|
120
|
-
currentPlane.origin = origin;
|
|
121
|
-
currentPlane.normal = normal;
|
|
122
|
-
nextTick(() => {
|
|
123
|
-
fromWidget = false;
|
|
124
|
-
});
|
|
125
|
-
debouncedApply();
|
|
126
|
-
});
|
|
127
|
-
return {
|
|
128
|
-
planeWidget,
|
|
129
|
-
widgetHandle,
|
|
130
|
-
subscription,
|
|
131
|
-
};
|
|
132
|
-
}
|
|
72
|
+
|
|
133
73
|
function syncWidgets(): void {
|
|
134
74
|
if (!widgetManager || !localRenderWindow) {
|
|
135
75
|
return;
|
|
136
76
|
}
|
|
137
|
-
|
|
138
|
-
const entry = widgetEntries.pop();
|
|
139
|
-
if (!entry) {
|
|
140
|
-
continue;
|
|
141
|
-
}
|
|
142
|
-
entry.subscription.unsubscribe();
|
|
143
|
-
widgetManager.removeWidget(entry.planeWidget);
|
|
144
|
-
entry.planeWidget.delete();
|
|
145
|
-
}
|
|
77
|
+
widgetEntryManager.removeExtraWidgets(widgetManager);
|
|
146
78
|
const { cubicBounds } = getSceneBoundsInfo();
|
|
147
79
|
for (const [idx, plane] of planes.value.entries()) {
|
|
148
|
-
|
|
149
|
-
const rgb = PLANE_COLORS[idx % PLANE_COLORS.length]!;
|
|
150
|
-
if (!widgetEntries[idx]) {
|
|
151
|
-
const planeWidget = vtkImplicitPlaneWidget();
|
|
152
|
-
const widgetHandle = widgetManager.addWidget(planeWidget);
|
|
153
|
-
widgetHandle.setAxisScale(AXIS_SCALE);
|
|
154
|
-
widgetHandle.setHandleSizeRatio(SIZE_RATIO);
|
|
155
|
-
widgetEntries.push(createWidgetEntry(planeWidget, widgetHandle, idx));
|
|
156
|
-
}
|
|
157
|
-
const entry = widgetEntries[idx];
|
|
158
|
-
if (!entry) {
|
|
159
|
-
continue;
|
|
160
|
-
}
|
|
161
|
-
entry.widgetHandle.setRepresentationStyle(getPlaneStyle(rgb));
|
|
162
|
-
fromWidget = true;
|
|
163
|
-
entry.widgetHandle.placeWidget(cubicBounds);
|
|
164
|
-
fromWidget = false;
|
|
165
|
-
entry.widgetHandle.setAxisScale(AXIS_SCALE);
|
|
166
|
-
entry.widgetHandle.setHandleSizeRatio(SIZE_RATIO);
|
|
167
|
-
const widgetState = entry.planeWidget.getWidgetState();
|
|
168
|
-
if (plane.origin) {
|
|
169
|
-
widgetState.setOrigin(plane.origin);
|
|
170
|
-
}
|
|
171
|
-
widgetState.setNormal(plane.normal);
|
|
80
|
+
widgetEntryManager.updateWidgetEntry(idx, plane, cubicBounds, widgetManager);
|
|
172
81
|
}
|
|
173
82
|
localRenderWindow.getRenderWindow().render();
|
|
174
83
|
}
|
|
84
|
+
|
|
175
85
|
function limitCameraZoomOut(camera: vtkCamera): void {
|
|
176
86
|
if (maxDistance <= 0 || isLimitingCameraZoom) {
|
|
177
87
|
return;
|
|
@@ -192,65 +102,33 @@ function useClippingPlanesWidget({
|
|
|
192
102
|
localRenderWindow?.getRenderWindow().render();
|
|
193
103
|
isLimitingCameraZoom = false;
|
|
194
104
|
}
|
|
195
|
-
|
|
196
|
-
// oxlint-disable-next-line complexity
|
|
105
|
+
|
|
197
106
|
function syncLocalCamera(): void {
|
|
198
107
|
if (!localRenderWindow) {
|
|
199
108
|
return;
|
|
200
109
|
}
|
|
201
110
|
const renderer = localRenderWindow.getRenderer();
|
|
202
111
|
const camera = renderer.getActiveCamera();
|
|
203
|
-
const mainCam = hybridViewerStore.camera_options as
|
|
204
|
-
focal_point?: number[];
|
|
205
|
-
position?: number[];
|
|
206
|
-
view_up?: number[];
|
|
207
|
-
};
|
|
112
|
+
const mainCam = hybridViewerStore.camera_options as MainCameraOptions;
|
|
208
113
|
const { center, cubicBounds } = getSceneBoundsInfo();
|
|
114
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- cubicBounds is always a 6-element bounds tuple.
|
|
209
115
|
renderer.resetCamera(cubicBounds as [number, number, number, number, number, number]);
|
|
210
|
-
|
|
211
|
-
const { focal_point, position } = mainCam;
|
|
212
|
-
const dir = [
|
|
213
|
-
(position[0] ?? 0) - (focal_point[0] ?? 0),
|
|
214
|
-
(position[1] ?? 0) - (focal_point[1] ?? 0),
|
|
215
|
-
(position[2] ?? 0) - (focal_point[2] ?? 0),
|
|
216
|
-
];
|
|
217
|
-
const dirLen = Math.hypot(...dir);
|
|
218
|
-
if (dirLen > 0) {
|
|
219
|
-
const distance = camera.getDistance();
|
|
220
|
-
const normDir = dir.map((component) => component / dirLen);
|
|
221
|
-
camera.setFocalPoint(center[0] ?? 0, center[1] ?? 0, center[2] ?? 0);
|
|
222
|
-
camera.setPosition(
|
|
223
|
-
(center[0] ?? 0) + (normDir[0] ?? 0) * distance,
|
|
224
|
-
(center[1] ?? 0) + (normDir[1] ?? 0) * distance,
|
|
225
|
-
(center[2] ?? 0) + (normDir[2] ?? 0) * distance,
|
|
226
|
-
);
|
|
227
|
-
if (mainCam.view_up) {
|
|
228
|
-
const [viewUpX = 0, viewUpY = 0, viewUpZ = 0] = mainCam.view_up;
|
|
229
|
-
camera.setViewUp(viewUpX, viewUpY, viewUpZ);
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
116
|
+
alignCameraToMainCamera(camera, mainCam, center);
|
|
233
117
|
limitCameraZoomOut(camera);
|
|
234
118
|
localRenderWindow.getRenderWindow().render();
|
|
235
119
|
}
|
|
120
|
+
|
|
236
121
|
function cleanupLocalWidget(): void {
|
|
237
122
|
maxDistance = 0;
|
|
238
123
|
isLimitingCameraZoom = false;
|
|
239
|
-
|
|
240
|
-
entry.subscription.unsubscribe();
|
|
241
|
-
if (widgetManager) {
|
|
242
|
-
widgetManager.removeWidget(entry.planeWidget);
|
|
243
|
-
}
|
|
244
|
-
entry.planeWidget.delete();
|
|
245
|
-
}
|
|
246
|
-
widgetEntries = [];
|
|
124
|
+
widgetEntryManager.cleanupAll(widgetManager);
|
|
247
125
|
if (localRenderWindow) {
|
|
248
126
|
localRenderWindow.delete();
|
|
249
127
|
localRenderWindow = undefined;
|
|
250
128
|
widgetManager = undefined;
|
|
251
129
|
}
|
|
252
130
|
}
|
|
253
|
-
function updateWidgetPlacement({ isReset = false } = {}): void {
|
|
131
|
+
function updateWidgetPlacement({ isReset = false }: { isReset?: boolean } = {}): void {
|
|
254
132
|
if (!widgetManager || !localRenderWindow) {
|
|
255
133
|
return;
|
|
256
134
|
}
|
|
@@ -272,20 +150,32 @@ function useClippingPlanesWidget({
|
|
|
272
150
|
|
|
273
151
|
function initLocalWidget(container: HTMLElement): void {
|
|
274
152
|
cleanupLocalWidget();
|
|
275
|
-
container.addEventListener(
|
|
153
|
+
container.addEventListener(
|
|
154
|
+
"wheel",
|
|
155
|
+
(event: WheelEvent) => {
|
|
156
|
+
event.stopPropagation();
|
|
157
|
+
},
|
|
158
|
+
{ passive: true },
|
|
159
|
+
);
|
|
276
160
|
localRenderWindow = vtkGenericRenderWindow({
|
|
277
161
|
background: [0, 0, 0, 0],
|
|
278
162
|
listenWindowResize: false,
|
|
279
163
|
});
|
|
280
164
|
localRenderWindow.setContainer(container);
|
|
281
165
|
const camera = localRenderWindow.getRenderer().getActiveCamera();
|
|
282
|
-
camera.onModified(() =>
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
166
|
+
camera.onModified(() => {
|
|
167
|
+
limitCameraZoomOut(camera);
|
|
168
|
+
});
|
|
169
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- trusted vtk.js OpenGL render window API boundary.
|
|
170
|
+
const openGLRenderWindow = localRenderWindow.getApiSpecificRenderWindow() as unknown as {
|
|
171
|
+
getCanvas: () => HTMLCanvasElement;
|
|
172
|
+
};
|
|
173
|
+
const canvas = openGLRenderWindow.getCanvas();
|
|
174
|
+
Object.assign(canvas.style, {
|
|
175
|
+
width: "100%",
|
|
176
|
+
height: "100%",
|
|
177
|
+
background: "transparent",
|
|
178
|
+
});
|
|
289
179
|
localRenderWindow.resize();
|
|
290
180
|
widgetManager = vtkWidgetManager();
|
|
291
181
|
widgetManager.setRenderer(localRenderWindow.getRenderer());
|
|
@@ -293,11 +183,13 @@ function useClippingPlanesWidget({
|
|
|
293
183
|
}
|
|
294
184
|
|
|
295
185
|
function isFromWidget(): boolean {
|
|
296
|
-
return
|
|
186
|
+
return widgetEntryManager.isFromWidget();
|
|
297
187
|
}
|
|
188
|
+
|
|
298
189
|
function setFromWidget(value: boolean): void {
|
|
299
|
-
|
|
190
|
+
widgetEntryManager.setFromWidget(value);
|
|
300
191
|
}
|
|
192
|
+
|
|
301
193
|
return {
|
|
302
194
|
getSceneCenter,
|
|
303
195
|
syncWidgets,
|
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AXIS_SCALE,
|
|
3
|
+
PLANE_COLORS,
|
|
4
|
+
SIZE_RATIO,
|
|
5
|
+
getPlaneStyle,
|
|
6
|
+
hasPlaneChanged,
|
|
7
|
+
} from "@ogw_front/utils/clipping_planes";
|
|
8
|
+
import type { vtkWidgetManager as WidgetManagerInstance } from "@kitware/vtk.js/Widgets/Core/WidgetManager";
|
|
9
|
+
import type vtkAbstractWidget from "@kitware/vtk.js/Widgets/Core/AbstractWidget";
|
|
10
|
+
import type vtkAbstractWidgetFactory from "@kitware/vtk.js/Widgets/Core/AbstractWidgetFactory";
|
|
11
|
+
import { newInstance as vtkImplicitPlaneWidget } from "@kitware/vtk.js/Widgets/Widgets3D/ImplicitPlaneWidget";
|
|
12
|
+
|
|
13
|
+
interface ClippingPlane {
|
|
14
|
+
origin?: number[];
|
|
15
|
+
normal: number[];
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
interface ClippingWidgetState {
|
|
19
|
+
getOrigin: () => number[];
|
|
20
|
+
setOrigin: (origin: readonly number[]) => void;
|
|
21
|
+
getNormal: () => number[];
|
|
22
|
+
setNormal: (normal: readonly number[]) => void;
|
|
23
|
+
onModified: (callback: () => void) => { unsubscribe: () => void };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
interface PlaneWidget {
|
|
27
|
+
getWidgetState: () => ClippingWidgetState;
|
|
28
|
+
delete: () => void;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
interface WidgetHandle {
|
|
32
|
+
setAxisScale: (scale: number) => void;
|
|
33
|
+
setHandleSizeRatio: (ratio: number) => void;
|
|
34
|
+
setRepresentationStyle: (style: unknown) => void;
|
|
35
|
+
placeWidget: (bounds: readonly number[]) => void;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
interface WidgetEntry {
|
|
39
|
+
planeWidget: PlaneWidget;
|
|
40
|
+
widgetHandle: WidgetHandle;
|
|
41
|
+
subscription: { unsubscribe: () => void };
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function asWidgetFactory(widget: PlaneWidget): vtkAbstractWidgetFactory<vtkAbstractWidget> {
|
|
45
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- vtk.js's WidgetManager APIs (addWidget/removeWidget) are untyped for our custom PlaneWidget shape; narrowed once here.
|
|
46
|
+
return widget as unknown as vtkAbstractWidgetFactory<vtkAbstractWidget>;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
interface WidgetEntryManagerParams {
|
|
50
|
+
planes: Ref<ClippingPlane[]>;
|
|
51
|
+
debouncedApply: (...args: readonly unknown[]) => void;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// oxlint-disable-next-line max-lines-per-function typescript/prefer-readonly-parameter-types -- Ref-backed params are inherently mutable through .value.
|
|
55
|
+
function useWidgetEntryManager({ planes, debouncedApply }: WidgetEntryManagerParams): {
|
|
56
|
+
removeExtraWidgets: (widgetManager: WidgetManagerInstance | undefined) => void;
|
|
57
|
+
updateWidgetEntry: (
|
|
58
|
+
idx: number,
|
|
59
|
+
plane: ClippingPlane,
|
|
60
|
+
cubicBounds: readonly number[],
|
|
61
|
+
widgetManager: WidgetManagerInstance,
|
|
62
|
+
) => void;
|
|
63
|
+
cleanupAll: (widgetManager: WidgetManagerInstance | undefined) => void;
|
|
64
|
+
isFromWidget: () => boolean;
|
|
65
|
+
setFromWidget: (value: boolean) => void;
|
|
66
|
+
} {
|
|
67
|
+
let widgetEntries: WidgetEntry[] = [];
|
|
68
|
+
let fromWidget = false;
|
|
69
|
+
|
|
70
|
+
function createWidgetEntry(
|
|
71
|
+
planeWidget: PlaneWidget,
|
|
72
|
+
widgetHandle: WidgetHandle,
|
|
73
|
+
planeIndex: number,
|
|
74
|
+
): WidgetEntry {
|
|
75
|
+
const widgetState = planeWidget.getWidgetState();
|
|
76
|
+
const plane = planes.value[planeIndex];
|
|
77
|
+
if (plane?.origin) {
|
|
78
|
+
widgetState.setOrigin(plane.origin);
|
|
79
|
+
}
|
|
80
|
+
if (plane) {
|
|
81
|
+
widgetState.setNormal(plane.normal);
|
|
82
|
+
}
|
|
83
|
+
const subscription = widgetState.onModified(() => {
|
|
84
|
+
if (fromWidget) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
const origin: number[] = widgetState.getOrigin().map((val: number) => Number(val.toFixed(4)));
|
|
88
|
+
const normal: number[] = widgetState.getNormal().map((val: number) => Number(val.toFixed(4)));
|
|
89
|
+
const currentPlane = planes.value[planeIndex];
|
|
90
|
+
if (
|
|
91
|
+
!currentPlane ||
|
|
92
|
+
!hasPlaneChanged(origin, normal, currentPlane.origin, currentPlane.normal)
|
|
93
|
+
) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
fromWidget = true;
|
|
97
|
+
currentPlane.origin = origin;
|
|
98
|
+
currentPlane.normal = normal;
|
|
99
|
+
nextTick(() => {
|
|
100
|
+
fromWidget = false;
|
|
101
|
+
// oxlint-disable-next-line promise/prefer-await-to-then -- fire-and-forget inside a sync widget callback; see codebase convention in global_attribute_style.ts.
|
|
102
|
+
}).catch(() => undefined);
|
|
103
|
+
debouncedApply();
|
|
104
|
+
});
|
|
105
|
+
return {
|
|
106
|
+
planeWidget,
|
|
107
|
+
widgetHandle,
|
|
108
|
+
subscription,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
function removeExtraWidgets(widgetManager: WidgetManagerInstance | undefined): void {
|
|
113
|
+
while (widgetEntries.length > planes.value.length) {
|
|
114
|
+
const entry = widgetEntries.pop();
|
|
115
|
+
if (!entry) {
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
entry.subscription.unsubscribe();
|
|
119
|
+
widgetManager?.removeWidget(asWidgetFactory(entry.planeWidget));
|
|
120
|
+
entry.planeWidget.delete();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function updateWidgetEntry(
|
|
125
|
+
idx: number,
|
|
126
|
+
plane: ClippingPlane,
|
|
127
|
+
cubicBounds: readonly number[],
|
|
128
|
+
widgetManager: WidgetManagerInstance,
|
|
129
|
+
): void {
|
|
130
|
+
// Modulo guarantees this index is within bounds of the non-empty PLANE_COLORS array.
|
|
131
|
+
const rgb = PLANE_COLORS[idx % PLANE_COLORS.length];
|
|
132
|
+
if (rgb === undefined) {
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
if (!widgetEntries[idx]) {
|
|
136
|
+
// oxlint-disable-next-line no-unsafe-call no-unsafe-type-assertion -- vtk.js has no types for ImplicitPlaneWidget's factory; narrowed here.
|
|
137
|
+
const planeWidget = vtkImplicitPlaneWidget() as PlaneWidget;
|
|
138
|
+
const widgetHandle = widgetManager.addWidget(
|
|
139
|
+
asWidgetFactory(planeWidget),
|
|
140
|
+
// oxlint-disable-next-line no-unsafe-type-assertion -- vtk.js WidgetManager.addWidget is untyped for our custom WidgetHandle shape; narrowed here.
|
|
141
|
+
) as unknown as WidgetHandle;
|
|
142
|
+
widgetEntries.push(createWidgetEntry(planeWidget, widgetHandle, idx));
|
|
143
|
+
}
|
|
144
|
+
const entry = widgetEntries[idx];
|
|
145
|
+
if (!entry) {
|
|
146
|
+
return;
|
|
147
|
+
}
|
|
148
|
+
entry.widgetHandle.setRepresentationStyle(getPlaneStyle(rgb));
|
|
149
|
+
fromWidget = true;
|
|
150
|
+
entry.widgetHandle.placeWidget(cubicBounds);
|
|
151
|
+
fromWidget = false;
|
|
152
|
+
entry.widgetHandle.setAxisScale(AXIS_SCALE);
|
|
153
|
+
entry.widgetHandle.setHandleSizeRatio(SIZE_RATIO);
|
|
154
|
+
const widgetState = entry.planeWidget.getWidgetState();
|
|
155
|
+
if (plane.origin) {
|
|
156
|
+
widgetState.setOrigin(plane.origin);
|
|
157
|
+
}
|
|
158
|
+
widgetState.setNormal(plane.normal);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function cleanupAll(widgetManager: WidgetManagerInstance | undefined): void {
|
|
162
|
+
for (const entry of widgetEntries) {
|
|
163
|
+
entry.subscription.unsubscribe();
|
|
164
|
+
if (widgetManager) {
|
|
165
|
+
widgetManager.removeWidget(asWidgetFactory(entry.planeWidget));
|
|
166
|
+
}
|
|
167
|
+
entry.planeWidget.delete();
|
|
168
|
+
}
|
|
169
|
+
widgetEntries = [];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function isFromWidget(): boolean {
|
|
173
|
+
return fromWidget;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
function setFromWidget(value: boolean): void {
|
|
177
|
+
fromWidget = value;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return {
|
|
181
|
+
removeExtraWidgets,
|
|
182
|
+
updateWidgetEntry,
|
|
183
|
+
cleanupAll,
|
|
184
|
+
isFromWidget,
|
|
185
|
+
setFromWidget,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
export { useWidgetEntryManager, type ClippingPlane };
|