@selvajs/visualization 1.0.0-beta.0 → 1.0.0-beta.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 CHANGED
@@ -53,7 +53,7 @@ Only what a consumer genuinely needs is exported. In particular:
53
53
  - **`createSceneOutliner` composes the scene layer.** Content filtering, layer grouping, visibility
54
54
  and selection state are reachable via `outliner.visibility` / `.selection` / `.layerGroups()`.
55
55
  - **The SLVA binary wire format is private.** Magics, version gates, flag bits and the low-level
56
- binary parser are implementation details of `parseMeshBatch*` and change without a major bump.
56
+ binary parser are implementation details of `parseBinaryMeshBatch*` and change without a major bump.
57
57
 
58
58
  When adding a feature, resist re-exporting a symbol just because it exists — a published surface is
59
59
  a compatibility promise.
@@ -83,7 +83,8 @@ covered by `pnpm type-check`, so a rename that breaks a demo fails the build ins
83
83
 
84
84
  ## Dependencies
85
85
 
86
- This package depends on **nothing from Selva** — only `three`, `rhino3dm` and `fflate`. It owns its
86
+ This package depends on **nothing from Selva** — only `fflate`, and `three` as a peer
87
+ dependency. It owns its
87
88
  own errors ([`shared/errors.ts`](./src/shared/errors.ts)), logging
88
89
  ([`shared/logger.ts`](./src/shared/logger.ts)) and base64 decoding
89
90
  ([`shared/encoding.ts`](./src/shared/encoding.ts)) rather than importing them from
@@ -102,7 +103,7 @@ The package logs nothing by default. To route its output into a host's logger
102
103
 
103
104
  ```ts
104
105
  import { setLogger } from '@selvajs/visualization/render';
105
- import { getLogger } from '@selvajs/compute';
106
+ import { getLogger } from '@selvajs/compute/core';
106
107
 
107
108
  setLogger(getLogger());
108
109
  ```
