three-cad-viewer 4.1.2 → 4.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/Readme.md +12 -5
- package/dist/camera/camera.d.ts +14 -2
- package/dist/core/studio-manager.d.ts +91 -0
- package/dist/core/types.d.ts +260 -9
- package/dist/core/viewer-state.d.ts +28 -2
- package/dist/core/viewer.d.ts +200 -6
- package/dist/index.d.ts +7 -2
- package/dist/rendering/environment.d.ts +239 -0
- package/dist/rendering/light-detection.d.ts +44 -0
- package/dist/rendering/material-factory.d.ts +77 -2
- package/dist/rendering/material-presets.d.ts +32 -0
- package/dist/rendering/room-environment.d.ts +13 -0
- package/dist/rendering/studio-composer.d.ts +130 -0
- package/dist/rendering/studio-floor.d.ts +53 -0
- package/dist/rendering/texture-cache.d.ts +142 -0
- package/dist/rendering/triplanar.d.ts +37 -0
- package/dist/scene/animation.d.ts +1 -1
- package/dist/scene/clipping.d.ts +31 -0
- package/dist/scene/nestedgroup.d.ts +64 -27
- package/dist/scene/objectgroup.d.ts +47 -0
- package/dist/three-cad-viewer.css +339 -29
- package/dist/three-cad-viewer.esm.js +27567 -11874
- package/dist/three-cad-viewer.esm.js.map +1 -1
- package/dist/three-cad-viewer.esm.min.js +10 -4
- package/dist/three-cad-viewer.js +27486 -11787
- package/dist/three-cad-viewer.min.js +10 -4
- package/dist/ui/display.d.ts +147 -0
- package/dist/utils/decode-instances.d.ts +60 -0
- package/dist/utils/utils.d.ts +10 -0
- package/package.json +4 -2
- package/src/_version.ts +1 -1
- package/src/camera/camera.ts +27 -10
- package/src/core/studio-manager.ts +682 -0
- package/src/core/types.ts +328 -9
- package/src/core/viewer-state.ts +84 -4
- package/src/core/viewer.ts +453 -22
- package/src/index.ts +25 -1
- package/src/rendering/environment.ts +840 -0
- package/src/rendering/light-detection.ts +327 -0
- package/src/rendering/material-factory.ts +456 -2
- package/src/rendering/material-presets.ts +303 -0
- package/src/rendering/raycast.ts +2 -2
- package/src/rendering/room-environment.ts +192 -0
- package/src/rendering/studio-composer.ts +577 -0
- package/src/rendering/studio-floor.ts +108 -0
- package/src/rendering/texture-cache.ts +1020 -0
- package/src/rendering/triplanar.ts +329 -0
- package/src/scene/animation.ts +3 -2
- package/src/scene/clipping.ts +59 -0
- package/src/scene/nestedgroup.ts +399 -0
- package/src/scene/objectgroup.ts +186 -11
- package/src/scene/orientation.ts +12 -0
- package/src/scene/render-shape.ts +55 -21
- package/src/types/n8ao.d.ts +28 -0
- package/src/ui/display.ts +1032 -27
- package/src/ui/index.html +181 -44
- package/src/utils/decode-instances.ts +233 -0
- package/src/utils/utils.ts +33 -20
package/src/core/types.ts
CHANGED
|
@@ -28,7 +28,7 @@ export type UpDirection = "Z" | "Y" | "legacy";
|
|
|
28
28
|
export type AnimationMode = "none" | "animation" | "explode";
|
|
29
29
|
|
|
30
30
|
/** Active sidebar tab */
|
|
31
|
-
export type ActiveTab = "tree" | "clip" | "material" | "zebra";
|
|
31
|
+
export type ActiveTab = "tree" | "clip" | "material" | "zebra" | "studio";
|
|
32
32
|
|
|
33
33
|
/** Zebra color scheme */
|
|
34
34
|
export type ZebraColorScheme = "blackwhite" | "colorful" | "grayscale";
|
|
@@ -36,6 +36,23 @@ export type ZebraColorScheme = "blackwhite" | "colorful" | "grayscale";
|
|
|
36
36
|
/** Zebra mapping mode */
|
|
37
37
|
export type ZebraMappingMode = "reflection" | "normal";
|
|
38
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Studio environment preset name.
|
|
41
|
+
* - "studio": Built-in procedural RoomEnvironment (zero network)
|
|
42
|
+
* - "none": No environment map
|
|
43
|
+
* - Any other string: Poly Haven HDR preset slug or custom HDR URL
|
|
44
|
+
*/
|
|
45
|
+
export type StudioEnvironment = string;
|
|
46
|
+
|
|
47
|
+
/** Studio tone mapping algorithm */
|
|
48
|
+
export type StudioToneMapping = "neutral" | "ACES" | "none";
|
|
49
|
+
|
|
50
|
+
/** Studio background mode */
|
|
51
|
+
export type StudioBackground = "grey" | "darkgrey" | "white" | "gradient" | "gradient-dark" | "environment" | "transparent";
|
|
52
|
+
|
|
53
|
+
/** Studio texture mapping mode */
|
|
54
|
+
export type StudioTextureMapping = "triplanar" | "parametric";
|
|
55
|
+
|
|
39
56
|
/** Shape type */
|
|
40
57
|
export type ShapeType = "shapes" | "edges" | "vertices";
|
|
41
58
|
|
|
@@ -70,6 +87,9 @@ export type ColorValue = number | string;
|
|
|
70
87
|
/** RGB color as tuple [r, g, b] with values 0-1 */
|
|
71
88
|
export type RGBColor = [number, number, number];
|
|
72
89
|
|
|
90
|
+
/** RGBA color as tuple [r, g, b, a] with values 0-1 */
|
|
91
|
+
export type RGBAColor = [number, number, number, number];
|
|
92
|
+
|
|
73
93
|
/** Axis colors per theme - array of RGB colors for X, Y, Z axes */
|
|
74
94
|
export type AxisColors = Record<Theme, RGBColor[]>;
|
|
75
95
|
|
|
@@ -184,7 +204,7 @@ export type ActionShortcutName =
|
|
|
184
204
|
| "reset" | "resize" | "iso" | "front" | "rear" | "top" | "bottom" | "left" | "right"
|
|
185
205
|
| "explode" | "distance" | "properties" | "select" | "help"
|
|
186
206
|
| "play" | "stop"
|
|
187
|
-
| "tree" | "clip" | "material" | "zebra";
|
|
207
|
+
| "tree" | "clip" | "material" | "zebra" | "studio";
|
|
188
208
|
|
|
189
209
|
/** Action keymap: action name → key character */
|
|
190
210
|
export type ActionKeymap = Partial<Record<ActionShortcutName, string>>;
|
|
@@ -224,21 +244,27 @@ export interface DisplayOptions {
|
|
|
224
244
|
zscaleTool?: boolean;
|
|
225
245
|
/** Show zebra tool (default: true) */
|
|
226
246
|
zebraTool?: boolean;
|
|
247
|
+
/** Show studio tool (default: true) */
|
|
248
|
+
studioTool?: boolean;
|
|
227
249
|
/** Enable measurement debug mode (default: false) */
|
|
228
250
|
measurementDebug?: boolean;
|
|
251
|
+
/** External canvas element to use for the WebGL renderer, enabling shared WebGL context scenarios (default: undefined — renderer creates its own canvas) */
|
|
252
|
+
canvas?: HTMLCanvasElement;
|
|
253
|
+
/** External WebGL context to use for the renderer. When provided together with `canvas`, the renderer will use this context instead of creating a new one. Useful for sharing a context with other renderers like PixiJS. (default: undefined) */
|
|
254
|
+
gl?: WebGLRenderingContext | WebGL2RenderingContext;
|
|
229
255
|
}
|
|
230
256
|
|
|
231
257
|
/** Render options */
|
|
232
258
|
export interface RenderOptions {
|
|
233
259
|
/** Default edge color (default: 0x707070) */
|
|
234
260
|
edgeColor?: number;
|
|
235
|
-
/** Ambient light intensity (default:
|
|
261
|
+
/** Ambient light intensity (default: 1) */
|
|
236
262
|
ambientIntensity?: number;
|
|
237
|
-
/** Direct light intensity (default:
|
|
263
|
+
/** Direct light intensity (default: 1.1) */
|
|
238
264
|
directIntensity?: number;
|
|
239
|
-
/** Metalness (default: 0.
|
|
265
|
+
/** Metalness (default: 0.3) */
|
|
240
266
|
metalness?: number;
|
|
241
|
-
/** Roughness (default: 0.
|
|
267
|
+
/** Roughness (default: 0.65) */
|
|
242
268
|
roughness?: number;
|
|
243
269
|
/** Default opacity level for transparency (default: 0.5) */
|
|
244
270
|
defaultOpacity?: number;
|
|
@@ -246,8 +272,8 @@ export interface RenderOptions {
|
|
|
246
272
|
normalLen?: number;
|
|
247
273
|
}
|
|
248
274
|
|
|
249
|
-
/** Viewer options */
|
|
250
|
-
export interface ViewerOptions {
|
|
275
|
+
/** Viewer options (includes studio mode configuration) */
|
|
276
|
+
export interface ViewerOptions extends StudioModeOptions {
|
|
251
277
|
/** Use OrbitControls or TrackballControls (default: "orbit") */
|
|
252
278
|
control?: ControlType;
|
|
253
279
|
/** Show X-, Y-, Z-axes (default: false) */
|
|
@@ -324,8 +350,34 @@ export interface ZebraOptions {
|
|
|
324
350
|
zebraMappingMode?: ZebraMappingMode;
|
|
325
351
|
}
|
|
326
352
|
|
|
353
|
+
/** Studio mode options (environment, tone mapping, edges) */
|
|
354
|
+
export interface StudioModeOptions {
|
|
355
|
+
/** Environment preset or custom HDR URL (default: "studio") */
|
|
356
|
+
studioEnvironment?: string;
|
|
357
|
+
/** Environment map intensity, 0-1 (default: 0.5) */
|
|
358
|
+
studioEnvIntensity?: number;
|
|
359
|
+
/** Background mode (default: "environment") */
|
|
360
|
+
studioBackground?: StudioBackground;
|
|
361
|
+
/** Tone mapping algorithm (default: "neutral") */
|
|
362
|
+
studioToneMapping?: StudioToneMapping;
|
|
363
|
+
/** Tone mapping exposure, 0-2 (default: 1.0) */
|
|
364
|
+
studioExposure?: number;
|
|
365
|
+
/** Use 4K environment maps instead of 2K (default: false) */
|
|
366
|
+
studio4kEnvMaps?: boolean;
|
|
367
|
+
/** Texture mapping mode: triplanar projection or parametric UVs (default: "triplanar") */
|
|
368
|
+
studioTextureMapping?: StudioTextureMapping;
|
|
369
|
+
/** Environment map rotation in degrees, 0-360 (default: 0) */
|
|
370
|
+
studioEnvRotation?: number;
|
|
371
|
+
/** Shadow intensity, 0-1 (default: 0 = off) */
|
|
372
|
+
studioShadowIntensity?: number;
|
|
373
|
+
/** Shadow softness, 0-1 (default: 0.3) */
|
|
374
|
+
studioShadowSoftness?: number;
|
|
375
|
+
/** Ambient occlusion intensity, 0-3.0 (default: 0 = off) */
|
|
376
|
+
studioAOIntensity?: number;
|
|
377
|
+
}
|
|
378
|
+
|
|
327
379
|
/** Combined options for initialization */
|
|
328
|
-
export type CombinedOptions = DisplayOptions & RenderOptions & ViewerOptions & ZebraOptions;
|
|
380
|
+
export type CombinedOptions = DisplayOptions & RenderOptions & ViewerOptions & ZebraOptions & StudioModeOptions;
|
|
329
381
|
|
|
330
382
|
// =============================================================================
|
|
331
383
|
// Viewer State Shape
|
|
@@ -349,6 +401,7 @@ export interface ViewerStateShape {
|
|
|
349
401
|
explodeTool: boolean;
|
|
350
402
|
zscaleTool: boolean;
|
|
351
403
|
zebraTool: boolean;
|
|
404
|
+
studioTool: boolean;
|
|
352
405
|
measurementDebug: boolean;
|
|
353
406
|
|
|
354
407
|
// Render
|
|
@@ -399,6 +452,19 @@ export interface ViewerStateShape {
|
|
|
399
452
|
zebraColorScheme: ZebraColorScheme;
|
|
400
453
|
zebraMappingMode: ZebraMappingMode;
|
|
401
454
|
|
|
455
|
+
// Studio
|
|
456
|
+
studioEnvironment: string;
|
|
457
|
+
studioEnvIntensity: number;
|
|
458
|
+
studioBackground: StudioBackground;
|
|
459
|
+
studioToneMapping: StudioToneMapping;
|
|
460
|
+
studioExposure: number;
|
|
461
|
+
studio4kEnvMaps: boolean;
|
|
462
|
+
studioTextureMapping: StudioTextureMapping;
|
|
463
|
+
studioEnvRotation: number;
|
|
464
|
+
studioShadowIntensity: number;
|
|
465
|
+
studioShadowSoftness: number;
|
|
466
|
+
studioAOIntensity: number;
|
|
467
|
+
|
|
402
468
|
// Runtime
|
|
403
469
|
activeTool: string | null;
|
|
404
470
|
animationMode: AnimationMode;
|
|
@@ -411,6 +477,235 @@ export interface ViewerStateShape {
|
|
|
411
477
|
/** Keys of ViewerStateShape */
|
|
412
478
|
export type StateKey = keyof ViewerStateShape;
|
|
413
479
|
|
|
480
|
+
// =============================================================================
|
|
481
|
+
// Material Appearance (Studio Mode)
|
|
482
|
+
// =============================================================================
|
|
483
|
+
|
|
484
|
+
/**
|
|
485
|
+
* Material appearance definition for Studio mode.
|
|
486
|
+
*
|
|
487
|
+
* All fields are optional. Only provided fields override defaults.
|
|
488
|
+
* In Studio mode the viewer uses MeshPhysicalMaterial; properties left
|
|
489
|
+
* unset default to their "off" values (transmission=0, clearcoat=0, etc.)
|
|
490
|
+
* which the shader skips at near-zero cost.
|
|
491
|
+
*
|
|
492
|
+
* This is a data-format interface (describes JSON input), not a Three.js material.
|
|
493
|
+
* Texture string fields reference either a key in the root-level `textures` table,
|
|
494
|
+
* a data URI, or a URL resolved against the HTML page.
|
|
495
|
+
*/
|
|
496
|
+
export interface MaterialAppearance {
|
|
497
|
+
/** Display name */
|
|
498
|
+
name?: string;
|
|
499
|
+
/** Reference to a built-in preset (e.g., "stainless-steel", "car-paint") */
|
|
500
|
+
builtin?: string;
|
|
501
|
+
|
|
502
|
+
// -- Color --
|
|
503
|
+
|
|
504
|
+
/** sRGB base color. Accepts RGBA tuple [r,g,b,a] (0-1) or CSS hex string "#rrggbb". */
|
|
505
|
+
color?: RGBAColor | string;
|
|
506
|
+
/** Texture reference for base color */
|
|
507
|
+
map?: string;
|
|
508
|
+
|
|
509
|
+
// -- Metallic-Roughness PBR --
|
|
510
|
+
|
|
511
|
+
/** Metalness factor, 0-1 (default: 0.0) */
|
|
512
|
+
metalness?: number;
|
|
513
|
+
/** Roughness factor, 0-1 (default: 0.5) */
|
|
514
|
+
roughness?: number;
|
|
515
|
+
|
|
516
|
+
// -- Textures (Standard) --
|
|
517
|
+
|
|
518
|
+
/** Normal map texture reference */
|
|
519
|
+
normalMap?: string;
|
|
520
|
+
/** Ambient occlusion texture reference */
|
|
521
|
+
aoMap?: string;
|
|
522
|
+
/** Metalness map texture reference */
|
|
523
|
+
metalnessMap?: string;
|
|
524
|
+
/** Roughness map texture reference */
|
|
525
|
+
roughnessMap?: string;
|
|
526
|
+
|
|
527
|
+
// -- Emissive --
|
|
528
|
+
|
|
529
|
+
/** Emissive color, linear RGB */
|
|
530
|
+
emissive?: RGBColor;
|
|
531
|
+
/** Emissive map texture reference */
|
|
532
|
+
emissiveMap?: string;
|
|
533
|
+
/** Emissive intensity multiplier (default: 1.0) */
|
|
534
|
+
emissiveIntensity?: number;
|
|
535
|
+
|
|
536
|
+
// -- Alpha --
|
|
537
|
+
|
|
538
|
+
/** Alpha blending mode */
|
|
539
|
+
alphaMode?: "OPAQUE" | "MASK" | "BLEND";
|
|
540
|
+
/** Alpha cutoff threshold for MASK mode (default: 0.5) */
|
|
541
|
+
alphaCutoff?: number;
|
|
542
|
+
|
|
543
|
+
// -- Transmission (glass, water) --
|
|
544
|
+
|
|
545
|
+
/** Transmission factor, 0-1 */
|
|
546
|
+
transmission?: number;
|
|
547
|
+
/** Transmission map texture reference */
|
|
548
|
+
transmissionMap?: string;
|
|
549
|
+
|
|
550
|
+
// -- Clearcoat (car paint, varnish) --
|
|
551
|
+
|
|
552
|
+
/** Clearcoat intensity, 0-1 */
|
|
553
|
+
clearcoat?: number;
|
|
554
|
+
/** Clearcoat roughness */
|
|
555
|
+
clearcoatRoughness?: number;
|
|
556
|
+
/** Clearcoat intensity texture reference */
|
|
557
|
+
clearcoatMap?: string;
|
|
558
|
+
/** Clearcoat roughness texture reference */
|
|
559
|
+
clearcoatRoughnessMap?: string;
|
|
560
|
+
/** Clearcoat normal map texture reference */
|
|
561
|
+
clearcoatNormalMap?: string;
|
|
562
|
+
|
|
563
|
+
// -- Volume (subsurface: jade, wax, skin) --
|
|
564
|
+
|
|
565
|
+
/** Thickness for volume effects */
|
|
566
|
+
thickness?: number;
|
|
567
|
+
/** Thickness map texture reference */
|
|
568
|
+
thicknessMap?: string;
|
|
569
|
+
/** Attenuation distance for volume absorption */
|
|
570
|
+
attenuationDistance?: number;
|
|
571
|
+
/** Attenuation color, linear RGB */
|
|
572
|
+
attenuationColor?: RGBColor;
|
|
573
|
+
|
|
574
|
+
// -- IOR --
|
|
575
|
+
|
|
576
|
+
/** Index of refraction (default: 1.5) */
|
|
577
|
+
ior?: number;
|
|
578
|
+
|
|
579
|
+
// -- Specular --
|
|
580
|
+
|
|
581
|
+
/** Specular intensity, 0-1 */
|
|
582
|
+
specularIntensity?: number;
|
|
583
|
+
/** Specular tint color, linear RGB */
|
|
584
|
+
specularColor?: RGBColor;
|
|
585
|
+
/** Specular intensity texture reference */
|
|
586
|
+
specularIntensityMap?: string;
|
|
587
|
+
/** Specular color texture reference */
|
|
588
|
+
specularColorMap?: string;
|
|
589
|
+
|
|
590
|
+
// -- Sheen (fabric, velvet) --
|
|
591
|
+
|
|
592
|
+
/** Sheen intensity, 0-1 (required to enable sheen layer) */
|
|
593
|
+
sheen?: number;
|
|
594
|
+
/** Sheen tint color, linear RGB */
|
|
595
|
+
sheenColor?: RGBColor;
|
|
596
|
+
/** Sheen roughness */
|
|
597
|
+
sheenRoughness?: number;
|
|
598
|
+
/** Sheen color texture reference */
|
|
599
|
+
sheenColorMap?: string;
|
|
600
|
+
/** Sheen roughness texture reference */
|
|
601
|
+
sheenRoughnessMap?: string;
|
|
602
|
+
|
|
603
|
+
// -- Anisotropy (brushed metal) --
|
|
604
|
+
|
|
605
|
+
/** Anisotropy strength, 0-1 */
|
|
606
|
+
anisotropy?: number;
|
|
607
|
+
/** Anisotropy rotation in radians */
|
|
608
|
+
anisotropyRotation?: number;
|
|
609
|
+
/** Anisotropy direction texture reference */
|
|
610
|
+
anisotropyMap?: string;
|
|
611
|
+
|
|
612
|
+
// -- Misc --
|
|
613
|
+
|
|
614
|
+
/** Use MeshBasicMaterial (unlit, no shading) */
|
|
615
|
+
unlit?: boolean;
|
|
616
|
+
/** Render both sides of faces (THREE.DoubleSide) */
|
|
617
|
+
doubleSided?: boolean;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
// =============================================================================
|
|
621
|
+
// MaterialX Material (threejs-materials format)
|
|
622
|
+
// =============================================================================
|
|
623
|
+
|
|
624
|
+
/**
|
|
625
|
+
* Material definition from threejs-materials (Three.js MeshPhysicalMaterial-compatible).
|
|
626
|
+
*
|
|
627
|
+
* This format is produced by the threejs-materials Python library, which catalogs
|
|
628
|
+
* PBR materials from ambientCG, GPUOpen, PolyHaven, and PhysicallyBased.
|
|
629
|
+
* The `properties` dict uses simplified property names (e.g., "color", "roughness",
|
|
630
|
+
* "normal") where each entry has an optional `value` (scalar or color array in
|
|
631
|
+
* linear RGB) and/or `texture` (inline data URI).
|
|
632
|
+
*
|
|
633
|
+
* Detected by the presence of the `properties` key.
|
|
634
|
+
* Extra keys from threejs-materials (id, name, source, url, license) pass through
|
|
635
|
+
* harmlessly and are not part of this interface.
|
|
636
|
+
*/
|
|
637
|
+
export interface MaterialXMaterial {
|
|
638
|
+
/** Material properties from threejs-materials. Each key maps to { value?, texture? } */
|
|
639
|
+
properties: Record<string, { value?: unknown; texture?: string }>;
|
|
640
|
+
/** Optional texture tiling [u, v], default [1, 1]. Applied to all textures. */
|
|
641
|
+
textureRepeat?: [number, number];
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
/**
|
|
645
|
+
* Type guard to check if a material entry is a threejs-materials format dict.
|
|
646
|
+
* Detected by the presence of the `properties` key.
|
|
647
|
+
*/
|
|
648
|
+
export function isMaterialXMaterial(m: unknown): m is MaterialXMaterial {
|
|
649
|
+
return typeof m === "object" && m !== null && "properties" in m;
|
|
650
|
+
}
|
|
651
|
+
|
|
652
|
+
// =============================================================================
|
|
653
|
+
// Texture Entry (Studio Mode)
|
|
654
|
+
// =============================================================================
|
|
655
|
+
|
|
656
|
+
/**
|
|
657
|
+
* Entry in the root-level `textures` table.
|
|
658
|
+
*
|
|
659
|
+
* Each entry is either embedded (base64-encoded image data) or a URL reference
|
|
660
|
+
* loaded on demand. At least one of `data`+`format` or `url` must be provided.
|
|
661
|
+
* An empty TextureEntry is invalid and will be ignored at runtime.
|
|
662
|
+
* Multiple builtin preset texture fields can reference the same key for
|
|
663
|
+
* deduplication. threejs-materials carry their own textures as inline data URIs.
|
|
664
|
+
*/
|
|
665
|
+
export interface TextureEntry {
|
|
666
|
+
/** Base64-encoded image data (for embedded textures) */
|
|
667
|
+
data?: string;
|
|
668
|
+
/** Image format, e.g., "png", "jpg", "webp" (required when data is provided) */
|
|
669
|
+
format?: string;
|
|
670
|
+
/** URL to load the texture from (for URL-referenced textures) */
|
|
671
|
+
url?: string;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
// =============================================================================
|
|
675
|
+
// Studio Options
|
|
676
|
+
// =============================================================================
|
|
677
|
+
|
|
678
|
+
/**
|
|
679
|
+
* Root-level Studio mode configuration.
|
|
680
|
+
*
|
|
681
|
+
* Optional configuration for the rendering environment, only used when
|
|
682
|
+
* the Studio tab is active. Fields map directly to ViewerState keys on load.
|
|
683
|
+
*/
|
|
684
|
+
export interface StudioOptions {
|
|
685
|
+
/** Environment preset slug, custom HDR URL, or "none" (default: "studio") */
|
|
686
|
+
environment?: StudioEnvironment;
|
|
687
|
+
/** Environment map intensity, 0-1 (default: 0.5) */
|
|
688
|
+
envIntensity?: number;
|
|
689
|
+
/** Background mode (default: "environment") */
|
|
690
|
+
background?: StudioBackground;
|
|
691
|
+
/** Tone mapping algorithm (default: "neutral") */
|
|
692
|
+
toneMapping?: StudioToneMapping;
|
|
693
|
+
/** Tone mapping exposure (default: 1.0) */
|
|
694
|
+
toneMappingExposure?: number;
|
|
695
|
+
/** Use 4K environment maps instead of 2K (default: false) */
|
|
696
|
+
use4kEnvMaps?: boolean;
|
|
697
|
+
/** Texture mapping mode (default: "triplanar") */
|
|
698
|
+
textureMapping?: StudioTextureMapping;
|
|
699
|
+
/** Environment map rotation in degrees (default: 0) */
|
|
700
|
+
envRotation?: number;
|
|
701
|
+
/** Shadow intensity, 0-1 (default: 0 = off) */
|
|
702
|
+
shadowIntensity?: number;
|
|
703
|
+
/** Shadow softness, 0-1 (default: 0.3) */
|
|
704
|
+
shadowSoftness?: number;
|
|
705
|
+
/** Ambient occlusion intensity, 0-3.0 (default: 0 = off) */
|
|
706
|
+
aoIntensity?: number;
|
|
707
|
+
}
|
|
708
|
+
|
|
414
709
|
// =============================================================================
|
|
415
710
|
// Shape & Texture Types
|
|
416
711
|
// =============================================================================
|
|
@@ -451,6 +746,8 @@ export interface Shape {
|
|
|
451
746
|
triangles_per_face?: number[] | Uint32Array;
|
|
452
747
|
/** Number of segments per edge (when edges is flat) */
|
|
453
748
|
segments_per_edge?: number[] | Uint32Array;
|
|
749
|
+
/** UV coordinates (2 floats per vertex, same indexing as vertices) */
|
|
750
|
+
uvs?: number[] | Float32Array;
|
|
454
751
|
}
|
|
455
752
|
|
|
456
753
|
/**
|
|
@@ -481,6 +778,16 @@ export interface ShapeNested {
|
|
|
481
778
|
face_types: number[];
|
|
482
779
|
}
|
|
483
780
|
|
|
781
|
+
/**
|
|
782
|
+
* Shape reference for the instanced/compressed format.
|
|
783
|
+
* Before decoding, a part's shape field may be `{ ref: N }` referencing
|
|
784
|
+
* the Nth entry in the instances array. After decoding, all ShapeRefs
|
|
785
|
+
* are replaced with full Shape objects.
|
|
786
|
+
*/
|
|
787
|
+
export interface ShapeRef {
|
|
788
|
+
ref: number;
|
|
789
|
+
}
|
|
790
|
+
|
|
484
791
|
/**
|
|
485
792
|
* Check if shape uses binary format (has triangles_per_face).
|
|
486
793
|
*/
|
|
@@ -565,6 +872,18 @@ export interface Shapes {
|
|
|
565
872
|
width?: number | undefined;
|
|
566
873
|
/** Vertex size in pixels (added during decomposition for vertex shapes) */
|
|
567
874
|
size?: number | undefined;
|
|
875
|
+
/** Material tag referencing materials table or built-in preset (leaf nodes) */
|
|
876
|
+
material?: string | undefined;
|
|
877
|
+
/** User-defined material library (root node).
|
|
878
|
+
* Values can be:
|
|
879
|
+
* - string: builtin preset reference (e.g., "builtin:car-paint")
|
|
880
|
+
* - MaterialXMaterial: threejs-materials format (detected by `properties` key)
|
|
881
|
+
* - MaterialAppearance: preset with overrides (e.g., { builtin: "acrylic-clear", color: "#55a0e3" })
|
|
882
|
+
*/
|
|
883
|
+
materials?: Record<string, string | MaterialXMaterial | MaterialAppearance> | undefined;
|
|
884
|
+
/** Shared texture table for builtin preset materials (root node).
|
|
885
|
+
* threejs-materials carry their own textures inline. */
|
|
886
|
+
textures?: Record<string, TextureEntry> | undefined;
|
|
568
887
|
}
|
|
569
888
|
|
|
570
889
|
// =============================================================================
|
package/src/core/viewer-state.ts
CHANGED
|
@@ -9,6 +9,9 @@ import {
|
|
|
9
9
|
type ActiveTab,
|
|
10
10
|
type ZebraColorScheme,
|
|
11
11
|
type ZebraMappingMode,
|
|
12
|
+
type StudioBackground,
|
|
13
|
+
type StudioToneMapping,
|
|
14
|
+
type StudioTextureMapping,
|
|
12
15
|
type Keymap,
|
|
13
16
|
type StateChange,
|
|
14
17
|
type StateSubscriber,
|
|
@@ -16,6 +19,7 @@ import {
|
|
|
16
19
|
type SubscribeOptions,
|
|
17
20
|
type RenderOptions,
|
|
18
21
|
type ViewerOptions,
|
|
22
|
+
type StudioOptions,
|
|
19
23
|
} from "./types";
|
|
20
24
|
import { logger } from "../utils/logger.js";
|
|
21
25
|
|
|
@@ -38,6 +42,7 @@ interface DisplayDefaults {
|
|
|
38
42
|
explodeTool: boolean;
|
|
39
43
|
zscaleTool: boolean;
|
|
40
44
|
zebraTool: boolean;
|
|
45
|
+
studioTool: boolean;
|
|
41
46
|
measurementDebug: boolean;
|
|
42
47
|
}
|
|
43
48
|
|
|
@@ -101,6 +106,23 @@ interface ZebraDefaults {
|
|
|
101
106
|
zebraMappingMode: ZebraMappingMode;
|
|
102
107
|
}
|
|
103
108
|
|
|
109
|
+
/**
|
|
110
|
+
* Studio mode defaults
|
|
111
|
+
*/
|
|
112
|
+
interface StudioModeDefaults {
|
|
113
|
+
studioEnvironment: string;
|
|
114
|
+
studioEnvIntensity: number;
|
|
115
|
+
studioBackground: StudioBackground;
|
|
116
|
+
studioToneMapping: StudioToneMapping;
|
|
117
|
+
studioExposure: number;
|
|
118
|
+
studio4kEnvMaps: boolean;
|
|
119
|
+
studioTextureMapping: StudioTextureMapping;
|
|
120
|
+
studioEnvRotation: number;
|
|
121
|
+
studioShadowIntensity: number;
|
|
122
|
+
studioShadowSoftness: number;
|
|
123
|
+
studioAOIntensity: number;
|
|
124
|
+
}
|
|
125
|
+
|
|
104
126
|
/**
|
|
105
127
|
* Runtime state defaults
|
|
106
128
|
*/
|
|
@@ -116,7 +138,7 @@ interface RuntimeDefaults {
|
|
|
116
138
|
/**
|
|
117
139
|
* Complete state shape
|
|
118
140
|
*/
|
|
119
|
-
type StateShape = DisplayDefaults & RenderDefaults & ViewerDefaults & ZebraDefaults & RuntimeDefaults;
|
|
141
|
+
type StateShape = DisplayDefaults & RenderDefaults & ViewerDefaults & ZebraDefaults & StudioModeDefaults & RuntimeDefaults;
|
|
120
142
|
|
|
121
143
|
/**
|
|
122
144
|
* Keys of the state shape
|
|
@@ -141,7 +163,7 @@ const STATE_KEYS: ReadonlySet<string> = new Set<StateKey>([
|
|
|
141
163
|
// Display
|
|
142
164
|
"theme", "cadWidth", "treeWidth", "treeHeight", "height", "pinning", "glass", "tools",
|
|
143
165
|
"keymap", "newTreeBehavior", "measureTools", "selectTool", "explodeTool", "zscaleTool",
|
|
144
|
-
"zebraTool", "measurementDebug",
|
|
166
|
+
"zebraTool", "studioTool", "measurementDebug",
|
|
145
167
|
// Render
|
|
146
168
|
"ambientIntensity", "directIntensity", "metalness", "roughness", "defaultOpacity",
|
|
147
169
|
"edgeColor", "normalLen",
|
|
@@ -153,6 +175,10 @@ const STATE_KEYS: ReadonlySet<string> = new Set<StateKey>([
|
|
|
153
175
|
"panSpeed", "rotateSpeed", "zoomSpeed", "timeit",
|
|
154
176
|
// Zebra
|
|
155
177
|
"zebraCount", "zebraOpacity", "zebraDirection", "zebraColorScheme", "zebraMappingMode",
|
|
178
|
+
// Studio
|
|
179
|
+
"studioEnvironment", "studioEnvIntensity", "studioBackground",
|
|
180
|
+
"studioToneMapping", "studioExposure", "studio4kEnvMaps", "studioTextureMapping",
|
|
181
|
+
"studioEnvRotation", "studioShadowIntensity", "studioShadowSoftness", "studioAOIntensity",
|
|
156
182
|
// Runtime
|
|
157
183
|
"activeTool", "animationMode", "animationSliderValue", "zscaleActive", "highlightedButton",
|
|
158
184
|
"activeTab",
|
|
@@ -211,6 +237,18 @@ const STATE_TO_NOTIFICATION_KEY: Partial<Record<StateKey, string>> = {
|
|
|
211
237
|
zebraDirection: "zebra_direction",
|
|
212
238
|
zebraColorScheme: "zebra_color_scheme",
|
|
213
239
|
zebraMappingMode: "zebra_mapping_mode",
|
|
240
|
+
// Studio settings
|
|
241
|
+
studioEnvironment: "studio_environment",
|
|
242
|
+
studioEnvIntensity: "studio_env_intensity",
|
|
243
|
+
studioBackground: "studio_background",
|
|
244
|
+
studioToneMapping: "studio_tone_mapping",
|
|
245
|
+
studioExposure: "studio_exposure",
|
|
246
|
+
studio4kEnvMaps: "studio_4k_env_maps",
|
|
247
|
+
studioTextureMapping: "studio_texture_mapping",
|
|
248
|
+
studioEnvRotation: "studio_env_rotation",
|
|
249
|
+
studioShadowIntensity: "studio_shadow_intensity",
|
|
250
|
+
studioShadowSoftness: "studio_shadow_softness",
|
|
251
|
+
studioAOIntensity: "studio_ao_intensity",
|
|
214
252
|
// Animation/Explode slider (shared state, mutually exclusive modes)
|
|
215
253
|
animationSliderValue: "relative_time",
|
|
216
254
|
};
|
|
@@ -288,7 +326,7 @@ class ViewerState {
|
|
|
288
326
|
static DISPLAY_DEFAULTS: DisplayDefaults = {
|
|
289
327
|
theme: "light",
|
|
290
328
|
cadWidth: 800,
|
|
291
|
-
treeWidth:
|
|
329
|
+
treeWidth: 260,
|
|
292
330
|
treeHeight: 400,
|
|
293
331
|
height: 600,
|
|
294
332
|
pinning: false,
|
|
@@ -300,7 +338,7 @@ class ViewerState {
|
|
|
300
338
|
reset: "R", resize: "r",
|
|
301
339
|
iso: "5", front: "1", rear: "3", top: "8", bottom: "2", left: "4", right: "6",
|
|
302
340
|
explode: "x", zscale: "L", distance: "D", properties: "P", select: "S", help: "h", play: " ", stop: "Escape",
|
|
303
|
-
tree: "T", clip: "C", material: "M", zebra: "Z",
|
|
341
|
+
tree: "T", clip: "C", material: "M", zebra: "Z", studio: "s",
|
|
304
342
|
},
|
|
305
343
|
newTreeBehavior: true,
|
|
306
344
|
measureTools: true,
|
|
@@ -308,6 +346,7 @@ class ViewerState {
|
|
|
308
346
|
explodeTool: true,
|
|
309
347
|
zscaleTool: false,
|
|
310
348
|
zebraTool: true,
|
|
349
|
+
studioTool: true,
|
|
311
350
|
measurementDebug: false,
|
|
312
351
|
};
|
|
313
352
|
|
|
@@ -371,6 +410,23 @@ class ViewerState {
|
|
|
371
410
|
zebraMappingMode: "reflection",
|
|
372
411
|
};
|
|
373
412
|
|
|
413
|
+
/**
|
|
414
|
+
* Studio mode settings
|
|
415
|
+
*/
|
|
416
|
+
static STUDIO_MODE_DEFAULTS: StudioModeDefaults = {
|
|
417
|
+
studioEnvironment: "studio",
|
|
418
|
+
studioEnvIntensity: 1.0,
|
|
419
|
+
studioBackground: "environment",
|
|
420
|
+
studioToneMapping: "neutral",
|
|
421
|
+
studioExposure: 1.0,
|
|
422
|
+
studio4kEnvMaps: false,
|
|
423
|
+
studioTextureMapping: "triplanar",
|
|
424
|
+
studioEnvRotation: 0,
|
|
425
|
+
studioShadowIntensity: 0.5,
|
|
426
|
+
studioShadowSoftness: 0.2,
|
|
427
|
+
studioAOIntensity: 0.5,
|
|
428
|
+
};
|
|
429
|
+
|
|
374
430
|
/**
|
|
375
431
|
* Runtime state (not from options, changes during execution)
|
|
376
432
|
*/
|
|
@@ -400,6 +456,7 @@ class ViewerState {
|
|
|
400
456
|
...ViewerState.RENDER_DEFAULTS,
|
|
401
457
|
...ViewerState.VIEWER_DEFAULTS,
|
|
402
458
|
...ViewerState.ZEBRA_DEFAULTS,
|
|
459
|
+
...ViewerState.STUDIO_MODE_DEFAULTS,
|
|
403
460
|
...ViewerState.RUNTIME_DEFAULTS,
|
|
404
461
|
};
|
|
405
462
|
|
|
@@ -525,6 +582,26 @@ class ViewerState {
|
|
|
525
582
|
this._update(converted, notify);
|
|
526
583
|
}
|
|
527
584
|
|
|
585
|
+
/**
|
|
586
|
+
* Update studio state from StudioOptions (shapes.studioOptions).
|
|
587
|
+
* Maps short field names to prefixed state keys.
|
|
588
|
+
*/
|
|
589
|
+
updateStudioState(options: StudioOptions): void {
|
|
590
|
+
const map: Partial<StateShape> = {};
|
|
591
|
+
if (options.environment !== undefined) map.studioEnvironment = options.environment;
|
|
592
|
+
if (options.envIntensity !== undefined) map.studioEnvIntensity = options.envIntensity;
|
|
593
|
+
if (options.background !== undefined) map.studioBackground = options.background;
|
|
594
|
+
if (options.toneMapping !== undefined) map.studioToneMapping = options.toneMapping;
|
|
595
|
+
if (options.toneMappingExposure !== undefined) map.studioExposure = options.toneMappingExposure;
|
|
596
|
+
if (options.use4kEnvMaps !== undefined) map.studio4kEnvMaps = options.use4kEnvMaps;
|
|
597
|
+
if (options.textureMapping !== undefined) map.studioTextureMapping = options.textureMapping;
|
|
598
|
+
if (options.envRotation !== undefined) map.studioEnvRotation = options.envRotation;
|
|
599
|
+
if (options.shadowIntensity !== undefined) map.studioShadowIntensity = options.shadowIntensity;
|
|
600
|
+
if (options.shadowSoftness !== undefined) map.studioShadowSoftness = options.shadowSoftness;
|
|
601
|
+
if (options.aoIntensity !== undefined) map.studioAOIntensity = options.aoIntensity;
|
|
602
|
+
this._update(map, false);
|
|
603
|
+
}
|
|
604
|
+
|
|
528
605
|
/**
|
|
529
606
|
* Get all state as a plain object (for serialization)
|
|
530
607
|
*/
|
|
@@ -647,6 +724,7 @@ class ViewerState {
|
|
|
647
724
|
...ViewerState.RENDER_DEFAULTS,
|
|
648
725
|
...ViewerState.VIEWER_DEFAULTS,
|
|
649
726
|
...ViewerState.ZEBRA_DEFAULTS,
|
|
727
|
+
...ViewerState.STUDIO_MODE_DEFAULTS,
|
|
650
728
|
...ViewerState.RUNTIME_DEFAULTS,
|
|
651
729
|
};
|
|
652
730
|
|
|
@@ -677,6 +755,7 @@ class ViewerState {
|
|
|
677
755
|
...ViewerState.RENDER_DEFAULTS,
|
|
678
756
|
...ViewerState.VIEWER_DEFAULTS,
|
|
679
757
|
...ViewerState.ZEBRA_DEFAULTS,
|
|
758
|
+
...ViewerState.STUDIO_MODE_DEFAULTS,
|
|
680
759
|
...ViewerState.RUNTIME_DEFAULTS,
|
|
681
760
|
};
|
|
682
761
|
}
|
|
@@ -696,6 +775,7 @@ class ViewerState {
|
|
|
696
775
|
logCategory("Render", ViewerState.RENDER_DEFAULTS);
|
|
697
776
|
logCategory("View", ViewerState.VIEWER_DEFAULTS);
|
|
698
777
|
logCategory("Zebra", ViewerState.ZEBRA_DEFAULTS);
|
|
778
|
+
logCategory("Studio", ViewerState.STUDIO_MODE_DEFAULTS);
|
|
699
779
|
logCategory("Runtime", ViewerState.RUNTIME_DEFAULTS);
|
|
700
780
|
}
|
|
701
781
|
}
|