import * as THREE from "three"; import { BoundingBox } from "./bbox.js"; import { ObjectGroup, isObjectGroup } from "./objectgroup.js"; import { MaterialFactory } from "../rendering/material-factory.js"; import type { ZebraColorScheme, ZebraMappingMode, StudioTextureMapping, Shapes, ColorValue, MaterialAppearance, MaterialXMaterial } from "../core/types"; interface ShapeData { vertices: Float32Array | number[][]; normals: Float32Array | number[][]; triangles: Uint32Array | number[][]; edges?: Float32Array | number[][]; uvs?: Float32Array | number[]; } interface EdgeData { edges: Float32Array | number[][]; } interface VertexData { obj_vertices: Float32Array | number[]; } interface PolygonShape { refs: string[]; matrices?: number[]; height: number; } interface TextureData { format: string; data: string; } interface ShapeEntry { type: string; shape: ShapeData | EdgeData | VertexData | PolygonShape; id: string; name: string; color?: string | string[]; alpha?: number; width?: number; size?: number; state: number[]; loc?: [[number, number, number], [number, number, number, number]]; renderback?: boolean; exploded?: boolean; geomtype?: number | null; subtype?: string | null; texture?: { image: TextureData; width: number; height: number; }; material?: string; } type GroupsMap = Record; /** * A THREE.Group for compound geometry that contains ObjectGroups. * Follows Three.js convention with type identifier and type guard property. */ declare class CompoundGroup extends THREE.Group { /** Type identifier following Three.js convention */ readonly type = "CompoundGroup"; /** Type guard property following Three.js convention */ readonly isCompoundGroup = true; } declare class NestedGroup { shapes: Shapes; width: number; height: number; edgeColor: number; transparent: boolean; metalness: number; roughness: number; defaultOpacity: number; normalLen: number; blackEdges: boolean; backVisible: boolean; bb_max: number; delim: string; rootGroup: THREE.Group | null; instances: Record | null; bbox: BoundingBox | null; bsphere: THREE.Sphere | null; groups: GroupsMap; clipPlanes: THREE.Plane[] | null; materialFactory: MaterialFactory; materialsTable: Record | null; resolvedMaterials: Map; /** Cache for threejs-materials entries resolved from the materials table */ resolvedMaterialX: Map; private _textureCache; private _studioMaterialCache; /** Sharing keys of materials that have textures (for UV generation on cache hits) */ private _texturedMaterialKeys; private _isStudioMode; /** * Create a NestedGroup for rendering CAD geometry. * @param shapes - The tessellated shape data to render. * @param width - Canvas/viewport width for line material resolution. * @param height - Canvas/viewport height for line material resolution. * @param edgeColor - Default edge color as hex value (e.g., 0x000000). * @param transparent - Whether to render shapes with transparency. * @param opacity - Default opacity value (0.0 to 1.0). * @param metalness - Material metalness value (0.0 to 1.0). * @param roughness - Material roughness value (0.0 to 1.0). * @param normalLen - Length for vertex normal helpers (0 to disable). * @param bb_max - Maximum bounding box dimension. */ constructor(shapes: Shapes, width: number, height: number, edgeColor: number, transparent: boolean, opacity: number, metalness: number, roughness: number, normalLen: number, bb_max?: number); /** * Dispose of all resources and clean up memory. */ dispose(): void; /** * Resolve a material tag to its definition. * * Returns either a MaterialAppearance (for builtin presets) or a * MaterialXMaterial (for threejs-materials entries). The caller must check the * return type to determine which factory method to use. * * Resolution order: * 1. Check caches (resolvedMaterials / resolvedMaterialX) * 2. Look up in root-level `materials` table: * - string starting with "builtin:" → MATERIAL_PRESETS lookup * - object with `properties` key → threejs-materials entry * 3. Direct lookup in MATERIAL_PRESETS by tag name * 4. No match → warning, return null * * @param tag - The material tag from a leaf node * @param objectPath - The object path (for warning messages) * @returns Resolved material definition or null if not found */ resolveMaterialTag(tag: string, objectPath: string): MaterialAppearance | MaterialXMaterial | null; /** * Check if array is nested (number[][]). */ private _isNestedArray; /** * Convert array data to Float32Array, detecting nested arrays at runtime. */ private _toFloat32Array; /** * Convert array data to Uint32Array, detecting nested arrays at runtime. */ private _toUint32Array; /** * Internal method to render edge geometry as fat lines. */ private _renderEdges; /** * Render standalone edge geometry (not associated with a face). */ renderEdges(edgeData: EdgeData, lineWidth: number, color: ColorValue | ColorValue[] | null, path: string, name: string, state: number, geomtype?: { topo: string; geomtype: number | string | null; } | null): ObjectGroup; /** * Render vertex points as a point cloud. */ renderVertices(vertexData: VertexData, size: number, color: ColorValue | null, path: string, name: string, state: number, geomtype?: { topo: string; geomtype: number | string | null; } | null): ObjectGroup; /** * Render a tessellated 3D shape with front/back faces and optional edges. */ renderShape(shape: ShapeData, color: ColorValue, alpha: number | null, renderback: boolean, exploded: boolean, path: string, name: string, states: number[], geomtype?: { topo: string; geomtype: number | string | null; } | null, subtype?: string | null, texture_data?: TextureData | null, texture_width?: number | null, texture_height?: number | null): ObjectGroup; /** * Create edge geometry from extruded polygons. */ private _createEdgesFromPolygons; /** * Render extruded 2D polygons (GDS format) as 3D geometry. */ renderPolygons(shape: PolygonShape, minZ: number, color: ColorValue, alpha: number, renderback: boolean, _exploded: boolean, path: string, name: string, states: number[], geomtype?: { topo: string; geomtype: number | string | null; } | null, subtype?: string | null): ObjectGroup; /** * Recursively render all shapes in the shape tree. * Note: The shapes parameter uses the public Shapes type but internally * contains ShapeEntry/ShapeTree data after decomposition by viewer._decompose() */ renderLoop(shapes: Shapes): THREE.Group; /** * Main entry point to render all shapes. */ render(): THREE.Group; /** * Get the bounding box of all rendered geometry. */ boundingBox(): BoundingBox; /** * Traverse all ObjectGroup instances and call a method on each. * Note: Uses dynamic dispatch for methods that exist on ObjectGroup. */ private _traverse; /** * Get all currently selected ObjectGroup instances. */ selection(): ObjectGroup[]; /** * Clear selection and highlights from all selected objects. */ clearSelection(): void; /** * Set metalness value for all materials. */ setMetalness(value: number): void; /** * Set roughness value for all materials. */ setRoughness(value: number): void; /** * Enable or disable transparency for all shapes. */ setTransparent(flag: boolean): void; /** * Set whether edges should be rendered in black. */ setBlackEdges(flag: boolean): void; /** * Set visibility of back faces. */ setBackVisible(flag: boolean): void; /** * Set the edge color for all shapes. */ setEdgeColor(color: number): void; /** * Set the opacity for all shapes. */ setOpacity(opacity: number): void; /** * Set clip intersection mode for all materials. */ setClipIntersection(flag: boolean): void; /** * Set clipping planes for all materials. */ setClipPlanes(planes: THREE.Plane[]): void; /** * Set polygon offset for depth sorting. */ setPolygonOffset(offset: number): void; /** * Set Z-axis scale for all shapes (used for GDS extrusion visualization). */ setZScale(value: number): void; /** * Reset minimum Z position for all shapes. */ setMinZ(): void; /** * Mark all materials as needing update. */ updateMaterials(): void; /** * Enable or disable zebra stripe visualization. */ setZebra(flag: boolean): void; /** * Set the number of zebra stripes. */ setZebraCount(value: number): void; /** * Set the opacity of zebra stripes. */ setZebraOpacity(value: number): void; /** * Set the direction/angle of zebra stripes. */ setZebraDirection(value: number): void; /** * Set the color scheme for zebra stripes. */ setZebraColorScheme(flag: ZebraColorScheme): void; /** * Set the mapping mode for zebra stripes. */ setZebraMappingMode(flag: ZebraMappingMode): void; /** * Enter Studio mode: build and apply studio materials to all ObjectGroups. * * Material resolution per ObjectGroup: * 1. Resolve the material tag via `resolveMaterialTag()` * - MaterialXMaterial → `createStudioMaterialFromMaterialX` * - MaterialAppearance → `createStudioMaterial` (builtin presets) * - null (no tag) → fallback plastic-glossy preset tinted with CAD color * 2. Cache by sharing key for reuse across objects with the same tag+color * 3. Clone BackSide variant for renderback objects * 4. Auto-generate box-projected UVs when textured but geometry has no UVs */ enterStudioMode(textureMapping?: StudioTextureMapping): Promise; /** * Leave Studio mode: restore CAD materials on all ObjectGroups. * Does NOT clear the material cache (allows fast re-entry). */ leaveStudioMode(): void; /** * Clear cached Studio materials so they are rebuilt on next enterStudioMode. */ clearStudioMaterialCache(): void; /** * Set edge visibility across all ObjectGroups while in Studio mode. * @param visible - Whether edges should be visible */ setStudioShowEdges(visible: boolean): void; /** * Dispose all Studio mode resources (material cache + texture cache). */ private _disposeStudioResources; } /** * Type guard to check if an object is a CompoundGroup instance. * Uses the isCompoundGroup property following Three.js convention. */ declare function isCompoundGroup(obj: THREE.Object3D | null): obj is CompoundGroup; export { NestedGroup, ObjectGroup, CompoundGroup, isObjectGroup, isCompoundGroup, }; export type { ShapeEntry };