@@ -0,0 +1,2 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkBYLIBOAUcjs = require('./chunk-BYLIBOAU.cjs');var a={VALIDATION_ERROR:"VALIDATION_ERROR",INVALID_STATE:"INVALID_STATE",ENVIRONMENT_ERROR:"ENVIRONMENT_ERROR",INVALID_CONFIG:"INVALID_CONFIG",ENCODING_ERROR:"ENCODING_ERROR",UNKNOWN_ERROR:"UNKNOWN_ERROR"},s= exports.b =class extends Error{constructor(r,n=a.UNKNOWN_ERROR,t){super(r);_chunkBYLIBOAUcjs.a.call(void 0, this,"code");_chunkBYLIBOAUcjs.a.call(void 0, this,"context");_chunkBYLIBOAUcjs.a.call(void 0, this,"originalError");this.name="VisualizationError",this.code=n,this.context=_optionalChain([t, 'optionalAccess', _ => _.context]),this.originalError=_optionalChain([t, 'optionalAccess', _2 => _2.originalError]),_optionalChain([t, 'optionalAccess', _3 => _3.originalError])&&(this.cause=t.originalError)}};var l=class{debug(){}info(){}warn(){}error(){}},E=class{debug(o,...r){console.debug(o,...r)}info(o,...r){console.info(o,...r)}warn(o,...r){console.warn(o,...r)}error(o,...r){console.error(o,...r)}},g=new l;function p(){return g}function x(e){if(e===null){g=new l;return}let o=["debug","info","warn","error"].filter(r=>typeof e[r]!="function");if(o.length>0)throw new s(`Logger is missing required method(s): ${o.join(", ")}. A logger must implement debug, info, warn and error.`,a.INVALID_CONFIG,{context:{missingMethods:o}});g=e}function O(){x(new E)}var h=["technical","studio","showcase"];var _three = require('three'); var f = _interopRequireWildcard(_three); var i = _interopRequireWildcard(_three); var T = _interopRequireWildcard(_three);var v="technical",R= exports.i ={studio:{toneMapping:f.ACESFilmicToneMapping,toneMappingExposure:1,envMapIntensity:1,environmentIntensity:1,hemisphereIntensity:.75,ambientIntensity:.4,cullBackfaces:!1,ambientOcclusion:!1},technical:{toneMapping:f.NeutralToneMapping,toneMappingExposure:1,envMapIntensity:.9,environmentIntensity:1,hemisphereIntensity:.35,ambientIntensity:.25,cullBackfaces:!1,ambientOcclusion:!1},showcase:{toneMapping:f.ACESFilmicToneMapping,toneMappingExposure:1.15,envMapIntensity:1.4,environmentIntensity:1.25,hemisphereIntensity:.35,ambientIntensity:.15,cullBackfaces:!1,ambientOcclusion:!1}};function M(e){let o=R[e];return{envMapIntensity:o.envMapIntensity,cullBackfaces:o.cullBackfaces}}function I(){let e=globalThis.Buffer;return typeof e=="function"?e:void 0}function w(e){let o=e.replace(/[\t\n\f\r ]/g,"");if(o.length%4===0&&(o=o.replace(/={1,2}$/,"")),o.length%4===1||!/^[A-Za-z0-9+/]*$/.test(o))throw new s("Invalid base64 input.",a.ENCODING_ERROR,{context:{inputLength:e.length}});let r=I();if(r)return new Uint8Array(r.from(o,"base64"));if(typeof globalThis.atob=="function"){let n=globalThis.atob(o),t=new Uint8Array(n.length);for(let c=0;c<n.length;c++)t[c]=n.charCodeAt(c)&255;return t}throw new s("Base64 decoding not supported in this environment.",a.INVALID_STATE,{context:{environmentInfo:"atob or Buffer not available"}})}function L(e){if(!e||typeof e!="string")return p().warn(`Invalid color input: ${e}, using white`),new i.Color(16777215);let o=e.trim();if(/^#?[0-9A-Fa-f]{6}$/.test(o))try{let n=o.startsWith("#")?o:`#${o}`;return new i.Color(n)}catch (e2){return p().warn(`Invalid hex color: ${e}, using white`),new i.Color(16777215)}if(o.includes(",")){let n=o.split(",").map(t=>parseInt(t.trim(),10));if(n.length===3&&n.every(t=>!isNaN(t)&&t>=0&&t<=255))return new i.Color(n[0]/255,n[1]/255,n[2]/255)}let r=o.toLowerCase();return r in i.Color.NAMES?new i.Color(i.Color.NAMES[r]):(p().warn(`Invalid color string: ${e}, using white`),new i.Color(16777215))}function A(e,o,r="z"){e.forEach(n=>{n.position[r]-=o})}function N(e){let o=new i.Box3;return e.length===0||e.forEach(r=>{r.updateMatrixWorld(!0);let n=new i.Box3().setFromObject(r);o.union(n)}),o}var H=new Set;function b(e){return e?!H.has(e):!1}var d=new Set,m=1;function k(e){let o=Math.max(1,e);if(o!==m){m=o;for(let r of d)r(o)}}function C(e){return d.add(e),e(m),()=>d.delete(e)}function y(e){if(b(e)){for(let o of Object.values(e))o instanceof T.Texture&&o.dispose();e.dispose()}}function B(e){e&&(Array.isArray(e)?e.forEach(y):y(e))}function D(e,o={}){let{materials:r=!0}=o;e.traverse(n=>{let t=n;!t.geometry&&!t.material||(t.geometry&&_optionalChain([t, 'access', _4 => _4.geometry, 'optionalAccess', _5 => _5.dispose, 'call', _6 => _6()]),r&&B(t.material))})}exports.a = a; exports.b = s; exports.c = p; exports.d = x; exports.e = O; exports.f = w; exports.g = h; exports.h = v; exports.i = R; exports.j = M; exports.k = L; exports.l = A; exports.m = N; exports.n = k; exports.o = C; exports.p = D;
2
+ //# sourceMappingURL=chunk-AZ4GBXXL.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/selva/selva/packages/visualization/dist/chunk-AZ4GBXXL.cjs","../src/shared/errors.ts","../src/shared/logger.ts","../src/shared/types.ts","../src/shared/looks.ts","../src/shared/encoding.ts","../src/shared/geometry.ts"],"names":["ErrorCodes","VisualizationError","message","code","options","__publicField","NoOpLogger","ConsoleLogger","args","internalLogger","getLogger","setLogger","logger","missing","method","enableDebugLogging","LOOKS","DEFAULT_LOOK","LOOK_PRESETS","materialAppearanceForLook","look","preset","getNodeBuffer","buf","decodeBase64ToBinary","base64File","data","Buffer","binary","bytes","i","parseColor","colorString","trimmed","hex"],"mappings":"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","file":"/home/runner/work/selva/selva/packages/visualization/dist/chunk-AZ4GBXXL.cjs","sourcesContent":[null,"/**\n * Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which\n * mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`\n * values match compute's so existing catch-sites keep working.\n */\n\nexport const ErrorCodes = {\n\t/** Structural check failed: bad magic bytes, out-of-window index, malformed metadata. */\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_STATE: 'INVALID_STATE',\n\t/** No `DecompressionStream`, no WebGL context, etc. */\n\tENVIRONMENT_ERROR: 'ENVIRONMENT_ERROR',\n\tINVALID_CONFIG: 'INVALID_CONFIG',\n\t/** Base64 input could not be decoded. */\n\tENCODING_ERROR: 'ENCODING_ERROR',\n\tUNKNOWN_ERROR: 'UNKNOWN_ERROR'\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\nexport class VisualizationError extends Error {\n\tpublic readonly code: ErrorCode;\n\tpublic readonly context?: Record<string, unknown>;\n\tpublic readonly originalError?: Error;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: ErrorCode = ErrorCodes.UNKNOWN_ERROR,\n\t\toptions?: { context?: Record<string, unknown>; originalError?: Error }\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'VisualizationError';\n\t\tthis.code = code;\n\t\tthis.context = options?.context;\n\t\tthis.originalError = options?.originalError;\n\t\tif (options?.originalError) {\n\t\t\t(this as { cause?: unknown }).cause = options.originalError;\n\t\t}\n\t}\n}\n","/**\n * Logging facility for the visualization package. Deliberately local rather than imported from\n * `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host\n * wanting one sink for both can call `setLogger(computeLogger.getLogger())`.\n */\n\nimport { VisualizationError, ErrorCodes } from './errors.js';\n\nexport interface Logger {\n\tdebug(message: string, ...args: unknown[]): void;\n\tinfo(message: string, ...args: unknown[]): void;\n\twarn(message: string, ...args: unknown[]): void;\n\terror(message: string, ...args: unknown[]): void;\n}\n\nclass NoOpLogger implements Logger {\n\tdebug(): void {}\n\tinfo(): void {}\n\twarn(): void {}\n\terror(): void {}\n}\n\nclass ConsoleLogger implements Logger {\n\tdebug(message: string, ...args: unknown[]): void {\n\t\t// eslint-disable-next-line no-console -- this class exists to be the console sink\n\t\tconsole.debug(message, ...args);\n\t}\n\n\tinfo(message: string, ...args: unknown[]): void {\n\t\tconsole.info(message, ...args);\n\t}\n\n\twarn(message: string, ...args: unknown[]): void {\n\t\tconsole.warn(message, ...args);\n\t}\n\n\terror(message: string, ...args: unknown[]): void {\n\t\tconsole.error(message, ...args);\n\t}\n}\n\n// Defaults to no-op: a library that writes to the console uninvited is a nuisance in a host with\n// its own logging. Opt in with setLogger or enableDebugLogging.\nlet internalLogger: Logger = new NoOpLogger();\n\n// Call per-use rather than caching — the sink is settable at any time.\nexport function getLogger(): Logger {\n\treturn internalLogger;\n}\n\n// Validates logger shape up front: failing here beats a confusing \"getLogger().debug is not a\n// function\" at some later, unrelated call site.\nexport function setLogger(logger: Logger | Console | null): void {\n\tif (logger === null) {\n\t\tinternalLogger = new NoOpLogger();\n\t\treturn;\n\t}\n\n\tconst missing = (['debug', 'info', 'warn', 'error'] as const).filter(\n\t\t(method) => typeof (logger as unknown as Record<string, unknown>)[method] !== 'function'\n\t);\n\tif (missing.length > 0) {\n\t\tthrow new VisualizationError(\n\t\t\t`Logger is missing required method(s): ${missing.join(', ')}. A logger must implement debug, info, warn and error.`,\n\t\t\tErrorCodes.INVALID_CONFIG,\n\t\t\t{ context: { missingMethods: missing } }\n\t\t);\n\t}\n\n\tinternalLogger = logger as Logger;\n}\n\nexport function enableDebugLogging(): void {\n\tsetLogger(new ConsoleLogger());\n}\n","import type * as THREE from 'three';\n\n// ============================================================================\n// LOOKS\n// ============================================================================\n\n/** Source of truth for {@link Look} — lets consumers (e.g. a style picker) iterate instead of hardcoding names. */\nexport const LOOKS = ['technical', 'studio', 'showcase'] as const;\n\nexport type Look = (typeof LOOKS)[number];\n\n/**\n * The lighting/material dials a {@link Look} sets. Never carries edges or grid — those are\n * independent overlays.\n */\nexport type LookPreset = {\n\ttoneMapping: THREE.ToneMapping;\n\ttoneMappingExposure: number;\n\tenvMapIntensity: number;\n\t/** Multiplier on the HDR's IBL (`scene.environmentIntensity`). */\n\tenvironmentIntensity: number;\n\themisphereIntensity: number;\n\tambientIntensity: number;\n\tcullBackfaces: boolean;\n\tambientOcclusion: boolean;\n};\n\n/** How compute meshes read visually — the parse-time material choices baked from a {@link Look}. */\nexport interface MaterialAppearanceOptions {\n\t/** Default 1 (three.js's own material default) when omitted. */\n\tenvMapIntensity?: number;\n\t/**\n\t * `THREE.FrontSide` instead of `THREE.DoubleSide` — crisper silhouette on closed solids, but open\n\t * surfaces (which Rhino also emits) vanish when viewed from behind. Default false (DoubleSide) to\n\t * stay safe for surface geometry.\n\t */\n\tcullBackfaces?: boolean;\n}\n","import * as THREE from 'three';\n\nimport type { Look, LookPreset, MaterialAppearanceOptions } from './types.js';\n\n/** The look applied when the caller passes no `look` option. */\nexport const DEFAULT_LOOK: Look = 'technical';\n\n/**\n * Single source of truth for both `applyDefaults` (construction) and `setLook` (runtime), so the two\n * can't drift.\n *\n * `ambientOcclusion: false` on every look: GTAO is a heavy full-screen pass, so it stays opt-in\n * (`render.ambientOcclusion` or `setAmbientOcclusion(true)`) rather than costing every viewer 60fps.\n */\nexport const LOOK_PRESETS: Record<Look, LookPreset> = {\n\t// Fills shadows in (vs. showcase, which lets them fall off). IBL/fill kept modest so\n\t// env+hemisphere+ambient don't triple-stack into an ACES-washed look.\n\tstudio: {\n\t\ttoneMapping: THREE.ACESFilmicToneMapping,\n\t\ttoneMappingExposure: 1,\n\t\tenvMapIntensity: 1.0,\n\t\tenvironmentIntensity: 1.0,\n\t\themisphereIntensity: 0.75,\n\t\tambientIntensity: 0.4,\n\t\tcullBackfaces: false,\n\t\tambientOcclusion: false\n\t},\n\t// Flat ambient kept low — a full flat ambient flattens shading toward milky grey regardless of\n\t// face orientation — with IBL near full and a little hemisphere fill for under-facing surfaces.\n\ttechnical: {\n\t\ttoneMapping: THREE.NeutralToneMapping,\n\t\ttoneMappingExposure: 1,\n\t\tenvMapIntensity: 0.9,\n\t\tenvironmentIntensity: 1,\n\t\themisphereIntensity: 0.35,\n\t\tambientIntensity: 0.25,\n\t\tcullBackfaces: false,\n\t\tambientOcclusion: false\n\t},\n\t// Fill pulled DOWN (low ambient/hemisphere) so light-to-shadow falloff stays strong for a\n\t// dramatic hero shot, unlike `studio` which fills shadows in.\n\tshowcase: {\n\t\ttoneMapping: THREE.ACESFilmicToneMapping,\n\t\ttoneMappingExposure: 1.15,\n\t\tenvMapIntensity: 1.4,\n\t\tenvironmentIntensity: 1.25,\n\t\themisphereIntensity: 0.35,\n\t\tambientIntensity: 0.15,\n\t\tcullBackfaces: false,\n\t\tambientOcclusion: false\n\t}\n};\n\n/** Baked at parse time (not toggleable at runtime). */\nexport function materialAppearanceForLook(look: Look): MaterialAppearanceOptions {\n\tconst preset = LOOK_PRESETS[look];\n\treturn {\n\t\tenvMapIntensity: preset.envMapIntensity,\n\t\tcullBackfaces: preset.cullBackfaces\n\t};\n}\n","// Copied (not imported) from `@selvajs/compute`'s `decodeBase64ToBinary` to avoid depending on the\n// Rhino.Compute client for ~20 stable lines; keep the two in sync by hand.\n\nimport { VisualizationError, ErrorCodes } from './errors.js';\n\nfunction getNodeBuffer(): typeof Buffer | undefined {\n\tconst buf = (globalThis as { Buffer?: typeof Buffer }).Buffer;\n\treturn typeof buf === 'function' ? buf : undefined;\n}\n\n/**\n * @throws {VisualizationError} `ENCODING_ERROR` if invalid, or `INVALID_STATE` if no decoder is\n * available in this environment.\n */\nexport function decodeBase64ToBinary(base64File: string): Uint8Array {\n\t// Forgiving-base64: strip whitespace, then drop trailing padding only where length % 4 allows it.\n\tlet data = base64File.replace(/[\\t\\n\\f\\r ]/g, '');\n\tif (data.length % 4 === 0) data = data.replace(/={1,2}$/, '');\n\tif (data.length % 4 === 1 || !/^[A-Za-z0-9+/]*$/.test(data)) {\n\t\tthrow new VisualizationError('Invalid base64 input.', ErrorCodes.ENCODING_ERROR, {\n\t\t\tcontext: { inputLength: base64File.length }\n\t\t});\n\t}\n\n\t// Prefer Buffer in Node: faster, and avoids the atob + charCodeAt latin-1 detour.\n\tconst Buffer = getNodeBuffer();\n\tif (Buffer) {\n\t\t// Copy out of the Buffer — small Buffer.from results are views over Node's shared 8 KiB pool\n\t\t// slab, so returning one would retain the whole slab and leak unrelated pooled bytes to any\n\t\t// consumer touching `.buffer` (structuredClone, postMessage transfer, etc).\n\t\treturn new Uint8Array(Buffer.from(data, 'base64'));\n\t}\n\tif (typeof globalThis.atob === 'function') {\n\t\tconst binary = globalThis.atob(data);\n\t\tconst bytes = new Uint8Array(binary.length);\n\t\tfor (let i = 0; i < binary.length; i++) {\n\t\t\tbytes[i] = binary.charCodeAt(i) & 0xff;\n\t\t}\n\t\treturn bytes;\n\t}\n\n\tthrow new VisualizationError(\n\t\t'Base64 decoding not supported in this environment.',\n\t\tErrorCodes.INVALID_STATE,\n\t\t{ context: { environmentInfo: 'atob or Buffer not available' } }\n\t);\n}\n","import * as THREE from 'three';\n\nimport { getLogger } from './logger.js';\n\n// parse/ needs these and must never import upward from render/, so they live in shared/ instead\n// of render's three-helpers.\n\nexport function parseColor(colorString: string): THREE.Color {\n\tif (!colorString || typeof colorString !== 'string') {\n\t\tgetLogger().warn(`Invalid color input: ${colorString}, using white`);\n\t\treturn new THREE.Color(0xffffff);\n\t}\n\n\tconst trimmed = colorString.trim();\n\n\tif (/^#?[0-9A-Fa-f]{6}$/.test(trimmed)) {\n\t\ttry {\n\t\t\tconst hex = trimmed.startsWith('#') ? trimmed : `#${trimmed}`;\n\t\t\treturn new THREE.Color(hex);\n\t\t} catch {\n\t\t\tgetLogger().warn(`Invalid hex color: ${colorString}, using white`);\n\t\t\treturn new THREE.Color(0xffffff);\n\t\t}\n\t}\n\n\tif (trimmed.includes(',')) {\n\t\tconst rgb = trimmed.split(',').map((c) => parseInt(c.trim(), 10));\n\t\tif (rgb.length === 3 && rgb.every((n) => !isNaN(n) && n >= 0 && n <= 255)) {\n\t\t\treturn new THREE.Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255);\n\t\t}\n\t}\n\n\t// `new THREE.Color(name)` never throws on unknown names (it logs its own warning and leaves the\n\t// color white), so validate against three's CSS name table instead.\n\tconst named = trimmed.toLowerCase();\n\tif (named in THREE.Color.NAMES) {\n\t\treturn new THREE.Color(THREE.Color.NAMES[named as keyof typeof THREE.Color.NAMES]);\n\t}\n\n\tgetLogger().warn(`Invalid color string: ${colorString}, using white`);\n\treturn new THREE.Color(0xffffff);\n}\n\n/** Defaults to `z` (Rhino's up axis); pass an explicit axis when the scene uses a different `sceneUp`. */\nexport function applyOffset(\n\tmeshes: THREE.Object3D[],\n\toffset: number,\n\taxis: 'x' | 'y' | 'z' = 'z'\n): void {\n\tmeshes.forEach((mesh) => {\n\t\tmesh.position[axis] -= offset;\n\t});\n}\n\nexport function computeCombinedBoundingBox(meshes: THREE.Object3D[]): THREE.Box3 {\n\tconst combinedBoundingBox = new THREE.Box3();\n\tif (meshes.length === 0) return combinedBoundingBox;\n\tmeshes.forEach((mesh) => {\n\t\tmesh.updateMatrixWorld(true);\n\t\tconst bbox = new THREE.Box3().setFromObject(mesh);\n\t\tcombinedBoundingBox.union(bbox);\n\t});\n\treturn combinedBoundingBox;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["c:\\Users\\felix\\coding\\selva\\packages\\visualization\\dist\\chunk-BYLIBOAU.cjs"],"names":[],"mappings":"AAAA,6EAAI,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc","file":"C:\\Users\\felix\\coding\\selva\\packages\\visualization\\dist\\chunk-BYLIBOAU.cjs"}
1
+ {"version":3,"sources":["/home/runner/work/selva/selva/packages/visualization/dist/chunk-BYLIBOAU.cjs"],"names":[],"mappings":"AAAA,6EAAI,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc","file":"/home/runner/work/selva/selva/packages/visualization/dist/chunk-BYLIBOAU.cjs"}
@@ -0,0 +1,2 @@
1
+ import{a as u}from"./chunk-5XGN7UAV.js";var a={VALIDATION_ERROR:"VALIDATION_ERROR",INVALID_STATE:"INVALID_STATE",ENVIRONMENT_ERROR:"ENVIRONMENT_ERROR",INVALID_CONFIG:"INVALID_CONFIG",ENCODING_ERROR:"ENCODING_ERROR",UNKNOWN_ERROR:"UNKNOWN_ERROR"},s=class extends Error{constructor(r,n=a.UNKNOWN_ERROR,t){super(r);u(this,"code");u(this,"context");u(this,"originalError");this.name="VisualizationError",this.code=n,this.context=t?.context,this.originalError=t?.originalError,t?.originalError&&(this.cause=t.originalError)}};var l=class{debug(){}info(){}warn(){}error(){}},E=class{debug(o,...r){console.debug(o,...r)}info(o,...r){console.info(o,...r)}warn(o,...r){console.warn(o,...r)}error(o,...r){console.error(o,...r)}},g=new l;function p(){return g}function x(e){if(e===null){g=new l;return}let o=["debug","info","warn","error"].filter(r=>typeof e[r]!="function");if(o.length>0)throw new s(`Logger is missing required method(s): ${o.join(", ")}. A logger must implement debug, info, warn and error.`,a.INVALID_CONFIG,{context:{missingMethods:o}});g=e}function O(){x(new E)}var h=["technical","studio","showcase"];import*as f from"three";var v="technical",R={studio:{toneMapping:f.ACESFilmicToneMapping,toneMappingExposure:1,envMapIntensity:1,environmentIntensity:1,hemisphereIntensity:.75,ambientIntensity:.4,cullBackfaces:!1,ambientOcclusion:!1},technical:{toneMapping:f.NeutralToneMapping,toneMappingExposure:1,envMapIntensity:.9,environmentIntensity:1,hemisphereIntensity:.35,ambientIntensity:.25,cullBackfaces:!1,ambientOcclusion:!1},showcase:{toneMapping:f.ACESFilmicToneMapping,toneMappingExposure:1.15,envMapIntensity:1.4,environmentIntensity:1.25,hemisphereIntensity:.35,ambientIntensity:.15,cullBackfaces:!1,ambientOcclusion:!1}};function M(e){let o=R[e];return{envMapIntensity:o.envMapIntensity,cullBackfaces:o.cullBackfaces}}function I(){let e=globalThis.Buffer;return typeof e=="function"?e:void 0}function w(e){let o=e.replace(/[\t\n\f\r ]/g,"");if(o.length%4===0&&(o=o.replace(/={1,2}$/,"")),o.length%4===1||!/^[A-Za-z0-9+/]*$/.test(o))throw new s("Invalid base64 input.",a.ENCODING_ERROR,{context:{inputLength:e.length}});let r=I();if(r)return new Uint8Array(r.from(o,"base64"));if(typeof globalThis.atob=="function"){let n=globalThis.atob(o),t=new Uint8Array(n.length);for(let c=0;c<n.length;c++)t[c]=n.charCodeAt(c)&255;return t}throw new s("Base64 decoding not supported in this environment.",a.INVALID_STATE,{context:{environmentInfo:"atob or Buffer not available"}})}import*as i from"three";function L(e){if(!e||typeof e!="string")return p().warn(`Invalid color input: ${e}, using white`),new i.Color(16777215);let o=e.trim();if(/^#?[0-9A-Fa-f]{6}$/.test(o))try{let n=o.startsWith("#")?o:`#${o}`;return new i.Color(n)}catch{return p().warn(`Invalid hex color: ${e}, using white`),new i.Color(16777215)}if(o.includes(",")){let n=o.split(",").map(t=>parseInt(t.trim(),10));if(n.length===3&&n.every(t=>!isNaN(t)&&t>=0&&t<=255))return new i.Color(n[0]/255,n[1]/255,n[2]/255)}let r=o.toLowerCase();return r in i.Color.NAMES?new i.Color(i.Color.NAMES[r]):(p().warn(`Invalid color string: ${e}, using white`),new i.Color(16777215))}function A(e,o,r="z"){e.forEach(n=>{n.position[r]-=o})}function N(e){let o=new i.Box3;return e.length===0||e.forEach(r=>{r.updateMatrixWorld(!0);let n=new i.Box3().setFromObject(r);o.union(n)}),o}var H=new Set;function b(e){return e?!H.has(e):!1}var d=new Set,m=1;function k(e){let o=Math.max(1,e);if(o!==m){m=o;for(let r of d)r(o)}}function C(e){return d.add(e),e(m),()=>d.delete(e)}import*as T from"three";function y(e){if(b(e)){for(let o of Object.values(e))o instanceof T.Texture&&o.dispose();e.dispose()}}function B(e){e&&(Array.isArray(e)?e.forEach(y):y(e))}function D(e,o={}){let{materials:r=!0}=o;e.traverse(n=>{let t=n;!t.geometry&&!t.material||(t.geometry&&t.geometry?.dispose(),r&&B(t.material))})}export{a,s as b,p as c,x as d,O as e,w as f,h as g,v as h,R as i,M as j,L as k,A as l,N as m,k as n,C as o,D as p};
2
+ //# sourceMappingURL=chunk-KRA5RVHM.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/shared/errors.ts","../src/shared/logger.ts","../src/shared/types.ts","../src/shared/looks.ts","../src/shared/encoding.ts","../src/shared/geometry.ts","../src/shared/gpu-ownership.ts","../src/shared/gpu-capabilities.ts","../src/shared/gpu-dispose.ts"],"sourcesContent":["/**\n * Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which\n * mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`\n * values match compute's so existing catch-sites keep working.\n */\n\nexport const ErrorCodes = {\n\t/** Structural check failed: bad magic bytes, out-of-window index, malformed metadata. */\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_STATE: 'INVALID_STATE',\n\t/** No `DecompressionStream`, no WebGL context, etc. */\n\tENVIRONMENT_ERROR: 'ENVIRONMENT_ERROR',\n\tINVALID_CONFIG: 'INVALID_CONFIG',\n\t/** Base64 input could not be decoded. */\n\tENCODING_ERROR: 'ENCODING_ERROR',\n\tUNKNOWN_ERROR: 'UNKNOWN_ERROR'\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\nexport class VisualizationError extends Error {\n\tpublic readonly code: ErrorCode;\n\tpublic readonly context?: Record<string, unknown>;\n\tpublic readonly originalError?: Error;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: ErrorCode = ErrorCodes.UNKNOWN_ERROR,\n\t\toptions?: { context?: Record<string, unknown>; originalError?: Error }\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'VisualizationError';\n\t\tthis.code = code;\n\t\tthis.context = options?.context;\n\t\tthis.originalError = options?.originalError;\n\t\tif (options?.originalError) {\n\t\t\t(this as { cause?: unknown }).cause = options.originalError;\n\t\t}\n\t}\n}\n","/**\n * Logging facility for the visualization package. Deliberately local rather than imported from\n * `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host\n * wanting one sink for both can call `setLogger(computeLogger.getLogger())`.\n */\n\nimport { VisualizationError, ErrorCodes } from './errors.js';\n\nexport interface Logger {\n\tdebug(message: string, ...args: unknown[]): void;\n\tinfo(message: string, ...args: unknown[]): void;\n\twarn(message: string, ...args: unknown[]): void;\n\terror(message: string, ...args: unknown[]): void;\n}\n\nclass NoOpLogger implements Logger {\n\tdebug(): void {}\n\tinfo(): void {}\n\twarn(): void {}\n\terror(): void {}\n}\n\nclass ConsoleLogger implements Logger {\n\tdebug(message: string, ...args: unknown[]): void {\n\t\t// eslint-disable-next-line no-console -- this class exists to be the console sink\n\t\tconsole.debug(message, ...args);\n\t}\n\n\tinfo(message: string, ...args: unknown[]): void {\n\t\tconsole.info(message, ...args);\n\t}\n\n\twarn(message: string, ...args: unknown[]): void {\n\t\tconsole.warn(message, ...args);\n\t}\n\n\terror(message: string, ...args: unknown[]): void {\n\t\tconsole.error(message, ...args);\n\t}\n}\n\n// Defaults to no-op: a library that writes to the console uninvited is a nuisance in a host with\n// its own logging. Opt in with setLogger or enableDebugLogging.\nlet internalLogger: Logger = new NoOpLogger();\n\n// Call per-use rather than caching — the sink is settable at any time.\nexport function getLogger(): Logger {\n\treturn internalLogger;\n}\n\n// Validates logger shape up front: failing here beats a confusing \"getLogger().debug is not a\n// function\" at some later, unrelated call site.\nexport function setLogger(logger: Logger | Console | null): void {\n\tif (logger === null) {\n\t\tinternalLogger = new NoOpLogger();\n\t\treturn;\n\t}\n\n\tconst missing = (['debug', 'info', 'warn', 'error'] as const).filter(\n\t\t(method) => typeof (logger as unknown as Record<string, unknown>)[method] !== 'function'\n\t);\n\tif (missing.length > 0) {\n\t\tthrow new VisualizationError(\n\t\t\t`Logger is missing required method(s): ${missing.join(', ')}. A logger must implement debug, info, warn and error.`,\n\t\t\tErrorCodes.INVALID_CONFIG,\n\t\t\t{ context: { missingMethods: missing } }\n\t\t);\n\t}\n\n\tinternalLogger = logger as Logger;\n}\n\nexport function enableDebugLogging(): void {\n\tsetLogger(new ConsoleLogger());\n}\n","import type * as THREE from 'three';\n\n// ============================================================================\n// LOOKS\n// ============================================================================\n\n/** Source of truth for {@link Look} — lets consumers (e.g. a style picker) iterate instead of hardcoding names. */\nexport const LOOKS = ['technical', 'studio', 'showcase'] as const;\n\nexport type Look = (typeof LOOKS)[number];\n\n/**\n * The lighting/material dials a {@link Look} sets. Never carries edges or grid — those are\n * independent overlays.\n */\nexport type LookPreset = {\n\ttoneMapping: THREE.ToneMapping;\n\ttoneMappingExposure: number;\n\tenvMapIntensity: number;\n\t/** Multiplier on the HDR's IBL (`scene.environmentIntensity`). */\n\tenvironmentIntensity: number;\n\themisphereIntensity: number;\n\tambientIntensity: number;\n\tcullBackfaces: boolean;\n\tambientOcclusion: boolean;\n};\n\n/** How compute meshes read visually — the parse-time material choices baked from a {@link Look}. */\nexport interface MaterialAppearanceOptions {\n\t/** Default 1 (three.js's own material default) when omitted. */\n\tenvMapIntensity?: number;\n\t/**\n\t * `THREE.FrontSide` instead of `THREE.DoubleSide` — crisper silhouette on closed solids, but open\n\t * surfaces (which Rhino also emits) vanish when viewed from behind. Default false (DoubleSide) to\n\t * stay safe for surface geometry.\n\t */\n\tcullBackfaces?: boolean;\n}\n","import * as THREE from 'three';\n\nimport type { Look, LookPreset, MaterialAppearanceOptions } from './types.js';\n\n/** The look applied when the caller passes no `look` option. */\nexport const DEFAULT_LOOK: Look = 'technical';\n\n/**\n * Single source of truth for both `applyDefaults` (construction) and `setLook` (runtime), so the two\n * can't drift.\n *\n * `ambientOcclusion: false` on every look: GTAO is a heavy full-screen pass, so it stays opt-in\n * (`render.ambientOcclusion` or `setAmbientOcclusion(true)`) rather than costing every viewer 60fps.\n */\nexport const LOOK_PRESETS: Record<Look, LookPreset> = {\n\t// Fills shadows in (vs. showcase, which lets them fall off). IBL/fill kept modest so\n\t// env+hemisphere+ambient don't triple-stack into an ACES-washed look.\n\tstudio: {\n\t\ttoneMapping: THREE.ACESFilmicToneMapping,\n\t\ttoneMappingExposure: 1,\n\t\tenvMapIntensity: 1.0,\n\t\tenvironmentIntensity: 1.0,\n\t\themisphereIntensity: 0.75,\n\t\tambientIntensity: 0.4,\n\t\tcullBackfaces: false,\n\t\tambientOcclusion: false\n\t},\n\t// Flat ambient kept low — a full flat ambient flattens shading toward milky grey regardless of\n\t// face orientation — with IBL near full and a little hemisphere fill for under-facing surfaces.\n\ttechnical: {\n\t\ttoneMapping: THREE.NeutralToneMapping,\n\t\ttoneMappingExposure: 1,\n\t\tenvMapIntensity: 0.9,\n\t\tenvironmentIntensity: 1,\n\t\themisphereIntensity: 0.35,\n\t\tambientIntensity: 0.25,\n\t\tcullBackfaces: false,\n\t\tambientOcclusion: false\n\t},\n\t// Fill pulled DOWN (low ambient/hemisphere) so light-to-shadow falloff stays strong for a\n\t// dramatic hero shot, unlike `studio` which fills shadows in.\n\tshowcase: {\n\t\ttoneMapping: THREE.ACESFilmicToneMapping,\n\t\ttoneMappingExposure: 1.15,\n\t\tenvMapIntensity: 1.4,\n\t\tenvironmentIntensity: 1.25,\n\t\themisphereIntensity: 0.35,\n\t\tambientIntensity: 0.15,\n\t\tcullBackfaces: false,\n\t\tambientOcclusion: false\n\t}\n};\n\n/** Baked at parse time (not toggleable at runtime). */\nexport function materialAppearanceForLook(look: Look): MaterialAppearanceOptions {\n\tconst preset = LOOK_PRESETS[look];\n\treturn {\n\t\tenvMapIntensity: preset.envMapIntensity,\n\t\tcullBackfaces: preset.cullBackfaces\n\t};\n}\n","// Copied (not imported) from `@selvajs/compute`'s `decodeBase64ToBinary` to avoid depending on the\n// Rhino.Compute client for ~20 stable lines; keep the two in sync by hand.\n\nimport { VisualizationError, ErrorCodes } from './errors.js';\n\nfunction getNodeBuffer(): typeof Buffer | undefined {\n\tconst buf = (globalThis as { Buffer?: typeof Buffer }).Buffer;\n\treturn typeof buf === 'function' ? buf : undefined;\n}\n\n/**\n * @throws {VisualizationError} `ENCODING_ERROR` if invalid, or `INVALID_STATE` if no decoder is\n * available in this environment.\n */\nexport function decodeBase64ToBinary(base64File: string): Uint8Array {\n\t// Forgiving-base64: strip whitespace, then drop trailing padding only where length % 4 allows it.\n\tlet data = base64File.replace(/[\\t\\n\\f\\r ]/g, '');\n\tif (data.length % 4 === 0) data = data.replace(/={1,2}$/, '');\n\tif (data.length % 4 === 1 || !/^[A-Za-z0-9+/]*$/.test(data)) {\n\t\tthrow new VisualizationError('Invalid base64 input.', ErrorCodes.ENCODING_ERROR, {\n\t\t\tcontext: { inputLength: base64File.length }\n\t\t});\n\t}\n\n\t// Prefer Buffer in Node: faster, and avoids the atob + charCodeAt latin-1 detour.\n\tconst Buffer = getNodeBuffer();\n\tif (Buffer) {\n\t\t// Copy out of the Buffer — small Buffer.from results are views over Node's shared 8 KiB pool\n\t\t// slab, so returning one would retain the whole slab and leak unrelated pooled bytes to any\n\t\t// consumer touching `.buffer` (structuredClone, postMessage transfer, etc).\n\t\treturn new Uint8Array(Buffer.from(data, 'base64'));\n\t}\n\tif (typeof globalThis.atob === 'function') {\n\t\tconst binary = globalThis.atob(data);\n\t\tconst bytes = new Uint8Array(binary.length);\n\t\tfor (let i = 0; i < binary.length; i++) {\n\t\t\tbytes[i] = binary.charCodeAt(i) & 0xff;\n\t\t}\n\t\treturn bytes;\n\t}\n\n\tthrow new VisualizationError(\n\t\t'Base64 decoding not supported in this environment.',\n\t\tErrorCodes.INVALID_STATE,\n\t\t{ context: { environmentInfo: 'atob or Buffer not available' } }\n\t);\n}\n","import * as THREE from 'three';\n\nimport { getLogger } from './logger.js';\n\n// parse/ needs these and must never import upward from render/, so they live in shared/ instead\n// of render's three-helpers.\n\nexport function parseColor(colorString: string): THREE.Color {\n\tif (!colorString || typeof colorString !== 'string') {\n\t\tgetLogger().warn(`Invalid color input: ${colorString}, using white`);\n\t\treturn new THREE.Color(0xffffff);\n\t}\n\n\tconst trimmed = colorString.trim();\n\n\tif (/^#?[0-9A-Fa-f]{6}$/.test(trimmed)) {\n\t\ttry {\n\t\t\tconst hex = trimmed.startsWith('#') ? trimmed : `#${trimmed}`;\n\t\t\treturn new THREE.Color(hex);\n\t\t} catch {\n\t\t\tgetLogger().warn(`Invalid hex color: ${colorString}, using white`);\n\t\t\treturn new THREE.Color(0xffffff);\n\t\t}\n\t}\n\n\tif (trimmed.includes(',')) {\n\t\tconst rgb = trimmed.split(',').map((c) => parseInt(c.trim(), 10));\n\t\tif (rgb.length === 3 && rgb.every((n) => !isNaN(n) && n >= 0 && n <= 255)) {\n\t\t\treturn new THREE.Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255);\n\t\t}\n\t}\n\n\t// `new THREE.Color(name)` never throws on unknown names (it logs its own warning and leaves the\n\t// color white), so validate against three's CSS name table instead.\n\tconst named = trimmed.toLowerCase();\n\tif (named in THREE.Color.NAMES) {\n\t\treturn new THREE.Color(THREE.Color.NAMES[named as keyof typeof THREE.Color.NAMES]);\n\t}\n\n\tgetLogger().warn(`Invalid color string: ${colorString}, using white`);\n\treturn new THREE.Color(0xffffff);\n}\n\n/** Defaults to `z` (Rhino's up axis); pass an explicit axis when the scene uses a different `sceneUp`. */\nexport function applyOffset(\n\tmeshes: THREE.Object3D[],\n\toffset: number,\n\taxis: 'x' | 'y' | 'z' = 'z'\n): void {\n\tmeshes.forEach((mesh) => {\n\t\tmesh.position[axis] -= offset;\n\t});\n}\n\nexport function computeCombinedBoundingBox(meshes: THREE.Object3D[]): THREE.Box3 {\n\tconst combinedBoundingBox = new THREE.Box3();\n\tif (meshes.length === 0) return combinedBoundingBox;\n\tmeshes.forEach((mesh) => {\n\t\tmesh.updateMatrixWorld(true);\n\t\tconst bbox = new THREE.Box3().setFromObject(mesh);\n\t\tcombinedBoundingBox.union(bbox);\n\t});\n\treturn combinedBoundingBox;\n}\n","import type * as THREE from 'three';\n\n// ============================================================================\n// GPU resource ownership — the single rule every disposal path obeys\n// ============================================================================\n\n/**\n * A GPU resource has exactly one owner: a **module singleton** (nobody ever frees it) or the\n * **scene** (freed on teardown). Every disposal path asks {@link canDisposeMaterial} and disposes\n * only if true. Geometries and textures are always scene-owned, so they have no claim to check.\n */\n\n// Module-scope singletons from `render/three-materials.ts`, shared across meshes and solves —\n// disposing one would free textures still in use and force a recompile. Held here (not imported\n// there) to avoid an import cycle.\nconst protectedMaterials = new Set<THREE.Material>();\n\n/** Register materials as never-disposable. Called once by `render/three-materials.ts`. */\nexport function protectMaterials(materials: Iterable<THREE.Material>): void {\n\tfor (const material of materials) protectedMaterials.add(material);\n}\n\n/** True when `material` is scene-owned (not one of the protected singletons). */\nexport function canDisposeMaterial(material: THREE.Material | undefined): boolean {\n\tif (!material) return false;\n\treturn !protectedMaterials.has(material);\n}\n","// ============================================================================\n// GPU capabilities — published by the renderer, read by whoever needs them\n// ============================================================================\n\n// Lets a renderer publish GPU capabilities (max anisotropy) without `render/` and `parse/` importing\n// each other: the renderer publishes on init, interested parties subscribe.\n\ntype AnisotropyObserver = (value: number) => void;\n\nconst observers = new Set<AnisotropyObserver>();\n\n// Module load order between layers isn't guaranteed, so a subscriber arriving after init still\n// needs the current value rather than waiting for a second renderer to publish.\nlet maxAnisotropy = 1;\n\nexport function publishMaxAnisotropy(value: number): void {\n\tconst next = Math.max(1, value);\n\tif (next === maxAnisotropy) return;\n\tmaxAnisotropy = next;\n\tfor (const observe of observers) observe(next);\n}\n\n/** Fires immediately with the current value (1 until a renderer has reported), then on every change. */\nexport function observeMaxAnisotropy(observe: AnisotropyObserver): () => void {\n\tobservers.add(observe);\n\tobserve(maxAnisotropy);\n\treturn () => observers.delete(observe);\n}\n","import * as THREE from 'three';\n\nimport { canDisposeMaterial } from './gpu-ownership.js';\n\n// ============================================================================\n// The disposal walkers — every teardown path in the package goes through these\n// ============================================================================\n\n/** Frees a material and its textures, respecting ownership (`./gpu-ownership.ts`). */\nexport function disposeMaterial(material: THREE.Material): void {\n\tif (!canDisposeMaterial(material)) return;\n\n\tfor (const value of Object.values(material)) {\n\t\tif (value instanceof THREE.Texture) {\n\t\t\tvalue.dispose();\n\t\t}\n\t}\n\tmaterial.dispose();\n}\n\nfunction disposeMaterials(material: THREE.Material | THREE.Material[] | undefined): void {\n\tif (!material) return;\n\tif (Array.isArray(material)) material.forEach(disposeMaterial);\n\telse disposeMaterial(material);\n}\n\nexport interface DisposeOptions {\n\t/** Free materials and their textures too. Default true; the solve memo passes false. */\n\tmaterials?: boolean;\n\t/** Called for each geometry before disposal, so a subsystem can free derived resources keyed on it (e.g. edge caches). */\n\tonGeometry?: (geometry: THREE.BufferGeometry) => void;\n}\n\n/**\n * Frees the GPU resources of an object subtree, respecting ownership. **The only traversal that\n * should dispose scene content** — a second disposing `traverse` risks missing an ownership guard.\n */\nexport function disposeObjectTree(root: THREE.Object3D, options: DisposeOptions = {}): void {\n\tconst { materials = true } = options;\n\n\troot.traverse((object) => {\n\t\tconst renderable = object as Partial<THREE.Mesh> & THREE.Object3D;\n\t\tif (!renderable.geometry && !renderable.material) return;\n\n\t\tif (renderable.geometry) {\n\t\t\trenderable.geometry?.dispose();\n\t\t}\n\n\t\tif (materials) disposeMaterials(renderable.material);\n\t});\n}\n"],"mappings":"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","names":["ErrorCodes","VisualizationError","message","code","options","__publicField","NoOpLogger","ConsoleLogger","message","args","internalLogger","getLogger","setLogger","logger","missing","method","VisualizationError","ErrorCodes","enableDebugLogging","LOOKS","THREE","DEFAULT_LOOK","LOOK_PRESETS","materialAppearanceForLook","look","preset","getNodeBuffer","buf","decodeBase64ToBinary","base64File","data","VisualizationError","ErrorCodes","Buffer","binary","bytes","i","THREE","parseColor","colorString","getLogger","trimmed","hex","rgb","c","n","named","applyOffset","meshes","offset","axis","mesh","computeCombinedBoundingBox","combinedBoundingBox","bbox","protectedMaterials","canDisposeMaterial","material","protectedMaterials","observers","maxAnisotropy","publishMaxAnisotropy","value","next","observe","observeMaxAnisotropy","THREE","disposeMaterial","material","canDisposeMaterial","value","disposeMaterials","disposeObjectTree","root","options","materials","object","renderable"]}
@@ -1 +1 @@
1
- {"version":3,"sources":["c:\\Users\\felix\\coding\\selva\\packages\\visualization\\dist\\index.cjs"],"names":[],"mappings":"AAAA","file":"C:\\Users\\felix\\coding\\selva\\packages\\visualization\\dist\\index.cjs"}
1
+ {"version":3,"sources":["/home/runner/work/selva/selva/packages/visualization/dist/index.cjs"],"names":[],"mappings":"AAAA","file":"/home/runner/work/selva/selva/packages/visualization/dist/index.cjs"}
package/dist/parse.cjs CHANGED
@@ -1,10 +1,10 @@
1
- "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkAQJPVUH3cjs = require('./chunk-AQJPVUH3.cjs');require('./chunk-BYLIBOAU.cjs');function bt(e){return e.map(t=>{let r=t.clone(!0),n=[];t.traverse(a=>n.push(a));let o=0;return r.traverse(a=>{let s=n[o++],u=a;if(!s.geometry)return;let i=s.geometry.clone();i.userData={...i.userData},delete i.userData[_chunkAQJPVUH3cjs.n],u.geometry=i}),r})}function Et(e){e.forEach(t=>_chunkAQJPVUH3cjs.v.call(void 0, t,{materials:!1}))}var xt={clone:bt,release:Et};var _three = require('three'); var de = _interopRequireWildcard(_three); var _e = _interopRequireWildcard(_three); var P = _interopRequireWildcard(_three); var V = _interopRequireWildcard(_three); var z = _interopRequireWildcard(_three); var ce = _interopRequireWildcard(_three); var O = _interopRequireWildcard(_three);var _Line2js = require('three/addons/lines/Line2.js');var _LineGeometryjs = require('three/addons/lines/LineGeometry.js');var _LineMaterialjs = require('three/addons/lines/LineMaterial.js');var At="#ffffff";function te(e,t){let r=_nullishCoalesce(t, () => (1));return{color:new _e.Color(_nullishCoalesce(e, () => (At))),transparent:r<1,opacity:r}}var Fe=12,Rt=4e-4,vt=12,St=.05,Ct=2;function Pe(e,t){if(!t)return _chunkAQJPVUH3cjs.c.call(void 0, ).warn("No rhino3dm instance provided; skipping curve display item."),null;let r=Bt(e.json,t);if(!r)return null;let n;try{n=It(r)}catch(l){return _chunkAQJPVUH3cjs.c.call(void 0, ).warn("Failed to tessellate curve display item; skipping.",l),null}finally{Y(r)}if(n.length<2)return null;let o=[];for(let l of n)o.push(l.x,l.y,l.z);let a=new _LineGeometryjs.LineGeometry;a.setPositions(o);let s=te(e.color,e.opacity),u=new (0, _LineMaterialjs.LineMaterial)({color:s.color}),i=u;i.linewidth=_nullishCoalesce(e.width, () => (Ct)),i.transparent=s.transparent,i.opacity=s.opacity;let f=new (0, _Line2js.Line2)(a,u);return f.computeLineDistances(),f.name=e.name,f.userData={source:"compute",id:e.id,layer:e.layer,kind:"curve",metadata:e.metadata},f}function Y(e){_optionalChain([e, 'optionalAccess', _2 => _2.delete, 'optionalCall', _3 => _3()])}function Bt(e,t){try{let r=JSON.parse(e),n=t.CommonObject.decode(r);return n&&typeof n.pointAt=="function"?n:(Y(n),_chunkAQJPVUH3cjs.c.call(void 0, ).warn("Decoded display-item JSON is not a curve; skipping."),null)}catch(r){return _chunkAQJPVUH3cjs.c.call(void 0, ).warn("Failed to decode curve display item JSON:",r),null}}function It(e){let t=Dt(e);return t||Ot(e)}function Dt(e){if(!e.isPolyline())return null;let t=e.tryGetPolyline(),r=Array.isArray(t)?t[1]:t;if(!r||typeof r.count!="number"||r.count<2)return Y(r),null;let n=[];for(let o=0;o<r.count;o++){let a=r.get(o);n.push(new de.Vector3(a[0],a[1],a[2]))}return Y(r),n}function Ot(e){let t=e.domain,r=t[0],o=t[1]-r,a=l=>{let y=e.pointAt(l);return new de.Vector3(y[0],y[1],y[2])},s=Ut(e),u=r,i=a(r),f=[i];for(let l=0;l<Fe;l++){let y=r+o*(l+1)/Fe,b=a(y);me(u,i,y,b,a,s,vt,f),f.push(b),u=y,i=b}return f}function me(e,t,r,n,o,a,s,u){if(s<=0)return;let i=(e+r)/2,f=o(i),l=Lt(f,t,n),y=Ht(t,f,n);l<=a&&y<=St||(me(e,t,i,f,o,a,s-1,u),u.push(f),me(i,f,r,n,o,a,s-1,u))}function Ut(e){let t=e.getBoundingBox(),r=t.min,n=t.max;Y(t);let o=Math.hypot(n[0]-r[0],n[1]-r[1],n[2]-r[2]);return Math.max(o*Rt,1e-6)}function Ht(e,t,r){let n=t.x-e.x,o=t.y-e.y,a=t.z-e.z,s=r.x-t.x,u=r.y-t.y,i=r.z-t.z,f=Math.sqrt(n*n+o*o+a*a),l=Math.sqrt(s*s+u*u+i*i);if(f===0||l===0)return 0;let y=n*s+o*u+a*i,b=Math.max(-1,Math.min(1,y/(f*l)));return Math.acos(b)}function Lt(e,t,r){let n=r.x-t.x,o=r.y-t.y,a=r.z-t.z,s=n*n+o*o+a*a;if(s===0)return e.distanceTo(t);let u=e.x-t.x,i=e.y-t.y,f=e.z-t.z,l=Math.max(0,Math.min(1,(u*n+i*o+f*a)/s)),y=u-n*l,b=i-o*l,w=f-a*l;return Math.sqrt(y*y+b*b+w*w)}function Ve(e){let{position:t}=e;if(!t||typeof t.X!="number"||!Number.isFinite(t.X)||typeof t.Y!="number"||!Number.isFinite(t.Y)||typeof t.Z!="number"||!Number.isFinite(t.Z))return _chunkAQJPVUH3cjs.c.call(void 0, ).warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let r=new P.BufferGeometry;r.setAttribute("position",new P.Float32BufferAttribute([t.X,t.Y,t.Z],3));let n=new P.PointsMaterial({...te(e.color,e.opacity),size:6,sizeAttenuation:!1}),o=new P.Points(r,n);return o.name=e.name,o.userData={source:"compute",id:e.id,layer:e.layer,kind:"point",metadata:e.metadata},o}function pe(e,t={}){if(!e||e.length===0)return[];let{rhino:r}=t,n=[];for(let o of e)switch(o.kind){case"curve":{let a=Pe(o,r);a&&n.push(a);break}case"point":{let a=Ve(o);a&&n.push(a);break}default:{let s=o;_chunkAQJPVUH3cjs.c.call(void 0, ).warn(`Skipping unknown display item kind: ${String(s.kind)}`);break}}return n}var ke=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;var _fflate = require('fflate');function Ge(e){return typeof e=="string"?_chunkAQJPVUH3cjs.f.call(void 0, e):e instanceof Uint8Array?e:new Uint8Array(e)}function Ne(e){if(e.byteLength<8)return e;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint32(0,!0)!==1515605075)return e;let r=t.getUint32(4,!0),n=e.subarray(8),o=Math.max(n.byteLength*1032+1024,1<<20);if(r>o)throw I("SLVZ header declares an implausible uncompressed length",{uncompressedLen:r,deflatedBytes:n.byteLength,maxPlausibleLen:o});let a;try{a=_fflate.inflateSync.call(void 0, n,{out:new Uint8Array(r+1)})}catch(s){throw I(`Failed to inflate SLVZ blob: ${s instanceof Error?s.message:String(s)}`,{uncompressedLen:r,deflatedBytes:n.byteLength})}if(a.byteLength!==r)throw I("SLVZ payload inflated to a different size than the header declares.",{declaredLen:r,actualLen:a.byteLength,deflatedBytes:n.byteLength});return a}function je(e){if(typeof TextDecoder<"u")return new TextDecoder("utf-8").decode(e);if(typeof globalThis.Buffer<"u")return globalThis.Buffer.from(e).toString("utf-8");throw new (0, _chunkAQJPVUH3cjs.b)("No UTF-8 decoder available in this environment.",_chunkAQJPVUH3cjs.a.INVALID_STATE)}function $e(e,t,r){if(r===0)return new Int16Array(0);if(t%2===0)return new Int16Array(e,t,r);let n=new Uint8Array(r*2);return n.set(new Uint8Array(e,t,r*2)),new Int16Array(n.buffer)}function re(e,t,r){if(r===0)return new Float32Array(0);if(t%4===0)return new Float32Array(e,t,r);let n=new Uint8Array(r*4);return n.set(new Uint8Array(e,t,r*4)),new Float32Array(n.buffer)}function W(e,t,r){if(r===0)return new Uint16Array(0);if(t%2===0)return new Uint16Array(e,t,r);let n=new Uint8Array(r*2);return n.set(new Uint8Array(e,t,r*2)),new Uint16Array(n.buffer)}function ze(e,t,r){if(r===0)return new Uint32Array(0);if(t%4===0)return new Uint32Array(e,t,r);let n=new Uint8Array(r*4);return n.set(new Uint8Array(e,t,r*4)),new Uint32Array(n.buffer)}function Ye(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let r=0;r<e.length;r++)if(e[r]>=t)throw I("Index out of range of vertexCount.",{indexPosition:r,indexValue:e[r],vertexCount:t})}}function L(e){return e>>>1^-(e&1)}function We(e){let t=new Int16Array(e.length),r=0,n=0,o=0;for(let a=0;a<e.length;a+=3)r=r+L(e[a])<<16>>16,n=n+L(e[a+1])<<16>>16,o=o+L(e[a+2])<<16>>16,t[a]=r,t[a+1]=n,t[a+2]=o;return t}function Je(e){let t=new Uint16Array(e.length),r=0;for(let n=0;n<e.length;n++)r=r+L(e[n])&65535,t[n]=r;return t}function Xe(e){let t=new Uint32Array(e.length),r=0;for(let n=0;n<e.length;n++)r=r+L(e[n])>>>0,t[n]=r;return t}function I(e,t){return new (0, _chunkAQJPVUH3cjs.b)(e,_chunkAQJPVUH3cjs.a.VALIDATION_ERROR,{context:t})}var Ke=36;function qe(e,t,r,n,o){if(r+Ke>e.byteLength)throw I("Insufficient data to read UV chunk header.",{expectedBytes:Ke,availableBytes:e.byteLength-r,offset:r});let a=t.getUint32(r,!0);r+=4;let s=t.getFloat64(r,!0);r+=8;let u=t.getFloat64(r,!0);r+=8;let i=t.getFloat64(r,!0);r+=8;let f=t.getFloat64(r,!0);r+=8;let l=n*2,y=a===1,b=l*(y?4:2);if(r+b>e.byteLength)throw I("Insufficient data to read UV chunk.",{expectedBytes:b,availableBytes:e.byteLength-r,offset:r,uvFormat:a,vertexCount:n});let w=e.byteOffset+r,v;if(y)v=re(e.buffer,w,l).slice();else{let C=W(e.buffer,w,l);v=new Float32Array(l);let c=0,d=0;for(let p=0;p<l;p+=2)o?(c=c+L(C[p])&65535,d=d+L(C[p+1])&65535):(c=C[p],d=C[p+1]),v[p]=s+c*i,v[p+1]=u+d*f}return{uvs:v,offset:r+b}}function Ze(e,t,r,n){let o=r*3;if(t+o>e.byteLength)throw I("Insufficient data to read vertex-color chunk.",{expectedBytes:o,availableBytes:e.byteLength-t,offset:t,vertexCount:r});let a=e.subarray(t,t+o);if(!n)return a.slice();let s=new Uint8Array(o),u=0,i=0,f=0;for(let l=0;l<o;l+=3)u=u+L(a[l])&255,i=i+L(a[l+1])&255,f=f+L(a[l+2])&255,s[l]=u,s[l+1]=i,s[l+2]=f;return s}function he(e){let t=ge(e),r;t.isFloat32?r=t.vertexData:t.deltaEncoded?r=We(t.vertexData):r=t.vertexData;let n=t.indexData;return t.deltaEncoded&&(n=n instanceof Uint16Array?Je(n):Xe(n)),Ye(n,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:r,indices:n,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function ge(e){if(!ke)throw new (0, _chunkAQJPVUH3cjs.b)("SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.",_chunkAQJPVUH3cjs.a.ENVIRONMENT_ERROR);let t=Ne(Ge(e)),r=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<12)throw I("Blob too small to contain SLVA header.",{expectedBytes:12,availableBytes:t.byteLength});let n=0,o=r.getUint32(n,!0);if(n+=4,o!==1096174675)throw I(`Invalid SLVA magic: 0x${o.toString(16)}`,{expectedMagic:`0x${1096174675 .toString(16)}`,actualMagic:`0x${o.toString(16)}`});let a=r.getUint32(n,!0);if(n+=4,a<1||a>3)throw I(`Unsupported SLVA version: ${a}`,{minSupportedVersion:1,maxSupportedVersion:3,actualVersion:a});let s=r.getUint32(n,!0);if(n+=4,n+s>t.byteLength)throw I("Insufficient data to read metadata JSON.",{expectedBytes:s,availableBytes:t.byteLength-n,offset:n});let u=t.subarray(n,n+s);n+=s;let i;try{i=JSON.parse(je(u))}catch(U){throw I(`Failed to parse metadata JSON: ${U instanceof Error?U.message:String(U)}`,{metadataLen:s})}if(n+56>t.byteLength)throw I("Insufficient data to read geometry header.",{expectedBytes:56,availableBytes:t.byteLength-n,offset:n});let f=r.getUint32(n,!0);n+=4;let l=r.getFloat64(n,!0);n+=8;let y=r.getFloat64(n,!0);n+=8;let b=r.getFloat64(n,!0);n+=8;let w=r.getFloat64(n,!0);n+=8;let v=r.getFloat64(n,!0);n+=8;let C=r.getFloat64(n,!0);n+=8;let c=r.getUint32(n,!0);n+=4;let d=(f&1)!==0,p=(f&4)!==0,m=c*3,S=m*(d?4:2);if(n+S>t.byteLength)throw I("Insufficient data to read vertices.",{expectedBytes:S,availableBytes:t.byteLength-n,offset:n,useFloat32:d,vertexCount:c});let T=t.byteOffset+n,g;if(d?g=re(t.buffer,T,m):p?g=W(t.buffer,T,m):g=$e(t.buffer,T,m),n+=S,n+4>t.byteLength)throw I("Insufficient data to read index count.",{expectedBytes:4,availableBytes:t.byteLength-n,offset:n});let x=r.getUint32(n,!0);n+=4;let R=(f&2)!==0,M=x*(R?2:4);if(n+M>t.byteLength)throw I("Insufficient data to read indices.",{expectedBytes:M,availableBytes:t.byteLength-n,offset:n,indexCount:x,useUint16Indices:R});let B=R?W(t.buffer,t.byteOffset+n,x):ze(t.buffer,t.byteOffset+n,x);n+=M;let D=null;if((f&8)!==0){let U=qe(t,r,n,c,p);D=U.uvs,n=U.offset}let H=null;return(f&16)!==0&&(H=Ze(t,n,c,p)),{metadata:i,flags:f,vertexData:g,indexData:B,isFloat32:d,deltaEncoded:p,vertexCount:c,origin:[l,y,b],scale:[w,v,C],uvs:D,colors:H}}var ot=256*1024*1024,ne=1024,_=new Map,oe=0;function at(e,t){let r=2166136261,n=o=>{r^=o,r=Math.imul(r,16777619)};for(let o=0;o<t.length;o++)n(t.charCodeAt(o));for(let o of e){if(!o){n(57005);continue}let a=o.byteLength;if(n(a),(o.byteOffset&3)===0&&(a&3)===0){let s=new Uint32Array(o.buffer,o.byteOffset,a>>2),u=Math.min(ne,s.length);for(let i=0;i<u;i++)n(s[i]);for(let i=Math.max(u,s.length-ne);i<s.length;i++)n(s[i])}else{let s=new Uint8Array(o.buffer,o.byteOffset,a),u=Math.min(ne*4,s.length);for(let i=0;i<u;i++)n(s[i]);for(let i=Math.max(u,s.length-ne*4);i<s.length;i++)n(s[i])}}return`${(r>>>0).toString(36)}:${e.length}`}function Gt(e){let t=_nullishCoalesce(_optionalChain([e, 'access', _4 => _4.index, 'optionalAccess', _5 => _5.array, 'access', _6 => _6.byteLength]), () => (0));for(let r of Object.values(e.attributes))t+=r.array.byteLength;return t}function J(e){let t=_.get(e);if(t)return _.delete(e),_.set(e,t),t.geometry}function X(e,t){let r=Gt(t);if(!(r>ot)&&!_.has(e))for(t.userData[_chunkAQJPVUH3cjs.n]=!0,_.set(e,{geometry:t,bytes:r}),oe+=r;oe>ot&&_.size>1;){let n=_.keys().next().value,o=_.get(n);_.delete(n),oe-=o.bytes,delete o.geometry.userData[_chunkAQJPVUH3cjs.n],o.geometry.dispose()}}_chunkAQJPVUH3cjs.q.call(void 0, ()=>Nt());function Nt(){for(let e of _.values())delete e.geometry.userData[_chunkAQJPVUH3cjs.n],e.geometry.dispose();_.clear(),oe=0}function jt(e){let{isFloat32:t,deltaEncoded:r,origin:n,scale:o,uvs:a,colors:s,jobs:u}=e,i=c=>c>>>1^-(c&1),f;if(t)f=e.vertexData;else{let c;if(r){let g=e.vertexData;c=new Int16Array(g.length);let x=0,R=0,E=0;for(let M=0;M<g.length;M+=3)x=x+i(g[M])<<16>>16,R=R+i(g[M+1])<<16>>16,E=E+i(g[M+2])<<16>>16,c[M]=x,c[M+1]=R,c[M+2]=E}else c=e.vertexData;f=new Float32Array(c.length);let d=n[0],p=n[1],m=n[2],h=o[0],S=o[1],T=o[2];for(let g=0;g<c.length;g+=3)f[g]=d+(c[g]+32767)*h,f[g+1]=p+(c[g+1]+32767)*S,f[g+2]=m+(c[g+2]+32767)*T}let l;if(r){let c=e.indexData;if(c instanceof Uint16Array){let d=new Uint16Array(c.length),p=0;for(let m=0;m<c.length;m++)p=p+i(c[m])&65535,d[m]=p;l=d}else{let d=new Uint32Array(c.length),p=0;for(let m=0;m<c.length;m++)p=p+i(c[m])>>>0,d[m]=p;l=d}}else l=e.indexData;let y=f.length/3;for(let c=0;c<l.length;c++)if(l[c]>=y)throw new Error(`Index ${l[c]} out of range of vertexCount ${y}`);let b=1024,w=(c,d)=>{let p=2166136261,m=h=>{p^=h,p=Math.imul(p,16777619)};for(let h=0;h<d.length;h++)m(d.charCodeAt(h));for(let h of c){if(!h){m(57005);continue}let S=h.byteLength;if(m(S),(h.byteOffset&3)===0&&(S&3)===0){let T=new Uint32Array(h.buffer,h.byteOffset,S>>2),g=Math.min(b,T.length);for(let x=0;x<g;x++)m(T[x]);for(let x=Math.max(g,T.length-b);x<T.length;x++)m(T[x])}else{let T=new Uint8Array(h.buffer,h.byteOffset,S),g=Math.min(b*4,T.length);for(let x=0;x<g;x++)m(T[x]);for(let x=Math.max(g,T.length-b*4);x<T.length;x++)m(T[x])}}return`${(p>>>0).toString(36)}:${c.length}`},v=(c,d)=>{let p=[],m=c;for(let h of d){m+=`|${h.vertexStart},${h.vertexCount},${h.indexStart},${h.indexCount}`;let S=h.vertexStart*3,T=S+h.vertexCount*3;p.push(f.subarray(S,T)),p.push(l.subarray(h.indexStart,h.indexStart+h.indexCount)),p.push(a?a.subarray(h.vertexStart*2,(h.vertexStart+h.vertexCount)*2):null),p.push(s?s.subarray(S,T):null)}return w(p,m)},C=[];for(let c of u){let d=0,p=0;for(let E of c.windows)d+=E.vertexCount,p+=E.indexCount;let m=new Float32Array(d*3),h=new Uint32Array(p),S=a?new Float32Array(d*2):null,T=s?new Uint8Array(d*3):null,g=0,x=0;for(let E of c.windows){let M=E.vertexStart*3;m.set(f.subarray(M,M+E.vertexCount*3),g*3),S&&a&&S.set(a.subarray(E.vertexStart*2,(E.vertexStart+E.vertexCount)*2),g*2),T&&s&&T.set(s.subarray(M,M+E.vertexCount*3),g*3);let B=E.vertexStart,D=E.vertexStart+E.vertexCount,H=g-E.vertexStart;for(let U=0;U<E.indexCount;U++){let k=l[E.indexStart+U];if(k<B||k>=D)throw new Error(`Index ${k} outside vertex window [${B}, ${D})`);h[x+U]=k+H}g+=E.vertexCount,x+=E.indexCount}let R=new Float32Array(d*3);for(let E=0;E<h.length;E+=3){let M=h[E]*3,B=h[E+1]*3,D=h[E+2]*3,H=m[D]-m[B],U=m[D+1]-m[B+1],k=m[D+2]-m[B+2],ve=m[M]-m[B],Se=m[M+1]-m[B+1],Ce=m[M+2]-m[B+2],le=U*Ce-k*Se,ue=k*ve-H*Ce,fe=H*Se-U*ve;R[M]+=le,R[M+1]+=ue,R[M+2]+=fe,R[B]+=le,R[B+1]+=ue,R[B+2]+=fe,R[D]+=le,R[D+1]+=ue,R[D+2]+=fe}for(let E=0;E<R.length;E+=3){let M=R[E],B=R[E+1],D=R[E+2],H=Math.sqrt(M*M+B*B+D*D)||1;R[E]=M/H,R[E+1]=B/H,R[E+2]=D/H}C.push({key:v(c.kind,c.windows),positions:m,normals:R,indices:h,uvs:S,colors:T})}return C}function st(){return[`const assemble = ${jt.toString()};`,"self.onmessage = (event) => {"," const { id, input } = event.data;"," try {"," const geometries = assemble(input);"," const transfer = [];"," for (const g of geometries) {"," transfer.push(g.positions.buffer, g.normals.buffer, g.indices.buffer);"," if (g.uvs) transfer.push(g.uvs.buffer);"," if (g.colors) transfer.push(g.colors.buffer);"," }"," self.postMessage({ id, geometries }, transfer);"," } catch (error) {"," self.postMessage({ id, error: String((error && error.message) || error) });"," }","};"].join(`
2
- `)}var it=5e4,j,K=new Map,$t=1;function ct(){if(j!==void 0)return j;if(typeof Worker>"u"||typeof Blob>"u"||typeof URL>"u"||typeof URL.createObjectURL!="function")return j=null,null;try{let e=URL.createObjectURL(new Blob([st()],{type:"text/javascript"})),t=new Worker(e);t.onmessage=r=>{let{id:n,geometries:o,error:a}=r.data,s=K.get(n);s&&(K.delete(n),o?s.resolve(o):s.reject(new Error(_nullishCoalesce(a, () => ("mesh assembly failed in worker")))))},t.onerror=()=>{for(let r of K.values())r.reject(new Error("mesh assembly worker crashed"));K.clear(),t.terminate(),j=null},j=t}catch (e2){j=null}return j}function lt(e,t,r){return new Promise((n,o)=>{let a=$t++;K.set(a,{resolve:n,reject:o}),e.postMessage({id:a,input:t},r)})}var zt=64,Yt=256,F=new Map,q=new Map,ae=0,ie=class extends Error{constructor(t){super(`Texture load for ${t} resolved after clearTextureCache(); texture disposed.`),this.name="StaleTextureLoadError"}},se=1;function ut(e){se=Math.max(1,e);for(let t of F.values())t.anisotropy!==se&&(t.anisotropy=se,t.needsUpdate=!0)}_chunkAQJPVUH3cjs.u.call(void 0, ut);function ft(e,t){let r=Jt(t),n=F.get(r);if(n){F.delete(r),F.set(r,n),e.map=n,e.needsUpdate=!0;return}typeof document>"u"||qt(t,r).then(o=>{e.map=o,e.needsUpdate=!0}).catch(o=>{o instanceof ie||_chunkAQJPVUH3cjs.c.call(void 0, ).warn(`Failed to load material texture ${t}:`,o)})}_chunkAQJPVUH3cjs.q.call(void 0, ()=>Wt());function Wt(){ae++;for(let e of F.values())delete e.userData[_chunkAQJPVUH3cjs.o],e.dispose();F.clear(),q.clear()}function Jt(e){return e.length<=Yt?e:`data-uri:${Xt(e).toString(16)}:${e.length}`}function Xt(e){let t=2166136261;for(let r=0;r<e.length;r++)t^=e.charCodeAt(r),t=Math.imul(t,16777619);return t>>>0}function Kt(e,t){for(t.userData[_chunkAQJPVUH3cjs.o]=!0,F.set(e,t);F.size>zt;){let r=F.keys().next().value,n=F.get(r);F.delete(r),delete n.userData[_chunkAQJPVUH3cjs.o],n.dispose()}}function qt(e,t){let r=q.get(t);if(!r){let n=ae;r=new Promise((o,a)=>{new ce.TextureLoader().load(e,s=>{if(n!==ae){s.dispose(),a(new ie(e));return}s.colorSpace=ce.SRGBColorSpace,s.anisotropy=se,Kt(t,s),q.delete(t),o(s)},void 0,s=>{n===ae&&q.delete(t),a(s)})}),q.set(t,r)}return r}var Zt=.5,Qt=.5,er=.3;function be(e,t){let r=_chunkAQJPVUH3cjs.k.call(void 0, e.color),n=_nullishCoalesce(_optionalChain([t, 'optionalAccess', _7 => _7.vertexColors]), () => (!1)),o=_optionalChain([t, 'optionalAccess', _8 => _8.appearance]),a=new z.MeshPhysicalMaterial({color:r,metalness:e.metalness,roughness:e.roughness,opacity:e.opacity,transparent:e.transparent,vertexColors:n,side:_optionalChain([o, 'optionalAccess', _9 => _9.cullBackfaces])?z.FrontSide:z.DoubleSide,polygonOffset:!0,polygonOffsetFactor:.5,polygonOffsetUnits:.5,depthWrite:!0,depthTest:!0});return _optionalChain([o, 'optionalAccess', _10 => _10.envMapIntensity])!=null&&(a.envMapIntensity=o.envMapIntensity),e.metalness>Zt&&(a.clearcoat=Qt,a.clearcoatRoughness=er),n&&tr(a),e.map&&ft(a,e.map),a}function tr(e){e.onBeforeCompile=t=>{t.vertexShader=t.vertexShader.replace("#include <color_vertex>",`#include <color_vertex>
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }var _chunkAZ4GBXXLcjs = require('./chunk-AZ4GBXXL.cjs');require('./chunk-BYLIBOAU.cjs');function Xe(e){return e.map(t=>{let r=t.clone(!0),n=[];t.traverse(o=>n.push(o));let a=0;return r.traverse(o=>{let i=n[a++],c=o;i.geometry&&(c.geometry=i.geometry.clone())}),r})}function Ze(e){e.forEach(t=>_chunkAZ4GBXXLcjs.p.call(void 0, t,{materials:!1}))}var qe={clone:Xe,release:Ze};var _Line2js = require('three/addons/lines/Line2.js');var _LineGeometryjs = require('three/addons/lines/LineGeometry.js');var _LineMaterialjs = require('three/addons/lines/LineMaterial.js');var _three = require('three'); var ye = _interopRequireWildcard(_three); var H = _interopRequireWildcard(_three); var P = _interopRequireWildcard(_three); var N = _interopRequireWildcard(_three); var Y = _interopRequireWildcard(_three); var R = _interopRequireWildcard(_three);var Ke="#ffffff";function z(e,t){let r=_nullishCoalesce(t, () => (1));return{color:new ye.Color(_nullishCoalesce(e, () => (Ke))),transparent:r<1,opacity:r}}var rt=2,nt=6;function he(e){let t=ot(e);if(!t)return null;let r=new _LineGeometryjs.LineGeometry;r.setPositions(t);let n=z(e.color,e.opacity),a=new (0, _LineMaterialjs.LineMaterial)({color:n.color}),o=a;o.linewidth=_nullishCoalesce(e.width, () => (rt)),o.transparent=n.transparent,o.opacity=n.opacity;let i=new (0, _Line2js.Line2)(r,a);return i.computeLineDistances(),i.name=e.name,i.userData={source:"compute",id:e.id,layer:e.layer,kind:"curve",metadata:e.metadata},i}function ot(e){if(!e.points)throw new (0, _chunkAZ4GBXXLcjs.b)(`Curve display item '${e.id}' has no tessellated points. It was produced by an outdated Display component \u2014 upgrade it in Grasshopper (Solution \u2192 Upgrade obsolete components) and re-save the definition.`,_chunkAZ4GBXXLcjs.a.INVALID_CONFIG,{context:{itemId:e.id,kind:e.kind}});return e.points.length>=nt?e.points:null}function be(e){let{position:t}=e;if(!t||typeof t.X!="number"||!Number.isFinite(t.X)||typeof t.Y!="number"||!Number.isFinite(t.Y)||typeof t.Z!="number"||!Number.isFinite(t.Z))return _chunkAZ4GBXXLcjs.c.call(void 0, ).warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let r=new H.BufferGeometry;r.setAttribute("position",new H.Float32BufferAttribute([t.X,t.Y,t.Z],3));let n=new H.PointsMaterial({...z(e.color,e.opacity),size:6,sizeAttenuation:!1}),a=new H.Points(r,n);return a.name=e.name,a.userData={source:"compute",id:e.id,layer:e.layer,kind:"point",metadata:e.metadata},a}function q(e){if(!e||e.length===0)return[];let t=[];for(let r of e)switch(r.kind){case"curve":{let n=he(r);n&&t.push(n);break}case"point":{let n=be(r);n&&t.push(n);break}default:{let a=r;_chunkAZ4GBXXLcjs.c.call(void 0, ).warn(`Skipping unknown display item kind: ${String(a.kind)}`);break}}return t}var ge=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;var _fflate = require('fflate');function Ae(e){return typeof e=="string"?_chunkAZ4GBXXLcjs.f.call(void 0, e):e instanceof Uint8Array?e:new Uint8Array(e)}function xe(e){if(e.byteLength<8)return e;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint32(0,!0)!==1515605075)return e;let r=t.getUint32(4,!0),n=e.subarray(8),a=Math.max(n.byteLength*1032+1024,1<<20);if(r>a)throw T("SLVZ header declares an implausible uncompressed length",{uncompressedLen:r,deflatedBytes:n.byteLength,maxPlausibleLen:a});let o;try{o=_fflate.inflateSync.call(void 0, n,{out:new Uint8Array(r+1)})}catch(i){throw T(`Failed to inflate SLVZ blob: ${i instanceof Error?i.message:String(i)}`,{uncompressedLen:r,deflatedBytes:n.byteLength})}if(o.byteLength!==r)throw T("SLVZ payload inflated to a different size than the header declares.",{declaredLen:r,actualLen:o.byteLength,deflatedBytes:n.byteLength});return o}function Ee(e){if(typeof TextDecoder<"u")return new TextDecoder("utf-8").decode(e);if(typeof globalThis.Buffer<"u")return globalThis.Buffer.from(e).toString("utf-8");throw new (0, _chunkAZ4GBXXLcjs.b)("No UTF-8 decoder available in this environment.",_chunkAZ4GBXXLcjs.a.INVALID_STATE)}function we(e,t,r){if(r===0)return new Int16Array(0);if(t%2===0)return new Int16Array(e,t,r);let n=new Uint8Array(r*2);return n.set(new Uint8Array(e,t,r*2)),new Int16Array(n.buffer)}function W(e,t,r){if(r===0)return new Float32Array(0);if(t%4===0)return new Float32Array(e,t,r);let n=new Uint8Array(r*4);return n.set(new Uint8Array(e,t,r*4)),new Float32Array(n.buffer)}function V(e,t,r){if(r===0)return new Uint16Array(0);if(t%2===0)return new Uint16Array(e,t,r);let n=new Uint8Array(r*2);return n.set(new Uint8Array(e,t,r*2)),new Uint16Array(n.buffer)}function Me(e,t,r){if(r===0)return new Uint32Array(0);if(t%4===0)return new Uint32Array(e,t,r);let n=new Uint8Array(r*4);return n.set(new Uint8Array(e,t,r*4)),new Uint32Array(n.buffer)}function ve(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let r=0;r<e.length;r++)if(e[r]>=t)throw T("Index out of range of vertexCount.",{indexPosition:r,indexValue:e[r],vertexCount:t})}}function C(e){return e>>>1^-(e&1)}function Se(e){let t=new Int16Array(e.length),r=0,n=0,a=0;for(let o=0;o<e.length;o+=3)r=r+C(e[o])<<16>>16,n=n+C(e[o+1])<<16>>16,a=a+C(e[o+2])<<16>>16,t[o]=r,t[o+1]=n,t[o+2]=a;return t}function Te(e){let t=new Uint16Array(e.length),r=0;for(let n=0;n<e.length;n++)r=r+C(e[n])&65535,t[n]=r;return t}function Re(e){let t=new Uint32Array(e.length),r=0;for(let n=0;n<e.length;n++)r=r+C(e[n])>>>0,t[n]=r;return t}function T(e,t){return new (0, _chunkAZ4GBXXLcjs.b)(e,_chunkAZ4GBXXLcjs.a.VALIDATION_ERROR,{context:t})}var Be=36;function Ie(e,t,r,n,a){if(r+Be>e.byteLength)throw T("Insufficient data to read UV chunk header.",{expectedBytes:Be,availableBytes:e.byteLength-r,offset:r});let o=t.getUint32(r,!0);r+=4;let i=t.getFloat64(r,!0);r+=8;let c=t.getFloat64(r,!0);r+=8;let f=t.getFloat64(r,!0);r+=8;let m=t.getFloat64(r,!0);r+=8;let l=n*2,w=o===1,M=l*(w?4:2);if(r+M>e.byteLength)throw T("Insufficient data to read UV chunk.",{expectedBytes:M,availableBytes:e.byteLength-r,offset:r,uvFormat:o,vertexCount:n});let d=e.byteOffset+r,h;if(w)h=W(e.buffer,d,l).slice();else{let u=V(e.buffer,d,l);h=new Float32Array(l);let s=0,y=0;for(let x=0;x<l;x+=2)a?(s=s+C(u[x])&65535,y=y+C(u[x+1])&65535):(s=u[x],y=u[x+1]),h[x]=i+s*f,h[x+1]=c+y*m}return{uvs:h,offset:r+M}}function De(e,t,r,n){let a=r*3;if(t+a>e.byteLength)throw T("Insufficient data to read vertex-color chunk.",{expectedBytes:a,availableBytes:e.byteLength-t,offset:t,vertexCount:r});let o=e.subarray(t,t+a);if(!n)return o.slice();let i=new Uint8Array(a),c=0,f=0,m=0;for(let l=0;l<a;l+=3)c=c+C(o[l])&255,f=f+C(o[l+1])&255,m=m+C(o[l+2])&255,i[l]=c,i[l+1]=f,i[l+2]=m;return i}function Q(e){let t=ee(e),r;t.isFloat32?r=t.vertexData:t.deltaEncoded?r=Se(t.vertexData):r=t.vertexData;let n=t.indexData;return t.deltaEncoded&&(n=n instanceof Uint16Array?Te(n):Re(n)),ve(n,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:r,indices:n,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function ee(e){if(!ge)throw new (0, _chunkAZ4GBXXLcjs.b)("SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.",_chunkAZ4GBXXLcjs.a.ENVIRONMENT_ERROR);let t=xe(Ae(e)),r=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<12)throw T("Blob too small to contain SLVA header.",{expectedBytes:12,availableBytes:t.byteLength});let n=0,a=r.getUint32(n,!0);if(n+=4,a!==1096174675)throw T(`Invalid SLVA magic: 0x${a.toString(16)}`,{expectedMagic:`0x${1096174675 .toString(16)}`,actualMagic:`0x${a.toString(16)}`});let o=r.getUint32(n,!0);if(n+=4,o<1||o>3)throw T(`Unsupported SLVA version: ${o}`,{minSupportedVersion:1,maxSupportedVersion:3,actualVersion:o});let i=r.getUint32(n,!0);if(n+=4,n+i>t.byteLength)throw T("Insufficient data to read metadata JSON.",{expectedBytes:i,availableBytes:t.byteLength-n,offset:n});let c=t.subarray(n,n+i);n+=i;let f;try{f=JSON.parse(Ee(c))}catch(L){throw T(`Failed to parse metadata JSON: ${L instanceof Error?L.message:String(L)}`,{metadataLen:i})}if(n+56>t.byteLength)throw T("Insufficient data to read geometry header.",{expectedBytes:56,availableBytes:t.byteLength-n,offset:n});let m=r.getUint32(n,!0);n+=4;let l=r.getFloat64(n,!0);n+=8;let w=r.getFloat64(n,!0);n+=8;let M=r.getFloat64(n,!0);n+=8;let d=r.getFloat64(n,!0);n+=8;let h=r.getFloat64(n,!0);n+=8;let u=r.getFloat64(n,!0);n+=8;let s=r.getUint32(n,!0);n+=4;let y=(m&1)!==0,x=(m&4)!==0,A=s*3,B=A*(y?4:2);if(n+B>t.byteLength)throw T("Insufficient data to read vertices.",{expectedBytes:B,availableBytes:t.byteLength-n,offset:n,useFloat32:y,vertexCount:s});let b=t.byteOffset+n,p;if(y?p=W(t.buffer,b,A):x?p=V(t.buffer,b,A):p=we(t.buffer,b,A),n+=B,n+4>t.byteLength)throw T("Insufficient data to read index count.",{expectedBytes:4,availableBytes:t.byteLength-n,offset:n});let E=r.getUint32(n,!0);n+=4;let S=(m&2)!==0,D=E*(S?2:4);if(n+D>t.byteLength)throw T("Insufficient data to read indices.",{expectedBytes:D,availableBytes:t.byteLength-n,offset:n,indexCount:E,useUint16Indices:S});let O=S?V(t.buffer,t.byteOffset+n,E):Me(t.buffer,t.byteOffset+n,E);n+=D;let U=null;if((m&8)!==0){let L=Ie(t,r,n,s,x);U=L.uvs,n=L.offset}let G=null;return(m&16)!==0&&(G=De(t,n,s,x)),{metadata:f,flags:m,vertexData:p,indexData:O,isFloat32:y,deltaEncoded:x,vertexCount:s,origin:[l,w,M],scale:[d,h,u],uvs:U,colors:G}}function ut(e){let{isFloat32:t,deltaEncoded:r,origin:n,scale:a,uvs:o,colors:i,jobs:c}=e,f=d=>d>>>1^-(d&1),m;if(t)m=e.vertexData;else{let d;if(r){let g=e.vertexData;d=new Int16Array(g.length);let B=0,b=0,p=0;for(let E=0;E<g.length;E+=3)B=B+f(g[E])<<16>>16,b=b+f(g[E+1])<<16>>16,p=p+f(g[E+2])<<16>>16,d[E]=B,d[E+1]=b,d[E+2]=p}else d=e.vertexData;m=new Float32Array(d.length);let h=n[0],u=n[1],s=n[2],y=a[0],x=a[1],A=a[2];for(let g=0;g<d.length;g+=3)m[g]=h+(d[g]+32767)*y,m[g+1]=u+(d[g+1]+32767)*x,m[g+2]=s+(d[g+2]+32767)*A}let l;if(r){let d=e.indexData;if(d instanceof Uint16Array){let h=new Uint16Array(d.length),u=0;for(let s=0;s<d.length;s++)u=u+f(d[s])&65535,h[s]=u;l=h}else{let h=new Uint32Array(d.length),u=0;for(let s=0;s<d.length;s++)u=u+f(d[s])>>>0,h[s]=u;l=h}}else l=e.indexData;let w=m.length/3;for(let d=0;d<l.length;d++)if(l[d]>=w)throw new Error(`Index ${l[d]} out of range of vertexCount ${w}`);let M=[];for(let d of c){let h=0,u=0;for(let p of d.windows)h+=p.vertexCount,u+=p.indexCount;let s=new Float32Array(h*3),y=new Uint32Array(u),x=o?new Float32Array(h*2):null,A=i?new Uint8Array(h*3):null,g=0,B=0;for(let p of d.windows){let E=p.vertexStart*3;s.set(m.subarray(E,E+p.vertexCount*3),g*3),x&&o&&x.set(o.subarray(p.vertexStart*2,(p.vertexStart+p.vertexCount)*2),g*2),A&&i&&A.set(i.subarray(E,E+p.vertexCount*3),g*3);let S=p.vertexStart,I=p.vertexStart+p.vertexCount,D=g-p.vertexStart;for(let O=0;O<p.indexCount;O++){let U=l[p.indexStart+O];if(U<S||U>=I)throw new Error(`Index ${U} outside vertex window [${S}, ${I})`);y[B+O]=U+D}g+=p.vertexCount,B+=p.indexCount}let b=new Float32Array(h*3);for(let p=0;p<y.length;p+=3){let E=y[p]*3,S=y[p+1]*3,I=y[p+2]*3,D=s[I]-s[S],O=s[I+1]-s[S+1],U=s[I+2]-s[S+2],G=s[E]-s[S],L=s[E+1]-s[S+1],le=s[E+2]-s[S+2],J=O*le-U*L,X=U*G-D*le,Z=D*L-O*G;b[E]+=J,b[E+1]+=X,b[E+2]+=Z,b[S]+=J,b[S+1]+=X,b[S+2]+=Z,b[I]+=J,b[I+1]+=X,b[I+2]+=Z}for(let p=0;p<b.length;p+=3){let E=b[p],S=b[p+1],I=b[p+2],D=Math.sqrt(E*E+S*S+I*I)||1;b[p]=E/D,b[p+1]=S/D,b[p+2]=I/D}M.push({positions:s,normals:b,indices:y,uvs:x,colors:A})}return M}function _e(){return[`const assemble = ${ut.toString()};`,"self.onmessage = (event) => {"," const { id, input } = event.data;"," try {"," const geometries = assemble(input);"," const transfer = [];"," for (const g of geometries) {"," transfer.push(g.positions.buffer, g.normals.buffer, g.indices.buffer);"," if (g.uvs) transfer.push(g.uvs.buffer);"," if (g.colors) transfer.push(g.colors.buffer);"," }"," self.postMessage({ id, geometries }, transfer);"," } catch (error) {"," self.postMessage({ id, error: String((error && error.message) || error) });"," }","};"].join(`
2
+ `)}var He=5e4,k,j=new Map,ft=1;function Pe(){if(k!==void 0)return k;if(typeof Worker>"u"||typeof Blob>"u"||typeof URL>"u"||typeof URL.createObjectURL!="function")return k=null,null;try{let e=URL.createObjectURL(new Blob([_e()],{type:"text/javascript"})),t=new Worker(e);t.onmessage=r=>{let{id:n,geometries:a,error:o}=r.data,i=j.get(n);i&&(j.delete(n),a?i.resolve(a):i.reject(new Error(_nullishCoalesce(o, () => ("mesh assembly failed in worker")))))},t.onerror=()=>{for(let r of j.values())r.reject(new Error("mesh assembly worker crashed"));j.clear(),t.terminate(),k=null},k=t}catch (e2){k=null}return k}function ke(e,t,r){return new Promise((n,a)=>{let o=ft++;j.set(o,{resolve:n,reject:a}),e.postMessage({id:o,input:t},r)})}var Ne=1;function Ge(e){Ne=Math.max(1,e)}_chunkAZ4GBXXLcjs.o.call(void 0, Ge);function Ve(e,t){typeof document>"u"||new Y.TextureLoader().load(t,r=>{r.colorSpace=Y.SRGBColorSpace,r.anisotropy=Ne,e.map=r,e.needsUpdate=!0},void 0,r=>{_chunkAZ4GBXXLcjs.c.call(void 0, ).warn(`Failed to load material texture ${t}:`,r)})}var mt=.5,dt=.5,pt=.3;function te(e,t){let r=_chunkAZ4GBXXLcjs.k.call(void 0, e.color),n=_nullishCoalesce(_optionalChain([t, 'optionalAccess', _2 => _2.vertexColors]), () => (!1)),a=_optionalChain([t, 'optionalAccess', _3 => _3.appearance]),o=new N.MeshPhysicalMaterial({color:r,metalness:e.metalness,roughness:e.roughness,opacity:e.opacity,transparent:e.transparent,vertexColors:n,side:_optionalChain([a, 'optionalAccess', _4 => _4.cullBackfaces])?N.FrontSide:N.DoubleSide,polygonOffset:!0,polygonOffsetFactor:.5,polygonOffsetUnits:.5,depthWrite:!0,depthTest:!0});return _optionalChain([a, 'optionalAccess', _5 => _5.envMapIntensity])!=null&&(o.envMapIntensity=a.envMapIntensity),e.metalness>mt&&(o.clearcoat=dt,o.clearcoatRoughness=pt),n&&yt(o),e.map&&Ve(o,e.map),o}function yt(e){e.onBeforeCompile=t=>{t.vertexShader=t.vertexShader.replace("#include <color_vertex>",`#include <color_vertex>
3
3
  #if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )
4
4
  vColor.rgb = mix(
5
5
  vColor.rgb / 12.92,
6
6
  pow( ( vColor.rgb + 0.055 ) / 1.055, vec3( 2.4 ) ),
7
7
  step( vec3( 0.04045 ), vColor.rgb )
8
8
  );
9
- #endif`)}}function Z(e,t){return new (0, _chunkAQJPVUH3cjs.b)(e,_chunkAQJPVUH3cjs.a.VALIDATION_ERROR,{context:t})}function Ee(e,t,r,n){for(let o of e){if(!Number.isInteger(o.materialId)||o.materialId<0||o.materialId>=t)throw Z("Group materialId out of range of the materials array.",{materialId:o.materialId,materialCount:t});for(let a of o.meshes){let s={vertexStart:a.vertexStart,vertexCount:a.vertexCount,indexStart:a.indexStart,indexCount:a.indexCount};for(let[u,i]of Object.entries(s))if(!Number.isInteger(i)||i<0)throw Z(`Mesh metadata field "${u}" must be a non-negative integer.`,{meshName:a.name,field:u,value:i});if(a.vertexStart+a.vertexCount>r)throw Z("Mesh vertex window exceeds the batch vertex buffer.",{meshName:a.name,vertexStart:a.vertexStart,vertexCount:a.vertexCount,totalVertexCount:r});if(a.indexStart+a.indexCount>n)throw Z("Mesh index window exceeds the batch index buffer.",{meshName:a.name,indexStart:a.indexStart,indexCount:a.indexCount,totalIndexCount:n})}}}function xe(e,t){return Z("Index references a vertex outside its mesh's vertex window.",{meshName:t.name,indexValue:e,vertexStart:t.vertexStart,vertexCount:t.vertexCount})}function Ae(e,t,r,n,o,a){let s=[],u=e;for(let i of t){u+=`|${i.vertexStart},${i.vertexCount},${i.indexStart},${i.indexCount}`;let f=i.vertexStart*3,l=f+i.vertexCount*3;s.push(r.subarray(f,l)),s.push(n.subarray(i.indexStart,i.indexStart+i.indexCount)),s.push(o?o.subarray(i.vertexStart*2,(i.vertexStart+i.vertexCount)*2):null),s.push(a?a.subarray(f,l):null)}return at(s,u)}function mt(e,t,r){let n=new Float32Array(e.length),o=t[0],a=t[1],s=t[2],u=r[0],i=r[1],f=r[2];for(let l=0;l<e.length;l+=3)n[l]=o+(e[l]+32767)*u,n[l+1]=a+(e[l+1]+32767)*i,n[l+2]=s+(e[l+2]+32767)*f;return n}function dt(e,t,r,n,o=null,a=null){let s=Ae("merged",e.meshes,t,r,o,a),u=J(s);if(!u){let i=0,f=0;for(let c of e.meshes)i+=c.vertexCount,f+=c.indexCount;let l=new Float32Array(i*3),y=new Uint32Array(f),b=o?new Float32Array(i*2):null,w=a?new Uint8Array(i*3):null,v=0,C=0;for(let c of e.meshes){let d=c.vertexStart*3,p=c.vertexCount*3;if(l.set(t.subarray(d,d+p),v*3),b&&o){let g=c.vertexStart*2;b.set(o.subarray(g,g+c.vertexCount*2),v*2)}w&&a&&w.set(a.subarray(d,d+p),v*3);let m=r.subarray(c.indexStart,c.indexStart+c.indexCount),h=v-c.vertexStart,S=c.vertexStart,T=c.vertexStart+c.vertexCount;for(let g=0;g<m.length;g++){let x=m[g];if(x<S||x>=T)throw xe(x,c);y[C+g]=x+h}v+=c.vertexCount,C+=c.indexCount}u=new O.BufferGeometry,u.setAttribute("position",new O.BufferAttribute(l,3)),u.setIndex(new O.BufferAttribute(y,1)),b&&u.setAttribute("uv",new O.BufferAttribute(b,2)),w&&u.setAttribute("color",new O.BufferAttribute(w,3,!0)),u.computeVertexNormals(),X(s,u)}return Me(u,e,n)}function Me(e,t,r){let n=new O.Mesh(e,r[t.materialId]),o=t.meshes[0],a=t.meshes.map(s=>s.name).filter(s=>s&&s.length>0);return n.name=a.length>0?a[0]:`merged_material_${t.materialId}`,n.castShadow=!0,n.receiveShadow=!0,n.userData={source:"compute",name:n.name,layer:_nullishCoalesce(_optionalChain([o, 'optionalAccess', _11 => _11.layer]), () => ("")),originalIndex:_nullishCoalesce(_optionalChain([o, 'optionalAccess', _12 => _12.originalIndex]), () => (0)),metadata:_nullishCoalesce(_optionalChain([o, 'optionalAccess', _13 => _13.metadata]), () => ({})),mergedFrom:t.meshes.slice(1).map(s=>({name:s.name,layer:s.layer,originalIndex:s.originalIndex}))},n}function pt(e,t,r,n,o=null,a=null){let s=[];for(let u of e.meshes){let i=u.vertexStart*3,f=u.vertexCount*3,l=Ae("single",[u],t,r,o,a),y=J(l);if(!y){let b=t.slice(i,i+f),w=r.subarray(u.indexStart,u.indexStart+u.indexCount),v=new Uint32Array(w.length),C=u.vertexStart,c=u.vertexStart+u.vertexCount;for(let d=0;d<w.length;d++){let p=w[d];if(p<C||p>=c)throw xe(p,u);v[d]=p-C}if(y=new O.BufferGeometry,y.setAttribute("position",new O.BufferAttribute(b,3)),y.setIndex(new O.BufferAttribute(v,1)),o){let d=u.vertexStart*2,p=o.slice(d,d+u.vertexCount*2);y.setAttribute("uv",new O.BufferAttribute(p,2))}if(a){let d=a.slice(i,i+f);y.setAttribute("color",new O.BufferAttribute(d,3,!0))}y.computeVertexNormals(),X(l,y)}s.push(we(y,u,e,n))}return s}function we(e,t,r,n){let o=new O.Mesh(e,n[r.materialId]);return o.name=t.name,o.userData={source:"compute",name:t.name,layer:_nullishCoalesce(t.layer, () => ("")),originalIndex:t.originalIndex,metadata:_nullishCoalesce(t.metadata, () => ({}))},o.castShadow=!0,o.receiveShadow=!0,o}async function Te(e,t,r){let{mergeByMaterial:n=!0,debug:o=!1,material:a}=_nullishCoalesce(t, () => ({})),{parseTime:s=0,perfStart:u=o?performance.now():0}=_nullishCoalesce(r, () => ({}));if(!e.compressedData)return[];let i=await ht(e.compressedData,{mergeByMaterial:n,debug:o,material:a,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}});if(i)return i;let f=performance.now(),l=he(e.compressedData),y=performance.now()-f,b=o?nr(e.compressedData):0;return yt(l,{mergeByMaterial:n,debug:o,material:a,parseTime:s,decodeTime:y,perfStart:u,blobBytes:b,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}})}async function rr(e,t){let{mergeByMaterial:r=!0,debug:n=!1,material:o}=_nullishCoalesce(t, () => ({})),a=n?performance.now():0,s=await ht(e,{mergeByMaterial:r,debug:n,material:o});if(s)return s;let u=performance.now(),i=he(e),f=performance.now()-u,l=e.byteLength;return yt(i,{mergeByMaterial:r,debug:n,material:o,parseTime:0,decodeTime:f,perfStart:a,blobBytes:l})}function yt(e,t){let{mergeByMaterial:r,debug:n,material:o,parseTime:a,decodeTime:s,perfStart:u,blobBytes:i,fallback:f}=t,l=_nullishCoalesce(_nullishCoalesce(e.metadata.materials, () => (_optionalChain([f, 'optionalAccess', _14 => _14.materials]))), () => ([])),y=_nullishCoalesce(_nullishCoalesce(e.metadata.groups, () => (_optionalChain([f, 'optionalAccess', _15 => _15.groups]))), () => ([])),b=_nullishCoalesce(_optionalChain([f, 'optionalAccess', _16 => _16.sourceComponentId]), () => (e.metadata.sourceComponentId)),w=(e.flags&1)!==0;Ee(y,l.length,e.vertices.length/3,e.indices.length);let v=w?e.vertices:mt(e.vertices,e.origin,e.scale);if(n){let m=e.vertices.byteLength+e.indices.byteLength;_chunkAQJPVUH3cjs.c.call(void 0, ).debug("Mesh Batch Stats:"),_chunkAQJPVUH3cjs.c.call(void 0, ).debug(` Materials: ${l.length} | Groups: ${y.length}`),_chunkAQJPVUH3cjs.c.call(void 0, ).debug(` Vertices: ${e.vertices.length/3} | Indices: ${e.indices.length}`),_chunkAQJPVUH3cjs.c.call(void 0, ).debug(` Format: ${w?"float32":"int16 quantized"}`),_chunkAQJPVUH3cjs.c.call(void 0, ).debug(` Blob: ${(i/1024/1024).toFixed(2)} MB | Geometry on wire: ${(m/1024/1024).toFixed(2)} MB`)}let C=performance.now(),c=l.map(m=>be(m,{vertexColors:e.colors!=null,appearance:o})),d=[];for(let m of y)if(r&&m.meshes.length>1){let h=dt(m,v,e.indices,c,e.uvs,e.colors);h.userData.sourceComponentId=_nullishCoalesce(b, () => (null)),d.push(h)}else{let h=pt(m,v,e.indices,c,e.uvs,e.colors);for(let S of h)S.userData.sourceComponentId=_nullishCoalesce(b, () => (null));d.push(...h)}let p=performance.now()-C;if(n){let m=performance.now()-u;_chunkAQJPVUH3cjs.c.call(void 0, ).debug("Performance:"),a>0&&_chunkAQJPVUH3cjs.c.call(void 0, ).debug(` Parse JSON: ${a.toFixed(2)}ms`),_chunkAQJPVUH3cjs.c.call(void 0, ).debug(` Decode binary: ${s.toFixed(2)}ms`),_chunkAQJPVUH3cjs.c.call(void 0, ).debug(` Create Meshes: ${p.toFixed(2)}ms`),_chunkAQJPVUH3cjs.c.call(void 0, ).debug(` Total: ${m.toFixed(2)}ms`)}return Promise.resolve(d)}async function ht(e,t){if(typeof Worker>"u")return null;let r=ge(e);if(r.indexData.length/3<it)return null;let n=ct();if(!n)return null;let o=_nullishCoalesce(_nullishCoalesce(r.metadata.materials, () => (_optionalChain([t, 'access', _17 => _17.fallback, 'optionalAccess', _18 => _18.materials]))), () => ([])),a=_nullishCoalesce(_nullishCoalesce(r.metadata.groups, () => (_optionalChain([t, 'access', _19 => _19.fallback, 'optionalAccess', _20 => _20.groups]))), () => ([])),s=_nullishCoalesce(_optionalChain([t, 'access', _21 => _21.fallback, 'optionalAccess', _22 => _22.sourceComponentId]), () => (r.metadata.sourceComponentId));Ee(a,o.length,r.vertexCount,r.indexData.length);let u=c=>({vertexStart:c.vertexStart,vertexCount:c.vertexCount,indexStart:c.indexStart,indexCount:c.indexCount}),i=[],f=[];for(let c of a)if(t.mergeByMaterial&&c.meshes.length>1)i.push({kind:"merged",windows:c.meshes.map(u)}),f.push({kind:"merged",group:c});else for(let d of c.meshes)i.push({kind:"single",windows:[u(d)]}),f.push({kind:"single",group:c,meshMeta:d});let l=r.vertexData.slice(),y=r.indexData.slice(),b=[l.buffer,y.buffer];r.uvs&&b.push(r.uvs.buffer),r.colors&&b.push(r.colors.buffer);let w;try{w=await lt(n,{vertexData:l,isFloat32:r.isFloat32,deltaEncoded:r.deltaEncoded,origin:r.origin,scale:r.scale,indexData:y,uvs:r.uvs,colors:r.colors,jobs:i},b)}catch(c){return _chunkAQJPVUH3cjs.c.call(void 0, ).warn("Mesh assembly worker failed; falling back to main-thread parse.",c),null}if(w.length!==i.length)return null;let v=o.map(c=>be(c,{vertexColors:r.colors!=null,appearance:t.material})),C=[];for(let c=0;c<w.length;c++){let d=w[c],p=f[c],m=J(d.key);m||(m=new V.BufferGeometry,m.setAttribute("position",new V.BufferAttribute(d.positions,3)),m.setAttribute("normal",new V.BufferAttribute(d.normals,3)),m.setIndex(new V.BufferAttribute(d.indices,1)),d.uvs&&m.setAttribute("uv",new V.BufferAttribute(d.uvs,2)),d.colors&&m.setAttribute("color",new V.BufferAttribute(d.colors,3,!0)),X(d.key,m));let h=p.kind==="merged"?Me(m,p.group,v):we(m,p.meshMeta,p.group,v);h.userData.sourceComponentId=_nullishCoalesce(s, () => (null)),C.push(h)}return t.debug&&_chunkAQJPVUH3cjs.c.call(void 0, ).debug(`Mesh batch assembled off-thread: ${C.length} meshes, ${r.indexData.length/3} triangles`),C}function nr(e){return Math.floor(e.length*3/4)}var Re={Angstroms:1e-10,Nanometers:1e-9,Microns:1e-6,Millimeters:.001,Centimeters:.01,Decimeters:.1,Meters:1,Dekameters:10,Hectometers:100,Kilometers:1e3,Megameters:1e6,Gigameters:1e9,Microinches:254e-10,Mils:254e-7,Inches:.0254,Feet:.3048,Yards:.9144,Miles:1609.344,NauticalMiles:1852},or="Display",ar="DisplayBatch";function sr(e){let t=e.split(".");return t.includes(or)||t.includes(ar)}var gt=new Set;async function ir(e,t){let r=performance.now(),n=[],{allowScaling:o=!0,allowAutoPosition:a=!1,groundAxis:s="z",rhino:u,debug:i=!1,parsing:f={}}=_nullishCoalesce(t, () => ({}));try{let l=o?cr(e.modelunits):1;return await lr(e,n,l,f,u,i),a&&dr(n,s),n}catch(l){throw pr(l,n),l}finally{i&&hr(r)}}function cr(e){let t=Re[e];return t!==void 0?t:(gt.has(e)||(gt.add(e),_chunkAQJPVUH3cjs.c.call(void 0, ).warn(`Unknown Rhino model unit "${e}" \u2014 geometry will not be scaled (factor 1). Known units: ${Object.keys(Re).join(", ")}.`)),1)}async function lr(e,t,r,n,o,a){for(let s of e.values){let u=s.InnerTree;for(let i in u){let f=u[i];f&&await ur(f,t,r,n,o,a)}}}async function ur(e,t,r,n,o,a){for(let s of e){if(!sr(s.type))continue;let u={mergeByMaterial:!0,debug:!1,...n},i=fr(s.data);if(!i){_chunkAQJPVUH3cjs.c.call(void 0, ).error("Error parsing display batch envelope: invalid JSON");continue}let f=await Te(i,u),l=pe(i.items,{rhino:o}),y=[...f,...l];if(r!==1)for(let b of y)b.scale.set(r,r,r);t.push(...y),a&&_chunkAQJPVUH3cjs.c.call(void 0, ).debug(`Extracted ${f.length} meshes and ${l.length} items from batch`)}}function fr(e){return typeof e=="string"?mr(e):e}function mr(e){try{return JSON.parse(e)}catch (e3){return}}function dr(e,t){if(e.length===0)return;let r=_chunkAQJPVUH3cjs.m.call(void 0, e);_chunkAQJPVUH3cjs.l.call(void 0, e,r.min[t],t)}function pr(e,t){_chunkAQJPVUH3cjs.c.call(void 0, ).error("An unexpected error occurred:",e),yr(t)}function yr(e){for(let t of e){let r=t;r.geometry&&r.geometry.dispose(),r.material&&(Array.isArray(r.material)?r.material.forEach(n=>n.dispose()):r.material.dispose())}}function hr(e){let t=performance.now()-e;_chunkAQJPVUH3cjs.c.call(void 0, ).info("Time to process meshes:",`${t.toFixed(2)}ms`)}function gr(){_chunkAQJPVUH3cjs.r.call(void 0, )}exports.SCALE_FACTORS = Re; exports.getThreeMeshesFromComputeResponse = ir; exports.meshPolicy = xt; exports.parseDisplayItems = pe; exports.parseMeshBatchBlob = rr; exports.parseMeshBatchObject = Te; exports.releaseParseCaches = gr; exports.setTextureAnisotropy = ut;
9
+ #endif`)}}function $(e,t){return new (0, _chunkAZ4GBXXLcjs.b)(e,_chunkAZ4GBXXLcjs.a.VALIDATION_ERROR,{context:t})}function re(e,t,r,n){for(let a of e){if(!Number.isInteger(a.materialId)||a.materialId<0||a.materialId>=t)throw $("Group materialId out of range of the materials array.",{materialId:a.materialId,materialCount:t});for(let o of a.meshes){let i={vertexStart:o.vertexStart,vertexCount:o.vertexCount,indexStart:o.indexStart,indexCount:o.indexCount};for(let[c,f]of Object.entries(i))if(!Number.isInteger(f)||f<0)throw $(`Mesh metadata field "${c}" must be a non-negative integer.`,{meshName:o.name,field:c,value:f});if(o.vertexStart+o.vertexCount>r)throw $("Mesh vertex window exceeds the batch vertex buffer.",{meshName:o.name,vertexStart:o.vertexStart,vertexCount:o.vertexCount,totalVertexCount:r});if(o.indexStart+o.indexCount>n)throw $("Mesh index window exceeds the batch index buffer.",{meshName:o.name,indexStart:o.indexStart,indexCount:o.indexCount,totalIndexCount:n})}}}function ne(e,t){return $("Index references a vertex outside its mesh's vertex window.",{meshName:t.name,indexValue:e,vertexStart:t.vertexStart,vertexCount:t.vertexCount})}function je(e,t,r){let n=new Float32Array(e.length),a=t[0],o=t[1],i=t[2],c=r[0],f=r[1],m=r[2];for(let l=0;l<e.length;l+=3)n[l]=a+(e[l]+32767)*c,n[l+1]=o+(e[l+1]+32767)*f,n[l+2]=i+(e[l+2]+32767)*m;return n}function $e(e,t,r,n,a=null,o=null){let i=0,c=0;for(let u of e.meshes)i+=u.vertexCount,c+=u.indexCount;let f=new Float32Array(i*3),m=new Uint32Array(c),l=a?new Float32Array(i*2):null,w=o?new Uint8Array(i*3):null,M=0,d=0;for(let u of e.meshes){let s=u.vertexStart*3,y=u.vertexCount*3;if(f.set(t.subarray(s,s+y),M*3),l&&a){let b=u.vertexStart*2;l.set(a.subarray(b,b+u.vertexCount*2),M*2)}w&&o&&w.set(o.subarray(s,s+y),M*3);let x=r.subarray(u.indexStart,u.indexStart+u.indexCount),A=M-u.vertexStart,g=u.vertexStart,B=u.vertexStart+u.vertexCount;for(let b=0;b<x.length;b++){let p=x[b];if(p<g||p>=B)throw ne(p,u);m[d+b]=p+A}M+=u.vertexCount,d+=u.indexCount}let h=new R.BufferGeometry;return h.setAttribute("position",new R.BufferAttribute(f,3)),h.setIndex(new R.BufferAttribute(m,1)),l&&h.setAttribute("uv",new R.BufferAttribute(l,2)),w&&h.setAttribute("color",new R.BufferAttribute(w,3,!0)),h.computeVertexNormals(),oe(h,e,n)}function oe(e,t,r){let n=new R.Mesh(e,r[t.materialId]),a=t.meshes[0],o=t.meshes.map(i=>i.name).filter(i=>i&&i.length>0);return n.name=o.length>0?o[0]:`merged_material_${t.materialId}`,n.castShadow=!0,n.receiveShadow=!0,n.userData={source:"compute",name:n.name,layer:_nullishCoalesce(_optionalChain([a, 'optionalAccess', _6 => _6.layer]), () => ("")),originalIndex:_nullishCoalesce(_optionalChain([a, 'optionalAccess', _7 => _7.originalIndex]), () => (0)),metadata:_nullishCoalesce(_optionalChain([a, 'optionalAccess', _8 => _8.metadata]), () => ({})),mergedFrom:t.meshes.slice(1).map(i=>({name:i.name,layer:i.layer,originalIndex:i.originalIndex}))},n}function ze(e,t,r,n,a=null,o=null){let i=[];for(let c of e.meshes){let f=c.vertexStart*3,m=c.vertexCount*3,l=t.slice(f,f+m),w=r.subarray(c.indexStart,c.indexStart+c.indexCount),M=new Uint32Array(w.length),d=c.vertexStart,h=c.vertexStart+c.vertexCount;for(let s=0;s<w.length;s++){let y=w[s];if(y<d||y>=h)throw ne(y,c);M[s]=y-d}let u=new R.BufferGeometry;if(u.setAttribute("position",new R.BufferAttribute(l,3)),u.setIndex(new R.BufferAttribute(M,1)),a){let s=c.vertexStart*2,y=a.slice(s,s+c.vertexCount*2);u.setAttribute("uv",new R.BufferAttribute(y,2))}if(o){let s=o.slice(f,f+m);u.setAttribute("color",new R.BufferAttribute(s,3,!0))}u.computeVertexNormals(),i.push(ae(u,c,e,n))}return i}function ae(e,t,r,n){let a=new R.Mesh(e,n[r.materialId]);return a.name=t.name,a.userData={source:"compute",name:t.name,layer:_nullishCoalesce(t.layer, () => ("")),originalIndex:t.originalIndex,metadata:_nullishCoalesce(t.metadata, () => ({}))},a.castShadow=!0,a.receiveShadow=!0,a}async function se(e,t,r){let{mergeByMaterial:n=!0,debug:a=!1,material:o}=_nullishCoalesce(t, () => ({})),{parseTime:i=0,perfStart:c=a?performance.now():0}=_nullishCoalesce(r, () => ({}));if(!e.compressedData)return[];let f=await Ye(e.compressedData,{mergeByMaterial:n,debug:a,material:o,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}});if(f)return f;let m=performance.now(),l=Q(e.compressedData),w=performance.now()-m,M=a?bt(e.compressedData):0;return We(l,{mergeByMaterial:n,debug:a,material:o,parseTime:i,decodeTime:w,perfStart:c,blobBytes:M,fallback:{materials:e.materials,groups:e.groups,sourceComponentId:e.sourceComponentId}})}async function ht(e,t){let{mergeByMaterial:r=!0,debug:n=!1,material:a}=_nullishCoalesce(t, () => ({})),o=n?performance.now():0,i=await Ye(e,{mergeByMaterial:r,debug:n,material:a});if(i)return i;let c=performance.now(),f=Q(e),m=performance.now()-c,l=e.byteLength;return We(f,{mergeByMaterial:r,debug:n,material:a,parseTime:0,decodeTime:m,perfStart:o,blobBytes:l})}function We(e,t){let{mergeByMaterial:r,debug:n,material:a,parseTime:o,decodeTime:i,perfStart:c,blobBytes:f,fallback:m}=t,l=_nullishCoalesce(_nullishCoalesce(e.metadata.materials, () => (_optionalChain([m, 'optionalAccess', _9 => _9.materials]))), () => ([])),w=_nullishCoalesce(_nullishCoalesce(e.metadata.groups, () => (_optionalChain([m, 'optionalAccess', _10 => _10.groups]))), () => ([])),M=_nullishCoalesce(_optionalChain([m, 'optionalAccess', _11 => _11.sourceComponentId]), () => (e.metadata.sourceComponentId)),d=(e.flags&1)!==0;re(w,l.length,e.vertices.length/3,e.indices.length);let h=d?e.vertices:je(e.vertices,e.origin,e.scale);if(n){let A=e.vertices.byteLength+e.indices.byteLength;_chunkAZ4GBXXLcjs.c.call(void 0, ).debug("Mesh Batch Stats:"),_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(` Materials: ${l.length} | Groups: ${w.length}`),_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(` Vertices: ${e.vertices.length/3} | Indices: ${e.indices.length}`),_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(` Format: ${d?"float32":"int16 quantized"}`),_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(` Blob: ${(f/1024/1024).toFixed(2)} MB | Geometry on wire: ${(A/1024/1024).toFixed(2)} MB`)}let u=performance.now(),s=l.map(A=>te(A,{vertexColors:e.colors!=null,appearance:a})),y=[];for(let A of w)if(r&&A.meshes.length>1){let g=$e(A,h,e.indices,s,e.uvs,e.colors);g.userData.sourceComponentId=_nullishCoalesce(M, () => (null)),y.push(g)}else{let g=ze(A,h,e.indices,s,e.uvs,e.colors);for(let B of g)B.userData.sourceComponentId=_nullishCoalesce(M, () => (null));y.push(...g)}let x=performance.now()-u;if(n){let A=performance.now()-c;_chunkAZ4GBXXLcjs.c.call(void 0, ).debug("Performance:"),o>0&&_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(` Parse JSON: ${o.toFixed(2)}ms`),_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(` Decode binary: ${i.toFixed(2)}ms`),_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(` Create Meshes: ${x.toFixed(2)}ms`),_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(` Total: ${A.toFixed(2)}ms`)}return Promise.resolve(y)}async function Ye(e,t){if(typeof Worker>"u")return null;let r=ee(e);if(r.indexData.length/3<He)return null;let n=Pe();if(!n)return null;let a=_nullishCoalesce(_nullishCoalesce(r.metadata.materials, () => (_optionalChain([t, 'access', _12 => _12.fallback, 'optionalAccess', _13 => _13.materials]))), () => ([])),o=_nullishCoalesce(_nullishCoalesce(r.metadata.groups, () => (_optionalChain([t, 'access', _14 => _14.fallback, 'optionalAccess', _15 => _15.groups]))), () => ([])),i=_nullishCoalesce(_optionalChain([t, 'access', _16 => _16.fallback, 'optionalAccess', _17 => _17.sourceComponentId]), () => (r.metadata.sourceComponentId));re(o,a.length,r.vertexCount,r.indexData.length);let c=s=>({vertexStart:s.vertexStart,vertexCount:s.vertexCount,indexStart:s.indexStart,indexCount:s.indexCount}),f=[],m=[];for(let s of o)if(t.mergeByMaterial&&s.meshes.length>1)f.push({kind:"merged",windows:s.meshes.map(c)}),m.push({kind:"merged",group:s});else for(let y of s.meshes)f.push({kind:"single",windows:[c(y)]}),m.push({kind:"single",group:s,meshMeta:y});let l=r.vertexData.slice(),w=r.indexData.slice(),M=[l.buffer,w.buffer];r.uvs&&M.push(r.uvs.buffer),r.colors&&M.push(r.colors.buffer);let d;try{d=await ke(n,{vertexData:l,isFloat32:r.isFloat32,deltaEncoded:r.deltaEncoded,origin:r.origin,scale:r.scale,indexData:w,uvs:r.uvs,colors:r.colors,jobs:f},M)}catch(s){return _chunkAZ4GBXXLcjs.c.call(void 0, ).warn("Mesh assembly worker failed; falling back to main-thread parse.",s),null}if(d.length!==f.length)return null;let h=a.map(s=>te(s,{vertexColors:r.colors!=null,appearance:t.material})),u=[];for(let s=0;s<d.length;s++){let y=d[s],x=m[s],A=new P.BufferGeometry;A.setAttribute("position",new P.BufferAttribute(y.positions,3)),A.setAttribute("normal",new P.BufferAttribute(y.normals,3)),A.setIndex(new P.BufferAttribute(y.indices,1)),y.uvs&&A.setAttribute("uv",new P.BufferAttribute(y.uvs,2)),y.colors&&A.setAttribute("color",new P.BufferAttribute(y.colors,3,!0));let g=x.kind==="merged"?oe(A,x.group,h):ae(A,x.meshMeta,x.group,h);g.userData.sourceComponentId=_nullishCoalesce(i, () => (null)),u.push(g)}return t.debug&&_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(`Mesh batch assembled off-thread: ${u.length} meshes, ${r.indexData.length/3} triangles`),u}function bt(e){return Math.floor(e.length*3/4)}var ie={Angstroms:1e-10,Nanometers:1e-9,Microns:1e-6,Millimeters:.001,Centimeters:.01,Decimeters:.1,Meters:1,Dekameters:10,Hectometers:100,Kilometers:1e3,Megameters:1e6,Gigameters:1e9,Microinches:254e-10,Mils:254e-7,Inches:.0254,Feet:.3048,Yards:.9144,Miles:1609.344,NauticalMiles:1852},gt="Display",At="DisplayBatch";function xt(e){let t=e.split(".");return t.includes(gt)||t.includes(At)}var Je=new Set;async function Et(e,t){let r=performance.now(),n=[],{allowScaling:a=!0,allowAutoPosition:o=!1,groundAxis:i="z",debug:c=!1,parsing:f={}}=_nullishCoalesce(t, () => ({}));try{let m=a?wt(e.modelunits):1;return await Mt(e,n,m,f,c),o&&Rt(n,i),n}catch(m){throw Bt(m,n),m}finally{c&&Dt(r)}}function wt(e){let t=ie[e];return t!==void 0?t:(Je.has(e)||(Je.add(e),_chunkAZ4GBXXLcjs.c.call(void 0, ).warn(`Unknown Rhino model unit "${e}" \u2014 geometry will not be scaled (factor 1). Known units: ${Object.keys(ie).join(", ")}.`)),1)}async function Mt(e,t,r,n,a){for(let o of e.values){let i=o.InnerTree;for(let c in i){let f=i[c];f&&await vt(f,t,r,n,a)}}}async function vt(e,t,r,n,a){for(let o of e){if(!xt(o.type))continue;let i={mergeByMaterial:!0,debug:!1,...n},c=St(o.data);if(!c){_chunkAZ4GBXXLcjs.c.call(void 0, ).error("Error parsing display batch envelope: invalid JSON");continue}let f=await se(c,i),m=q(c.items),l=[...f,...m];if(r!==1)for(let w of l)w.scale.set(r,r,r);t.push(...l),a&&_chunkAZ4GBXXLcjs.c.call(void 0, ).debug(`Extracted ${f.length} meshes and ${m.length} items from batch`)}}function St(e){return typeof e=="string"?Tt(e):e}function Tt(e){try{return JSON.parse(e)}catch (e3){return}}function Rt(e,t){if(e.length===0)return;let r=_chunkAZ4GBXXLcjs.m.call(void 0, e);_chunkAZ4GBXXLcjs.l.call(void 0, e,r.min[t],t)}function Bt(e,t){_chunkAZ4GBXXLcjs.c.call(void 0, ).error("An unexpected error occurred:",e),It(t)}function It(e){for(let t of e){let r=t;r.geometry&&r.geometry.dispose(),r.material&&(Array.isArray(r.material)?r.material.forEach(n=>n.dispose()):r.material.dispose())}}function Dt(e){let t=performance.now()-e;_chunkAZ4GBXXLcjs.c.call(void 0, ).info("Time to process meshes:",`${t.toFixed(2)}ms`)}exports.SCALE_FACTORS = ie; exports.getThreeMeshesFromComputeResponse = Et; exports.meshPolicy = qe; exports.parseDisplayItems = q; exports.parseMeshBatchBlob = ht; exports.parseMeshBatchObject = se; exports.setTextureAnisotropy = Ge;
10
10
  //# sourceMappingURL=parse.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["c:\\Users\\felix\\coding\\selva\\packages\\visualization\\dist\\parse.cjs"],"names":[],"mappings":"AAAA,2/BAAoI,gCAA6B,SAAU,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC,QAAQ,CAAC,mBAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,EAAE,iCAAE,CAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,gUAAwB,sDAAqD,oEAAmE,oEAAmE,IAA8B,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,kBAAC,CAAC,SAAE,GAAC,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,KAAK,kBAAC,CAAC,SAAE,IAAE,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,iCAAC,CAAE,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,iCAAC,CAAE,CAAC,IAAI,CAAC,oDAAoD,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,4BAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,iCAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,kBAAC,CAAC,CAAC,KAAK,SAAE,IAAE,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,mBAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,oBAAoB,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,iBAAC,CAAC,6BAAE,MAAM,0BAAE,CAAC,GAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,iCAAC,CAAE,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,iCAAC,CAAE,CAAC,IAAI,CAAC,2CAA2C,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAiC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,iCAAC,CAAE,CAAC,IAAI,CAAC,CAAC,qEAAqE,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,iCAAC,CAAE,CAAC,IAAI,CAAC,CAAC,oCAAoC,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,SAAA","file":"C:\\Users\\felix\\coding\\selva\\packages\\visualization\\dist\\parse.cjs","sourcesContent":[null]}
