@faicad/faijs 0.14.1 → 0.16.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/dist/api/api-namespace.d.ts +7 -0
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +23 -22
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +26 -8
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +4 -1
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/generated/cad/script-face.d.ts +1 -1
- package/dist/api/generated/cad/script-face.d.ts.map +1 -1
- package/dist/api/generated/cad/script-face.js +1 -2
- package/dist/api/generated/cad/script-face.js.map +1 -1
- package/dist/api/generated/operations.js +16 -16
- package/dist/api/generated/operations.js.map +1 -1
- package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
- package/dist/api/generated/script-face-manifest.js +0 -1
- package/dist/api/generated/script-face-manifest.js.map +1 -1
- package/dist/api/generated/script-face.d.ts +1 -4
- package/dist/api/generated/script-face.d.ts.map +1 -1
- package/dist/api/generated/script-face.js +2 -3
- package/dist/api/generated/script-face.js.map +1 -1
- package/dist/api/generated/sketching.js +1 -1
- package/dist/api/generated/sketching.js.map +1 -1
- package/dist/api/generated/topology.d.ts +0 -8
- package/dist/api/generated/topology.d.ts.map +1 -1
- package/dist/api/generated/topology.js +19 -26
- package/dist/api/generated/topology.js.map +1 -1
- package/dist/api/index.d.ts +1 -10
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +10 -18
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-projection.d.ts +3 -1
- package/dist/api/internal/compat-projection.d.ts.map +1 -1
- package/dist/api/internal/compat-projection.js +8 -5
- package/dist/api/internal/compat-projection.js.map +1 -1
- package/dist/api/internal/replica-role-table.d.ts +36 -0
- package/dist/api/internal/replica-role-table.d.ts.map +1 -0
- package/dist/api/internal/replica-role-table.js +73 -0
- package/dist/api/internal/replica-role-table.js.map +1 -0
- package/dist/api/internal/result-unwrap.d.ts +3 -1
- package/dist/api/internal/result-unwrap.d.ts.map +1 -1
- package/dist/api/internal/result-unwrap.js +2 -2
- package/dist/api/internal/result-unwrap.js.map +1 -1
- package/dist/api/occt-kernel-bridge.d.ts +105 -27
- package/dist/api/occt-kernel-bridge.d.ts.map +1 -1
- package/dist/api/occt-kernel-bridge.js +255 -41
- package/dist/api/occt-kernel-bridge.js.map +1 -1
- package/dist/api/pattern.d.ts.map +1 -1
- package/dist/api/pattern.js +25 -61
- package/dist/api/pattern.js.map +1 -1
- package/dist/api/replicate.d.ts +145 -0
- package/dist/api/replicate.d.ts.map +1 -0
- package/dist/api/replicate.js +351 -0
- package/dist/api/replicate.js.map +1 -0
- package/dist/api/revolve.d.ts +36 -0
- package/dist/api/revolve.d.ts.map +1 -0
- package/dist/api/revolve.js +165 -0
- package/dist/api/revolve.js.map +1 -0
- package/dist/api/surface/arg-spec.d.ts +8 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js +37 -36
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/surface/projection-overrides.d.ts.map +1 -1
- package/dist/api/surface/projection-overrides.js +6 -0
- package/dist/api/surface/projection-overrides.js.map +1 -1
- package/dist/boolean/deriveNormals.d.ts +5 -4
- package/dist/boolean/deriveNormals.d.ts.map +1 -1
- package/dist/boolean/deriveNormals.js +24 -7
- package/dist/boolean/deriveNormals.js.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +58 -0
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brepkit.js +39 -1
- package/dist/brep/engine/adapters/brepkit.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts +1 -5
- package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
- package/dist/brep/engine/adapters/occt.js +232 -18
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +79 -0
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/types.d.ts +18 -1
- package/dist/brep/engine/types.d.ts.map +1 -1
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +81 -11
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/browser.d.ts +6 -28
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +6 -17
- package/dist/browser.js.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts +13 -18
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +25 -18
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.d.ts +4 -2
- package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +2 -0
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.d.ts +4 -6
- package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.js +4 -9
- package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
- package/dist/cad-runtime/ports.d.ts +0 -7
- package/dist/cad-runtime/ports.d.ts.map +1 -1
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +1 -3
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +13 -18
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/env-agnostic.d.ts +38 -0
- package/dist/env-agnostic.d.ts.map +1 -0
- package/dist/env-agnostic.js +29 -0
- package/dist/env-agnostic.js.map +1 -0
- package/dist/fcstd/codegen.d.ts.map +1 -1
- package/dist/fcstd/codegen.js +8 -1
- package/dist/fcstd/codegen.js.map +1 -1
- package/dist/fcstd/expressions.d.ts +24 -0
- package/dist/fcstd/expressions.d.ts.map +1 -1
- package/dist/fcstd/expressions.js +91 -0
- package/dist/fcstd/expressions.js.map +1 -1
- package/dist/fcstd/feature-translate.d.ts.map +1 -1
- package/dist/fcstd/feature-translate.js +16 -2
- package/dist/fcstd/feature-translate.js.map +1 -1
- package/dist/fcstd/structural-types.d.ts.map +1 -1
- package/dist/fcstd/structural-types.js +5 -0
- package/dist/fcstd/structural-types.js.map +1 -1
- package/dist/index.d.ts +7 -24
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -16
- package/dist/index.js.map +1 -1
- package/dist/lang/determinism-scanner.d.ts +9 -0
- package/dist/lang/determinism-scanner.d.ts.map +1 -1
- package/dist/lang/determinism-scanner.js +7 -1
- package/dist/lang/determinism-scanner.js.map +1 -1
- package/dist/lang/symbol-table.d.ts +31 -0
- package/dist/lang/symbol-table.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.d.ts +6 -16
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +6 -16
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/lang/symbol-table.js +50 -1
- package/dist/lang/symbol-table.js.map +1 -1
- package/dist/mesh/creased-normals.d.ts +50 -0
- package/dist/mesh/creased-normals.d.ts.map +1 -0
- package/dist/mesh/creased-normals.js +114 -0
- package/dist/mesh/creased-normals.js.map +1 -0
- package/dist/mesh/decoration-provider.d.ts +53 -0
- package/dist/mesh/decoration-provider.d.ts.map +1 -0
- package/dist/mesh/decoration-provider.js +21 -0
- package/dist/mesh/decoration-provider.js.map +1 -0
- package/dist/mesh/engrave.d.ts +4 -0
- package/dist/mesh/engrave.d.ts.map +1 -1
- package/dist/mesh/engrave.js +22 -31
- package/dist/mesh/engrave.js.map +1 -1
- package/dist/mesh/index.d.ts +5 -14
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +7 -19
- package/dist/mesh/index.js.map +1 -1
- package/dist/mesh/io.d.ts +2 -1
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +5 -7
- package/dist/mesh/io.js.map +1 -1
- package/dist/mesh/primitives.d.ts +5 -18
- package/dist/mesh/primitives.d.ts.map +1 -1
- package/dist/mesh/primitives.js +4 -48
- package/dist/mesh/primitives.js.map +1 -1
- package/dist/mesh/stl-loader.d.ts +23 -0
- package/dist/mesh/stl-loader.d.ts.map +1 -0
- package/dist/mesh/stl-loader.js +139 -0
- package/dist/mesh/stl-loader.js.map +1 -0
- package/dist/module-resolver/parse-imports.d.ts +37 -0
- package/dist/module-resolver/parse-imports.d.ts.map +1 -0
- package/dist/module-resolver/parse-imports.js +39 -0
- package/dist/module-resolver/parse-imports.js.map +1 -0
- package/dist/module-resolver/resolver.d.ts +1 -1
- package/dist/module-resolver/resolver.js +2 -2
- package/dist/module-resolver/resolver.js.map +1 -1
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +1 -22
- package/dist/node-host/cli.js.map +1 -1
- package/dist/primitives/text/cjk-font.d.ts +42 -0
- package/dist/primitives/text/cjk-font.d.ts.map +1 -0
- package/dist/primitives/text/cjk-font.js +86 -0
- package/dist/primitives/text/cjk-font.js.map +1 -0
- package/dist/sdk.d.ts +2 -2
- package/dist/sdk.js +2 -2
- package/dist/sdk.js.map +1 -1
- package/dist/symbol-table.d.ts +15 -0
- package/dist/symbol-table.d.ts.map +1 -0
- package/dist/symbol-table.js +14 -0
- package/dist/symbol-table.js.map +1 -0
- package/dist/topology/naming/lineage-resolve.js +1 -1
- package/dist/topology/naming/lineage-resolve.js.map +1 -1
- package/dist/vendored/brepjs/kernel/index.d.ts +5 -0
- package/dist/vendored/brepjs/kernel/index.d.ts.map +1 -1
- package/dist/vendored/brepjs/kernel/index.js +11 -0
- package/dist/vendored/brepjs/kernel/index.js.map +1 -1
- package/dist/weapp.d.ts +3 -3
- package/dist/weapp.d.ts.map +1 -1
- package/dist/weapp.js +6 -3
- package/dist/weapp.js.map +1 -1
- package/package.json +16 -14
- package/dist/api/compat/index.d.ts +0 -173
- package/dist/api/compat/index.d.ts.map +0 -1
- package/dist/api/compat/index.js +0 -222
- package/dist/api/compat/index.js.map +0 -1
- package/dist/api/compound.d.ts +0 -110
- package/dist/api/compound.d.ts.map +0 -1
- package/dist/api/compound.js +0 -164
- package/dist/api/compound.js.map +0 -1
- package/dist/api/copy.d.ts +0 -40
- package/dist/api/copy.d.ts.map +0 -1
- package/dist/api/copy.js +0 -83
- package/dist/api/copy.js.map +0 -1
- package/dist/api/fai_drill.d.ts +0 -46
- package/dist/api/fai_drill.d.ts.map +0 -1
- package/dist/api/fai_drill.js +0 -243
- package/dist/api/fai_drill.js.map +0 -1
- package/dist/api/fai_extrude.d.ts +0 -36
- package/dist/api/fai_extrude.d.ts.map +0 -1
- package/dist/api/fai_extrude.js +0 -79
- package/dist/api/fai_extrude.js.map +0 -1
- package/dist/api/fai_split.d.ts +0 -46
- package/dist/api/fai_split.d.ts.map +0 -1
- package/dist/api/fai_split.js +0 -254
- package/dist/api/fai_split.js.map +0 -1
- package/dist/api/load.d.ts +0 -41
- package/dist/api/load.d.ts.map +0 -1
- package/dist/api/load.js +0 -84
- package/dist/api/load.js.map +0 -1
- package/dist/api/svgExtrude.d.ts +0 -32
- package/dist/api/svgExtrude.d.ts.map +0 -1
- package/dist/api/svgExtrude.js +0 -74
- package/dist/api/svgExtrude.js.map +0 -1
- package/dist/api/text.d.ts +0 -34
- package/dist/api/text.d.ts.map +0 -1
- package/dist/api/text.js +0 -101
- package/dist/api/text.js.map +0 -1
- package/dist/brep/text/fontTestHelper.d.ts +0 -30
- package/dist/brep/text/fontTestHelper.d.ts.map +0 -1
- package/dist/brep/text/fontTestHelper.js +0 -57
- package/dist/brep/text/fontTestHelper.js.map +0 -1
- package/dist/cad-runtime/module-executor.d.ts +0 -271
- package/dist/cad-runtime/module-executor.d.ts.map +0 -1
- package/dist/cad-runtime/module-executor.js +0 -630
- package/dist/cad-runtime/module-executor.js.map +0 -1
- package/dist/cad-runtime/terminal-dag.d.ts +0 -65
- package/dist/cad-runtime/terminal-dag.d.ts.map +0 -1
- package/dist/cad-runtime/terminal-dag.js +0 -167
- package/dist/cad-runtime/terminal-dag.js.map +0 -1
- package/dist/faqts/browser.d.ts +0 -16
- package/dist/faqts/browser.d.ts.map +0 -1
- package/dist/faqts/browser.js +0 -13
- package/dist/faqts/browser.js.map +0 -1
- package/dist/faqts/exec-blob.d.ts +0 -14
- package/dist/faqts/exec-blob.d.ts.map +0 -1
- package/dist/faqts/exec-blob.js +0 -22
- package/dist/faqts/exec-blob.js.map +0 -1
- package/dist/faqts/exec-node.d.ts +0 -15
- package/dist/faqts/exec-node.d.ts.map +0 -1
- package/dist/faqts/exec-node.js +0 -29
- package/dist/faqts/exec-node.js.map +0 -1
- package/dist/faqts/imports.d.ts +0 -74
- package/dist/faqts/imports.d.ts.map +0 -1
- package/dist/faqts/imports.js +0 -95
- package/dist/faqts/imports.js.map +0 -1
- package/dist/faqts/index.d.ts +0 -22
- package/dist/faqts/index.d.ts.map +0 -1
- package/dist/faqts/index.js +0 -21
- package/dist/faqts/index.js.map +0 -1
- package/dist/faqts/node.d.ts +0 -23
- package/dist/faqts/node.d.ts.map +0 -1
- package/dist/faqts/node.js +0 -23
- package/dist/faqts/node.js.map +0 -1
- package/dist/faqts/run.d.ts +0 -62
- package/dist/faqts/run.d.ts.map +0 -1
- package/dist/faqts/run.js +0 -62
- package/dist/faqts/run.js.map +0 -1
- package/dist/faqts/transform.d.ts +0 -43
- package/dist/faqts/transform.d.ts.map +0 -1
- package/dist/faqts/transform.js +0 -35
- package/dist/faqts/transform.js.map +0 -1
- package/dist/lang/compile.d.ts +0 -50
- package/dist/lang/compile.d.ts.map +0 -1
- package/dist/lang/compile.js +0 -368
- package/dist/lang/compile.js.map +0 -1
- package/dist/lang/keep.d.ts +0 -109
- package/dist/lang/keep.d.ts.map +0 -1
- package/dist/lang/keep.js +0 -226
- package/dist/lang/keep.js.map +0 -1
- package/dist/lang/parser.d.ts +0 -91
- package/dist/lang/parser.d.ts.map +0 -1
- package/dist/lang/parser.js +0 -1594
- package/dist/lang/parser.js.map +0 -1
- package/dist/mesh/drill-hole/DrillHoleCore.d.ts +0 -90
- package/dist/mesh/drill-hole/DrillHoleCore.d.ts.map +0 -1
- package/dist/mesh/drill-hole/DrillHoleCore.js +0 -287
- package/dist/mesh/drill-hole/DrillHoleCore.js.map +0 -1
- package/dist/mesh/drill-hole/drill-types.d.ts +0 -34
- package/dist/mesh/drill-hole/drill-types.d.ts.map +0 -1
- package/dist/mesh/drill-hole/drill-types.js +0 -7
- package/dist/mesh/drill-hole/drill-types.js.map +0 -1
- package/dist/mesh/fai_drill.d.ts +0 -21
- package/dist/mesh/fai_drill.d.ts.map +0 -1
- package/dist/mesh/fai_drill.js +0 -92
- package/dist/mesh/fai_drill.js.map +0 -1
- package/dist/mesh/fai_extrude.d.ts +0 -24
- package/dist/mesh/fai_extrude.d.ts.map +0 -1
- package/dist/mesh/fai_extrude.js +0 -42
- package/dist/mesh/fai_extrude.js.map +0 -1
- package/dist/mesh/fai_split.d.ts +0 -164
- package/dist/mesh/fai_split.d.ts.map +0 -1
- package/dist/mesh/fai_split.js +0 -269
- package/dist/mesh/fai_split.js.map +0 -1
- package/dist/primitives/svg-extrude.d.ts +0 -43
- package/dist/primitives/svg-extrude.d.ts.map +0 -1
- package/dist/primitives/svg-extrude.js +0 -78
- package/dist/primitives/svg-extrude.js.map +0 -1
- package/dist/primitives/text/cjk.d.ts +0 -61
- package/dist/primitives/text/cjk.d.ts.map +0 -1
- package/dist/primitives/text/cjk.js +0 -215
- package/dist/primitives/text/cjk.js.map +0 -1
- package/dist/primitives/text-geometry.d.ts +0 -47
- package/dist/primitives/text-geometry.d.ts.map +0 -1
- package/dist/primitives/text-geometry.js +0 -127
- package/dist/primitives/text-geometry.js.map +0 -1
- package/dist/test-helpers.d.ts +0 -31
- package/dist/test-helpers.d.ts.map +0 -1
- package/dist/test-helpers.js +0 -55
- package/dist/test-helpers.js.map +0 -1
- package/dist/vendored/brepjs/core/kernelReentrancy.d.ts +0 -41
- package/dist/vendored/brepjs/core/kernelReentrancy.d.ts.map +0 -1
- package/dist/vendored/brepjs/core/kernelReentrancy.js +0 -68
- package/dist/vendored/brepjs/core/kernelReentrancy.js.map +0 -1
package/dist/mesh/index.d.ts
CHANGED
|
@@ -16,17 +16,17 @@ import * as primitives from './primitives.js';
|
|
|
16
16
|
import * as brepPrimitives from '../brep/primitives-brep.js';
|
|
17
17
|
import * as brepOps from '../brep/index.js';
|
|
18
18
|
import * as booleanOps from './boolean.js';
|
|
19
|
-
import * as splitOps from './fai_split.js';
|
|
20
|
-
import * as drillOps from './fai_drill.js';
|
|
21
|
-
import * as extrudeOps from './fai_extrude.js';
|
|
22
19
|
import * as engraveOps from './engrave.js';
|
|
23
20
|
import * as transformOps from './transform.js';
|
|
24
21
|
import * as queryOps from './query.js';
|
|
25
22
|
import * as ioOps from './io.js';
|
|
26
23
|
/**
|
|
27
24
|
* Unified `cad` API object aggregating the pure-data mesh operations: mesh and
|
|
28
|
-
* BREP primitives, transforms, booleans,
|
|
29
|
-
*
|
|
25
|
+
* BREP primitives, transforms, booleans, engrave/knurl, geometry queries, file
|
|
26
|
+
* IO, and BREP feature operations.
|
|
27
|
+
*
|
|
28
|
+
* D1(2026-09-23 扩展库拆分):`text` / `svgExtrude` / `fai_*` 键已随
|
|
29
|
+
* `@faicad/faijs-extra` 迁出——它们的实现在扩展库的 mesh 面(`editorCad`)。
|
|
30
30
|
*/
|
|
31
31
|
export declare const cad: {
|
|
32
32
|
box: typeof primitives.box;
|
|
@@ -34,9 +34,7 @@ export declare const cad: {
|
|
|
34
34
|
cylinder: typeof primitives.cylinder;
|
|
35
35
|
cone: typeof primitives.cone;
|
|
36
36
|
wedge: typeof primitives.wedge;
|
|
37
|
-
text: typeof primitives.text;
|
|
38
37
|
screw: typeof primitives.screw;
|
|
39
|
-
svgExtrude: typeof primitives.svgExtrude;
|
|
40
38
|
sdf: typeof primitives.sdf;
|
|
41
39
|
boxBrep: typeof brepPrimitives.boxBrep;
|
|
42
40
|
sphereBrep: typeof brepPrimitives.sphereBrep;
|
|
@@ -51,13 +49,6 @@ export declare const cad: {
|
|
|
51
49
|
union: typeof booleanOps.union;
|
|
52
50
|
subtract: typeof booleanOps.subtract;
|
|
53
51
|
intersect: typeof booleanOps.intersect;
|
|
54
|
-
fai_split: typeof splitOps.split;
|
|
55
|
-
fai_splitWithParams: typeof splitOps.splitWithParams;
|
|
56
|
-
dovetailSplit: typeof splitOps.dovetailSplit;
|
|
57
|
-
dowelSplit: typeof splitOps.dowelSplit;
|
|
58
|
-
tenonSplit: typeof splitOps.tenonSplit;
|
|
59
|
-
fai_drill: typeof drillOps.drill;
|
|
60
|
-
fai_extrude: typeof extrudeOps.extrude;
|
|
61
52
|
engrave: typeof engraveOps.engrave;
|
|
62
53
|
knurl: typeof engraveOps.knurl;
|
|
63
54
|
boundingBox: typeof queryOps.boundingBox;
|
package/dist/mesh/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mesh/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,UAAU,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/mesh/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,UAAU,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,MAAM,CAAA;AAI7B;;;;;;;GAOG;AACH,eAAO,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA0Df,CAAA;AAID,YAAY,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAA;AACvE,YAAY,EACV,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAChE,UAAU,EAAE,gBAAgB,EAAE,SAAS,EACvC,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EACtD,UAAU,EAAE,WAAW,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,gBAAgB,GACjF,MAAM,SAAS,CAAA;AAGhB,YAAY,EACV,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,eAAe,EACjE,iBAAiB,GAClB,MAAM,SAAS,CAAA;AAChB,OAAO,EACL,oBAAoB,EAAE,kBAAkB,EAAE,qBAAqB,EAC/D,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAA"}
|
package/dist/mesh/index.js
CHANGED
|
@@ -16,9 +16,6 @@ import * as primitives from './primitives.js';
|
|
|
16
16
|
import * as brepPrimitives from '../brep/primitives-brep.js';
|
|
17
17
|
import * as brepOps from '../brep/index.js';
|
|
18
18
|
import * as booleanOps from './boolean.js';
|
|
19
|
-
import * as splitOps from './fai_split.js';
|
|
20
|
-
import * as drillOps from './fai_drill.js';
|
|
21
|
-
import * as extrudeOps from './fai_extrude.js';
|
|
22
19
|
import * as engraveOps from './engrave.js';
|
|
23
20
|
import * as transformOps from './transform.js';
|
|
24
21
|
import * as queryOps from './query.js';
|
|
@@ -26,8 +23,11 @@ import * as ioOps from './io.js';
|
|
|
26
23
|
// ── 统一 cad API 对象 ──
|
|
27
24
|
/**
|
|
28
25
|
* Unified `cad` API object aggregating the pure-data mesh operations: mesh and
|
|
29
|
-
* BREP primitives, transforms, booleans,
|
|
30
|
-
*
|
|
26
|
+
* BREP primitives, transforms, booleans, engrave/knurl, geometry queries, file
|
|
27
|
+
* IO, and BREP feature operations.
|
|
28
|
+
*
|
|
29
|
+
* D1(2026-09-23 扩展库拆分):`text` / `svgExtrude` / `fai_*` 键已随
|
|
30
|
+
* `@faicad/faijs-extra` 迁出——它们的实现在扩展库的 mesh 面(`editorCad`)。
|
|
31
31
|
*/
|
|
32
32
|
export const cad = {
|
|
33
33
|
// 创建(mesh 路径)
|
|
@@ -36,9 +36,7 @@ export const cad = {
|
|
|
36
36
|
cylinder: primitives.cylinder,
|
|
37
37
|
cone: primitives.cone,
|
|
38
38
|
wedge: primitives.wedge,
|
|
39
|
-
text: primitives.text,
|
|
40
39
|
screw: primitives.screw,
|
|
41
|
-
svgExtrude: primitives.svgExtrude,
|
|
42
40
|
sdf: primitives.sdf,
|
|
43
41
|
// 创建(BREP 路径 — OCCT 精确实体三角化)
|
|
44
42
|
boxBrep: brepPrimitives.boxBrep,
|
|
@@ -57,18 +55,8 @@ export const cad = {
|
|
|
57
55
|
subtract: booleanOps.subtract,
|
|
58
56
|
intersect: booleanOps.intersect,
|
|
59
57
|
// 分割
|
|
60
|
-
// fai_
|
|
61
|
-
// `
|
|
62
|
-
// **变更其 API 形态必须同步更新 `../3d_editor`**(见 api/fai_*.ts 的 @deprecated)。
|
|
63
|
-
fai_split: splitOps.split,
|
|
64
|
-
fai_splitWithParams: splitOps.splitWithParams,
|
|
65
|
-
dovetailSplit: splitOps.dovetailSplit,
|
|
66
|
-
dowelSplit: splitOps.dowelSplit,
|
|
67
|
-
tenonSplit: splitOps.tenonSplit,
|
|
68
|
-
// 钻孔
|
|
69
|
-
fai_drill: drillOps.drill,
|
|
70
|
-
// 拉伸
|
|
71
|
-
fai_extrude: extrudeOps.extrude,
|
|
58
|
+
// `fai_*` 键(编辑器消费面)已随扩展库迁出:@faicad/faijs-extra 的 mesh 面
|
|
59
|
+
// 经 `mesh/fai_split.ts` / `mesh/fai_drill.ts` / `mesh/fai_extrude.ts` 提供。
|
|
72
60
|
// 雕刻
|
|
73
61
|
engrave: engraveOps.engrave,
|
|
74
62
|
knurl: engraveOps.knurl,
|
package/dist/mesh/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mesh/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,UAAU,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/mesh/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,UAAU,MAAM,cAAc,CAAA;AAC1C,OAAO,KAAK,cAAc,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,OAAO,MAAM,SAAS,CAAA;AAClC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,UAAU,MAAM,WAAW,CAAA;AACvC,OAAO,KAAK,YAAY,MAAM,aAAa,CAAA;AAC3C,OAAO,KAAK,QAAQ,MAAM,SAAS,CAAA;AACnC,OAAO,KAAK,KAAK,MAAM,MAAM,CAAA;AAE7B,sBAAsB;AAEtB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,GAAG,GAAG;IACjB,cAAc;IACd,GAAG,EAAE,UAAU,CAAC,GAAG;IACnB,MAAM,EAAE,UAAU,CAAC,MAAM;IACzB,QAAQ,EAAE,UAAU,CAAC,QAAQ;IAC7B,IAAI,EAAE,UAAU,CAAC,IAAI;IACrB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,GAAG,EAAE,UAAU,CAAC,GAAG;IAEnB,6BAA6B;IAC7B,OAAO,EAAE,cAAc,CAAC,OAAO;IAC/B,UAAU,EAAE,cAAc,CAAC,UAAU;IACrC,YAAY,EAAE,cAAc,CAAC,YAAY;IACzC,QAAQ,EAAE,cAAc,CAAC,QAAQ;IACjC,SAAS,EAAE,cAAc,CAAC,SAAS;IAEnC,KAAK;IACL,SAAS,EAAE,YAAY,CAAC,SAAS;IACjC,YAAY,EAAE,YAAY,CAAC,YAAY;IACvC,KAAK,EAAE,YAAY,CAAC,KAAK;IACzB,OAAO,EAAE,YAAY,CAAC,OAAO;IAC7B,eAAe,EAAE,YAAY,CAAC,eAAe;IAE7C,KAAK;IACL,KAAK,EAAE,UAAU,CAAC,KAAK;IACvB,QAAQ,EAAE,UAAU,CAAC,QAAQ;IAC7B,SAAS,EAAE,UAAU,CAAC,SAAS;IAE/B,KAAK;IACL,wDAAwD;IACxD,0EAA0E;IAE1E,KAAK;IACL,OAAO,EAAE,UAAU,CAAC,OAAO;IAC3B,KAAK,EAAE,UAAU,CAAC,KAAK;IAEvB,KAAK;IACL,WAAW,EAAE,QAAQ,CAAC,WAAW;IACjC,UAAU,EAAE,QAAQ,CAAC,UAAU;IAC/B,MAAM,EAAE,QAAQ,CAAC,MAAM;IACvB,MAAM,EAAE,QAAQ,CAAC,MAAM;IAEvB,KAAK;IACL,IAAI,EAAE,KAAK,CAAC,UAAU;IAEtB,mCAAmC;IACnC,aAAa,EAAE,OAAO,CAAC,aAAa;IACpC,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAC1B,OAAO,EAAE,OAAO,CAAC,OAAO;IACxB,UAAU,EAAE,OAAO,CAAC,UAAU;IAC9B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,SAAS,EAAE,OAAO,CAAC,SAAS;IAC5B,WAAW,EAAE,OAAO,CAAC,WAAW;IAChC,QAAQ,EAAE,OAAO,CAAC,QAAQ;IAC1B,YAAY,EAAE,OAAO,CAAC,YAAY;CACnC,CAAA;AAiBD,OAAO,EACL,oBAAoB,EAAE,kBAAkB,EAAE,qBAAqB,EAC/D,YAAY,EACZ,WAAW,GACZ,MAAM,SAAS,CAAA","sourcesContent":["/**\n * mesh — 纯数据几何 API 统一入口\n *\n * See docs/api-contract.md §1 (architecture layers) and §10 (stdlib function catalog).\n *\n * 原则(§5.1):\n * 1. 全部纯数据:输入输出是 Shape (ManifoldMeshData),不碰 THREE 场景、不读 store\n * 2. 不可变:每个 API 返回新几何,不修改输入\n * 3. 同步签名、异步执行:API 签名同步(或 async);worker 边界由 ScriptEngine 处理\n * 4. 坐标系:右手系 +Z 向上、毫米、角度用度\n *\n * P1 阶段:mesh 是对现有纯函数的薄包装层,行为完全不变。\n * P3+ 阶段:mesh 将由 ScriptEngine 驱动,在 worker 中执行。\n */\n\nimport * as primitives from './primitives'\nimport * as brepPrimitives from '../brep/primitives-brep'\nimport * as brepOps from '../brep'\nimport * as booleanOps from './boolean'\nimport * as engraveOps from './engrave'\nimport * as transformOps from './transform'\nimport * as queryOps from './query'\nimport * as ioOps from './io'\n\n// ── 统一 cad API 对象 ──\n\n/**\n * Unified `cad` API object aggregating the pure-data mesh operations: mesh and\n * BREP primitives, transforms, booleans, engrave/knurl, geometry queries, file\n * IO, and BREP feature operations.\n *\n * D1(2026-09-23 扩展库拆分):`text` / `svgExtrude` / `fai_*` 键已随\n * `@faicad/faijs-extra` 迁出——它们的实现在扩展库的 mesh 面(`editorCad`)。\n */\nexport const cad = {\n // 创建(mesh 路径)\n box: primitives.box,\n sphere: primitives.sphere,\n cylinder: primitives.cylinder,\n cone: primitives.cone,\n wedge: primitives.wedge,\n screw: primitives.screw,\n sdf: primitives.sdf,\n\n // 创建(BREP 路径 — OCCT 精确实体三角化)\n boxBrep: brepPrimitives.boxBrep,\n sphereBrep: brepPrimitives.sphereBrep,\n cylinderBrep: brepPrimitives.cylinderBrep,\n coneBrep: brepPrimitives.coneBrep,\n wedgeBrep: brepPrimitives.wedgeBrep,\n\n // 变换\n translate: transformOps.translate,\n rotate_euler: transformOps.rotate_euler,\n scale: transformOps.scale,\n scale3d: transformOps.scale3d,\n transformMatrix: transformOps.transformMatrix,\n\n // 布尔\n union: booleanOps.union,\n subtract: booleanOps.subtract,\n intersect: booleanOps.intersect,\n\n // 分割\n // `fai_*` 键(编辑器消费面)已随扩展库迁出:@faicad/faijs-extra 的 mesh 面\n // 经 `mesh/fai_split.ts` / `mesh/fai_drill.ts` / `mesh/fai_extrude.ts` 提供。\n\n // 雕刻\n engrave: engraveOps.engrave,\n knurl: engraveOps.knurl,\n\n // 查询\n boundingBox: queryOps.boundingBox,\n bboxCenter: queryOps.bboxCenter,\n volume: queryOps.volume,\n faceAt: queryOps.faceAt,\n\n // IO\n load: ioOps.importFile,\n\n // BREP 特征操作(Phase 2 — OCCT 精确实体运算)\n translateBrep: brepOps.translateBrep,\n rotateBrep: brepOps.rotateBrep,\n scaleBrep: brepOps.scaleBrep,\n fuseBrep: brepOps.fuseBrep,\n cutBrep: brepOps.cutBrep,\n commonBrep: brepOps.commonBrep,\n drillBrep: brepOps.drillBrep,\n splitBrep: brepOps.splitBrep,\n extrudeBrep: brepOps.extrudeBrep,\n loadBrep: brepOps.loadBrep,\n solidToShape: brepOps.solidToShape,\n}\n\n// ── 类型导出 ──\n\nexport type { Shape, Vec3, BoundingBox, FaceDescriptor } from './types'\nexport type {\n BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams,\n TextParams, SvgExtrudeParams, SdfParams,\n DrillParams, ExtrudeParams, EngraveParams, KnurlParams,\n SplitPlane, SplitResult, DovetailSplitParams, DowelSplitParams, TenonSplitParams,\n} from './types'\n\n// BREP ops 类型导出\nexport type {\n BrepChainState, DrillBrepParams, SplitBrepParams, SplitBrepResult,\n ExtrudeBrepParams,\n} from '../brep'\nexport {\n createBrepChainState, initBrepChainState, releaseBrepChainState,\n solidToShape,\n isCadFormat,\n} from '../brep'\n"]}
|
package/dist/mesh/io.d.ts
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
* mesh IO API — headless 文件加载
|
|
3
3
|
*
|
|
4
4
|
* 替代浏览器版的 io.ts(依赖 fileBlobStore / formatLoaders / model-store)。
|
|
5
|
-
*
|
|
5
|
+
* STL 由 core 自持的 `mesh/stl-loader.ts` 解析(零 three addons——`three/examples`
|
|
6
|
+
* 不在 three 的版本兼容承诺内,且会把不可控模块带进每个消费方,含小程序 worker)。
|
|
6
7
|
*/
|
|
7
8
|
import type { Shape } from './types.js';
|
|
8
9
|
/**
|
package/dist/mesh/io.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"io.d.ts","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAEpC;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,MAAM,EAAE,WAAW,EACnB,MAAM,CAAC,EAAE,MAAM,GACd,OAAO,CAAC,KAAK,CAAC,CAahB"}
|
package/dist/mesh/io.js
CHANGED
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
* mesh IO API — headless 文件加载
|
|
3
3
|
*
|
|
4
4
|
* 替代浏览器版的 io.ts(依赖 fileBlobStore / formatLoaders / model-store)。
|
|
5
|
-
*
|
|
5
|
+
* STL 由 core 自持的 `mesh/stl-loader.ts` 解析(零 three addons——`three/examples`
|
|
6
|
+
* 不在 three 的版本兼容承诺内,且会把不可控模块带进每个消费方,含小程序 worker)。
|
|
6
7
|
*/
|
|
7
8
|
import { geoToManifoldMesh } from '../boolean/geo-convert.js';
|
|
9
|
+
import { parseStl } from './stl-loader.js';
|
|
8
10
|
/**
|
|
9
11
|
* Load geometry from raw file bytes (headless variant). STL is parsed
|
|
10
12
|
* directly; unsupported formats fall back to STL parsing.
|
|
@@ -16,15 +18,11 @@ import { geoToManifoldMesh } from '../boolean/geo-convert.js';
|
|
|
16
18
|
export async function importFile(buffer, format) {
|
|
17
19
|
const fmt = (format ?? 'stl').toLowerCase();
|
|
18
20
|
if (fmt === 'stl') {
|
|
19
|
-
|
|
20
|
-
const geo = new STLLoader().parse(buffer);
|
|
21
|
-
return geoToManifoldMesh(geo);
|
|
21
|
+
return geoToManifoldMesh(parseStl(buffer));
|
|
22
22
|
}
|
|
23
23
|
// For other formats, try STL as fallback
|
|
24
24
|
try {
|
|
25
|
-
|
|
26
|
-
const geo = new STLLoader().parse(buffer);
|
|
27
|
-
return geoToManifoldMesh(geo);
|
|
25
|
+
return geoToManifoldMesh(parseStl(buffer));
|
|
28
26
|
}
|
|
29
27
|
catch {
|
|
30
28
|
throw new Error(`[mesh/io] unsupported format: ${fmt}`);
|
package/dist/mesh/io.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"io.js","sourceRoot":"","sources":["../../src/mesh/io.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAA;AAGvC;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,MAAmB,EACnB,MAAe;IAEf,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC,WAAW,EAAE,CAAA;IAE3C,IAAI,GAAG,KAAK,KAAK,EAAE,CAAC;QAClB,OAAO,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5C,CAAC;IAED,yCAAyC;IACzC,IAAI,CAAC;QACH,OAAO,iBAAiB,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,iCAAiC,GAAG,EAAE,CAAC,CAAA;IACzD,CAAC;AACH,CAAC","sourcesContent":["/**\n * mesh IO API — headless 文件加载\n *\n * 替代浏览器版的 io.ts(依赖 fileBlobStore / formatLoaders / model-store)。\n * STL 由 core 自持的 `mesh/stl-loader.ts` 解析(零 three addons——`three/examples`\n * 不在 three 的版本兼容承诺内,且会把不可控模块带进每个消费方,含小程序 worker)。\n */\n\nimport { geoToManifoldMesh } from '../boolean/geo-convert'\nimport { parseStl } from './stl-loader'\nimport type { Shape } from './types'\n\n/**\n * Load geometry from raw file bytes (headless variant). STL is parsed\n * directly; unsupported formats fall back to STL parsing.\n *\n * @param buffer - the raw file bytes to parse.\n * @param format - format identifier such as 'stl' (defaults to 'stl').\n * @returns the loaded shape.\n */\nexport async function importFile(\n buffer: ArrayBuffer,\n format?: string,\n): Promise<Shape> {\n const fmt = (format ?? 'stl').toLowerCase()\n\n if (fmt === 'stl') {\n return geoToManifoldMesh(parseStl(buffer))\n }\n\n // For other formats, try STL as fallback\n try {\n return geoToManifoldMesh(parseStl(buffer))\n } catch {\n throw new Error(`[mesh/io] unsupported format: ${fmt}`)\n }\n}\n"]}
|
|
@@ -3,14 +3,16 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 提取来源(§5.7):
|
|
5
5
|
* - box/sphere/cylinder/cone/wedge ← engine/primitives/mesh-primitives.ts (makePrimitiveGeo)
|
|
6
|
-
* - text ← engine/components/engraving/EngravingCore.ts (createTextGeometry)
|
|
7
6
|
* - screw ← engine/primitives/screw/screw.ts (makeScrew)
|
|
8
|
-
*
|
|
7
|
+
*
|
|
8
|
+
* `text` / `svgExtrude`(three 的 Shape / ExtrudeGeometry / SVGLoader 链)已随
|
|
9
|
+
* B 组迁到 `@faicad/faijs-extra` 的 `mesh/primitives.ts`,core 的 mesh 面不再
|
|
10
|
+
* 承载 three 的非基础几何生成链。
|
|
9
11
|
*
|
|
10
12
|
* 所有函数返回 Shape (ManifoldMeshData):THREE.BufferGeometry → geoToManifoldMesh 转换。
|
|
11
13
|
* 坐标系:Z-up、毫米。
|
|
12
14
|
*/
|
|
13
|
-
import type { Shape, BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams,
|
|
15
|
+
import type { Shape, BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams, SdfParams } from './types.js';
|
|
14
16
|
/**
|
|
15
17
|
* Create a box solid (brepjs contract, §4.1 A 决策).
|
|
16
18
|
*
|
|
@@ -63,14 +65,6 @@ export declare function cone(params: ConeParams): Shape;
|
|
|
63
65
|
* @returns the wedge shape.
|
|
64
66
|
*/
|
|
65
67
|
export declare function wedge(params: WedgeParams): Shape;
|
|
66
|
-
/**
|
|
67
|
-
* Create text geometry. Font loading is asynchronous, so this function is
|
|
68
|
-
* async; CJK text is rendered with the system font when one is available.
|
|
69
|
-
*
|
|
70
|
-
* @param params - text parameters (text, size, depth).
|
|
71
|
-
* @returns the text shape.
|
|
72
|
-
*/
|
|
73
|
-
export declare function text(params: TextParams): Promise<Shape>;
|
|
74
68
|
/**
|
|
75
69
|
* Create a screw (threaded) geometry.
|
|
76
70
|
*
|
|
@@ -86,13 +80,6 @@ export declare function screw(params: {
|
|
|
86
80
|
head: 'hex' | 'chc' | 'none';
|
|
87
81
|
nRad?: number;
|
|
88
82
|
}): Promise<Shape>;
|
|
89
|
-
/**
|
|
90
|
-
* Create an extruded geometry from an SVG source.
|
|
91
|
-
*
|
|
92
|
-
* @param params - SVG extrude parameters (svg, depth, target size, optional natural size).
|
|
93
|
-
* @returns the extruded shape.
|
|
94
|
-
*/
|
|
95
|
-
export declare function svgExtrude(params: SvgExtrudeParams): Shape;
|
|
96
83
|
/**
|
|
97
84
|
* Create a mesh from SDF (signed distance field) code, sampling the field with
|
|
98
85
|
* marching cubes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/mesh/primitives.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/mesh/primitives.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAYjH;;;;;;;;;;;GAWG;AACH,wBAAgB,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,KAAK,CAsB5C;AAED;;;;;GAKG;AACH,wBAAgB,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,KAAK,CAOlD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,KAAK,CAWtD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,IAAI,CAAC,MAAM,EAAE,UAAU,GAAG,KAAK,CA8B9C;AAED;;;;;GAKG;AACH,wBAAgB,KAAK,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CA0DhD;AAED;;;;;GAKG;AACH,wBAAsB,KAAK,CAAC,MAAM,EAAE;IAClC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAA;IAC7B,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,MAAM,CAAA;IAC7C,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,CAAA;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAA;CACd,GAAG,OAAO,CAAC,KAAK,CAAC,CAYjB;AAED;;;;;;GAMG;AACH,wBAAsB,GAAG,CAAC,MAAM,EAAE,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,CAc3D"}
|
package/dist/mesh/primitives.js
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
*
|
|
4
4
|
* 提取来源(§5.7):
|
|
5
5
|
* - box/sphere/cylinder/cone/wedge ← engine/primitives/mesh-primitives.ts (makePrimitiveGeo)
|
|
6
|
-
* - text ← engine/components/engraving/EngravingCore.ts (createTextGeometry)
|
|
7
6
|
* - screw ← engine/primitives/screw/screw.ts (makeScrew)
|
|
8
|
-
*
|
|
7
|
+
*
|
|
8
|
+
* `text` / `svgExtrude`(three 的 Shape / ExtrudeGeometry / SVGLoader 链)已随
|
|
9
|
+
* B 组迁到 `@faicad/faijs-extra` 的 `mesh/primitives.ts`,core 的 mesh 面不再
|
|
10
|
+
* 承载 three 的非基础几何生成链。
|
|
9
11
|
*
|
|
10
12
|
* 所有函数返回 Shape (ManifoldMeshData):THREE.BufferGeometry → geoToManifoldMesh 转换。
|
|
11
13
|
* 坐标系:Z-up、毫米。
|
|
@@ -13,7 +15,6 @@
|
|
|
13
15
|
import * as THREE from 'three';
|
|
14
16
|
import { makePrimitiveGeo } from '../primitives/mesh-primitives.js';
|
|
15
17
|
import { geoToManifoldMesh } from '../boolean/csg-backend.js';
|
|
16
|
-
import { svgToExtrudedGeometry } from '../primitives/svg-extrude.js';
|
|
17
18
|
import { clampNRad } from './types.js';
|
|
18
19
|
// ── 内部工具 ──
|
|
19
20
|
/** THREE.BufferGeometry → Shape (ManifoldMeshData) */
|
|
@@ -191,36 +192,6 @@ export function wedge(params) {
|
|
|
191
192
|
}
|
|
192
193
|
return geoToShape(geo);
|
|
193
194
|
}
|
|
194
|
-
/**
|
|
195
|
-
* Create text geometry. Font loading is asynchronous, so this function is
|
|
196
|
-
* async; CJK text is rendered with the system font when one is available.
|
|
197
|
-
*
|
|
198
|
-
* @param params - text parameters (text, size, depth).
|
|
199
|
-
* @returns the text shape.
|
|
200
|
-
*/
|
|
201
|
-
export async function text(params) {
|
|
202
|
-
const { getOpentypeFont, createTextGeometry } = await import('../primitives/text-geometry.js');
|
|
203
|
-
const { containsCjk, loadSystemCjkFont, createMixedTextGeometry } = await import('../primitives/text/cjk.js');
|
|
204
|
-
const font = await getOpentypeFont();
|
|
205
|
-
let geo;
|
|
206
|
-
if (containsCjk(params.text)) {
|
|
207
|
-
const cjkFont = await loadSystemCjkFont();
|
|
208
|
-
if (cjkFont) {
|
|
209
|
-
geo = await createMixedTextGeometry(params.text, params.size, params.depth, cjkFont.font, font);
|
|
210
|
-
}
|
|
211
|
-
else {
|
|
212
|
-
// No CJK font available: replace CJK chars with '?' so geometry still
|
|
213
|
-
// can be created (graceful degradation). Without this, createTextGeometry
|
|
214
|
-
// would throw because CJK glyphs are .notdef in OpenSans Regular.
|
|
215
|
-
const fallback = params.text.replace(/[\u4E00-\u9FFF\u3400-\u4DBF\u2F800-\u2FA1F\u3000-\u303F\uFF00-\uFFEF]/g, '?');
|
|
216
|
-
geo = await createTextGeometry(fallback, params.size, params.depth, font);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
else {
|
|
220
|
-
geo = await createTextGeometry(params.text, params.size, params.depth, font);
|
|
221
|
-
}
|
|
222
|
-
return geoToShape(geo);
|
|
223
|
-
}
|
|
224
195
|
/**
|
|
225
196
|
* Create a screw (threaded) geometry.
|
|
226
197
|
*
|
|
@@ -240,21 +211,6 @@ export async function screw(params) {
|
|
|
240
211
|
});
|
|
241
212
|
return geoToShape(geo);
|
|
242
213
|
}
|
|
243
|
-
/**
|
|
244
|
-
* Create an extruded geometry from an SVG source.
|
|
245
|
-
*
|
|
246
|
-
* @param params - SVG extrude parameters (svg, depth, target size, optional natural size).
|
|
247
|
-
* @returns the extruded shape.
|
|
248
|
-
*/
|
|
249
|
-
export function svgExtrude(params) {
|
|
250
|
-
const geo = svgToExtrudedGeometry(params.svg, {
|
|
251
|
-
depth: params.depth,
|
|
252
|
-
targetLongSide: params.targetLongSide ?? 20,
|
|
253
|
-
naturalWidth: params.naturalWidth ?? 0,
|
|
254
|
-
naturalHeight: params.naturalHeight ?? 0,
|
|
255
|
-
});
|
|
256
|
-
return geoToShape(geo);
|
|
257
|
-
}
|
|
258
214
|
/**
|
|
259
215
|
* Create a mesh from SDF (signed distance field) code, sampling the field with
|
|
260
216
|
* marching cubes.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/mesh/primitives.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh 基本体 API — 从现有纯函数提取的统一接口\n *\n * 提取来源(§5.7):\n * - box/sphere/cylinder/cone/wedge ← engine/primitives/mesh-primitives.ts (makePrimitiveGeo)\n * - text ← engine/components/engraving/EngravingCore.ts (createTextGeometry)\n * - screw ← engine/primitives/screw/screw.ts (makeScrew)\n * - svgExtrude ← engine/primitives/svg-extrude/ (svgToExtrudedGeometry)\n *\n * 所有函数返回 Shape (ManifoldMeshData):THREE.BufferGeometry → geoToManifoldMesh 转换。\n * 坐标系:Z-up、毫米。\n */\n\nimport * as THREE from 'three'\nimport { makePrimitiveGeo } from '../primitives/mesh-primitives'\nimport { geoToManifoldMesh } from '../boolean/csg-backend'\nimport { svgToExtrudedGeometry } from '../primitives/svg-extrude'\nimport type { Shape, BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams, TextParams, SvgExtrudeParams, SdfParams } from './types'\nimport { clampNRad } from './types'\n\n// ── 内部工具 ──\n\n/** THREE.BufferGeometry → Shape (ManifoldMeshData) */\nfunction geoToShape(geo: THREE.BufferGeometry): Shape {\n return geoToManifoldMesh(geo)\n}\n\n// ── 创建 API ──\n\n/**\n * Create a box solid (brepjs contract, §4.1 A 决策).\n *\n * `box(width, depth, height)` — X=width, Y=depth, Z=height — places the\n * min-corner at the origin by default (`centered:false`). `centered: true`\n * centers the box at the origin; `at` is CENTER semantics and takes precedence\n * over `centered`. The `segments` option is consumed by the tessellation\n * caller (this mesh builder keeps it via clampNRad when present).\n *\n * @param params - box parameters (width/depth/height, optional at/centered/segments).\n * @returns the box shape.\n */\nexport function box(params: BoxParams): Shape {\n const { width, depth, height } = params\n // THREE.BoxGeometry(a, b, c) is Y-up (X=a, Y=b, Z=c); after the +90° rotateX\n // the dims map to X=a, Y=c, Z=b. To reach X=width, Y=depth, Z=height the\n // pre-rotation sizes must be (width, height, depth) — 裁决 7 xyz contract.\n const geo = new THREE.BoxGeometry(width, height, depth)\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // brepjs box semantics: corner at origin by default; centered at origin when\n // `centered` (no `at`); `at` (CENTER semantics) takes precedence.\n const at = params.at\n let tx = 0\n let ty = 0\n let tz = 0\n if (at !== undefined) {\n ;[tx, ty, tz] = at\n } else if (!params.centered) {\n tx = width / 2\n ty = depth / 2\n tz = height / 2\n }\n if (tx !== 0 || ty !== 0 || tz !== 0) geo.translate(tx, ty, tz)\n return geoToShape(geo)\n}\n\n/**\n * Create a sphere centered at the origin (or the optional `center`).\n *\n * @param params - sphere parameters (radius, optional segments, optional center).\n * @returns the sphere shape.\n */\nexport function sphere(params: SphereParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = makePrimitiveGeo('sphere', params.radius * 2, segs)\n if (params.center) {\n geo.translate(params.center[0], params.center[1], params.center[2])\n }\n return geoToShape(geo)\n}\n\n/**\n * Create a cylinder along +Z (`cylinder(radius, height, { at?, centered?,\n * segments? })` brepjs 契约,§4.3 A 决策;与 brep 路径逐点对齐)。\n *\n * 锚点:`at` 是**底面轴心**(BASE)语义(默认 [0,0,0],底面在原点、+Z 延伸);\n * `centered:true` 指底面落到 −h/2(无 at 时居中到原点)——与 `at` 同给时以\n * `at` 为中心。`segments` 经 clampNRad 消费(P0 §5)。\n *\n * @param params - cylinder parameters (radius, height, optional at/centered/segments).\n * @returns the cylinder shape.\n */\nexport function cylinder(params: CylinderParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = new THREE.CylinderGeometry(params.radius, params.radius, params.height, segs)\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // geometry(rotateX 后)沿 z ∈ [-h/2, +h/2](three 默认 Y-up 居中):\n // 目标底面中心 in baseZ = (at?.[2] ?? 0) - (centered ? h/2 : 0) → 平移到 baseZ + h/2。\n const baseX = params.at?.[0] ?? 0\n const baseY = params.at?.[1] ?? 0\n const baseZ = (params.at?.[2] ?? 0) - (params.centered === true ? params.height / 2 : 0)\n geo.translate(baseX, baseY, baseZ + params.height / 2)\n return geoToShape(geo)\n}\n\n/**\n * Create a cone, or a frustum when the top and bottom radii differ\n * (`cone(bottomRadius, topRadius, height, { at?, centered?, segments? })` brepjs\n * 契约,§4.1 P 决策;与 brep 路径逐点对齐)。\n *\n * 锚点:`at` 是**底面轴心**(BASE)语义(默认 [0,0,0],底面在原点、+Z 延伸);\n * `centered:true` 指底面落到 −h/2(无 at 时居中到原点)——与 `at` 同给时以\n * `at` 为中心。`segments` 经 clampNRad 消费(P0 §5)。\n *\n * @param params - cone parameters (radiusBottom, radiusTop, height, optional at/centered/segments).\n * @returns the cone shape.\n */\nexport function cone(params: ConeParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = new THREE.ConeGeometry(\n Math.max(params.radiusBottom, params.radiusTop),\n params.height,\n segs,\n )\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // radiusTop === 0 → 尖锥(ConeGeometry 顶点在顶);其余(含 radiusTop ===\n // radiusBottom 的等径圆柱/圆台)用 CylinderGeometry(radiusTop/bottom 各就各位)。\n let resultGeo: THREE.BufferGeometry\n if (params.radiusTop === 0) {\n resultGeo = geo\n } else {\n const geo2 = new THREE.CylinderGeometry(\n params.radiusTop,\n params.radiusBottom,\n params.height,\n segs,\n )\n geo2.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n resultGeo = geo2\n }\n // geometry(rotateX 后)沿 z ∈ [-h/2, +h/2](three 默认 Y-up 居中):\n // 目标底面中心 in baseZ = (at?.[2] ?? 0) - (centered ? h/2 : 0) → 平坦平移 baseZ + h/2。\n const baseX = params.at?.[0] ?? 0\n const baseY = params.at?.[1] ?? 0\n const baseZ = (params.at?.[2] ?? 0) - (params.centered === true ? params.height / 2 : 0)\n resultGeo.translate(baseX, baseY, baseZ + params.height / 2)\n return geoToShape(resultGeo)\n}\n\n/**\n * Create a wedge (ramp) solid, fully parameterized and Z-up.\n *\n * @param params - wedge parameters (width, height, angle, length, optional center).\n * @returns the wedge shape.\n */\nexport function wedge(params: WedgeParams): Shape {\n const width = params.width\n const height = params.height\n const angle = params.angle\n const length = params.length\n\n const angleRad = (angle * Math.PI) / 180\n const halfExtrude = length / 2\n const hw = width / 2\n const halfTopWidth = Math.max(0, hw - height / Math.tan(angleRad))\n // 顶边塌缩(斜坡已在宽度内到顶)→ 三角棱柱(与 brep wedge 的退化处理一致,\n // 保证 mesh/brep 同参数 bbox 一致;零面积三角形会破坏 manifold)。\n const degenerate = halfTopWidth <= 1e-12\n\n const positions = degenerate\n ? new Float32Array([\n -halfExtrude, -hw, 0,\n -halfExtrude, hw, 0,\n -halfExtrude, 0, height,\n halfExtrude, -hw, 0,\n halfExtrude, hw, 0,\n halfExtrude, 0, height,\n ])\n : new Float32Array([\n -halfExtrude, -hw, 0,\n -halfExtrude, hw, 0,\n -halfExtrude, halfTopWidth, height,\n -halfExtrude, -halfTopWidth, height,\n halfExtrude, -hw, 0,\n halfExtrude, hw, 0,\n halfExtrude, halfTopWidth, height,\n halfExtrude, -halfTopWidth, height,\n ])\n\n const indices = degenerate\n ? new Uint32Array([\n 0, 1, 2, 3, 5, 4,\n 0, 3, 4, 0, 4, 1,\n 0, 2, 5, 0, 5, 3,\n 1, 4, 5, 1, 5, 2,\n ])\n : new Uint32Array([\n 0, 1, 2, 0, 2, 3,\n 4, 6, 5, 4, 7, 6,\n 0, 4, 5, 0, 5, 1,\n 3, 2, 6, 3, 6, 7,\n 0, 3, 7, 0, 7, 4,\n 1, 5, 6, 1, 6, 2,\n ])\n\n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geo.setIndex(new THREE.BufferAttribute(indices, 1))\n\n if (params.center) {\n geo.translate(params.center[0], params.center[1], params.center[2])\n }\n return geoToShape(geo)\n}\n\n/**\n * Create text geometry. Font loading is asynchronous, so this function is\n * async; CJK text is rendered with the system font when one is available.\n *\n * @param params - text parameters (text, size, depth).\n * @returns the text shape.\n */\nexport async function text(params: TextParams): Promise<Shape> {\n const { getOpentypeFont, createTextGeometry } = await import(\n '../primitives/text-geometry'\n )\n const { containsCjk, loadSystemCjkFont, createMixedTextGeometry } = await import(\n '../primitives/text/cjk'\n )\n const font = await getOpentypeFont()\n let geo: THREE.BufferGeometry\n if (containsCjk(params.text)) {\n const cjkFont = await loadSystemCjkFont()\n if (cjkFont) {\n geo = await createMixedTextGeometry(params.text, params.size, params.depth, cjkFont.font, font)\n } else {\n // No CJK font available: replace CJK chars with '?' so geometry still\n // can be created (graceful degradation). Without this, createTextGeometry\n // would throw because CJK glyphs are .notdef in OpenSans Regular.\n const fallback = params.text.replace(/[\\u4E00-\\u9FFF\\u3400-\\u4DBF\\u2F800-\\u2FA1F\\u3000-\\u303F\\uFF00-\\uFFEF]/g, '?')\n geo = await createTextGeometry(fallback, params.size, params.depth, font)\n }\n } else {\n geo = await createTextGeometry(params.text, params.size, params.depth, font)\n }\n return geoToShape(geo)\n}\n\n/**\n * Create a screw (threaded) geometry.\n *\n * @param params - screw parameters (system, specIdx, thread, length, head, optional pitchCustom and nRad).\n * @returns the screw shape.\n */\nexport async function screw(params: {\n system: 'metric' | 'imperial'\n specIdx: number\n thread: 'coarse' | 'fine' | 'custom' | 'none'\n pitchCustom?: number\n length: number\n head: 'hex' | 'chc' | 'none'\n nRad?: number\n}): Promise<Shape> {\n const { makeScrew } = await import('../primitives/screw/screw')\n const geo = makeScrew({\n system: params.system,\n specIdx: params.specIdx,\n thread: params.thread,\n pitchCustom: params.pitchCustom ?? 0,\n length: params.length,\n head: params.head,\n nRad: clampNRad(params.nRad),\n })\n return geoToShape(geo)\n}\n\n/**\n * Create an extruded geometry from an SVG source.\n *\n * @param params - SVG extrude parameters (svg, depth, target size, optional natural size).\n * @returns the extruded shape.\n */\nexport function svgExtrude(params: SvgExtrudeParams): Shape {\n const geo = svgToExtrudedGeometry(params.svg, {\n depth: params.depth,\n targetLongSide: params.targetLongSide ?? 20,\n naturalWidth: params.naturalWidth ?? 0,\n naturalHeight: params.naturalHeight ?? 0,\n })\n return geoToShape(geo)\n}\n\n/**\n * Create a mesh from SDF (signed distance field) code, sampling the field with\n * marching cubes.\n *\n * @param params - SDF parameters (code, optional bounds, params, resolution).\n * @returns the sampled shape.\n */\nexport async function sdf(params: SdfParams): Promise<Shape> {\n const { runSdf } = await import('../sdf/sdf-runner')\n const box = params.box ?? [[-10, -10, -10], [10, 10, 10]]\n const bounds: [number, number, number, number, number, number] = [\n box[0][0], box[0][1], box[0][2],\n box[1][0], box[1][1], box[1][2],\n ]\n const mesh = await runSdf(\n params.code,\n params.params ?? {},\n bounds,\n params.resolution ?? 1.0,\n )\n return { positions: mesh.positions, indices: mesh.indices }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/mesh/primitives.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * mesh 基本体 API — 从现有纯函数提取的统一接口\n *\n * 提取来源(§5.7):\n * - box/sphere/cylinder/cone/wedge ← engine/primitives/mesh-primitives.ts (makePrimitiveGeo)\n * - screw ← engine/primitives/screw/screw.ts (makeScrew)\n *\n * `text` / `svgExtrude`(three 的 Shape / ExtrudeGeometry / SVGLoader 链)已随\n * B 组迁到 `@faicad/faijs-extra` 的 `mesh/primitives.ts`,core 的 mesh 面不再\n * 承载 three 的非基础几何生成链。\n *\n * 所有函数返回 Shape (ManifoldMeshData):THREE.BufferGeometry → geoToManifoldMesh 转换。\n * 坐标系:Z-up、毫米。\n */\n\nimport * as THREE from 'three'\nimport { makePrimitiveGeo } from '../primitives/mesh-primitives'\nimport { geoToManifoldMesh } from '../boolean/csg-backend'\nimport type { Shape, BoxParams, SphereParams, CylinderParams, ConeParams, WedgeParams, SdfParams } from './types'\nimport { clampNRad } from './types'\n\n// ── 内部工具 ──\n\n/** THREE.BufferGeometry → Shape (ManifoldMeshData) */\nfunction geoToShape(geo: THREE.BufferGeometry): Shape {\n return geoToManifoldMesh(geo)\n}\n\n// ── 创建 API ──\n\n/**\n * Create a box solid (brepjs contract, §4.1 A 决策).\n *\n * `box(width, depth, height)` — X=width, Y=depth, Z=height — places the\n * min-corner at the origin by default (`centered:false`). `centered: true`\n * centers the box at the origin; `at` is CENTER semantics and takes precedence\n * over `centered`. The `segments` option is consumed by the tessellation\n * caller (this mesh builder keeps it via clampNRad when present).\n *\n * @param params - box parameters (width/depth/height, optional at/centered/segments).\n * @returns the box shape.\n */\nexport function box(params: BoxParams): Shape {\n const { width, depth, height } = params\n // THREE.BoxGeometry(a, b, c) is Y-up (X=a, Y=b, Z=c); after the +90° rotateX\n // the dims map to X=a, Y=c, Z=b. To reach X=width, Y=depth, Z=height the\n // pre-rotation sizes must be (width, height, depth) — 裁决 7 xyz contract.\n const geo = new THREE.BoxGeometry(width, height, depth)\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // brepjs box semantics: corner at origin by default; centered at origin when\n // `centered` (no `at`); `at` (CENTER semantics) takes precedence.\n const at = params.at\n let tx = 0\n let ty = 0\n let tz = 0\n if (at !== undefined) {\n ;[tx, ty, tz] = at\n } else if (!params.centered) {\n tx = width / 2\n ty = depth / 2\n tz = height / 2\n }\n if (tx !== 0 || ty !== 0 || tz !== 0) geo.translate(tx, ty, tz)\n return geoToShape(geo)\n}\n\n/**\n * Create a sphere centered at the origin (or the optional `center`).\n *\n * @param params - sphere parameters (radius, optional segments, optional center).\n * @returns the sphere shape.\n */\nexport function sphere(params: SphereParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = makePrimitiveGeo('sphere', params.radius * 2, segs)\n if (params.center) {\n geo.translate(params.center[0], params.center[1], params.center[2])\n }\n return geoToShape(geo)\n}\n\n/**\n * Create a cylinder along +Z (`cylinder(radius, height, { at?, centered?,\n * segments? })` brepjs 契约,§4.3 A 决策;与 brep 路径逐点对齐)。\n *\n * 锚点:`at` 是**底面轴心**(BASE)语义(默认 [0,0,0],底面在原点、+Z 延伸);\n * `centered:true` 指底面落到 −h/2(无 at 时居中到原点)——与 `at` 同给时以\n * `at` 为中心。`segments` 经 clampNRad 消费(P0 §5)。\n *\n * @param params - cylinder parameters (radius, height, optional at/centered/segments).\n * @returns the cylinder shape.\n */\nexport function cylinder(params: CylinderParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = new THREE.CylinderGeometry(params.radius, params.radius, params.height, segs)\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // geometry(rotateX 后)沿 z ∈ [-h/2, +h/2](three 默认 Y-up 居中):\n // 目标底面中心 in baseZ = (at?.[2] ?? 0) - (centered ? h/2 : 0) → 平移到 baseZ + h/2。\n const baseX = params.at?.[0] ?? 0\n const baseY = params.at?.[1] ?? 0\n const baseZ = (params.at?.[2] ?? 0) - (params.centered === true ? params.height / 2 : 0)\n geo.translate(baseX, baseY, baseZ + params.height / 2)\n return geoToShape(geo)\n}\n\n/**\n * Create a cone, or a frustum when the top and bottom radii differ\n * (`cone(bottomRadius, topRadius, height, { at?, centered?, segments? })` brepjs\n * 契约,§4.1 P 决策;与 brep 路径逐点对齐)。\n *\n * 锚点:`at` 是**底面轴心**(BASE)语义(默认 [0,0,0],底面在原点、+Z 延伸);\n * `centered:true` 指底面落到 −h/2(无 at 时居中到原点)——与 `at` 同给时以\n * `at` 为中心。`segments` 经 clampNRad 消费(P0 §5)。\n *\n * @param params - cone parameters (radiusBottom, radiusTop, height, optional at/centered/segments).\n * @returns the cone shape.\n */\nexport function cone(params: ConeParams): Shape {\n const segs = clampNRad(params.nRad ?? params.segments)\n const geo = new THREE.ConeGeometry(\n Math.max(params.radiusBottom, params.radiusTop),\n params.height,\n segs,\n )\n geo.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n // radiusTop === 0 → 尖锥(ConeGeometry 顶点在顶);其余(含 radiusTop ===\n // radiusBottom 的等径圆柱/圆台)用 CylinderGeometry(radiusTop/bottom 各就各位)。\n let resultGeo: THREE.BufferGeometry\n if (params.radiusTop === 0) {\n resultGeo = geo\n } else {\n const geo2 = new THREE.CylinderGeometry(\n params.radiusTop,\n params.radiusBottom,\n params.height,\n segs,\n )\n geo2.applyMatrix4(new THREE.Matrix4().makeRotationX(Math.PI / 2))\n resultGeo = geo2\n }\n // geometry(rotateX 后)沿 z ∈ [-h/2, +h/2](three 默认 Y-up 居中):\n // 目标底面中心 in baseZ = (at?.[2] ?? 0) - (centered ? h/2 : 0) → 平坦平移 baseZ + h/2。\n const baseX = params.at?.[0] ?? 0\n const baseY = params.at?.[1] ?? 0\n const baseZ = (params.at?.[2] ?? 0) - (params.centered === true ? params.height / 2 : 0)\n resultGeo.translate(baseX, baseY, baseZ + params.height / 2)\n return geoToShape(resultGeo)\n}\n\n/**\n * Create a wedge (ramp) solid, fully parameterized and Z-up.\n *\n * @param params - wedge parameters (width, height, angle, length, optional center).\n * @returns the wedge shape.\n */\nexport function wedge(params: WedgeParams): Shape {\n const width = params.width\n const height = params.height\n const angle = params.angle\n const length = params.length\n\n const angleRad = (angle * Math.PI) / 180\n const halfExtrude = length / 2\n const hw = width / 2\n const halfTopWidth = Math.max(0, hw - height / Math.tan(angleRad))\n // 顶边塌缩(斜坡已在宽度内到顶)→ 三角棱柱(与 brep wedge 的退化处理一致,\n // 保证 mesh/brep 同参数 bbox 一致;零面积三角形会破坏 manifold)。\n const degenerate = halfTopWidth <= 1e-12\n\n const positions = degenerate\n ? new Float32Array([\n -halfExtrude, -hw, 0,\n -halfExtrude, hw, 0,\n -halfExtrude, 0, height,\n halfExtrude, -hw, 0,\n halfExtrude, hw, 0,\n halfExtrude, 0, height,\n ])\n : new Float32Array([\n -halfExtrude, -hw, 0,\n -halfExtrude, hw, 0,\n -halfExtrude, halfTopWidth, height,\n -halfExtrude, -halfTopWidth, height,\n halfExtrude, -hw, 0,\n halfExtrude, hw, 0,\n halfExtrude, halfTopWidth, height,\n halfExtrude, -halfTopWidth, height,\n ])\n\n const indices = degenerate\n ? new Uint32Array([\n 0, 1, 2, 3, 5, 4,\n 0, 3, 4, 0, 4, 1,\n 0, 2, 5, 0, 5, 3,\n 1, 4, 5, 1, 5, 2,\n ])\n : new Uint32Array([\n 0, 1, 2, 0, 2, 3,\n 4, 6, 5, 4, 7, 6,\n 0, 4, 5, 0, 5, 1,\n 3, 2, 6, 3, 6, 7,\n 0, 3, 7, 0, 7, 4,\n 1, 5, 6, 1, 6, 2,\n ])\n\n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geo.setIndex(new THREE.BufferAttribute(indices, 1))\n\n if (params.center) {\n geo.translate(params.center[0], params.center[1], params.center[2])\n }\n return geoToShape(geo)\n}\n\n/**\n * Create a screw (threaded) geometry.\n *\n * @param params - screw parameters (system, specIdx, thread, length, head, optional pitchCustom and nRad).\n * @returns the screw shape.\n */\nexport async function screw(params: {\n system: 'metric' | 'imperial'\n specIdx: number\n thread: 'coarse' | 'fine' | 'custom' | 'none'\n pitchCustom?: number\n length: number\n head: 'hex' | 'chc' | 'none'\n nRad?: number\n}): Promise<Shape> {\n const { makeScrew } = await import('../primitives/screw/screw')\n const geo = makeScrew({\n system: params.system,\n specIdx: params.specIdx,\n thread: params.thread,\n pitchCustom: params.pitchCustom ?? 0,\n length: params.length,\n head: params.head,\n nRad: clampNRad(params.nRad),\n })\n return geoToShape(geo)\n}\n\n/**\n * Create a mesh from SDF (signed distance field) code, sampling the field with\n * marching cubes.\n *\n * @param params - SDF parameters (code, optional bounds, params, resolution).\n * @returns the sampled shape.\n */\nexport async function sdf(params: SdfParams): Promise<Shape> {\n const { runSdf } = await import('../sdf/sdf-runner')\n const box = params.box ?? [[-10, -10, -10], [10, 10, 10]]\n const bounds: [number, number, number, number, number, number] = [\n box[0][0], box[0][1], box[0][2],\n box[1][0], box[1][1], box[1][2],\n ]\n const mesh = await runSdf(\n params.code,\n params.params ?? {},\n bounds,\n params.resolution ?? 1.0,\n )\n return { positions: mesh.positions, indices: mesh.indices }\n}\n"]}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stl-loader — minimal STL parser (binary + ASCII), zero addons.
|
|
3
|
+
*
|
|
4
|
+
* Why hand-written: three's `STLLoader` lives in `three/examples/jsm/`, which is
|
|
5
|
+
* outside three's version-compatibility promise and would pull a second,
|
|
6
|
+
* unpinnable module into every faijs consumer — including the weapp worker,
|
|
7
|
+
* whose bundle must stay free of the addons. Precedent: `mesh/creased-normals.ts`
|
|
8
|
+
* ports three's `toCreasedNormals` for exactly this reason.
|
|
9
|
+
*
|
|
10
|
+
* Output matches `STLLoader.parse()`: a non-indexed `BufferGeometry` carrying
|
|
11
|
+
* `position` (one vertex triple per triangle, duplicates preserved) and `normal`
|
|
12
|
+
* attributes, so callers can keep using `geoToManifoldMesh` for welding.
|
|
13
|
+
*/
|
|
14
|
+
import * as THREE from 'three';
|
|
15
|
+
/**
|
|
16
|
+
* Parse STL bytes into a non-indexed BufferGeometry.
|
|
17
|
+
*
|
|
18
|
+
* @param buffer - the raw STL file bytes (binary or ASCII).
|
|
19
|
+
* @returns the parsed geometry (empty when the file holds no triangle).
|
|
20
|
+
* @throws when the buffer is neither a well-formed binary nor ASCII STL.
|
|
21
|
+
*/
|
|
22
|
+
export declare function parseStl(buffer: ArrayBuffer): THREE.BufferGeometry;
|
|
23
|
+
//# sourceMappingURL=stl-loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stl-loader.d.ts","sourceRoot":"","sources":["../../src/mesh/stl-loader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA4H9B;;;;;;GAMG;AACH,wBAAgB,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAAC,cAAc,CAKlE"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* stl-loader — minimal STL parser (binary + ASCII), zero addons.
|
|
3
|
+
*
|
|
4
|
+
* Why hand-written: three's `STLLoader` lives in `three/examples/jsm/`, which is
|
|
5
|
+
* outside three's version-compatibility promise and would pull a second,
|
|
6
|
+
* unpinnable module into every faijs consumer — including the weapp worker,
|
|
7
|
+
* whose bundle must stay free of the addons. Precedent: `mesh/creased-normals.ts`
|
|
8
|
+
* ports three's `toCreasedNormals` for exactly this reason.
|
|
9
|
+
*
|
|
10
|
+
* Output matches `STLLoader.parse()`: a non-indexed `BufferGeometry` carrying
|
|
11
|
+
* `position` (one vertex triple per triangle, duplicates preserved) and `normal`
|
|
12
|
+
* attributes, so callers can keep using `geoToManifoldMesh` for welding.
|
|
13
|
+
*/
|
|
14
|
+
import * as THREE from 'three';
|
|
15
|
+
/** Binary STL layout: 80-byte header + uint32 count + 50 bytes per triangle. */
|
|
16
|
+
const BINARY_HEADER_BYTES = 80;
|
|
17
|
+
const BINARY_TRIANGLE_BYTES = 50;
|
|
18
|
+
/**
|
|
19
|
+
* Decide whether `buffer` is a binary STL by checking the declared triangle
|
|
20
|
+
* count against the file size (the same test `STLLoader` uses).
|
|
21
|
+
*
|
|
22
|
+
* @param buffer - the raw file bytes.
|
|
23
|
+
* @returns true when the buffer is binary STL.
|
|
24
|
+
*/
|
|
25
|
+
function isBinaryStl(buffer) {
|
|
26
|
+
if (buffer.byteLength < BINARY_HEADER_BYTES + 4)
|
|
27
|
+
return false;
|
|
28
|
+
const view = new DataView(buffer);
|
|
29
|
+
const triangles = view.getUint32(BINARY_HEADER_BYTES, true);
|
|
30
|
+
if (triangles === 0)
|
|
31
|
+
return false;
|
|
32
|
+
return BINARY_HEADER_BYTES + 4 + triangles * BINARY_TRIANGLE_BYTES === buffer.byteLength;
|
|
33
|
+
}
|
|
34
|
+
/** Normalize a triangle normal, falling back to the geometric one. */
|
|
35
|
+
function normalOf(ax, ay, az, bx, by, bz, cx, cy, cz) {
|
|
36
|
+
const ux = bx - ax, uy = by - ay, uz = bz - az;
|
|
37
|
+
const vx = cx - ax, vy = cy - ay, vz = cz - az;
|
|
38
|
+
const nx = uy * vz - uz * vy;
|
|
39
|
+
const ny = uz * vx - ux * vz;
|
|
40
|
+
const nz = ux * vy - uy * vx;
|
|
41
|
+
const len = Math.hypot(nx, ny, nz);
|
|
42
|
+
if (len < 1e-20)
|
|
43
|
+
return [0, 0, 0];
|
|
44
|
+
return [nx / len, ny / len, nz / len];
|
|
45
|
+
}
|
|
46
|
+
function parseBinary(buffer) {
|
|
47
|
+
const view = new DataView(buffer);
|
|
48
|
+
const triangles = view.getUint32(BINARY_HEADER_BYTES, true);
|
|
49
|
+
const positions = new Float32Array(triangles * 9);
|
|
50
|
+
const normals = new Float32Array(triangles * 9);
|
|
51
|
+
let offset = BINARY_HEADER_BYTES + 4;
|
|
52
|
+
for (let t = 0; t < triangles; t++) {
|
|
53
|
+
// Stored facet normal — used when it is a usable unit vector.
|
|
54
|
+
let nx = view.getFloat32(offset, true);
|
|
55
|
+
let ny = view.getFloat32(offset + 4, true);
|
|
56
|
+
let nz = view.getFloat32(offset + 8, true);
|
|
57
|
+
const stored = Math.hypot(nx, ny, nz);
|
|
58
|
+
offset += 12;
|
|
59
|
+
const base = t * 9;
|
|
60
|
+
for (let v = 0; v < 3; v++) {
|
|
61
|
+
positions[base + v * 3] = view.getFloat32(offset, true);
|
|
62
|
+
positions[base + v * 3 + 1] = view.getFloat32(offset + 4, true);
|
|
63
|
+
positions[base + v * 3 + 2] = view.getFloat32(offset + 8, true);
|
|
64
|
+
offset += 12;
|
|
65
|
+
}
|
|
66
|
+
if (stored < 1e-20) {
|
|
67
|
+
;
|
|
68
|
+
[nx, ny, nz] = normalOf(positions[base], positions[base + 1], positions[base + 2], positions[base + 3], positions[base + 4], positions[base + 5], positions[base + 6], positions[base + 7], positions[base + 8]);
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
nx /= stored;
|
|
72
|
+
ny /= stored;
|
|
73
|
+
nz /= stored;
|
|
74
|
+
}
|
|
75
|
+
for (let v = 0; v < 3; v++) {
|
|
76
|
+
normals[base + v * 3] = nx;
|
|
77
|
+
normals[base + v * 3 + 1] = ny;
|
|
78
|
+
normals[base + v * 3 + 2] = nz;
|
|
79
|
+
}
|
|
80
|
+
offset += 2; // attribute byte count
|
|
81
|
+
}
|
|
82
|
+
const geo = new THREE.BufferGeometry();
|
|
83
|
+
geo.setAttribute('position', new THREE.BufferAttribute(positions, 3));
|
|
84
|
+
geo.setAttribute('normal', new THREE.BufferAttribute(normals, 3));
|
|
85
|
+
return geo;
|
|
86
|
+
}
|
|
87
|
+
function parseAscii(buffer) {
|
|
88
|
+
const text = new TextDecoder().decode(new Uint8Array(buffer));
|
|
89
|
+
const vertices = [];
|
|
90
|
+
const normals = [];
|
|
91
|
+
let facetNormal = null;
|
|
92
|
+
const pending = [];
|
|
93
|
+
const flush = () => {
|
|
94
|
+
if (pending.length !== 9)
|
|
95
|
+
return;
|
|
96
|
+
vertices.push(...pending);
|
|
97
|
+
const n = facetNormal ?? normalOf(pending[0], pending[1], pending[2], pending[3], pending[4], pending[5], pending[6], pending[7], pending[8]);
|
|
98
|
+
for (let v = 0; v < 3; v++)
|
|
99
|
+
normals.push(n[0], n[1], n[2]);
|
|
100
|
+
pending.length = 0;
|
|
101
|
+
};
|
|
102
|
+
for (const rawLine of text.split('\n')) {
|
|
103
|
+
const line = rawLine.trim();
|
|
104
|
+
if (line.startsWith('facet normal')) {
|
|
105
|
+
flush();
|
|
106
|
+
const parts = line.split(/\s+/);
|
|
107
|
+
facetNormal = [Number(parts[2]), Number(parts[3]), Number(parts[4])];
|
|
108
|
+
continue;
|
|
109
|
+
}
|
|
110
|
+
if (line.startsWith('vertex')) {
|
|
111
|
+
const parts = line.split(/\s+/);
|
|
112
|
+
pending.push(Number(parts[1]), Number(parts[2]), Number(parts[3]));
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (line.startsWith('endfacet')) {
|
|
116
|
+
flush();
|
|
117
|
+
facetNormal = null;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
flush();
|
|
121
|
+
const geo = new THREE.BufferGeometry();
|
|
122
|
+
geo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3));
|
|
123
|
+
geo.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3));
|
|
124
|
+
return geo;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Parse STL bytes into a non-indexed BufferGeometry.
|
|
128
|
+
*
|
|
129
|
+
* @param buffer - the raw STL file bytes (binary or ASCII).
|
|
130
|
+
* @returns the parsed geometry (empty when the file holds no triangle).
|
|
131
|
+
* @throws when the buffer is neither a well-formed binary nor ASCII STL.
|
|
132
|
+
*/
|
|
133
|
+
export function parseStl(buffer) {
|
|
134
|
+
if (buffer.byteLength === 0) {
|
|
135
|
+
throw new Error('[mesh/stl-loader] empty STL buffer');
|
|
136
|
+
}
|
|
137
|
+
return isBinaryStl(buffer) ? parseBinary(buffer) : parseAscii(buffer);
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=stl-loader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stl-loader.js","sourceRoot":"","sources":["../../src/mesh/stl-loader.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stl-loader — minimal STL parser (binary + ASCII), zero addons.\n *\n * Why hand-written: three's `STLLoader` lives in `three/examples/jsm/`, which is\n * outside three's version-compatibility promise and would pull a second,\n * unpinnable module into every faijs consumer — including the weapp worker,\n * whose bundle must stay free of the addons. Precedent: `mesh/creased-normals.ts`\n * ports three's `toCreasedNormals` for exactly this reason.\n *\n * Output matches `STLLoader.parse()`: a non-indexed `BufferGeometry` carrying\n * `position` (one vertex triple per triangle, duplicates preserved) and `normal`\n * attributes, so callers can keep using `geoToManifoldMesh` for welding.\n */\nimport * as THREE from 'three'\n\n/** Binary STL layout: 80-byte header + uint32 count + 50 bytes per triangle. */\nconst BINARY_HEADER_BYTES = 80\nconst BINARY_TRIANGLE_BYTES = 50\n\n/**\n * Decide whether `buffer` is a binary STL by checking the declared triangle\n * count against the file size (the same test `STLLoader` uses).\n *\n * @param buffer - the raw file bytes.\n * @returns true when the buffer is binary STL.\n */\nfunction isBinaryStl(buffer: ArrayBuffer): boolean {\n if (buffer.byteLength < BINARY_HEADER_BYTES + 4) return false\n const view = new DataView(buffer)\n const triangles = view.getUint32(BINARY_HEADER_BYTES, true)\n if (triangles === 0) return false\n return BINARY_HEADER_BYTES + 4 + triangles * BINARY_TRIANGLE_BYTES === buffer.byteLength\n}\n\n/** Normalize a triangle normal, falling back to the geometric one. */\nfunction normalOf(\n ax: number, ay: number, az: number,\n bx: number, by: number, bz: number,\n cx: number, cy: number, cz: number,\n): [number, number, number] {\n const ux = bx - ax, uy = by - ay, uz = bz - az\n const vx = cx - ax, vy = cy - ay, vz = cz - az\n const nx = uy * vz - uz * vy\n const ny = uz * vx - ux * vz\n const nz = ux * vy - uy * vx\n const len = Math.hypot(nx, ny, nz)\n if (len < 1e-20) return [0, 0, 0]\n return [nx / len, ny / len, nz / len]\n}\n\nfunction parseBinary(buffer: ArrayBuffer): THREE.BufferGeometry {\n const view = new DataView(buffer)\n const triangles = view.getUint32(BINARY_HEADER_BYTES, true)\n const positions = new Float32Array(triangles * 9)\n const normals = new Float32Array(triangles * 9)\n let offset = BINARY_HEADER_BYTES + 4\n for (let t = 0; t < triangles; t++) {\n // Stored facet normal — used when it is a usable unit vector.\n let nx = view.getFloat32(offset, true)\n let ny = view.getFloat32(offset + 4, true)\n let nz = view.getFloat32(offset + 8, true)\n const stored = Math.hypot(nx, ny, nz)\n offset += 12\n const base = t * 9\n for (let v = 0; v < 3; v++) {\n positions[base + v * 3] = view.getFloat32(offset, true)\n positions[base + v * 3 + 1] = view.getFloat32(offset + 4, true)\n positions[base + v * 3 + 2] = view.getFloat32(offset + 8, true)\n offset += 12\n }\n if (stored < 1e-20) {\n ;[nx, ny, nz] = normalOf(\n positions[base], positions[base + 1], positions[base + 2],\n positions[base + 3], positions[base + 4], positions[base + 5],\n positions[base + 6], positions[base + 7], positions[base + 8],\n )\n } else {\n nx /= stored; ny /= stored; nz /= stored\n }\n for (let v = 0; v < 3; v++) {\n normals[base + v * 3] = nx\n normals[base + v * 3 + 1] = ny\n normals[base + v * 3 + 2] = nz\n }\n offset += 2 // attribute byte count\n }\n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.BufferAttribute(positions, 3))\n geo.setAttribute('normal', new THREE.BufferAttribute(normals, 3))\n return geo\n}\n\nfunction parseAscii(buffer: ArrayBuffer): THREE.BufferGeometry {\n const text = new TextDecoder().decode(new Uint8Array(buffer))\n const vertices: number[] = []\n const normals: number[] = []\n let facetNormal: [number, number, number] | null = null\n const pending: number[] = []\n\n const flush = (): void => {\n if (pending.length !== 9) return\n vertices.push(...pending)\n const n = facetNormal ?? normalOf(\n pending[0], pending[1], pending[2],\n pending[3], pending[4], pending[5],\n pending[6], pending[7], pending[8],\n )\n for (let v = 0; v < 3; v++) normals.push(n[0], n[1], n[2])\n pending.length = 0\n }\n\n for (const rawLine of text.split('\\n')) {\n const line = rawLine.trim()\n if (line.startsWith('facet normal')) {\n flush()\n const parts = line.split(/\\s+/)\n facetNormal = [Number(parts[2]), Number(parts[3]), Number(parts[4])]\n continue\n }\n if (line.startsWith('vertex')) {\n const parts = line.split(/\\s+/)\n pending.push(Number(parts[1]), Number(parts[2]), Number(parts[3]))\n continue\n }\n if (line.startsWith('endfacet')) {\n flush()\n facetNormal = null\n }\n }\n flush()\n\n const geo = new THREE.BufferGeometry()\n geo.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3))\n geo.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(normals), 3))\n return geo\n}\n\n/**\n * Parse STL bytes into a non-indexed BufferGeometry.\n *\n * @param buffer - the raw STL file bytes (binary or ASCII).\n * @returns the parsed geometry (empty when the file holds no triangle).\n * @throws when the buffer is neither a well-formed binary nor ASCII STL.\n */\nexport function parseStl(buffer: ArrayBuffer): THREE.BufferGeometry {\n if (buffer.byteLength === 0) {\n throw new Error('[mesh/stl-loader] empty STL buffer')\n }\n return isBinaryStl(buffer) ? parseBinary(buffer) : parseAscii(buffer)\n}\n"]}
|