@nebula-spatial/cad-loader 0.1.0 → 0.2.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/CHANGELOG.md +14 -0
- package/README.md +56 -27
- package/dist/index.d.ts +9 -1
- package/dist/index.js +2797 -1632
- package/dist/loader/geo-loader.d.ts +3 -2
- package/dist/loader/internal/automatic-external-resources.d.ts +26 -0
- package/dist/loader/internal/geo-node.d.ts +22 -6
- package/dist/render-resource/cad-render-node.d.ts +71 -0
- package/dist/render-resource/geo-node-cad-render-node.d.ts +12 -0
- package/dist/selection/cad-text-selection.d.ts +31 -0
- package/dist/session/annotation-idle-gate.d.ts +14 -0
- package/dist/session/cad-document-session.d.ts +155 -0
- package/dist/session/cad-font-runtime.d.ts +11 -0
- package/dist/session/cad-insert-id.d.ts +6 -0
- package/dist/session/cad-text-warmup.d.ts +38 -0
- package/dist/session/create-cad-document-session.d.ts +5 -0
- package/dist/session/viewport-coverage.d.ts +32 -0
- package/package.json +2 -1
|
@@ -2,7 +2,7 @@ import type { ExternalBlockVariantManifestEntry, ParsedGeoPayload, TextEntity }
|
|
|
2
2
|
import { type CadLoadSource } from '../shared/cad-load-source';
|
|
3
3
|
import { GeoNode } from './internal/geo-node';
|
|
4
4
|
import type { ResolveTextFont } from '../shared/text-font';
|
|
5
|
-
import { type
|
|
5
|
+
import { type ExternalVariantDependencyOptions, type ExternalVariantDependencyPlan, type ParsedHeader, type CadExternalVariantDelta as GeoNodeExternalVariantDelta } from '../core';
|
|
6
6
|
export type { ExternalVariantDependencyOptions, ExternalVariantDependencyPlan } from '../core';
|
|
7
7
|
export interface ExternalVariantFetchSource {
|
|
8
8
|
readonly baseUrl: string;
|
|
@@ -25,6 +25,7 @@ export interface LoadGeoOptions {
|
|
|
25
25
|
externalVariantGeometryFetchIds?: readonly number[];
|
|
26
26
|
}
|
|
27
27
|
export interface LoadExternalVariantDeltaOptions {
|
|
28
|
+
signal?: AbortSignal;
|
|
28
29
|
beforeTextAppend?: (texts: readonly TextEntity[]) => void | Promise<void>;
|
|
29
30
|
hiddenInstanceIds?: readonly number[];
|
|
30
31
|
externalVariantFetchSource?: ExternalVariantFetchSource;
|
|
@@ -47,7 +48,7 @@ export declare function readBufferExternalAnnotationManifest(buf: ArrayBuffer):
|
|
|
47
48
|
export declare function readBufferExternalBlockAnnotations(buf: ArrayBuffer, options?: {
|
|
48
49
|
externalVariantBuffers?: ReadonlyMap<number, ArrayBuffer>;
|
|
49
50
|
hiddenInstanceIds?: ReadonlySet<number>;
|
|
50
|
-
}): DecodedAnnotationSidecar | null;
|
|
51
|
+
}): import("..").DecodedAnnotationSidecar | null;
|
|
51
52
|
export declare function loadExternalVariantDeltaFromBuffer(buf: ArrayBuffer, options: LoadExternalVariantDeltaFetchSourceOptions): GeoNodeExternalVariantDelta;
|
|
52
53
|
export declare function loadExternalVariantDeltaFromBuffer(buf: ArrayBuffer, options: LoadExternalVariantDeltaOptions): GeoNodeExternalVariantDelta;
|
|
53
54
|
export declare function assertValidSourceOrThrow(source: unknown): asserts source is import('../shared/types').GeoLoadSource;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { GeoLoadSource } from '../../shared/types';
|
|
2
|
+
import { readExternalAnnotationManifest, type DecodedAnnotationSidecar, type ExternalVariantDependencyOptions } from '../../core';
|
|
3
|
+
export type AutomaticExternalResourceOptions = {
|
|
4
|
+
readonly loadBlocks?: boolean;
|
|
5
|
+
readonly loadAnnotations?: boolean;
|
|
6
|
+
readonly externalVariantFetchSource?: unknown;
|
|
7
|
+
readonly externalVariantBuffers?: ReadonlyMap<number, ArrayBuffer>;
|
|
8
|
+
readonly requiredExternalVariantIds?: readonly number[];
|
|
9
|
+
readonly externalVariantGeometryFetchIds?: readonly number[];
|
|
10
|
+
};
|
|
11
|
+
export type AutomaticExternalResources = {
|
|
12
|
+
readonly requiredExternalVariantIds?: readonly number[];
|
|
13
|
+
readonly externalVariantGeometryFetchIds?: readonly number[];
|
|
14
|
+
readonly externalVariantBuffers?: ReadonlyMap<number, ArrayBuffer>;
|
|
15
|
+
readonly annotations: readonly DecodedAnnotationSidecar[];
|
|
16
|
+
};
|
|
17
|
+
export declare function resolveAbsoluteSourceUrl(source: GeoLoadSource): string | null;
|
|
18
|
+
export declare function hasAnnotationPayload(annotation: DecodedAnnotationSidecar | null): annotation is DecodedAnnotationSidecar;
|
|
19
|
+
export declare function fetchSceneAnnotation(baseUrl: string, manifest: NonNullable<ReturnType<typeof readExternalAnnotationManifest>>['scene'], signal: AbortSignal): Promise<DecodedAnnotationSidecar | null>;
|
|
20
|
+
export declare function resolveAutomaticExternalResources(source: GeoLoadSource, buffer: ArrayBuffer, options: AutomaticExternalResourceOptions, hiddenInstanceIds: ReadonlySet<number> | undefined, signal: AbortSignal): Promise<AutomaticExternalResources>;
|
|
21
|
+
export declare function buildExternalVariantDependencyOptions(input: {
|
|
22
|
+
readonly loadBlocks?: boolean;
|
|
23
|
+
readonly hiddenInstanceIds?: ReadonlySet<number>;
|
|
24
|
+
readonly viewport?: ExternalVariantDependencyOptions['viewport'];
|
|
25
|
+
readonly worldUnitsPerPixel?: number;
|
|
26
|
+
}): ExternalVariantDependencyOptions;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Group } from 'three';
|
|
1
|
+
import { Group, Object3D } from 'three';
|
|
2
2
|
import { type ResolveTextFont } from '../../shared/text-font';
|
|
3
3
|
import type { GeoMetaSnapshot, LayerBlockUsage, LayerSnapshot, LineRenderMode, TextEntity, ViewportRect } from '../../shared/types';
|
|
4
4
|
import { type ViewerThemeName } from '../../shared/viewer-theme';
|
|
@@ -23,12 +23,17 @@ export type ColorPipelineStatsSnapshot = {
|
|
|
23
23
|
};
|
|
24
24
|
type BBox = ViewportRect;
|
|
25
25
|
type YieldCallback = () => void | Promise<void>;
|
|
26
|
-
export type
|
|
27
|
-
export type
|
|
28
|
-
readonly kind:
|
|
26
|
+
export type GeoNodeChangeKind = 'structure' | 'visual';
|
|
27
|
+
export type GeoNodeChange = {
|
|
28
|
+
readonly kind: GeoNodeChangeKind;
|
|
29
29
|
};
|
|
30
|
-
export
|
|
31
|
-
|
|
30
|
+
export type GeoNodeChangeListener = (change: GeoNodeChange) => void;
|
|
31
|
+
/** @deprecated Use GeoNodeChangeKind. */
|
|
32
|
+
export type GeoNodeInternalChangeKind = GeoNodeChangeKind;
|
|
33
|
+
/** @deprecated Use GeoNodeChange. */
|
|
34
|
+
export type GeoNodeInternalChange = GeoNodeChange;
|
|
35
|
+
export declare const GEO_NODE_STRUCTURE_CHANGE: GeoNodeChange;
|
|
36
|
+
export declare const GEO_NODE_VISUAL_CHANGE: GeoNodeChange;
|
|
32
37
|
type FinalizeIncrementallyOptions = Record<string, never>;
|
|
33
38
|
export interface InsertInstanceMatrix2D {
|
|
34
39
|
readonly matA: number;
|
|
@@ -38,6 +43,11 @@ export interface InsertInstanceMatrix2D {
|
|
|
38
43
|
readonly tx: number;
|
|
39
44
|
readonly ty: number;
|
|
40
45
|
}
|
|
46
|
+
export interface InsertPreviewResource {
|
|
47
|
+
readonly object: Object3D;
|
|
48
|
+
readonly bounds: ViewportRect;
|
|
49
|
+
dispose(): void;
|
|
50
|
+
}
|
|
41
51
|
export declare function setGeoNodeLoadAbortHook(node: GeoNode, hook: (() => void) | null): void;
|
|
42
52
|
export declare class GeoNode extends Group {
|
|
43
53
|
private meta;
|
|
@@ -87,6 +97,7 @@ export declare class GeoNode extends Group {
|
|
|
87
97
|
private readonly worldSizedPointUniforms;
|
|
88
98
|
private lineResolution;
|
|
89
99
|
private internalChangeHook;
|
|
100
|
+
private readonly changeListeners;
|
|
90
101
|
private disposed;
|
|
91
102
|
private readySettled;
|
|
92
103
|
private layerBlockUsages;
|
|
@@ -101,6 +112,8 @@ export declare class GeoNode extends Group {
|
|
|
101
112
|
resolveTextFont?: ResolveTextFont;
|
|
102
113
|
});
|
|
103
114
|
get ready(): Promise<void>;
|
|
115
|
+
onChange(listener: GeoNodeChangeListener): () => void;
|
|
116
|
+
_notifyStructureChange(): void;
|
|
104
117
|
setLayerVisible(layerIndex: number, visible: boolean): void;
|
|
105
118
|
setAnnotationOverlayVisible(visible: boolean): void;
|
|
106
119
|
setDisplayTheme(themeName: ViewerThemeName, options?: {
|
|
@@ -138,6 +151,7 @@ export declare class GeoNode extends Group {
|
|
|
138
151
|
getInsertVariantGeometry(variantId: number): VariantGeometry | null;
|
|
139
152
|
getInsertInstanceMatrix(instanceId: number, variantId?: number): InsertInstanceMatrix2D | null;
|
|
140
153
|
getInsertPreviewRecordsForInstance(instanceId: number): readonly InsertInstanceRecord[];
|
|
154
|
+
createInsertPreviewResource(instanceId: number): InsertPreviewResource | null;
|
|
141
155
|
getEffectiveLayerColorHex(layerIndex: number): number | null;
|
|
142
156
|
private resolveInsertRuntimeInstance;
|
|
143
157
|
updateTextEntry(textId: number, patch: Partial<{
|
|
@@ -201,7 +215,9 @@ export declare class GeoNode extends Group {
|
|
|
201
215
|
_finalizeIncrementally(onYield?: YieldCallback, maxCompactOpsPerPass?: number, _options?: FinalizeIncrementallyOptions): Promise<void>;
|
|
202
216
|
_fail(err: Error): void;
|
|
203
217
|
_setInternalChangeHook(callback: ((change: GeoNodeInternalChange) => void) | null): void;
|
|
218
|
+
setViewportSize(width: number, height: number): void;
|
|
204
219
|
_setViewportSize(width: number, height: number): void;
|
|
220
|
+
private updateViewportSize;
|
|
205
221
|
private createPointMaterial;
|
|
206
222
|
private resolvePointWorldSize;
|
|
207
223
|
private appendTextChunk;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { Object3D } from 'three';
|
|
2
|
+
import type { CadDisplayContext, CadVisibilityFilter, CadWorldBounds } from '../session/cad-document-session';
|
|
3
|
+
import type { RenderDebugBreakdownEntry, SplitBlockLayerDetail } from '../shared/types';
|
|
4
|
+
export declare const CAD_RENDER_NODE_EDIT_METHODS: readonly ["updateTextEntry", "updateInsertInstanceTransform", "applyInsertTransform", "editBlock"];
|
|
5
|
+
export type CadRenderContentKind = 'geometry' | 'annotation';
|
|
6
|
+
export interface CadRenderContentChunk {
|
|
7
|
+
readonly documentFingerprint: string;
|
|
8
|
+
readonly variantId: string | number;
|
|
9
|
+
readonly chunkId: string;
|
|
10
|
+
readonly contentRevision: number;
|
|
11
|
+
readonly kind: CadRenderContentKind;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Disposable, read-only geometry borrowed from the CAD insert presenter.
|
|
15
|
+
* Disposing the preview releases only its presenter wrappers and materials;
|
|
16
|
+
* the document-owned block geometry remains owned by the render node.
|
|
17
|
+
*/
|
|
18
|
+
export interface CadInsertPreviewResource {
|
|
19
|
+
readonly object: Object3D;
|
|
20
|
+
readonly bounds: CadWorldBounds;
|
|
21
|
+
dispose(): void;
|
|
22
|
+
}
|
|
23
|
+
export interface CadRenderDiagnostics {
|
|
24
|
+
readonly entityCount: number;
|
|
25
|
+
readonly lineCount: number;
|
|
26
|
+
readonly fillCount: number;
|
|
27
|
+
readonly dotCount: number;
|
|
28
|
+
readonly textCount: number;
|
|
29
|
+
readonly lineRenderMode: string;
|
|
30
|
+
readonly renderableCount?: number;
|
|
31
|
+
readonly submittedVertexRefs?: number;
|
|
32
|
+
readonly blockVariantCount?: number;
|
|
33
|
+
readonly blockInstanceCount?: number;
|
|
34
|
+
readonly splitBlockLayerGroupCount?: number;
|
|
35
|
+
/** Draw-call source breakdown by renderable kind, for the debug popup. */
|
|
36
|
+
readonly renderDebugBreakdown?: RenderDebugBreakdownEntry[];
|
|
37
|
+
/** Top cross-layer block variants, for the debug popup. */
|
|
38
|
+
readonly splitBlockLayerDetails?: SplitBlockLayerDetail[];
|
|
39
|
+
}
|
|
40
|
+
export interface CadInsertVisibilityChange {
|
|
41
|
+
readonly insertId: string;
|
|
42
|
+
readonly visible: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Read-only CAD render resource. Editing methods belong to legacy GeoNode and
|
|
46
|
+
* must not appear on this type.
|
|
47
|
+
*/
|
|
48
|
+
export interface CadRenderNode {
|
|
49
|
+
readonly object: Object3D;
|
|
50
|
+
readonly contentRevision: number;
|
|
51
|
+
getAuthoritativeBounds(filter: CadVisibilityFilter): CadWorldBounds | null;
|
|
52
|
+
getMountedBounds(filter: CadVisibilityFilter): CadWorldBounds | null;
|
|
53
|
+
getUnmountedExternalBounds(filter: CadVisibilityFilter): CadWorldBounds | null;
|
|
54
|
+
appendContent(chunk: CadRenderContentChunk): boolean;
|
|
55
|
+
setDisplayContext(context: CadDisplayContext): void;
|
|
56
|
+
setLayerVisible(layerIndex: number, visible: boolean): void;
|
|
57
|
+
setLayerColorOverride(layerIndex: number, color: number | null): void;
|
|
58
|
+
setInsertVisible(insertId: string, visible: boolean): void;
|
|
59
|
+
/**
|
|
60
|
+
* Applies many insert visibility changes atomically: one hidden-set update,
|
|
61
|
+
* one presenter refresh, and one structure/onChange notification for the
|
|
62
|
+
* whole batch, instead of one per call.
|
|
63
|
+
*/
|
|
64
|
+
setInsertVisibleBatch(changes: ReadonlyArray<CadInsertVisibilityChange>): void;
|
|
65
|
+
createInsertPreview(instanceId: number): CadInsertPreviewResource | null;
|
|
66
|
+
getDiagnostics(): CadRenderDiagnostics;
|
|
67
|
+
onChange(listener: () => void): () => void;
|
|
68
|
+
dispose(): void;
|
|
69
|
+
}
|
|
70
|
+
export type CadRenderNodeEditMethod = (typeof CAD_RENDER_NODE_EDIT_METHODS)[number];
|
|
71
|
+
export declare function isCadRenderNodeEditMethod(value: string): value is CadRenderNodeEditMethod;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { GeoNode } from '../loader/internal/geo-node';
|
|
2
|
+
import type { CadWorldBounds } from '../session/cad-document-session';
|
|
3
|
+
import type { CadRenderNode } from './cad-render-node';
|
|
4
|
+
export declare function planarBoundsFromXy(bounds: readonly [number, number, number, number] | null | undefined): CadWorldBounds | null;
|
|
5
|
+
export declare function mergeWorldBounds(current: CadWorldBounds | null, next: CadWorldBounds | null): CadWorldBounds | null;
|
|
6
|
+
export declare function createGeoNodeCadRenderNode(input: {
|
|
7
|
+
readonly node: GeoNode;
|
|
8
|
+
readonly getHeaderBounds: () => CadWorldBounds | null;
|
|
9
|
+
readonly getUnmountedBounds: () => CadWorldBounds | null;
|
|
10
|
+
readonly hiddenInstanceIds: Set<number>;
|
|
11
|
+
readonly onInsertVisibilityChange: () => void;
|
|
12
|
+
}): CadRenderNode;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { GeoNode } from '../loader/internal/geo-node';
|
|
2
|
+
export interface CadPoint2D {
|
|
3
|
+
readonly x: number;
|
|
4
|
+
readonly y: number;
|
|
5
|
+
}
|
|
6
|
+
export interface CadTextSelectionId {
|
|
7
|
+
readonly kind: 'text';
|
|
8
|
+
readonly textId: number;
|
|
9
|
+
}
|
|
10
|
+
export interface CadTextDetails {
|
|
11
|
+
readonly id: CadTextSelectionId;
|
|
12
|
+
readonly content: string;
|
|
13
|
+
readonly x: number;
|
|
14
|
+
readonly y: number;
|
|
15
|
+
readonly height: number;
|
|
16
|
+
readonly rotation: number;
|
|
17
|
+
readonly layerName: string;
|
|
18
|
+
readonly layerIndex: number;
|
|
19
|
+
}
|
|
20
|
+
export interface CadTextSelection {
|
|
21
|
+
readonly documentKey: string | null;
|
|
22
|
+
readonly id: CadTextSelectionId;
|
|
23
|
+
readonly details: CadTextDetails | null;
|
|
24
|
+
}
|
|
25
|
+
export interface CadTextPickOptions {
|
|
26
|
+
/** Optional upper bound for callers that need to cap interactive scans. */
|
|
27
|
+
readonly maxTextCount?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function pickCadTextAtPoint(node: Pick<GeoNode, 'getTextEntries' | 'getLayers'>, point: CadPoint2D, options?: CadTextPickOptions): CadTextSelectionId | null;
|
|
30
|
+
export declare function resolveCadTextDetails(node: Pick<GeoNode, 'getTextEntries' | 'getLayers'>, id: CadTextSelectionId): CadTextDetails | null;
|
|
31
|
+
export declare function cadTextSelectionEquals(a: CadTextSelectionId | null, b: CadTextSelectionId | null): boolean;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { ViewportRect } from '../core';
|
|
2
|
+
import type { ExternalBlockVariantManifestEntry, ExternalSceneAnnotationManifestEntry } from '../shared/types';
|
|
3
|
+
/** Copied from the product annotation idle gate. */
|
|
4
|
+
export declare const ANNOTATION_TEXT_APPEND_IDLE_DELAY_MS = 450;
|
|
5
|
+
export declare const ANNOTATION_LOAD_MAX_WORLD_UNITS_PER_PIXEL = 250;
|
|
6
|
+
export declare const ANNOTATION_VIEWPORT_PADDING_RATIO = 0.25;
|
|
7
|
+
export declare function shouldLoadSceneAnnotations(input: {
|
|
8
|
+
readonly manifestBBox: ViewportRect | null;
|
|
9
|
+
readonly viewport: ViewportRect | null;
|
|
10
|
+
readonly worldUnitsPerPixel: number;
|
|
11
|
+
}): boolean;
|
|
12
|
+
export declare function sceneManifestBBox(scene: ExternalSceneAnnotationManifestEntry | null | undefined): ViewportRect | null;
|
|
13
|
+
export declare function hasBlockAnnotationPayload(entry: ExternalBlockVariantManifestEntry): boolean;
|
|
14
|
+
export declare function isAnnotationZoomReadable(worldUnitsPerPixel: number): boolean;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { CadInsertDetails, CadInsertSelectionId } from '../selection/cad-insert-selection';
|
|
2
|
+
import type { CadTextSelection } from '../selection/cad-text-selection';
|
|
3
|
+
import type { ResolveTextFont } from '../shared/text-font';
|
|
4
|
+
import type { CadTextWarmupOptions } from './cad-text-warmup';
|
|
5
|
+
import type { ViewportRect } from '../core';
|
|
6
|
+
export type { CadInsertDetails, CadInsertSelectionId } from '../selection/cad-insert-selection';
|
|
7
|
+
export type { CadTextDetails, CadTextSelection, CadTextSelectionId } from '../selection/cad-text-selection';
|
|
8
|
+
export type { CadLoadSource } from '../shared/cad-load-source';
|
|
9
|
+
export type { CadTextWarmupOptions, CadTextWarmupStats } from './cad-text-warmup';
|
|
10
|
+
export type { ViewportRect as CadViewportRect } from '../core';
|
|
11
|
+
export type CadSessionPhase = 'created' | 'header-ready' | 'initial-loading' | 'interactive' | 'failed' | 'disposed';
|
|
12
|
+
export declare const CAD_SESSION_PHASES: readonly ["created", "header-ready", "initial-loading", "interactive", "failed", "disposed"];
|
|
13
|
+
export interface CadWorldPoint {
|
|
14
|
+
readonly x: number;
|
|
15
|
+
readonly y: number;
|
|
16
|
+
readonly z: number;
|
|
17
|
+
}
|
|
18
|
+
/** Authoritative CAD bounds. Planar sources use a degenerate Z interval. */
|
|
19
|
+
export interface CadWorldBounds {
|
|
20
|
+
readonly minX: number;
|
|
21
|
+
readonly minY: number;
|
|
22
|
+
readonly minZ: number;
|
|
23
|
+
readonly maxX: number;
|
|
24
|
+
readonly maxY: number;
|
|
25
|
+
readonly maxZ: number;
|
|
26
|
+
readonly planar: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface CadLayerMeta {
|
|
29
|
+
readonly index: number;
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly color: readonly [number, number, number];
|
|
32
|
+
readonly visible: boolean;
|
|
33
|
+
}
|
|
34
|
+
export interface CadVisibilityFilter {
|
|
35
|
+
readonly layerVisible?: ReadonlyMap<number, boolean> | ((layerIndex: number) => boolean);
|
|
36
|
+
readonly insertVisible?: ReadonlySet<string> | ((insertId: string) => boolean);
|
|
37
|
+
readonly includeUnmountedExternal?: boolean;
|
|
38
|
+
}
|
|
39
|
+
export interface CadViewportDemand {
|
|
40
|
+
readonly documentRect: ViewportRect;
|
|
41
|
+
readonly worldUnitsPerPixel: number;
|
|
42
|
+
readonly viewportWidthPx: number;
|
|
43
|
+
readonly viewportHeightPx: number;
|
|
44
|
+
readonly viewMode: '2d' | '3d';
|
|
45
|
+
readonly interaction: 'active' | 'idle';
|
|
46
|
+
readonly visibilityRevision: number;
|
|
47
|
+
}
|
|
48
|
+
export interface CadDisplayContext {
|
|
49
|
+
/** Visible document-space bounds used to cull INSERT instances in 2D. */
|
|
50
|
+
readonly documentRect?: ViewportRect | null;
|
|
51
|
+
readonly viewportWidthPx: number;
|
|
52
|
+
readonly viewportHeightPx: number;
|
|
53
|
+
readonly devicePixelRatio: number;
|
|
54
|
+
readonly worldUnitsPerPixel: number;
|
|
55
|
+
readonly viewMode: '2d' | '3d';
|
|
56
|
+
readonly quality: 'auto' | 'full' | 'stress';
|
|
57
|
+
}
|
|
58
|
+
export interface CadDocumentHeader {
|
|
59
|
+
readonly bounds: CadWorldBounds | null;
|
|
60
|
+
readonly layers: readonly CadLayerMeta[];
|
|
61
|
+
readonly sourceFingerprint: string;
|
|
62
|
+
readonly format: string;
|
|
63
|
+
readonly filename: string | null;
|
|
64
|
+
}
|
|
65
|
+
export interface CadInsertSelection {
|
|
66
|
+
readonly documentKey: string | null;
|
|
67
|
+
readonly id: CadInsertSelectionId;
|
|
68
|
+
readonly details: CadInsertDetails | null;
|
|
69
|
+
}
|
|
70
|
+
export interface CadSessionHeaderEvent {
|
|
71
|
+
readonly header: CadDocumentHeader;
|
|
72
|
+
}
|
|
73
|
+
export interface CadSessionContentAppendedEvent {
|
|
74
|
+
readonly contentRevision: number;
|
|
75
|
+
readonly kind: 'geometry' | 'annotation';
|
|
76
|
+
}
|
|
77
|
+
export interface CadSessionDemandProgressEvent {
|
|
78
|
+
readonly demandRevision: number;
|
|
79
|
+
readonly pending: number;
|
|
80
|
+
readonly loaded: number;
|
|
81
|
+
readonly settled: boolean;
|
|
82
|
+
}
|
|
83
|
+
export interface CadSessionPhaseChangeEvent {
|
|
84
|
+
readonly phase: CadSessionPhase;
|
|
85
|
+
}
|
|
86
|
+
export interface CadSessionErrorEvent {
|
|
87
|
+
readonly error: Error;
|
|
88
|
+
}
|
|
89
|
+
export interface CadSessionEventMap {
|
|
90
|
+
header: CadSessionHeaderEvent;
|
|
91
|
+
'content-appended': CadSessionContentAppendedEvent;
|
|
92
|
+
'initial-content-ready': void;
|
|
93
|
+
'demand-progress': CadSessionDemandProgressEvent;
|
|
94
|
+
'phase-change': CadSessionPhaseChangeEvent;
|
|
95
|
+
'non-fatal-error': CadSessionErrorEvent;
|
|
96
|
+
'fatal-error': CadSessionErrorEvent;
|
|
97
|
+
}
|
|
98
|
+
export interface CadFontRequest {
|
|
99
|
+
readonly family?: string;
|
|
100
|
+
readonly styleName?: string;
|
|
101
|
+
readonly shxName?: string;
|
|
102
|
+
readonly weight?: number;
|
|
103
|
+
readonly italic?: boolean;
|
|
104
|
+
}
|
|
105
|
+
export interface CadResolvedFont {
|
|
106
|
+
readonly fontUrl?: string;
|
|
107
|
+
readonly family?: string;
|
|
108
|
+
readonly fallback: boolean;
|
|
109
|
+
readonly sourceFingerprint?: string;
|
|
110
|
+
}
|
|
111
|
+
export interface CadFontResolver {
|
|
112
|
+
resolve(request: CadFontRequest, signal?: AbortSignal): Promise<CadResolvedFont | null>;
|
|
113
|
+
}
|
|
114
|
+
export interface CadInsertUsageSummary {
|
|
115
|
+
readonly insertId: string;
|
|
116
|
+
readonly blockName: string;
|
|
117
|
+
readonly layerName: string;
|
|
118
|
+
readonly layerIndex: number;
|
|
119
|
+
readonly instanceId: number;
|
|
120
|
+
readonly variantId: number;
|
|
121
|
+
readonly label: string;
|
|
122
|
+
readonly canHighlight: boolean;
|
|
123
|
+
readonly visible: boolean;
|
|
124
|
+
}
|
|
125
|
+
export interface CadDocumentSession {
|
|
126
|
+
readonly phase: CadSessionPhase;
|
|
127
|
+
readonly headerReady: Promise<CadDocumentHeader>;
|
|
128
|
+
readonly initialContentReady: Promise<void>;
|
|
129
|
+
setViewportDemand(demand: CadViewportDemand): void;
|
|
130
|
+
setDisplayContext(context: CadDisplayContext): void;
|
|
131
|
+
on<K extends keyof CadSessionEventMap>(type: K, listener: (event: CadSessionEventMap[K]) => void): () => void;
|
|
132
|
+
getBounds(filter: CadVisibilityFilter): CadWorldBounds | null;
|
|
133
|
+
getLayers(): readonly CadLayerMeta[];
|
|
134
|
+
listInsertUsages(): readonly CadInsertUsageSummary[];
|
|
135
|
+
getBlockDetails(id: string): CadInsertDetails | null;
|
|
136
|
+
pickInsertAtPoint(point: CadWorldPoint, viewport: ViewportRect): CadInsertSelection | null;
|
|
137
|
+
/** Optional for compatibility with pre-text-picking session adapters. */
|
|
138
|
+
pickTextAtPoint?(point: CadWorldPoint): CadTextSelection | null;
|
|
139
|
+
abort(reason?: unknown): void;
|
|
140
|
+
dispose(): void;
|
|
141
|
+
}
|
|
142
|
+
export interface CadDocumentSessionOptions {
|
|
143
|
+
readonly documentKey?: string;
|
|
144
|
+
readonly filename?: string;
|
|
145
|
+
readonly loadAnnotations?: boolean;
|
|
146
|
+
readonly fontResolver?: CadFontResolver;
|
|
147
|
+
readonly resolveTextFont?: ResolveTextFont;
|
|
148
|
+
/**
|
|
149
|
+
* Troika glyph warmup policy. Defaults to enabled: characters of appended
|
|
150
|
+
* texts (initial load, delta variants, annotations) are preloaded in
|
|
151
|
+
* idle-delayed background batches. Set to `false` to disable.
|
|
152
|
+
*/
|
|
153
|
+
readonly textWarmup?: boolean | CadTextWarmupOptions;
|
|
154
|
+
readonly signal?: AbortSignal;
|
|
155
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type ResolveTextFont } from '../shared/text-font';
|
|
2
|
+
import type { CadFontResolver } from './cad-document-session';
|
|
3
|
+
export type CadFontRuntime = {
|
|
4
|
+
readonly resolveTextFont: ResolveTextFont;
|
|
5
|
+
dispose(): void;
|
|
6
|
+
};
|
|
7
|
+
export declare function createCadFontRuntime(input: {
|
|
8
|
+
readonly fontResolver?: CadFontResolver;
|
|
9
|
+
readonly signal: AbortSignal;
|
|
10
|
+
readonly onNonFatalError: (error: Error) => void;
|
|
11
|
+
}): CadFontRuntime;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { CadInsertSelectionId } from '../selection/cad-insert-selection';
|
|
2
|
+
export declare function formatCadInsertId(id: CadInsertSelectionId): string;
|
|
3
|
+
export declare function parseCadInsertId(value: string): CadInsertSelectionId | {
|
|
4
|
+
readonly instanceId: number;
|
|
5
|
+
} | null;
|
|
6
|
+
export declare function cadInsertInstanceId(value: string): number | null;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { ResolvedTextFont } from '../shared/text-font';
|
|
2
|
+
export interface CadTextWarmupOptions {
|
|
3
|
+
/** Idle delay before a scheduled warmup batch flushes. Default 600ms. */
|
|
4
|
+
readonly idleDelayMs?: number;
|
|
5
|
+
/** Max unique characters accumulated per font before capping. Default 256. */
|
|
6
|
+
readonly maxUniqueCharsPerFont?: number;
|
|
7
|
+
/** Per-preload timeout. Default 8000ms. */
|
|
8
|
+
readonly timeoutMs?: number;
|
|
9
|
+
/** Max remembered warm signatures. Default 96. */
|
|
10
|
+
readonly signatureCacheLimit?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface CadTextWarmupStats {
|
|
13
|
+
readonly scheduledTexts: number;
|
|
14
|
+
readonly preloadCalls: number;
|
|
15
|
+
readonly skippedRepeatedSignatures: number;
|
|
16
|
+
readonly failedWarmups: number;
|
|
17
|
+
readonly timedOutWarmups: number;
|
|
18
|
+
readonly evictedSignatures: number;
|
|
19
|
+
readonly warmedSignatures: number;
|
|
20
|
+
readonly inFlightWarmups: number;
|
|
21
|
+
}
|
|
22
|
+
export type CadTextWarmup = {
|
|
23
|
+
/** Schedules characters of `texts` for background glyph warmup (idle, deduped). */
|
|
24
|
+
scheduleForTexts(texts: readonly string[]): void;
|
|
25
|
+
/** Cancels pending timers and in-flight bookkeeping. In-flight preloads are left to settle. */
|
|
26
|
+
dispose(): void;
|
|
27
|
+
readonly stats: CadTextWarmupStats;
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Session-scoped Troika glyph warmup runtime. Characters are bucketed per
|
|
31
|
+
* resolved font URL, deduped by (font, charset) signature, and preloaded in a
|
|
32
|
+
* single idle-delayed background flush. SSR/headless environments are a no-op.
|
|
33
|
+
*/
|
|
34
|
+
export declare function createCadTextWarmup(input: {
|
|
35
|
+
readonly resolveTextFont: (text: string) => ResolvedTextFont;
|
|
36
|
+
readonly signal: AbortSignal;
|
|
37
|
+
readonly options?: CadTextWarmupOptions;
|
|
38
|
+
}): CadTextWarmup;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type CadLoadSource } from '../shared/cad-load-source';
|
|
2
|
+
import type { CadRenderNode } from '../render-resource/cad-render-node';
|
|
3
|
+
import type { CadDocumentSession, CadDocumentSessionOptions } from './cad-document-session';
|
|
4
|
+
export declare function getCadDocumentRenderResource(session: CadDocumentSession): CadRenderNode;
|
|
5
|
+
export declare function createCadDocumentSession(source: CadLoadSource, options?: CadDocumentSessionOptions): CadDocumentSession;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { ViewportRect } from '../core';
|
|
2
|
+
/** Copied from the product AppController viewport-sidecar refresh policy. */
|
|
3
|
+
export declare const EXTERNAL_VIEWPORT_REFRESH_COVERAGE_RATIO = 0.25;
|
|
4
|
+
export declare const EXTERNAL_VIEWPORT_REFRESH_SCALE_TOLERANCE_RATIO = 0.125;
|
|
5
|
+
export type CadViewportCoverageState = {
|
|
6
|
+
readonly viewport: ViewportRect | null;
|
|
7
|
+
readonly worldUnitsPerPixel: number;
|
|
8
|
+
};
|
|
9
|
+
export declare function coarseExternalViewportSignature(state: CadViewportCoverageState): string | null;
|
|
10
|
+
export declare function hiddenInstanceSignature(hiddenInstanceIds: ReadonlySet<number>): string;
|
|
11
|
+
export declare function isWorldUnitsPerPixelClose(previous: number | null, next: number): boolean;
|
|
12
|
+
export declare function canReuseExternalViewportPlan(input: {
|
|
13
|
+
readonly coverage: ViewportRect | null;
|
|
14
|
+
readonly coverageWorldUnitsPerPixel: number | null;
|
|
15
|
+
readonly coverageHiddenSignature: string | null;
|
|
16
|
+
readonly viewport: ViewportRect | null;
|
|
17
|
+
readonly worldUnitsPerPixel: number;
|
|
18
|
+
readonly hiddenSignature: string;
|
|
19
|
+
}): boolean;
|
|
20
|
+
export declare function isExternalViewportRequestStillCurrent(input: {
|
|
21
|
+
readonly requestedViewport: ViewportRect;
|
|
22
|
+
readonly requestedWorldUnitsPerPixel: number;
|
|
23
|
+
readonly requestedHiddenSignature: string;
|
|
24
|
+
readonly latestViewport: ViewportRect | null;
|
|
25
|
+
readonly latestWorldUnitsPerPixel: number;
|
|
26
|
+
readonly latestHiddenSignature: string;
|
|
27
|
+
}): boolean;
|
|
28
|
+
export declare function markExternalViewportCoverage(viewport: ViewportRect, worldUnitsPerPixel: number, hiddenSignature: string): {
|
|
29
|
+
readonly coverage: ViewportRect;
|
|
30
|
+
readonly worldUnitsPerPixel: number;
|
|
31
|
+
readonly hiddenSignature: string;
|
|
32
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nebula-spatial/cad-loader",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Browser-side DXB3/DXBS CAD pack loader runtime",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"engines": {
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
"files": [
|
|
11
11
|
"dist",
|
|
12
12
|
"README.md",
|
|
13
|
+
"CHANGELOG.md",
|
|
13
14
|
"package.json"
|
|
14
15
|
],
|
|
15
16
|
"main": "./dist/index.js",
|