1
+ {"version":3,"sources":["/home/runner/work/selva/selva/packages/visualization/dist/parse.cjs","../src/parse/mesh-policy.ts","../src/parse/display-items/items/curves.ts","../src/parse/display-items/items/appearance.ts","../src/parse/display-items/items/points.ts","../src/parse/display-items/display-items-parser.ts","../src/parse/webdisplay/batch/materials.ts","../src/parse/webdisplay/batch/merge.ts"],"names":["cloneSceneObjects","meshes","root","copy","sources","child","i","source","target","releaseSceneObjects","disposeObjectTree","meshPolicy","DEFAULT_COLOR","materialParams","color","opacity","resolved","DEFAULT_LINE_WIDTH","MIN_POSITIONS","buildCurveLine","item","positions","curvePositions","geometry","LineGeometry","params","material","LineMaterial","styled","line","Line2","VisualizationError","ErrorCodes","buildPoint","position","getLogger","points","parseDisplayItems","items","objects","point","unknown"],"mappings":"AAAA,2/BAAsG,gCAA6B,SCWnHA,EAAAA,CAAkBC,CAAAA,CAA4C,CAC7E,OAAOA,CAAAA,CAAO,GAAA,CAAKC,CAAAA,EAAS,CAC3B,IAAMC,CAAAA,CAAOD,CAAAA,CAAK,KAAA,CAAM,CAAA,CAAI,CAAA,CACtBE,CAAAA,CAA4B,CAAC,CAAA,CACnCF,CAAAA,CAAK,QAAA,CAAUG,CAAAA,EAAUD,CAAAA,CAAQ,IAAA,CAAKC,CAAK,CAAC,CAAA,CAC5C,IAAIC,CAAAA,CAAI,CAAA,CACR,OAAAH,CAAAA,CAAK,QAAA,CAAUE,CAAAA,EAAU,CACxB,IAAME,CAAAA,CAASH,CAAAA,CAAQE,CAAAA,EAAG,CAAA,CACpBE,CAAAA,CAASH,CAAAA,CACVE,CAAAA,CAAO,QAAA,EAAA,CACZC,CAAAA,CAAO,QAAA,CAAWD,CAAAA,CAAO,QAAA,CAAS,KAAA,CAAM,CAAA,CACzC,CAAC,CAAA,CACMJ,CACR,CAAC,CACF,CAGO,SAASM,EAAAA,CAAoBR,CAAAA,CAAgC,CACnEA,CAAAA,CAAO,OAAA,CAASC,CAAAA,EAASQ,iCAAAA,CAAkBR,CAAM,CAAE,SAAA,CAAW,CAAA,CAAM,CAAC,CAAC,CACvE,CAGO,IAAMS,EAAAA,CAGT,CACH,KAAA,CAAOX,EAAAA,CACP,OAAA,CAASS,EACV,CAAA,CCvCA,sDAAsB,oEACO,oEACA,qRCFN,IAEVG,EAAAA,CAAgB,SAAA,CAGtB,SAASC,CAAAA,CACfC,CAAAA,CACAC,CAAAA,CACgE,CAChE,IAAMC,CAAAA,kBAAWD,CAAAA,SAAW,GAAA,CAC5B,MAAO,CACN,KAAA,CAAO,IAAU,EAAA,CAAA,KAAA,kBAAMD,CAAAA,SAASF,IAAa,CAAA,CAC7C,WAAA,CAAaI,CAAAA,CAAW,CAAA,CACxB,OAAA,CAASA,CACV,CACD,CDNA,IAAMC,EAAAA,CAAqB,CAAA,CAGrBC,EAAAA,CAAgB,CAAA,CAYf,SAASC,EAAAA,CAAeC,CAAAA,CAAkC,CAChE,IAAMC,CAAAA,CAAYC,EAAAA,CAAeF,CAAI,CAAA,CACrC,EAAA,CAAI,CAACC,CAAAA,CAAW,OAAO,IAAA,CAEvB,IAAME,CAAAA,CAAW,IAAIC,4BAAAA,CACrBD,CAAAA,CAAS,YAAA,CAAaF,CAAS,CAAA,CAG/B,IAAMI,CAAAA,CAASZ,CAAAA,CAAeO,CAAAA,CAAK,KAAA,CAAOA,CAAAA,CAAK,OAAO,CAAA,CAChDM,CAAAA,CAAW,IAAIC,iCAAAA,CAAa,CAAE,KAAA,CAAOF,CAAAA,CAAO,KAAM,CAAC,CAAA,CACnDG,CAAAA,CAASF,CAAAA,CAKfE,CAAAA,CAAO,SAAA,kBAAYR,CAAAA,CAAK,KAAA,SAASH,IAAAA,CACjCW,CAAAA,CAAO,WAAA,CAAcH,CAAAA,CAAO,WAAA,CAC5BG,CAAAA,CAAO,OAAA,CAAUH,CAAAA,CAAO,OAAA,CAExB,IAAMI,CAAAA,CAAO,IAAIC,mBAAAA,CAAMP,CAAAA,CAAUG,CAAQ,CAAA,CACzC,OAAAG,CAAAA,CAAK,oBAAA,CAAqB,CAAA,CAC1BA,CAAAA,CAAK,IAAA,CAAOT,CAAAA,CAAK,IAAA,CACjBS,CAAAA,CAAK,QAAA,CAAW,CACf,MAAA,CAAQ,SAAA,CACR,EAAA,CAAIT,CAAAA,CAAK,EAAA,CACT,KAAA,CAAOA,CAAAA,CAAK,KAAA,CACZ,IAAA,CAAM,OAAA,CACN,QAAA,CAAUA,CAAAA,CAAK,QAChB,CAAA,CACOS,CACR,CAUA,SAASP,EAAAA,CAAeF,CAAAA,CAAqC,CAC5D,EAAA,CAAI,CAACA,CAAAA,CAAK,MAAA,CACT,MAAM,IAAIW,wBAAAA,CACT,CAAA,oBAAA,EAAuBX,CAAAA,CAAK,EAAE,CAAA,wLAAA,CAAA,CAG9BY,mBAAAA,CAAW,cAAA,CACX,CAAE,OAAA,CAAS,CAAE,MAAA,CAAQZ,CAAAA,CAAK,EAAA,CAAI,IAAA,CAAMA,CAAAA,CAAK,IAAK,CAAE,CACjD,CAAA,CAGD,OAAOA,CAAAA,CAAK,MAAA,CAAO,MAAA,EAAUF,EAAAA,CAAgBE,CAAAA,CAAK,MAAA,CAAS,IAC5D,CE5EA,SAOgBa,EAAAA,CAAWb,CAAAA,CAAyC,CAEnE,GAAM,CAAE,QAAA,CAAAc,CAAS,CAAA,CAAId,CAAAA,CACrB,EAAA,CACC,CAACc,CAAAA,EACD,OAAOA,CAAAA,CAAS,CAAA,EAAM,QAAA,EACtB,CAAC,MAAA,CAAO,QAAA,CAASA,CAAAA,CAAS,CAAC,CAAA,EAC3B,OAAOA,CAAAA,CAAS,CAAA,EAAM,QAAA,EACtB,CAAC,MAAA,CAAO,QAAA,CAASA,CAAAA,CAAS,CAAC,CAAA,EAC3B,OAAOA,CAAAA,CAAS,CAAA,EAAM,QAAA,EACtB,CAAC,MAAA,CAAO,QAAA,CAASA,CAAAA,CAAS,CAAC,CAAA,CAE3B,OAAAC,iCAAAA,CAAU,CAAE,IAAA,CACX,CAAA,qEAAA,EAAwE,MAAA,CAAOf,CAAAA,CAAK,EAAE,CAAC,CAAA,EAAA,CACxF,CAAA,CACO,IAAA,CAGR,IAAMG,CAAAA,CAAW,IAAU,CAAA,CAAA,cAAA,CAC3BA,CAAAA,CAAS,YAAA,CACR,UAAA,CACA,IAAU,CAAA,CAAA,sBAAA,CAAuB,CAACW,CAAAA,CAAS,CAAA,CAAGA,CAAAA,CAAS,CAAA,CAAGA,CAAAA,CAAS,CAAC,CAAA,CAAG,CAAC,CACzE,CAAA,CAEA,IAAMR,CAAAA,CAAW,IAAU,CAAA,CAAA,cAAA,CAAe,CACzC,GAAGb,CAAAA,CAAeO,CAAAA,CAAK,KAAA,CAAOA,CAAAA,CAAK,OAAO,CAAA,CAC1C,IAAA,CAAM,CAAA,CACN,eAAA,CAAiB,CAAA,CAClB,CAAC,CAAA,CAEKgB,CAAAA,CAAS,IAAU,CAAA,CAAA,MAAA,CAAOb,CAAAA,CAAUG,CAAQ,CAAA,CAClD,OAAAU,CAAAA,CAAO,IAAA,CAAOhB,CAAAA,CAAK,IAAA,CACnBgB,CAAAA,CAAO,QAAA,CAAW,CACjB,MAAA,CAAQ,SAAA,CACR,EAAA,CAAIhB,CAAAA,CAAK,EAAA,CACT,KAAA,CAAOA,CAAAA,CAAK,KAAA,CACZ,IAAA,CAAM,OAAA,CACN,QAAA,CAAUA,CAAAA,CAAK,QAChB,CAAA,CACOgB,CACR,CC/BO,SAASC,CAAAA,CAAkBC,CAAAA,CAAoD,CACrF,EAAA,CAAI,CAACA,CAAAA,EAASA,CAAAA,CAAM,MAAA,GAAW,CAAA,CAAG,MAAO,CAAC,CAAA,CAE1C,IAAMC,CAAAA,CAA4B,CAAC,CAAA,CAEnC,GAAA,CAAA,IAAWnB,EAAAA,GAAQkB,CAAAA,CAClB,MAAA,CAAQlB,CAAAA,CAAK,IAAA,CAAM,CAClB,IAAK,OAAA,CAAS,CACb,IAAMS,CAAAA,CAAOV,EAAAA,CAAeC,CAAI,CAAA,CAC5BS,CAAAA,EAAMU,CAAAA,CAAQ,IAAA,CAAKV,CAAI,CAAA,CAC3B,KACD,CACA,IAAK,OAAA,CAAS,CACb,IAAMW,CAAAA,CAAQP,EAAAA,CAAWb,CAAI,CAAA,CACzBoB,CAAAA,EAAOD,CAAAA,CAAQ,IAAA,CAAKC,CAAK,CAAA,CAC7B,KACD,CACA,OAAA,CAAS,CAGR,IAAMC,CAAAA,CADmBrB,CAAAA,CAEzBe,iCAAAA,CAAU,CAAE,IAAA,CAAK,CAAA,oCAAA,EAAuC,MAAA,CAAOM,CAAAA,CAAQ,IAAI,CAAC,CAAA,CAAA;ACsC7E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACoBF,SAAA","file":"/home/runner/work/selva/selva/packages/visualization/dist/parse.cjs","sourcesContent":[null,"// Mesh ownership policy for `@selvajs/solve`'s result memo: `SolveResult<TMesh>` is opaque to the\n// memo, so clone/release are injected here instead. The viewer disposes whatever it last rendered\n// (`clearScene`), so a memo handing out live references would serve a disposed object on the next\n// hit — `clone` copies geometry explicitly (`Object3D.clone()` shares it by reference) but leaves\n// materials shared, since `clearScene` already spares `SHARED_MATERIALS` singletons and recompiling\n// per-mesh materials as shaders is expensive.\n\nimport * as THREE from 'three';\n\nimport { disposeObjectTree } from '../shared/index.js';\n\nexport function cloneSceneObjects(meshes: THREE.Object3D[]): THREE.Object3D[] {\n\treturn meshes.map((root) => {\n\t\tconst copy = root.clone(true);\n\t\tconst sources: THREE.Object3D[] = [];\n\t\troot.traverse((child) => sources.push(child));\n\t\tlet i = 0;\n\t\tcopy.traverse((child) => {\n\t\t\tconst source = sources[i++] as Partial<THREE.Mesh> & THREE.Object3D;\n\t\t\tconst target = child as Partial<THREE.Mesh> & THREE.Object3D;\n\t\t\tif (!source.geometry) return;\n\t\t\ttarget.geometry = source.geometry.clone();\n\t\t});\n\t\treturn copy;\n\t});\n}\n\n/** Skips materials — the memo never owns those; see the file header. */\nexport function releaseSceneObjects(meshes: THREE.Object3D[]): void {\n\tmeshes.forEach((root) => disposeObjectTree(root, { materials: false }));\n}\n\n/** Structurally, not nominally, typed as `@selvajs/solve/client`'s `MeshPolicy<THREE.Object3D>` — avoids a dependency on solve. */\nexport const meshPolicy: {\n\tclone(meshes: THREE.Object3D[]): THREE.Object3D[];\n\trelease(meshes: THREE.Object3D[]): void;\n} = {\n\tclone: cloneSceneObjects,\n\trelease: releaseSceneObjects\n};\n","import { Line2 } from 'three/addons/lines/Line2.js';\nimport { LineGeometry } from 'three/addons/lines/LineGeometry.js';\nimport { LineMaterial } from 'three/addons/lines/LineMaterial.js';\n\nimport { ErrorCodes, VisualizationError } from '../../../shared/index.js';\nimport { materialParams } from './appearance.js';\n\nimport type { DisplayCurve } from '../types';\n\nconst DEFAULT_LINE_WIDTH = 2;\n\n/** Two vertices — the shortest renderable polyline. */\nconst MIN_POSITIONS = 6;\n\n/**\n * Curves arrive tessellated: the backend sends `points`, this builds the line. Nothing decodes\n * geometry in the browser.\n *\n * Uses `Line2`/`LineMaterial` instead of `THREE.Line`: plain `THREE.Line` is hard-capped at 1px on\n * every major GPU backend, so `item.width` would go unhonoured. `Line2.onBeforeRender` sets\n * `LineMaterial`'s required `resolution`, so no renderer reference is needed here.\n *\n * @throws VisualizationError when the item has no `points` — see {@link curvePositions}.\n */\nexport function buildCurveLine(item: DisplayCurve): Line2 | null {\n\tconst positions = curvePositions(item);\n\tif (!positions) return null;\n\n\tconst geometry = new LineGeometry();\n\tgeometry.setPositions(positions);\n\n\t// @types/three's LineMaterial omits `linewidth`/`transparent`/`opacity` though all exist at runtime.\n\tconst params = materialParams(item.color, item.opacity);\n\tconst material = new LineMaterial({ color: params.color });\n\tconst styled = material as LineMaterial & {\n\t\tlinewidth: number;\n\t\ttransparent: boolean;\n\t\topacity: number;\n\t};\n\tstyled.linewidth = item.width ?? DEFAULT_LINE_WIDTH; // CSS px (worldUnits defaults false)\n\tstyled.transparent = params.transparent;\n\tstyled.opacity = params.opacity;\n\n\tconst line = new Line2(geometry, material);\n\tline.computeLineDistances();\n\tline.name = item.name;\n\tline.userData = {\n\t\tsource: 'compute',\n\t\tid: item.id,\n\t\tlayer: item.layer,\n\t\tkind: 'curve',\n\t\tmetadata: item.metadata\n\t};\n\treturn line;\n}\n\n/**\n * Flat `[x,y,z, …]`, or null for a degenerate curve — one of those can't abort the batch.\n *\n * A curve with no `points` **throws** instead. It means the definition was solved by a Display\n * component predating backend tessellation, which is a stale definition rather than one bad curve:\n * skipping would render a scene silently missing geometry, indistinguishable from a definition that\n * has no curves, with the fix nowhere in sight.\n */\nfunction curvePositions(item: DisplayCurve): number[] | null {\n\tif (!item.points) {\n\t\tthrow new VisualizationError(\n\t\t\t`Curve display item '${item.id}' has no tessellated points. It was produced by an ` +\n\t\t\t\t'outdated Display component — upgrade it in Grasshopper (Solution → Upgrade obsolete ' +\n\t\t\t\t'components) and re-save the definition.',\n\t\t\tErrorCodes.INVALID_CONFIG,\n\t\t\t{ context: { itemId: item.id, kind: item.kind } }\n\t\t);\n\t}\n\n\treturn item.points.length >= MIN_POSITIONS ? item.points : null;\n}\n","import * as THREE from 'three';\n\nexport const DEFAULT_COLOR = '#ffffff';\n\n/** Opacity < 1 flips `transparent` on. */\nexport function materialParams(\n\tcolor: string | undefined,\n\topacity: number | undefined\n): { color: THREE.Color; transparent: boolean; opacity: number } {\n\tconst resolved = opacity ?? 1;\n\treturn {\n\t\tcolor: new THREE.Color(color ?? DEFAULT_COLOR),\n\t\ttransparent: resolved < 1,\n\t\topacity: resolved\n\t};\n}\n","import * as THREE from 'three';\n\nimport { getLogger } from '../../../shared/index.js';\nimport { materialParams } from './appearance.js';\n\nimport type { DisplayPoint } from '../types';\n\nexport function buildPoint(item: DisplayPoint): THREE.Points | null {\n\t// `position` comes off the wire — don't trust the declared type without validating.\n\tconst { position } = item as { position?: { X?: unknown; Y?: unknown; Z?: unknown } };\n\tif (\n\t\t!position ||\n\t\ttypeof position.X !== 'number' ||\n\t\t!Number.isFinite(position.X) ||\n\t\ttypeof position.Y !== 'number' ||\n\t\t!Number.isFinite(position.Y) ||\n\t\ttypeof position.Z !== 'number' ||\n\t\t!Number.isFinite(position.Z)\n\t) {\n\t\tgetLogger().warn(\n\t\t\t`Skipping point display item with missing or non-finite position (id: ${String(item.id)}).`\n\t\t);\n\t\treturn null;\n\t}\n\n\tconst geometry = new THREE.BufferGeometry();\n\tgeometry.setAttribute(\n\t\t'position',\n\t\tnew THREE.Float32BufferAttribute([position.X, position.Y, position.Z], 3)\n\t);\n\n\tconst material = new THREE.PointsMaterial({\n\t\t...materialParams(item.color, item.opacity),\n\t\tsize: 6,\n\t\tsizeAttenuation: false\n\t});\n\n\tconst points = new THREE.Points(geometry, material);\n\tpoints.name = item.name;\n\tpoints.userData = {\n\t\tsource: 'compute',\n\t\tid: item.id,\n\t\tlayer: item.layer,\n\t\tkind: 'point',\n\t\tmetadata: item.metadata\n\t};\n\treturn points;\n}\n","import * as THREE from 'three';\n\nimport { getLogger } from '../../shared/index.js';\n\nimport { buildCurveLine } from './items/curves.js';\nimport { buildPoint } from './items/points.js';\n\nimport type { DisplayItem } from './types';\n\n/**\n * Builds THREE objects for the batch's non-mesh items.\n *\n * @throws VisualizationError when a curve predates backend tessellation, so a stale definition\n * surfaces as an actionable error instead of a scene quietly missing its curves. Every other\n * unrenderable item is logged and skipped.\n */\nexport function parseDisplayItems(items: DisplayItem[] | undefined): THREE.Object3D[] {\n\tif (!items || items.length === 0) return [];\n\n\tconst objects: THREE.Object3D[] = [];\n\n\tfor (const item of items) {\n\t\tswitch (item.kind) {\n\t\t\tcase 'curve': {\n\t\t\t\tconst line = buildCurveLine(item);\n\t\t\t\tif (line) objects.push(line);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase 'point': {\n\t\t\t\tconst point = buildPoint(item);\n\t\t\t\tif (point) objects.push(point);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\t// Forces a compile error if a new DisplayItem kind is added without a case above.\n\t\t\t\tconst unhandled: never = item;\n\t\t\t\tconst unknown = unhandled as { kind?: string };\n\t\t\t\tgetLogger().warn(`Skipping unknown display item kind: ${String(unknown.kind)}`);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn objects;\n}\n","import * as THREE from 'three';\n\nimport { parseColor } from '../../../shared/index.js';\n\nimport { applyTextureMap } from '../apply-texture.js';\n\nimport type { MaterialAppearanceOptions, SerializableMaterial } from '../types.js';\n\n// A near-pure metal has no diffuse response, so under the low-IBL 'technical' look it goes flat and\n// reads as painted card. Real architectural sheet metal is coated, not a bare mirror, so meaningfully\n// metallic materials get a thin satin clearcoat — a glossy dielectric layer independent of base\n// metalness/envMap, so folds catch light even when the IBL is dialed down.\nconst METAL_CLEARCOAT_THRESHOLD = 0.5;\nconst METAL_CLEARCOAT = 0.5;\nconst METAL_CLEARCOAT_ROUGHNESS = 0.3;\n\nexport function createMaterial(\n\tmatData: SerializableMaterial,\n\toptions?: { vertexColors?: boolean; appearance?: MaterialAppearanceOptions }\n): THREE.MeshPhysicalMaterial {\n\tconst color = parseColor(matData.color);\n\tconst vertexColors = options?.vertexColors ?? false;\n\tconst appearance = options?.appearance;\n\n\tconst material = new THREE.MeshPhysicalMaterial({\n\t\tcolor,\n\t\tmetalness: matData.metalness,\n\t\troughness: matData.roughness,\n\t\topacity: matData.opacity,\n\t\ttransparent: matData.transparent,\n\t\tvertexColors,\n\t\t// Cull back faces for closed solids (crisper silhouette, less overdraw); keep both sides for\n\t\t// open surfaces. Caller-controlled since Rhino emits both — default DoubleSide is the safe read.\n\t\tside: appearance?.cullBackfaces ? THREE.FrontSide : THREE.DoubleSide,\n\t\tpolygonOffset: true, // avoids z-fighting on coplanar faces\n\t\tpolygonOffsetFactor: 0.5,\n\t\tpolygonOffsetUnits: 0.5,\n\t\tdepthWrite: true,\n\t\tdepthTest: true\n\t});\n\n\t// HDR image-based-lighting reflection strength. Left at three's default (1) unless the caller\n\t// dials it: <1 flattens reflections toward a matte/technical read, >1 pushes a glossier look.\n\tif (appearance?.envMapIntensity != null) {\n\t\tmaterial.envMapIntensity = appearance.envMapIntensity;\n\t}\n\n\t// See the constants above. Plastics/matte fall below the threshold and stay bare.\n\tif (matData.metalness > METAL_CLEARCOAT_THRESHOLD) {\n\t\tmaterial.clearcoat = METAL_CLEARCOAT;\n\t\tmaterial.clearcoatRoughness = METAL_CLEARCOAT_ROUGHNESS;\n\t}\n\n\tif (vertexColors) {\n\t\tapplyVertexColorSRGBDecode(material);\n\t}\n\n\t// Async; the mesh renders untextured until the image decodes.\n\tif (matData.map) {\n\t\tapplyTextureMap(material, matData.map);\n\t}\n\n\treturn material;\n}\n\n/**\n * three.js uploads vertex colors verbatim and multiplies them straight into linear working space\n * (unlike textures, which carry a `colorSpace` and get decoded) — so sRGB-authored vertex colors\n * render too bright without this shader patch. Done on the GPU rather than a CPU pass over the\n * buffer, to keep the hot per-solve parse cheap.\n */\nexport function applyVertexColorSRGBDecode(material: THREE.Material): void {\n\tmaterial.onBeforeCompile = (shader) => {\n\t\tshader.vertexShader = shader.vertexShader.replace(\n\t\t\t'#include <color_vertex>',\n\t\t\t`#include <color_vertex>\n\t\t\t#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )\n\t\t\t\tvColor.rgb = mix(\n\t\t\t\t\tvColor.rgb / 12.92,\n\t\t\t\t\tpow( ( vColor.rgb + 0.055 ) / 1.055, vec3( 2.4 ) ),\n\t\t\t\t\tstep( vec3( 0.04045 ), vColor.rgb )\n\t\t\t\t);\n\t\t\t#endif`\n\t\t);\n\t};\n}\n","import * as THREE from 'three';\n\nimport { indexOutOfWindow } from './metadata.js';\n\nimport type { MaterialGroup, MeshMetadata } from '../types.js';\n\n/**\n * Merges a material group's meshes into one BufferGeometry. Parser indices already address the\n * combined vertex array (rebased by the C# pipeline during batch assembly), so this copies each\n * mesh's vertex/index slices into a fresh contiguous buffer and shifts indices to match.\n */\nexport function createMergedMesh(\n\tgroup: MaterialGroup,\n\tallVertices: Float32Array,\n\tallIndices: Uint16Array | Uint32Array,\n\tmaterials: THREE.Material[],\n\tallUvs: Float32Array | null = null,\n\tallColors: Uint8Array | null = null\n): THREE.Mesh {\n\tlet totalVertexCount = 0;\n\tlet totalIndexCount = 0;\n\tfor (const meshMeta of group.meshes) {\n\t\ttotalVertexCount += meshMeta.vertexCount;\n\t\ttotalIndexCount += meshMeta.indexCount;\n\t}\n\n\tconst mergedVertices = new Float32Array(totalVertexCount * 3);\n\tconst mergedIndices = new Uint32Array(totalIndexCount);\n\tconst mergedUvs = allUvs ? new Float32Array(totalVertexCount * 2) : null;\n\tconst mergedColors = allColors ? new Uint8Array(totalVertexCount * 3) : null;\n\n\tlet vertexWriteCursor = 0;\n\tlet indexWriteCursor = 0;\n\n\tfor (const meshMeta of group.meshes) {\n\t\tconst componentStart = meshMeta.vertexStart * 3;\n\t\tconst componentLen = meshMeta.vertexCount * 3;\n\t\tmergedVertices.set(\n\t\t\tallVertices.subarray(componentStart, componentStart + componentLen),\n\t\t\tvertexWriteCursor * 3\n\t\t);\n\n\t\tif (mergedUvs && allUvs) {\n\t\t\tconst uvStart = meshMeta.vertexStart * 2;\n\t\t\tmergedUvs.set(\n\t\t\t\tallUvs.subarray(uvStart, uvStart + meshMeta.vertexCount * 2),\n\t\t\t\tvertexWriteCursor * 2\n\t\t\t);\n\t\t}\n\n\t\tif (mergedColors && allColors) {\n\t\t\tmergedColors.set(\n\t\t\t\tallColors.subarray(componentStart, componentStart + componentLen),\n\t\t\t\tvertexWriteCursor * 3\n\t\t\t);\n\t\t}\n\n\t\tconst indicesSlice = allIndices.subarray(\n\t\t\tmeshMeta.indexStart,\n\t\t\tmeshMeta.indexStart + meshMeta.indexCount\n\t\t);\n\t\tconst indexShift = vertexWriteCursor - meshMeta.vertexStart;\n\t\tconst windowStart = meshMeta.vertexStart;\n\t\tconst windowEnd = meshMeta.vertexStart + meshMeta.vertexCount;\n\t\tfor (let i = 0; i < indicesSlice.length; i++) {\n\t\t\tconst indexValue = indicesSlice[i]!;\n\t\t\tif (indexValue < windowStart || indexValue >= windowEnd) {\n\t\t\t\tthrow indexOutOfWindow(indexValue, meshMeta);\n\t\t\t}\n\t\t\tmergedIndices[indexWriteCursor + i] = indexValue + indexShift;\n\t\t}\n\n\t\tvertexWriteCursor += meshMeta.vertexCount;\n\t\tindexWriteCursor += meshMeta.indexCount;\n\t}\n\n\tconst geometry = new THREE.BufferGeometry();\n\tgeometry.setAttribute('position', new THREE.BufferAttribute(mergedVertices, 3));\n\tgeometry.setIndex(new THREE.BufferAttribute(mergedIndices, 1));\n\tif (mergedUvs) {\n\t\tgeometry.setAttribute('uv', new THREE.BufferAttribute(mergedUvs, 2));\n\t}\n\tif (mergedColors) {\n\t\tgeometry.setAttribute('color', new THREE.BufferAttribute(mergedColors, 3, true));\n\t}\n\tgeometry.computeVertexNormals();\n\n\treturn finalizeMergedMesh(geometry, group, materials);\n}\n\nexport function finalizeMergedMesh(\n\tgeometry: THREE.BufferGeometry,\n\tgroup: MaterialGroup,\n\tmaterials: THREE.Material[]\n): THREE.Mesh {\n\tconst threeMesh = new THREE.Mesh(geometry, materials[group.materialId]);\n\tconst firstMesh = group.meshes[0];\n\tconst meshNames = group.meshes.map((m) => m.name).filter((name) => name && name.length > 0);\n\tthreeMesh.name = meshNames.length > 0 ? meshNames[0]! : `merged_material_${group.materialId}`;\n\tthreeMesh.castShadow = true;\n\tthreeMesh.receiveShadow = true;\n\n\tthreeMesh.userData = {\n\t\tsource: 'compute',\n\t\tname: threeMesh.name,\n\t\tlayer: firstMesh?.layer ?? '',\n\t\toriginalIndex: firstMesh?.originalIndex ?? 0,\n\t\tmetadata: firstMesh?.metadata ?? {},\n\t\tmergedFrom: group.meshes.slice(1).map((m) => ({\n\t\t\tname: m.name,\n\t\t\tlayer: m.layer,\n\t\t\toriginalIndex: m.originalIndex\n\t\t}))\n\t};\n\n\treturn threeMesh;\n}\n\n/**\n * Creates individual meshes from a material group. Each mesh's indices are rebased so they\n * address its own local vertex slice starting from 0.\n */\nexport function createIndividualMeshes(\n\tgroup: MaterialGroup,\n\tallVertices: Float32Array,\n\tallIndices: Uint16Array | Uint32Array,\n\tmaterials: THREE.Material[],\n\tallUvs: Float32Array | null = null,\n\tallColors: Uint8Array | null = null\n): THREE.Mesh[] {\n\tconst meshes: THREE.Mesh[] = [];\n\n\tfor (const meshMeta of group.meshes) {\n\t\tconst componentStart = meshMeta.vertexStart * 3;\n\t\tconst componentLen = meshMeta.vertexCount * 3;\n\n\t\t// `subarray` returns a view; copy via `slice` so the BufferAttribute owns its memory and\n\t\t// downstream code (dispose/reuse) can't surprise us by sharing the parser's buffer.\n\t\tconst vertices = allVertices.slice(componentStart, componentStart + componentLen);\n\n\t\tconst indicesSlice = allIndices.subarray(\n\t\t\tmeshMeta.indexStart,\n\t\t\tmeshMeta.indexStart + meshMeta.indexCount\n\t\t);\n\t\tconst rebasedIndices = new Uint32Array(indicesSlice.length);\n\t\tconst baseIndex = meshMeta.vertexStart;\n\t\tconst windowEnd = meshMeta.vertexStart + meshMeta.vertexCount;\n\t\tfor (let i = 0; i < indicesSlice.length; i++) {\n\t\t\tconst indexValue = indicesSlice[i]!;\n\t\t\tif (indexValue < baseIndex || indexValue >= windowEnd) {\n\t\t\t\tthrow indexOutOfWindow(indexValue, meshMeta);\n\t\t\t}\n\t\t\trebasedIndices[i] = indexValue - baseIndex;\n\t\t}\n\n\t\tconst geometry = new THREE.BufferGeometry();\n\t\tgeometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));\n\t\tgeometry.setIndex(new THREE.BufferAttribute(rebasedIndices, 1));\n\t\tif (allUvs) {\n\t\t\tconst uvStart = meshMeta.vertexStart * 2;\n\t\t\tconst uvs = allUvs.slice(uvStart, uvStart + meshMeta.vertexCount * 2);\n\t\t\tgeometry.setAttribute('uv', new THREE.BufferAttribute(uvs, 2));\n\t\t}\n\t\tif (allColors) {\n\t\t\tconst colors = allColors.slice(componentStart, componentStart + componentLen);\n\t\t\tgeometry.setAttribute('color', new THREE.BufferAttribute(colors, 3, true));\n\t\t}\n\t\tgeometry.computeVertexNormals();\n\n\t\tmeshes.push(finalizeSingleMesh(geometry, meshMeta, group, materials));\n\t}\n\n\treturn meshes;\n}\n\nexport function finalizeSingleMesh(\n\tgeometry: THREE.BufferGeometry,\n\tmeshMeta: MeshMetadata,\n\tgroup: MaterialGroup,\n\tmaterials: THREE.Material[]\n): THREE.Mesh {\n\tconst mesh = new THREE.Mesh(geometry, materials[group.materialId]);\n\tmesh.name = meshMeta.name;\n\tmesh.userData = {\n\t\tsource: 'compute',\n\t\tname: meshMeta.name,\n\t\tlayer: meshMeta.layer ?? '',\n\t\toriginalIndex: meshMeta.originalIndex,\n\t\tmetadata: meshMeta.metadata ?? {}\n\t};\n\tmesh.castShadow = true;\n\tmesh.receiveShadow = true;\n\treturn mesh;\n}\n"]}
package/dist/parse.d.cts CHANGED
@@ -1,11 +1,7 @@
1
1
  import * as THREE from 'three';
