bimatter-viewer-react 0.0.1

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/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # React + TypeScript + Vite
2
+
3
+ This template provides a minimal setup to get React working in Vite with HMR and some ESLint rules.
4
+
5
+ Currently, two official plugins are available:
6
+
7
+ - [@vitejs/plugin-react](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react) uses [Oxc](https://oxc.rs)
8
+ - [@vitejs/plugin-react-swc](https://github.com/vitejs/vite-plugin-react/blob/main/packages/plugin-react-swc) uses [SWC](https://swc.rs/)
9
+
10
+ ## React Compiler
11
+
12
+ The React Compiler is not enabled on this template because of its impact on dev & build performances. To add it, see [this documentation](https://react.dev/learn/react-compiler/installation).
13
+
14
+ ## Expanding the ESLint configuration
15
+
16
+ If you are developing a production application, we recommend updating the configuration to enable type-aware lint rules:
17
+
18
+ ```js
19
+ export default defineConfig([
20
+ globalIgnores(['dist']),
21
+ {
22
+ files: ['**/*.{ts,tsx}'],
23
+ extends: [
24
+ // Other configs...
25
+
26
+ // Remove tseslint.configs.recommended and replace with this
27
+ tseslint.configs.recommendedTypeChecked,
28
+ // Alternatively, use this for stricter rules
29
+ tseslint.configs.strictTypeChecked,
30
+ // Optionally, add this for stylistic rules
31
+ tseslint.configs.stylisticTypeChecked,
32
+
33
+ // Other configs...
34
+ ],
35
+ languageOptions: {
36
+ parserOptions: {
37
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
38
+ tsconfigRootDir: import.meta.dirname,
39
+ },
40
+ // other options...
41
+ },
42
+ },
43
+ ])
44
+ ```
45
+
46
+ You can also install [eslint-plugin-react-x](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-x) and [eslint-plugin-react-dom](https://github.com/Rel1cx/eslint-react/tree/main/packages/plugins/eslint-plugin-react-dom) for React-specific lint rules:
47
+
48
+ ```js
49
+ // eslint.config.js
50
+ import reactX from 'eslint-plugin-react-x'
51
+ import reactDom from 'eslint-plugin-react-dom'
52
+
53
+ export default defineConfig([
54
+ globalIgnores(['dist']),
55
+ {
56
+ files: ['**/*.{ts,tsx}'],
57
+ extends: [
58
+ // Other configs...
59
+ // Enable lint rules for React
60
+ reactX.configs['recommended-typescript'],
61
+ // Enable lint rules for React DOM
62
+ reactDom.configs.recommended,
63
+ ],
64
+ languageOptions: {
65
+ parserOptions: {
66
+ project: ['./tsconfig.node.json', './tsconfig.app.json'],
67
+ tsconfigRootDir: import.meta.dirname,
68
+ },
69
+ // other options...
70
+ },
71
+ },
72
+ ])
73
+ ```
@@ -0,0 +1,2 @@
1
+ import type { ViewerControlsRef, ViewerLightRef, ViewerModelRef } from "../types";
2
+ export default function useFitCamera(): (ref: ViewerModelRef, controlRef: ViewerControlsRef, lightRef: ViewerLightRef) => void;
@@ -0,0 +1,35 @@
1
+ import { Mesh } from "three";
2
+ import type { MeshBVH } from "three-mesh-bvh";
3
+ import type { ViewerModelRef } from "../types";
4
+ export type IndexArray = Uint16Array | Uint32Array;
5
+ export type IndexRange = {
6
+ count: number;
7
+ start: number;
8
+ };
9
+ export type MeshGeometryRecord = {
10
+ hiddenIds: Set<number>;
11
+ initialVisible: boolean;
12
+ mesh: Mesh;
13
+ modelID: number;
14
+ originalBoundsTree: MeshBVH | null;
15
+ originalIndex: IndexArray;
16
+ visibleStateKey: string;
17
+ triangleRanges: Array<IndexRange & {
18
+ id: number;
19
+ }>;
20
+ };
21
+ export type ElementIndexEntry = {
22
+ record: MeshGeometryRecord;
23
+ vertexRanges: IndexRange[];
24
+ };
25
+ export type GeometryIndex = {
26
+ elementIndex: Map<number, ElementIndexEntry[]>;
27
+ indexedModel: unknown;
28
+ isolatedIdsByModel: Map<number, Set<number>> | null;
29
+ isolatedIds: Set<number> | null;
30
+ records: Set<MeshGeometryRecord>;
31
+ };
32
+ export type GeometryIndexApi = {
33
+ buildIndex: () => GeometryIndex;
34
+ };
35
+ export default function useGeometryIndex(modelRef: ViewerModelRef): GeometryIndexApi;
@@ -0,0 +1,13 @@
1
+ import type { GeometryIndexApi } from "./useGeometryIndex";
2
+ export type GeometryUtilsApi = {
3
+ buildIndex: GeometryIndexApi["buildIndex"];
4
+ getAllIds: () => number[];
5
+ hideByIds: (ids: number[]) => void;
6
+ hideSelected: () => void;
7
+ isolateByIds: (ids: number[]) => void;
8
+ isolateSelected: () => void;
9
+ resetIsolation: () => void;
10
+ showAll: () => void;
11
+ showByIds: (ids: number[]) => void;
12
+ };
13
+ export default function useGeometryUtils(geometryIndex: GeometryIndexApi): GeometryUtilsApi;
@@ -0,0 +1,2 @@
1
+ import type { GeometryUtilsApi } from "../GeometryUtils/useGeometryUtils";
2
+ export default function useHotkeys(geometryUtils: GeometryUtilsApi): void;
@@ -0,0 +1,51 @@
1
+ import pako from "pako";
2
+ export type BmtIndexArray = Uint16Array | Uint32Array;
3
+ export interface BmtMaterialData {
4
+ r: number;
5
+ g: number;
6
+ b: number;
7
+ opacity: number;
8
+ name: number;
9
+ }
10
+ export interface BmtGeomData {
11
+ pos: Float32Array;
12
+ ind: BmtIndexArray;
13
+ ids: Uint32Array;
14
+ matrix: string;
15
+ mat: BmtMaterialData;
16
+ }
17
+ export type BmtModelData = Record<number, BmtGeomData>;
18
+ type BmtMeshData = {
19
+ colorId: BmtMaterialData;
20
+ ids: Uint8Array;
21
+ ind: {
22
+ data: Uint8Array;
23
+ type: number;
24
+ };
25
+ pos: Uint8Array;
26
+ };
27
+ export declare class BinaryReader {
28
+ view: DataView;
29
+ offset: number;
30
+ constructor(buffer: ArrayBuffer);
31
+ readUint8(): number;
32
+ readUint32(): number;
33
+ readBytes(length: number): Uint8Array<ArrayBufferLike>;
34
+ eof(): boolean;
35
+ }
36
+ export declare class BMTLoader {
37
+ decodeBuffer(buffer: Uint8Array): string;
38
+ decoder: typeof pako;
39
+ textDecoder: TextDecoder;
40
+ ChunkType: {
41
+ PROP: number;
42
+ MESH: number;
43
+ STRUCTURE: number;
44
+ GRIDS: number;
45
+ MATRIX: number;
46
+ };
47
+ parseMesh(data: Uint8Array): BmtMeshData;
48
+ loadModel(path: string): Promise<BmtModelData>;
49
+ parseBinaryFile(data: ArrayBuffer): BmtModelData;
50
+ }
51
+ export {};
package/lib/Model.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type { BmtModelData } from "./Loaders/BmtLoader";
2
+ type ModelProps = {
3
+ modelID: number;
4
+ data: BmtModelData;
5
+ };
6
+ declare function Model({ modelID, data }: ModelProps): import("react/jsx-runtime").JSX.Element;
7
+ export default Model;
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { Matrix4 } from "three";
3
+ import type { BmtGeomData, BmtMaterialData } from "./Loaders/BmtLoader";
4
+ type SelectableMeshProps = {
5
+ data: BmtGeomData;
6
+ material: BmtMaterialData;
7
+ meshMatrix: Matrix4;
8
+ };
9
+ export declare const SelectableMesh: React.MemoExoticComponent<({ material, data, meshMatrix, }: SelectableMeshProps) => import("react/jsx-runtime").JSX.Element>;
10
+ export {};
@@ -0,0 +1,50 @@
1
+ import type { MutableRefObject } from "react";
2
+ import { Camera, Object3D, Vector2 } from "three";
3
+ export type ClientRectSelection = {
4
+ minX: number;
5
+ minY: number;
6
+ maxX: number;
7
+ maxY: number;
8
+ };
9
+ export type SelectionBoxMode = "contains" | "intersects";
10
+ export type SelectionBoxProfile = {
11
+ boundsCheckMs: number;
12
+ candidateIds: number;
13
+ containedCandidateVertices: number;
14
+ containedIdsMs: number;
15
+ containedVerticesVisited: number;
16
+ intersectsBoundsCalls: number;
17
+ intersectsBoundsMs: number;
18
+ intersectsRangeCalls: number;
19
+ intersectsRangeMs: number;
20
+ intersectsTriangleCalls: number;
21
+ intersectsTriangleMs: number;
22
+ matrixUpdateMs: number;
23
+ meshCount: number;
24
+ mode: SelectionBoxMode;
25
+ selectedIds: number;
26
+ shapecastMs: number;
27
+ skippedMeshCount: number;
28
+ totalMs: number;
29
+ trianglePointCalls: number;
30
+ trianglePointMs: number;
31
+ trianglePointVertices: number;
32
+ triangleProjectionMs: number;
33
+ };
34
+ export declare const MIN_BOX_SIZE = 6;
35
+ export declare function getClientSelectionRect(start: Vector2, end: Vector2): ClientRectSelection;
36
+ export declare function getSelectionBoxMode(start: Vector2, end: Vector2): SelectionBoxMode;
37
+ export declare function getBoxSelectedIds({ model, camera, domElement, rect, mode, profile, }: {
38
+ model: Object3D | null;
39
+ camera: Camera;
40
+ domElement: HTMLElement;
41
+ rect: ClientRectSelection;
42
+ mode: SelectionBoxMode;
43
+ profile?: SelectionBoxProfile;
44
+ }): Map<number, Set<number>>;
45
+ export declare function getBoxSelectedIdsProfiled(options: Parameters<typeof getBoxSelectedIds>[0]): {
46
+ ids: Map<number, Set<number>>;
47
+ profile: SelectionBoxProfile;
48
+ };
49
+ export declare function updateSelectionBoxElement(elementRef: MutableRefObject<HTMLDivElement | null>, start: Vector2, end: Vector2): void;
50
+ export declare function removeSelectionBoxElement(elementRef: MutableRefObject<HTMLDivElement | null>): void;
@@ -0,0 +1,3 @@
1
+ import type { GeometryIndexApi } from "../GeometryUtils/useGeometryIndex";
2
+ import type { ViewerControlsRef, ViewerModelRef } from "../types";
3
+ export default function useSelector(modelRef: ViewerModelRef, controlRef: ViewerControlsRef, geometryIndex: GeometryIndexApi): void;
@@ -0,0 +1,21 @@
1
+ import { type ComponentProps } from "react";
2
+ import type { BmtModelData } from "./Loaders/BmtLoader";
3
+ import { Canvas } from "@react-three/fiber";
4
+ import { type ViewerApi, type ViewerSelection } from "./api/ViewerApi";
5
+ import { type ViewerModelSource } from "./api/loader";
6
+ type ModelsData = Record<number, BmtModelData>;
7
+ export type ViewerModelsData = ModelsData;
8
+ export type ViewerProps = {
9
+ camera?: ComponentProps<typeof Canvas>["camera"];
10
+ dpr?: ComponentProps<typeof Canvas>["dpr"];
11
+ defaultSelected?: ViewerSelection;
12
+ modelUrls?: string[];
13
+ modelSources?: ViewerModelSource[];
14
+ modelsData?: ModelsData;
15
+ onReady?: (api: ViewerApi) => void;
16
+ onSelectedChange?: (selected: ViewerSelection) => void;
17
+ selected?: ViewerSelection;
18
+ showStats?: boolean;
19
+ };
20
+ declare const Viewer: import("react").ForwardRefExoticComponent<ViewerProps & import("react").RefAttributes<ViewerApi>>;
21
+ export default Viewer;
@@ -0,0 +1,40 @@
1
+ import type { SelectedStore, UserDevice, ViewerStoreApi } from "../store/ViewerStore";
2
+ export type ViewerSelection = Record<number, number[]>;
3
+ export type ViewerGeometryUtilsApi = {
4
+ getAllIds: () => number[];
5
+ hideByIds: (ids: number[]) => void;
6
+ hideSelected: () => void;
7
+ isolateByIds: (ids: number[]) => void;
8
+ isolateSelected: () => void;
9
+ resetIsolation: () => void;
10
+ showAll: () => void;
11
+ showByIds: (ids: number[]) => void;
12
+ };
13
+ export type ViewerSelectorApi = {
14
+ addSelected: (modelID: number, ids: number[]) => void;
15
+ getSelected: () => ViewerSelection;
16
+ removeSelected: (modelID: number, ids: number[]) => void;
17
+ resetSelection: (modelID?: number) => void;
18
+ setSelected: (modelID: number, ids: number[], reset?: boolean) => void;
19
+ };
20
+ export type ViewerUtilsApi = {
21
+ getShowStats: () => boolean;
22
+ getUserDevice: () => UserDevice;
23
+ setShowStats: (showStats: boolean) => void;
24
+ };
25
+ export type ViewerCameraApi = {
26
+ fitCamera: () => void;
27
+ };
28
+ export type ViewerApi = {
29
+ camera: ViewerCameraApi;
30
+ geometryUtils: ViewerGeometryUtilsApi;
31
+ selector: ViewerSelectorApi;
32
+ utils: ViewerUtilsApi;
33
+ };
34
+ export type ViewerSceneApi = {
35
+ camera: ViewerCameraApi;
36
+ geometryUtils: ViewerGeometryUtilsApi;
37
+ };
38
+ export declare function serializeSelected(selected: SelectedStore): ViewerSelection;
39
+ export declare function createSelectedStore(selection: ViewerSelection): SelectedStore;
40
+ export declare function createPublicViewerApi(viewerStore: ViewerStoreApi, getSceneApi: () => ViewerSceneApi | null): ViewerApi;
@@ -0,0 +1,8 @@
1
+ import { type BmtModelData } from "../Loaders/BmtLoader";
2
+ export type ViewerModelSource = string | File;
3
+ export type ViewerLoadedModels = Record<number, BmtModelData>;
4
+ declare function loadModel(sources: ViewerModelSource[]): Promise<ViewerLoadedModels>;
5
+ export declare const loader: {
6
+ loadModel: typeof loadModel;
7
+ };
8
+ export {};
package/lib/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ export { default as Viewer } from "./Viewer";
2
+ export type { ViewerModelsData, ViewerProps } from "./Viewer";
3
+ export type { ViewerApi, ViewerCameraApi, ViewerGeometryUtilsApi, ViewerSelection, ViewerSelectorApi, ViewerUtilsApi, } from "./api/ViewerApi";
4
+ export { BMTLoader } from "./Loaders/BmtLoader";
5
+ export type { BmtGeomData, BmtIndexArray, BmtMaterialData, BmtModelData, } from "./Loaders/BmtLoader";
6
+ export { loader } from "./api/loader";
7
+ export type { ViewerLoadedModels, ViewerModelSource } from "./api/loader";
8
+ export { createViewerStore, } from "./store/ViewerStore";
9
+ export { ViewerStoreProvider } from "./store/ViewerStoreProvider";
10
+ export { useViewerStore, useViewerStoreApi, } from "./store/useViewerStore";
11
+ export type { SelectedStore, UserDevice, ViewerStore, ViewerStoreApi, } from "./store/ViewerStore";