2
- import { RhinoModule } from 'rhino3dm';
3
- import { M as MaterialAppearanceOptions } from './types-CdF9R3qA.cjs';
2
+ import { M as MaterialAppearanceOptions } from './types-DCuos3gI.cjs';
4
3
 
5
- /**
6
- * Structural, not nominal: satisfies `@selvajs/solve/client`'s `MeshPolicy<THREE.Object3D>`
7
- * without this package depending on solve.
8
- */
4
+ /** Structurally, not nominally, typed as `@selvajs/solve/client`'s `MeshPolicy<THREE.Object3D>` — avoids a dependency on solve. */
9
5
  declare const meshPolicy: {
10
6
  clone(meshes: THREE.Object3D[]): THREE.Object3D[];
11
7
  release(meshes: THREE.Object3D[]): void;
@@ -33,11 +29,9 @@ interface DisplayComputeResponse {
33
29
  modelunits: string;
34
30
  }
35
31
 
36
- /** Shared by meshes and items so pick/filter/label code treats them uniformly. No color/material — that's per-kind. */
37
32
  interface DisplayIdentity {
38
- /** Stable pick key: `${sourceComponentId}:${originalIndex}`. */
33
+ /** Stable pick key: `${sourceComponentId}:${originalIndex}`. Distinct from `name` so renaming doesn't change identity. */
39
34
  id: string;
40
- /** Distinct from {@link id} — renaming must not change identity. */
41
35
  name: string;
42
36
  layer: string;
43
37
  /** Arbitrary key-value pairs from the GH Metadata input. */
@@ -46,7 +40,7 @@ interface DisplayIdentity {
46
40
  interface DisplayItemBase extends DisplayIdentity {
47
41
  /** Hex/rgb/named color string, parsed by `parseColor`. Falls back to a viewer default. */
48
42
  color?: string;
49
- /** 01. Omitted means fully opaque. */
43
+ /** 0-1; omitted means fully opaque. */
50
44
  opacity?: number;
51
45
  }
52
46
  /** Rhino's Z-up frame and `{X,Y,Z}` casing. */
@@ -55,11 +49,18 @@ interface DisplayPosition {
55
49
  Y: number;
56
50
  Z: number;
57
51
  }
58
- /** Rhino-native JSON (`curve.ToNurbsCurve().ToJSON()`), tessellated to a fat `Line2` on decode. */
52
+ /** Rendered as a fat `Line2` straight from `points` — nothing decodes geometry in the browser. */
59
53
  interface DisplayCurve extends DisplayItemBase {
60
54
  kind: 'curve';
61
- json: string;
62
- /** Screen-space CSS px, constant regardless of zoom. Omitted viewer default. */
55
+ /**
56
+ * Backend-tessellated polyline, flat `[x,y,z, …]` in Rhino's Z-up frame.
57
+ *
58
+ * Typed as required even though the plugin still sends a legacy `json` field alongside it: a
59
+ * payload without `points` came from a Display component too old to render, and parsing throws
60
+ * rather than treating it as a shape this package supports.
61
+ */
62
+ points: number[];
63
+ /** Screen-space CSS px, constant regardless of zoom. Omitted uses the viewer default. */
63
64
  width?: number;
64
65
  }
65
66
  interface DisplayPoint extends DisplayItemBase {
@@ -104,7 +105,6 @@ interface MeshMetadata {
104
105
  metadata?: Record<string, string>;
105
106
  }
106
107
  interface MaterialGroup {
107
- /** Index into the batch's materials array. */
108
108
  materialId: number;
109
109
  meshes: MeshMetadata[];
110
110
  }
@@ -131,7 +131,7 @@ interface DisplayBatch {
131
131
  items?: DisplayItem[];
132
132
  }
133
133
  interface MeshBatchParsingOptions {
134
- /** Merge meshes with same material into single geometry. Defaults to true. */
134
+ /** Merge meshes sharing a material into a single geometry. Defaults to true. */
135
135
  mergeByMaterial?: boolean;
136
136
  debug?: boolean;
137
137
  /**
@@ -144,7 +144,7 @@ interface MeshBatchParsingOptions {
144
144
 
145
145
  interface MeshExtractionOptions {
146
146
  parsing?: MeshBatchParsingOptions;
147
- /** Apply scaling based on model units. Defaults to true. */
147
+ /** Scale geometry to model units. Defaults to true. */
148
148
  allowScaling?: boolean;
149
149
  /**
150
150
  * Drop geometry so its lowest point sits on the ground plane. **Defaults to `false`** — content
@@ -156,23 +156,18 @@ interface MeshExtractionOptions {
156
156
  /** Up axis for `allowAutoPosition` grounding. Defaults to `'z'` (Rhino's frame) — only set this
157
157
  * if the viewer is configured with a non-default `sceneUp`. */
158
158
  groundAxis?: 'x' | 'y' | 'z';
159
- /** rhino3dm instance for decoding curve display items — selva-compute doesn't own the WASM
160
- * instance, the host threads it in. Omit to skip curves (points still render). */
161
- rhino?: RhinoModule;
162
159
  debug?: boolean;
163
160
  }
164
161
 
165
162
  /**
166
163
  * Metres per model unit, keyed by Rhino `UnitSystem` name (the `modelunits` string on the compute
167
- * response). Imperial factors are the exact international definitions (1 in = 0.0254 m,
168
- * 1 ft = 0.3048 m, 1 mi = 1609.344 m). Units not in this table scale 1 and log a one-time warning
169
- * — see {@link getScaleFactor}.
164
+ * response). Imperial factors are the exact international definitions. Units missing from this
165
+ * table scale by 1 and log a one-time warning — see {@link getScaleFactor}.
170
166
  */
171
167
  declare const SCALE_FACTORS: Record<string, number>;
172
168
  /**
173
169
  * Extracts display meshes and items from a Grasshopper WebDisplay compute response: decompresses,
174
- * scales to meters, and optionally grounds them. Requires the VektorNode Rhino.Compute fork (see
175
- * root CLAUDE.md).
170
+ * scales to meters, and optionally grounds them. Requires the VektorNode Rhino.Compute fork.
176
171
  *
177
172
  * Synchronous internally (large batches block the UI for their duration); `async` only so the
178
173
  * shape can stay stable if parsing moves off-thread later.
@@ -181,7 +176,6 @@ declare const SCALE_FACTORS: Record<string, number>;
181
176
  */
182
177
  declare function getThreeMeshesFromComputeResponse(data: DisplayComputeResponse, options?: MeshExtractionOptions): Promise<THREE.Object3D[]>;
183
178
 
184
- /** Internal telemetry only (not exposed in public options). */
185
179
  interface ParseTelemetry {
186
180
  parseTime?: number;
187
181
  perfStart?: number;
@@ -190,19 +184,19 @@ interface ParseTelemetry {
190
184
  * Parses a DisplayBatch object and creates Three.js meshes from its mesh blob.
191
185
  *
192
186
  * Synchronous internally — `parseBinaryMeshBatch` does no IO, just typed-array views over the
193
- * blob. Stays `async` so callers don't have to change shape if parsing moves into a worker later.
187
+ * blob. Stays `async` so callers don't need to change shape if parsing moves into a worker later.
194
188
  *
195
189
  * @throws {VisualizationError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
196
190
  */
197
191
  declare function parseMeshBatchObject(batch: DisplayBatch, options?: MeshBatchParsingOptions,
198
- /** @internal Timings threaded from an outer entry point; not a caller option. */
192
+ /** @internal Timings threaded from an outer entry point not a caller option. */
199
193
  telemetry?: ParseTelemetry): Promise<THREE.Mesh[]>;
200
194
  /**
201
195
  * Parses a raw binary mesh batch blob (SLVA wire format) and creates Three.js meshes.
202
196
  *
203
197
  * Use this entry point when the blob arrives as a binary WebSocket frame rather than inside a JSON
204
- * envelope. The blob is self-describing materials, groups, and `sourceComponentId` come from its
205
- * embedded metadata header.
198
+ * envelope the blob is self-describing, with materials, groups, and `sourceComponentId` coming
199
+ * from its embedded metadata header.
206
200
  *
207
201
  * @throws {VisualizationError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
208
202
  */
@@ -210,26 +204,18 @@ declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: Me
210
204
 
211
205
  /**
212
206
  * Subscribed to the renderer's own report below, so no host wiring is needed; still exported for a
213
- * host embedding a foreign renderer that wants to set it directly.
207
+ * host embedding a foreign renderer that wants to set it directly. Applies to textures loaded from
208
+ * here on — textures already decoded keep the value they were given.
214
209
  */
215
210
  declare function setTextureAnisotropy(value: number): void;
216
211
 
217
212
  /**
218
- * Free every cross-solve GPU cache cached geometries, textures and edge segments.
213
+ * Builds THREE objects for the batch's non-mesh items.
219
214
  *
220
- * **You do not normally need this.** These caches register themselves for teardown, so the viewer's
221
- * `dispose()` already frees them once the last live viewer goes away. It is exported for the cases
222
- * that sit outside a viewer lifecycle: reclaiming memory under pressure, or a test isolating
223
- * module-level state.
224
- *
225
- * Safe to call repeatedly and with a viewer running — the caches simply repopulate on the next solve.
215
+ * @throws VisualizationError when a curve predates backend tessellation, so a stale definition
216
+ * surfaces as an actionable error instead of a scene quietly missing its curves. Every other
217
+ * unrenderable item is logged and skipped.
226
218
  */
227
- declare function releaseParseCaches(): void;
228
-
229
- interface DisplayItemParseOptions {
230
- /** Omit to skip curves; points still render. */
231
- rhino?: RhinoModule;
232
- }
233
- declare function parseDisplayItems(items: DisplayItem[] | undefined, options?: DisplayItemParseOptions): THREE.Object3D[];
219
+ declare function parseDisplayItems(items: DisplayItem[] | undefined): THREE.Object3D[];
234
220
 
235
- export { type DisplayBatch, type DisplayComputeResponse, type DisplayCurve, type DisplayDataItem, type DisplayIdentity, type DisplayItem, type DisplayItemBase, type DisplayItemParseOptions, type DisplayPoint, type DisplayPosition, type DisplayResponseValue, type MaterialGroup, type MeshBatchParsingOptions, type MeshExtractionOptions, type MeshMetadata, SCALE_FACTORS, type SerializableMaterial, getThreeMeshesFromComputeResponse, meshPolicy, parseDisplayItems, parseMeshBatchBlob, parseMeshBatchObject, releaseParseCaches, setTextureAnisotropy };
221
+ export { type DisplayBatch, type DisplayComputeResponse, type DisplayCurve, type DisplayDataItem, type DisplayIdentity, type DisplayItem, type DisplayItemBase, type DisplayPoint, type DisplayPosition, type DisplayResponseValue, type MaterialGroup, type MeshBatchParsingOptions, type MeshExtractionOptions, type MeshMetadata, SCALE_FACTORS, type SerializableMaterial, getThreeMeshesFromComputeResponse, meshPolicy, parseDisplayItems, parseMeshBatchBlob, parseMeshBatchObject, setTextureAnisotropy };