@faicad/faijs 0.13.2 → 0.14.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.map +1 -1
- package/dist/api/api-namespace.js +30 -4
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/boolean.d.ts +19 -0
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +51 -10
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +8 -7
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/compound-geom.d.ts +45 -0
- package/dist/api/compound-geom.d.ts.map +1 -0
- package/dist/api/compound-geom.js +85 -0
- package/dist/api/compound-geom.js.map +1 -0
- package/dist/api/compound.d.ts +2 -0
- package/dist/api/compound.d.ts.map +1 -1
- package/dist/api/compound.js +2 -0
- package/dist/api/compound.js.map +1 -1
- package/dist/api/copy.d.ts +1 -0
- package/dist/api/copy.d.ts.map +1 -1
- package/dist/api/copy.js +4 -2
- package/dist/api/copy.js.map +1 -1
- package/dist/api/edge-ref.d.ts.map +1 -1
- package/dist/api/edge-ref.js +7 -4
- package/dist/api/edge-ref.js.map +1 -1
- package/dist/api/engrave.d.ts.map +1 -1
- package/dist/api/engrave.js +1 -0
- package/dist/api/engrave.js.map +1 -1
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +131 -3
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/face-ref.d.ts.map +1 -1
- package/dist/api/face-ref.js +7 -4
- package/dist/api/face-ref.js.map +1 -1
- package/dist/api/fai_drill.d.ts +1 -1
- package/dist/api/fai_drill.d.ts.map +1 -1
- package/dist/api/fai_drill.js +31 -18
- package/dist/api/fai_drill.js.map +1 -1
- package/dist/api/fai_extrude.d.ts +1 -1
- package/dist/api/fai_extrude.d.ts.map +1 -1
- package/dist/api/fai_extrude.js +2 -1
- package/dist/api/fai_extrude.js.map +1 -1
- package/dist/api/fai_split.d.ts +1 -1
- package/dist/api/fai_split.d.ts.map +1 -1
- package/dist/api/fai_split.js +2 -1
- package/dist/api/fai_split.js.map +1 -1
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +6 -5
- package/dist/api/fillet.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 -48
- package/dist/api/generated/topology.d.ts.map +1 -1
- package/dist/api/generated/topology.js +20 -62
- package/dist/api/generated/topology.js.map +1 -1
- package/dist/api/import-brep.d.ts +36 -0
- package/dist/api/import-brep.d.ts.map +1 -0
- package/dist/api/import-brep.js +72 -0
- package/dist/api/import-brep.js.map +1 -0
- package/dist/api/import-step.d.ts +28 -0
- package/dist/api/import-step.d.ts.map +1 -0
- package/dist/api/import-step.js +57 -0
- package/dist/api/import-step.js.map +1 -0
- package/dist/api/index.d.ts +7 -2
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +19 -5
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-op.d.ts.map +1 -1
- package/dist/api/internal/compat-op.js +2 -1
- package/dist/api/internal/compat-op.js.map +1 -1
- package/dist/api/knurl.d.ts.map +1 -1
- package/dist/api/knurl.js +1 -0
- package/dist/api/knurl.js.map +1 -1
- package/dist/api/load.d.ts +3 -1
- package/dist/api/load.d.ts.map +1 -1
- package/dist/api/load.js +3 -1
- package/dist/api/load.js.map +1 -1
- package/dist/api/pattern.d.ts +32 -0
- package/dist/api/pattern.d.ts.map +1 -0
- package/dist/api/pattern.js +121 -0
- package/dist/api/pattern.js.map +1 -0
- package/dist/api/place.d.ts +35 -0
- package/dist/api/place.d.ts.map +1 -0
- package/dist/api/place.js +113 -0
- package/dist/api/place.js.map +1 -0
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +10 -3
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/screw.d.ts.map +1 -1
- package/dist/api/screw.js +1 -0
- package/dist/api/screw.js.map +1 -1
- package/dist/api/sdf.d.ts.map +1 -1
- package/dist/api/sdf.js +1 -0
- package/dist/api/sdf.js.map +1 -1
- package/dist/api/sketch.d.ts.map +1 -1
- package/dist/api/sketch.js +1 -0
- package/dist/api/sketch.js.map +1 -1
- package/dist/api/split.d.ts +31 -0
- package/dist/api/split.d.ts.map +1 -0
- package/dist/api/split.js +96 -0
- package/dist/api/split.js.map +1 -0
- package/dist/api/surface/arg-spec.d.ts +9 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js +49 -30
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/svgExtrude.d.ts.map +1 -1
- package/dist/api/svgExtrude.js +1 -0
- package/dist/api/svgExtrude.js.map +1 -1
- package/dist/api/text.d.ts.map +1 -1
- package/dist/api/text.js +1 -0
- package/dist/api/text.js.map +1 -1
- package/dist/api/topo-resolve.d.ts.map +1 -1
- package/dist/api/topo-resolve.js +65 -3
- package/dist/api/topo-resolve.js.map +1 -1
- package/dist/api/transform.d.ts +4 -0
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +44 -12
- package/dist/api/transform.js.map +1 -1
- package/dist/brep/brep-ops.d.ts +34 -1
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +62 -22
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +8 -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 +6 -1
- package/dist/brep/engine/adapters/brepkit.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
- package/dist/brep/engine/adapters/occt.js +24 -1
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +17 -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 +49 -6
- package/dist/brep/engine/types.d.ts.map +1 -1
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brep/export/step.d.ts.map +1 -1
- package/dist/brep/export/step.js +6 -1
- package/dist/brep/export/step.js.map +1 -1
- package/dist/brep/face-evolution.d.ts +78 -8
- package/dist/brep/face-evolution.d.ts.map +1 -1
- package/dist/brep/face-evolution.js +130 -17
- package/dist/brep/face-evolution.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +27 -1
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts +19 -1
- package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
- package/dist/cad-runtime/admit-compat-lib.js +21 -1
- package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.d.ts +44 -3
- package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +46 -3
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.d.ts +2 -0
- package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.js +9 -1
- package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +14 -4
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/module-registry.d.ts +3 -1
- package/dist/cad-runtime/module-registry.d.ts.map +1 -1
- package/dist/cad-runtime/module-registry.js +13 -1
- package/dist/cad-runtime/module-registry.js.map +1 -1
- package/dist/cad-runtime/ports.d.ts +7 -0
- package/dist/cad-runtime/ports.d.ts.map +1 -1
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/runtime-concurrent-error.d.ts +38 -0
- package/dist/cad-runtime/runtime-concurrent-error.d.ts.map +1 -0
- package/dist/cad-runtime/runtime-concurrent-error.js +43 -0
- package/dist/cad-runtime/runtime-concurrent-error.js.map +1 -0
- package/dist/cad-runtime/runtime.d.ts +54 -2
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +186 -10
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +22 -0
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +82 -12
- package/dist/define-op.js.map +1 -1
- package/dist/fcstd/attachment.d.ts +8 -1
- package/dist/fcstd/attachment.d.ts.map +1 -1
- package/dist/fcstd/attachment.js +7 -1
- package/dist/fcstd/attachment.js.map +1 -1
- package/dist/fcstd/build-fai-zip.d.ts.map +1 -1
- package/dist/fcstd/build-fai-zip.js +12 -7
- package/dist/fcstd/build-fai-zip.js.map +1 -1
- package/dist/fcstd/codegen.d.ts +10 -1
- package/dist/fcstd/codegen.d.ts.map +1 -1
- package/dist/fcstd/codegen.js +150 -48
- package/dist/fcstd/codegen.js.map +1 -1
- package/dist/fcstd/contour.d.ts.map +1 -1
- package/dist/fcstd/contour.js +23 -24
- package/dist/fcstd/contour.js.map +1 -1
- package/dist/fcstd/convert.d.ts +2 -18
- package/dist/fcstd/convert.d.ts.map +1 -1
- package/dist/fcstd/convert.js +35 -53
- package/dist/fcstd/convert.js.map +1 -1
- package/dist/fcstd/external-geo.d.ts +12 -1
- package/dist/fcstd/external-geo.d.ts.map +1 -1
- package/dist/fcstd/external-geo.js +15 -1
- package/dist/fcstd/external-geo.js.map +1 -1
- package/dist/fcstd/feature-translate.d.ts +21 -1
- package/dist/fcstd/feature-translate.d.ts.map +1 -1
- package/dist/fcstd/feature-translate.js +108 -6
- package/dist/fcstd/feature-translate.js.map +1 -1
- package/dist/fcstd/structural-types.d.ts +83 -0
- package/dist/fcstd/structural-types.d.ts.map +1 -0
- package/dist/fcstd/structural-types.js +116 -0
- package/dist/fcstd/structural-types.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lang/determinism-scanner.d.ts +62 -0
- package/dist/lang/determinism-scanner.d.ts.map +1 -0
- package/dist/lang/determinism-scanner.js +619 -0
- package/dist/lang/determinism-scanner.js.map +1 -0
- package/dist/lang/symbol-table.generated.d.ts +7 -3
- package/dist/lang/symbol-table.generated.d.ts.map +1 -1
- package/dist/lang/symbol-table.generated.js +7 -3
- package/dist/lang/symbol-table.generated.js.map +1 -1
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +3 -2
- package/dist/mesh/index.js.map +1 -1
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +56 -2
- package/dist/node-host/cli.js.map +1 -1
- package/dist/runtime-state.d.ts +18 -6
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +9 -1
- package/dist/runtime-state.js.map +1 -1
- package/dist/shape.d.ts +15 -0
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +26 -3
- package/dist/shape.js.map +1 -1
- package/dist/topology/naming/build-naming.d.ts +14 -30
- package/dist/topology/naming/build-naming.d.ts.map +1 -1
- package/dist/topology/naming/build-naming.js +21 -54
- package/dist/topology/naming/build-naming.js.map +1 -1
- package/dist/topology/naming/capture-topo-ref.d.ts.map +1 -1
- package/dist/topology/naming/capture-topo-ref.js +5 -0
- package/dist/topology/naming/capture-topo-ref.js.map +1 -1
- package/dist/topology/naming/index.d.ts +3 -0
- package/dist/topology/naming/index.d.ts.map +1 -1
- package/dist/topology/naming/index.js +3 -0
- package/dist/topology/naming/index.js.map +1 -1
- package/dist/topology/naming/lineage-resolve.d.ts +80 -0
- package/dist/topology/naming/lineage-resolve.d.ts.map +1 -0
- package/dist/topology/naming/lineage-resolve.js +120 -0
- package/dist/topology/naming/lineage-resolve.js.map +1 -0
- package/dist/topology/naming/lineage.d.ts +349 -0
- package/dist/topology/naming/lineage.d.ts.map +1 -0
- package/dist/topology/naming/lineage.js +398 -0
- package/dist/topology/naming/lineage.js.map +1 -0
- package/dist/topology/naming/migrate.d.ts +41 -0
- package/dist/topology/naming/migrate.d.ts.map +1 -0
- package/dist/topology/naming/migrate.js +88 -0
- package/dist/topology/naming/migrate.js.map +1 -0
- package/dist/topology/naming/role-name.d.ts +176 -0
- package/dist/topology/naming/role-name.d.ts.map +1 -0
- package/dist/topology/naming/role-name.js +344 -0
- package/dist/topology/naming/role-name.js.map +1 -0
- package/dist/topology/naming/roles.d.ts +20 -22
- package/dist/topology/naming/roles.d.ts.map +1 -1
- package/dist/topology/naming/roles.js +51 -49
- package/dist/topology/naming/roles.js.map +1 -1
- package/dist/topology/naming/types.d.ts +65 -18
- package/dist/topology/naming/types.d.ts.map +1 -1
- package/dist/topology/naming/types.js.map +1 -1
- package/dist/weapp.d.ts +1 -1
- package/dist/weapp.d.ts.map +1 -1
- package/dist/weapp.js +1 -1
- package/dist/weapp.js.map +1 -1
- package/package.json +1 -1
package/dist/api/extrude.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"extrude.js","sourceRoot":"","sources":["../../src/api/extrude.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib extrude — `cad.extrude`(平台 parity op,BREP-only)\n *\n * 归属(分层红线):`cad.extrude` 是「面 → 棱柱」的**平台** op,FCStd Pad/Pocket\n * 链路与 TS 面共用它(docs/plans/2026-09-15-fcstd-to-faijs-port-plan.md M4.6:\n * 「原 `cad.fai_extrude` 路线废弃」)。up-to(拉伸到面 / 到支持体端面)属\n * CadQuery `until=` 同族语义,因此落在**本 op**;`fai_extrude`(`fai_` 前缀的\n * faijs 扩展 op,与 fai_drill / fai_split 同族)不得承载它。\n *\n * 为什么是手写 op 而不是继续用生成投影:生成投影\n * `compatOp(projectBrepOp('extrude', ['face','height'], 'A', vendoredExtrude))`\n * 有两个硬约束——\n * ① 参数表只有位置形参;D11 归一化只在「单 plain-object 形态」下按 params 表\n * 映射(api/internal/dual-form-args.ts),`(face, { upTo })` 属位置形态 →\n * 原样喂给 vendored extrude → 报错,无法表达对象形态;\n * ② compatOp 的入参先经 `borrowDeep` 借成 brepjs 视图(api/internal/compat-op.ts),\n * 在那一层 `brepOf()` 取不到 → 依赖 faceRef / brepOf / 内核直调的 up-to 实现\n * 必然走空(同 AGENTS.md 记录的「compatOp 自动提升边界」)。\n * 先例:arg-spec 的 `fillet` 条目(faijs 侧由手写 dual-op 覆盖,生成模块符号为\n * 孤儿 by design)。\n *\n * 长度形态**委托给生成投影**(`projectedExtrude`):vendored 仍是唯一拉伸引擎,\n * 既有 `cad.extrude(face, [x,y,z])` 语义零漂移。\n */\n\nimport { extrude as projectedExtrude } from './generated/operations'\nimport * as THREE from 'three'\nimport { solidToShape, matrixToArray } from '../brep/brep-ops'\nimport { getSolidBoundingBox } from '../brep/brep-utils'\nimport { getBackends } from '../runtime-state'\nimport { fromBrep, brepOf } from '../shape'\nimport { defineOp } from '../sdk'\nimport { assertPositiveNumber } from './assert'\nimport type { Shape, Vec3 } from '../mesh/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { TopoRefError } from '../topology/naming'\n\n/** 显式平面目标(up-to 截断面):点 + 法向(点在平面上即可,无需共面于面边界)。 */\nexport interface UpToPlaneSpec {\n /** 平面上一点(世界坐标)。type:[x,y,z] */\n point: Vec3\n /** 平面法向(世界坐标,方向仅定半空间语义,截断取两侧之一)。type:[x,y,z] */\n normal: Vec3\n}\n\n/** up-to 目标:显式面引用 / 显式平面 / 支持体沿拉伸方向的远端(last)/近端(first)端面。 */\nexport type ExtrudeUpTo = FaceTopoRef | 'last' | 'first' | { plane: UpToPlaneSpec }\n\n/** `cad.extrude` 的对象形态参数(位置形态由 {@link normalizeExtrudeOptions} 归一到这里)。 */\nexport interface ExtrudeOptions {\n /** 拉伸量(mm,>0)。up-to 模式下无需给。 */\n length?: number\n /** 拉伸方向(世界坐标);缺省 [0,0,1]。 */\n normal?: Vec3\n /** 沿 normal 的前进方向;缺省 'forward'('backward' 等价于方向取反)。 */\n mode?: 'forward' | 'backward'\n /** 拉伸到面 / 到支持体端面;提供时忽略 length。 */\n upTo?: ExtrudeUpTo\n /** upTo 'last'/'first' 的支持体(累积支持体,由转换器显式传入)。 */\n baseFeature?: Shape\n /** 截断面沿其法向的偏移(mm);缺省 0。 */\n offset?: number\n}\n\n/** 判定是否为朴素对象(对象形态判别器,避免误吞 Shape / 数组)。 */\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v) && Object.getPrototypeOf(v) === Object.prototype\n}\n\n/**\n * 归一化 `cad.extrude` 的两种调用形态。\n *\n * - 位置形态(与生成投影同款,历史产物在用):`cad.extrude(face, 10)` /\n * `cad.extrude(face, [x,y,z])`——向量即「方向 × 长度」,恒为沿该方向前进。\n * - 对象形态(faijs 面):`cad.extrude(face, { length, normal, mode, upTo, ... })`。\n *\n * @param params - 调用点第二实参(数字 / 向量 / 对象)。\n * @returns 归一化后的对象形态参数。\n * @throws Error 参数既非数字 / 向量 / 朴素对象时(不猜)。\n */\nfunction normalizeExtrudeOptions(params: unknown): ExtrudeOptions {\n if (isPlainObject(params)) return params as ExtrudeOptions\n if (Array.isArray(params)) {\n const v = params as Vec3\n const len = Math.hypot(v[0] ?? 0, v[1] ?? 0, v[2] ?? 0)\n if (!Number.isFinite(len) || len < 1e-12) {\n throw new Error('E_EXTRUDE_ZERO_VECTOR: extrude direction vector has zero length')\n }\n return { length: len, normal: [v[0] / len, v[1] / len, v[2] / len], mode: 'forward' }\n }\n if (typeof params === 'number') return { length: params, normal: [0, 0, 1], mode: 'forward' }\n throw new Error('E_EXTRUDE_BAD_PARAMS: extrude expects (face, number | [x,y,z] | { length | upTo, ... })')\n}\n\n/**\n * 参数自校验:up-to 模式下无需 length;否则 length 必须为正数。\n *\n * @param o - 归一化后的参数。\n */\nfunction assertExtrudeOptions(o: ExtrudeOptions): void {\n if (o.upTo !== undefined) return // up-to 模式:长度由目标面决定\n assertPositiveNumber(o.length, 'extrude.length')\n}\n\n/** bbox 对角线长度(长试探的余量基数)。 */\nfunction bboxDiag(bbox: { min: Vec3; max: Vec3 }): number {\n return Math.hypot(bbox.max[0] - bbox.min[0], bbox.max[1] - bbox.min[1], bbox.max[2] - bbox.min[2])\n}\n\n/**\n * 目标面法向负侧的半空间覆盖盒(截断长拉伸用)——定向版。\n *\n * GOTCHA(PadTest Pad001 斜置基准面实测):轴对齐盒的边界不是斜面本身,\n * 截断呈台阶而非精确斜平面(体积 7076 vs 真值 4860)。正确做法:在局部基\n * (u, v, n) 里构造盒(深度沿 −n 伸出 R、横向 ±R),再用 kernel.transform\n * 旋到世界系——盒的 n=R 端面就是精确的目标平面。\n *\n * @param kernel - BREP 内核。\n * @param faceCenter - 目标面中心(世界坐标,盒的 n=0 端面过此点)。\n * @param faceNormal - 目标面法向(半空间保留 −n 侧…即盒占据 −n 侧深度)。\n * @param reach - 覆盖半径 R。\n * @returns 定向半空间盒的 brep 句柄。\n */\nfunction farSideBox(kernel: BrepEngineApi, faceCenter: Vec3, faceNormal: Vec3, reach: number): BrepHandle {\n const unit = new THREE.Vector3(...faceNormal).normalize()\n const center = new THREE.Vector3(...faceCenter)\n // 与 n 正交的正交基 u,v\n const aux = Math.abs(unit.y) < 0.9 ? new THREE.Vector3(0, 1, 0) : new THREE.Vector3(1, 0, 0)\n const u = new THREE.Vector3().crossVectors(unit, aux).normalize()\n const v = new THREE.Vector3().crossVectors(unit, u).normalize()\n const R = reach\n // 局部系盒:x∈[−R,R] (u), y∈[−R,R] (v), z∈[−R,0] (n 深度侧)\n const box = kernel.makeBoxFromCorners(\n { x: -R, y: -R, z: -R },\n { x: R, y: R, z: 0 },\n )\n // 旋转矩阵:列 = u, v, n;平移 = center(局部 z=0 端面落到过 center 的目标平面)\n const m = new THREE.Matrix4().makeBasis(u, v, unit).setPosition(center)\n return kernel.transform(box, matrixToArray(m))\n}\n\n/**\n * up-to 拉伸:occt-wasm 未暴露 `BRepFeat_MakePrism`,用「长拉伸 → 与目标面侧\n * 半空间盒求交」等价组合;长试探上限只作布尔构造辅助,不进入结果几何。\n *\n * @param kernel - BREP 内核。\n * @param inputSolid - 轮廓实体句柄。\n * @param o - 归一化参数(需带 upTo)。\n * @returns 截断后的实体句柄。\n * @throws Error E_UP_TO_* 系列:缺支持体 / 方向与目标面平行 / 不相交(禁静默)。\n */\nfunction extrudeUpToSolid(kernel: BrepEngineApi, inputSolid: BrepHandle, o: ExtrudeOptions): BrepHandle {\n const normal = new THREE.Vector3(...(o.normal ?? [0, 0, 1])).normalize()\n const offset = o.offset ?? 0\n const upTo = o.upTo as ExtrudeUpTo\n\n // 1) 方向目标:FaceTopoRef → 现场面几何;'last'/'first' → baseFeature 支持体\n // 沿拉伸方向的端面(远端 last / 近端 first)。\n let targetCenter: Vec3\n let targetNormal: Vec3\n if (typeof upTo === 'string') {\n const base = o.baseFeature\n const baseSolid = base ? (brepOf(base) as BrepHandle | undefined) : undefined\n if (!baseSolid) {\n throw new Error('E_UP_TO_NO_BASE: upTo \"last\"/\"first\" requires a baseFeature shape')\n }\n // 支持体 bbox 沿拉伸方向的远端/近端平面(R-C:baseFeature 显式传参)\n const bbox = getSolidBoundingBox(kernel, baseSolid)\n const pick = (which: 'max' | 'min'): Vec3 => {\n const c: Vec3 = [\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n ]\n const extent = which === 'max' ? 1 : -1\n const proj =\n (bbox.max[0] - bbox.min[0]) * Math.abs(normal.x) +\n (bbox.max[1] - bbox.min[1]) * Math.abs(normal.y) +\n (bbox.max[2] - bbox.min[2]) * Math.abs(normal.z)\n return [\n c[0] + ((normal.x * proj) / 2) * extent,\n c[1] + ((normal.y * proj) / 2) * extent,\n c[2] + ((normal.z * proj) / 2) * extent,\n ]\n }\n targetCenter = pick(upTo === 'last' ? 'max' : 'min')\n targetNormal = [normal.x, normal.y, normal.z]\n } else if (upTo && typeof upTo === 'object' && 'plane' in upTo) {\n // 显式平面目标(datum plane 等无限平面:截断面由平面方程决定,不受\n // 目标面边界限制——斜置基准面时顶面是斜的,定长路径语义错误)。\n targetCenter = [...upTo.plane.point] as Vec3\n targetNormal = [...upTo.plane.normal] as Vec3\n } else {\n // GOTCHA(探针实测):FaceTopoRef 携带的 hint 是 faceRef 现场捕获的\n // center/normal 快照,直接使用;不要对拉伸轮廓(sketch 面)做二次\n // resolveFaceGeometry——引用的面在目标体上、不在轮廓上,会 E_TOPO_NOT_FOUND。\n if (upTo.hint.center && upTo.hint.normal) {\n targetCenter = [...upTo.hint.center] as Vec3\n targetNormal = [...upTo.hint.normal] as Vec3\n } else {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'extrude upTo: face ref hint has no center/normal snapshot')\n }\n }\n\n // 2) 长试探长度:GOTCHA(探针实测)——不能按轮廓自身 bbox 对角线算(小轮廓够不到\n // 远处目标面);必须取「截断平面沿拉伸方向的投影距离」加余量,保证长拉伸至\n // 少穿过目标面。\n const bbox = getSolidBoundingBox(kernel, inputSolid)\n const shiftedCenter0: Vec3 = [\n targetCenter[0] + targetNormal[0] * offset,\n targetCenter[1] + targetNormal[1] * offset,\n targetCenter[2] + targetNormal[2] * offset,\n ]\n // 自动定向(仅 { plane } 目标):FreeCAD UpToFace 朝目标面所在方向拉伸。\n // GOTCHA(PadTest Pad001 实测,probe 探针):斜置基准面在草图局部坐标里\n // 位于轮廓的反方向(圆心处平面交点 t=−26 而非 +26),固定沿 +Z 拉截不到\n // 平面(体积 597 ≠ 真值 4860)。轮廓 bbox 中心到截断平面的有向投影与\n // 拉伸方向异号 → 翻转拉伸方向(就地翻转 Vector3,后续 tMax/keepSide 自洽)。\n if (upTo && typeof upTo === 'object' && 'plane' in upTo) {\n const c0: Vec3 = [\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n ]\n const tnAuto = new THREE.Vector3(...targetNormal).normalize()\n const dAuto =\n (c0[0] - shiftedCenter0[0]) * tnAuto.x +\n (c0[1] - shiftedCenter0[1]) * tnAuto.y +\n (c0[2] - shiftedCenter0[2]) * tnAuto.z\n // 沿拉伸方向到平面的有向交点参数:t = −((c0−plane)·n) / (dir·n)。\n // t<0 → 平面在行进反方向 → 翻转(FreeCAD UpToFace 朝平面拉伸)。\n const tAuto = -dAuto / normal.dot(tnAuto)\n if (tAuto < 0) {\n normal.multiplyScalar(-1)\n }\n }\n const cornerProjections = [\n [bbox.min[0], bbox.min[1], bbox.min[2]],\n [bbox.max[0], bbox.min[1], bbox.min[2]],\n [bbox.min[0], bbox.max[1], bbox.min[2]],\n [bbox.min[0], bbox.min[1], bbox.max[2]],\n [bbox.max[0], bbox.max[1], bbox.min[2]],\n [bbox.max[0], bbox.min[1], bbox.max[2]],\n [bbox.min[0], bbox.max[1], bbox.max[2]],\n [bbox.max[0], bbox.max[1], bbox.max[2]],\n ] as Vec3[]\n const planePoint0 = new THREE.Vector3(...shiftedCenter0)\n const tn0 = new THREE.Vector3(...targetNormal).normalize()\n const planeD = planePoint0.dot(tn0)\n const dirD = normal.dot(tn0)\n if (Math.abs(dirD) < 1e-9) {\n throw new Error('E_UP_TO_PARALLEL: extrude direction is parallel to the target face plane')\n }\n const tMax = cornerProjections\n .map((p) => (planeD - new THREE.Vector3(...p).dot(tn0)) / dirD)\n .reduce((a, b) => Math.max(a, b), 0)\n const L = tMax + Math.abs(offset) + bboxDiag(bbox) * 0.1 + 1\n const longSolid = kernel.extrude(inputSolid, normal.x * L, normal.y * L, normal.z * L)\n\n // 3) 截断平面 = 目标面 + offset(沿面法向)。GOTCHA(探针实测):半空间侧不能固定\n // 取「法向负侧」——目标面法向朝向与拉伸方向无必然关系。正确语义:保留「包含\n // 拉伸起点」的那一侧。farSideBox 覆盖「传入法向的反侧」,因此传 -keepSide。\n const tn = tn0\n const startCenter = new THREE.Vector3(\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n )\n const planePoint = new THREE.Vector3(...shiftedCenter0)\n const d = startCenter.sub(planePoint).dot(tn)\n // 保留侧法向:起点所在侧(d 与 tn 同号 → 正侧;异号 → 负侧);d≈0 时退化为\n // 拉伸方向(起点在面上时按拉伸方向截)\n const keepSide = Math.abs(d) < 1e-9 ? normal.clone() : tn.clone().multiplyScalar(Math.sign(d))\n // GOTCHA(PadTest Pad001 斜置基准面实测):targetCenter 可以是平面上离轮廓\n // 很远的任意一点(基准面 point 在草图局部坐标里横向偏 ~100),reach 若只取\n // L(按轮廓到截断面的投影距离)则半空间盒横向盖不住长拉伸体 → common 为空。\n // reach 必须 ≥ 平面点到拉伸体的距离 + 体对角线(全方向覆盖)。\n const reach =\n new THREE.Vector3(...shiftedCenter0).distanceTo(\n new THREE.Vector3((bbox.min[0] + bbox.max[0]) / 2, (bbox.min[1] + bbox.max[1]) / 2, (bbox.min[2] + bbox.max[2]) / 2),\n ) + bboxDiag(bbox) + Math.abs(offset) + 1\n const halfspace = farSideBox(kernel, shiftedCenter0, [-keepSide.x, -keepSide.y, -keepSide.z], reach)\n\n // 4) 求交:长拉伸 ∩ 半空间盒\n const clipped = kernel.common(longSolid, halfspace)\n kernel.release(longSolid)\n kernel.release(halfspace)\n\n // 预检:方向上不相交 → 显式报错(禁静默)\n const clippedBBox = getSolidBoundingBox(kernel, clipped)\n if (!Number.isFinite(bboxDiag(clippedBBox)) || bboxDiag(clippedBBox) < 1e-9) {\n kernel.release(clipped)\n throw new Error('E_UP_TO_NO_INTERSECTION: extrude direction does not reach the target face')\n }\n return clipped\n}\n\n/**\n * 沿 normal 拉伸几何(面 → 棱柱)。\n *\n * up-to 模式(`upTo`)与长度模式(`length`)二选一;长度模式委托生成投影\n * (vendored extrude 为唯一引擎),up-to 模式走半空间组合。\n *\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name extrude\n * @returns Shape 拉伸后的几何。\n * @param input - 目标几何(平面面)。type:Shape required:true\n * @param params.length - 总拉伸量(mm,>0)。up-to 模式下无需给。type:number\n * @param params.normal - 拉伸方向(世界坐标)。type:[x,y,z] 默认 [0,0,1]\n * @param params.mode - 沿 normal 的前进方向:forward 正向 / backward 反向。type:'forward' | 'backward' 默认 'forward'\n * @param params.upTo - 拉伸到面:FaceTopoRef 指定面 / 'last' 支持体远端面 / 'first' 近端面(需 baseFeature)。提供时忽略 length。type:'last' | 'first' | FaceTopoRef\n * @param params.baseFeature - upTo 'last'/'first' 的支持体几何(累积支持体)。type:Shape\n * @param params.offset - 截断面沿其法向的偏移(mm)。type:number 默认 0\n * @example\n * const p = await cad.extrude(part0, [0, 0, 10])\n * const p = await cad.extrude(part0, { length: 10 })\n * const p = await cad.extrude(sk, { upTo: cad.faceRef(part0, 3) })\n * const p = await cad.extrude(sk, { upTo: 'last', baseFeature: part0 })\n */\nexport const extrude = defineOp({\n name: 'extrude',\n brep: async (input: Shape, params: unknown): Promise<Shape> => {\n if (!input) throw new Error('[stdlib/extrude] no input geometry')\n const o = normalizeExtrudeOptions(params)\n assertExtrudeOptions(o)\n\n if (o.upTo !== undefined) {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/extrude] no OCCT kernel')\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/extrude] input is not BREP')\n const clipped = extrudeUpToSolid(kernel, inputSolid, o)\n return fromBrep(solidToShape(kernel, clipped), { solid: clipped })\n }\n\n // 长度形态:委托生成投影(生成投影自带借入 / Result 翻转 / 收养)\n const normal = new THREE.Vector3(...(o.normal ?? [0, 0, 1])).normalize()\n const sign = o.mode === 'backward' ? -1 : 1\n const v: Vec3 = [normal.x * o.length! * sign, normal.y * o.length! * sign, normal.z * o.length! * sign]\n return (await projectedExtrude(input, v)) as Shape\n },\n})\n"]}
|
|
1
|
+
{"version":3,"file":"extrude.js","sourceRoot":"","sources":["../../src/api/extrude.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib extrude — `cad.extrude`(平台 parity op,BREP-only)\n *\n * 归属(分层红线):`cad.extrude` 是「面 → 棱柱」的**平台** op,FCStd Pad/Pocket\n * 链路与 TS 面共用它(docs/plans/2026-09-15-fcstd-to-faijs-port-plan.md M4.6:\n * 「原 `cad.fai_extrude` 路线废弃」)。up-to(拉伸到面 / 到支持体端面)属\n * CadQuery `until=` 同族语义,因此落在**本 op**;`fai_extrude`(`fai_` 前缀的\n * faijs 扩展 op,与 fai_drill / fai_split 同族)不得承载它。\n *\n * 为什么是手写 op 而不是继续用生成投影:生成投影\n * `compatOp(projectBrepOp('extrude', ['face','height'], 'A', vendoredExtrude))`\n * 有两个硬约束——\n * ① 参数表只有位置形参;D11 归一化只在「单 plain-object 形态」下按 params 表\n * 映射(api/internal/dual-form-args.ts),`(face, { upTo })` 属位置形态 →\n * 原样喂给 vendored extrude → 报错,无法表达对象形态;\n * ② compatOp 的入参先经 `borrowDeep` 借成 brepjs 视图(api/internal/compat-op.ts),\n * 在那一层 `brepOf()` 取不到 → 依赖 faceRef / brepOf / 内核直调的 up-to 实现\n * 必然走空(同 AGENTS.md 记录的「compatOp 自动提升边界」)。\n * 先例:arg-spec 的 `fillet` 条目(faijs 侧由手写 dual-op 覆盖,生成模块符号为\n * 孤儿 by design)。\n *\n * 长度形态**委托给生成投影**(`projectedExtrude`):vendored 仍是唯一拉伸引擎,\n * 既有 `cad.extrude(face, [x,y,z])` 语义零漂移。\n */\n\nimport { extrude as projectedExtrude } from './generated/operations'\nimport * as THREE from 'three'\nimport { solidToShape, matrixToArray } from '../brep/brep-ops'\nimport { getSolidBoundingBox } from '../brep/brep-utils'\nimport { getBackends, getCurrentStmt } from '../runtime-state'\nimport { fromBrep, brepOf } from '../shape'\nimport { formatRoleName, semantic, wall } from '../topology/naming/role-name'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { defineOp } from '../sdk'\nimport { assertPositiveNumber } from './assert'\nimport type { Shape, Vec3 } from '../mesh/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { TopoRefError } from '../topology/naming'\n\n/**\n\n * extrude 的 construct 词汇表(计划 §4.4):`cap:bottom` / `cap:top` / `wall:<i>`。\n *\n * 判定口径:\n * - 拉伸方向取自一对平面端面法向的**带符号差**(两法向指向相反)——不依赖脚本\n * 怎么写方向,现场几何是唯一真值;\n * - 面法向与拉伸轴 |cos| ≈ 1 → 端面:中心沿轴分量小者 `cap:bottom`、大者 `cap:top`;\n * - 面法向与拉伸轴 |cos| ≈ 0 → 侧面 `wall:<i>`,i = 该面在侧面枚举中的相对序\n * (OCCT prism 的侧面顺序 = profile wire 的边序——makeWire 按构造顺序收边,\n * prism 不重排;G3-L1 改参重放依赖该稳定性);\n * - 非平面/无法向的面不进表:缺身份是显式状态(naming 行 role=null),不伪造。\n *\n * @param kernel - the OCCT kernel.\n * @param solid - the extruded solid.\n * @returns role(线格式串)→ hash 子表。\n */\nfunction extrudeConstructRoles(kernel: BrepEngineApi, solid: BrepHandle): Map<string, number[]> {\n const roles = new Map<string, number[]>()\n const faceHandles = kernel.getSubShapes(solid, 'face')\n try {\n const hashes = kernel.subShapeHashes(solid, 'face', 2147483647)\n // 每面的法向(仅平面;侧面可能是圆柱/其它——wall 只挂平面侧面的前提是\n // 直拉伸,斜面/圆柱侧面留待 3.1 的完整枚举器)\n const normals: (readonly [number, number, number] | undefined)[] = faceHandles.map((f) => {\n if (kernel.surfaceType(f) !== 'plane') return undefined\n const uv = kernel.uvBounds(f)\n const n = kernel.surfaceNormal(f, (uv.uMin + uv.uMax) / 2, (uv.vMin + uv.vMax) / 2)\n return [n.x, n.y, n.z] as const\n })\n const centers = faceHandles.map((f) => {\n const c = kernel.getSurfaceCenterOfMass(f)\n return [c.x, c.y, c.z] as const\n })\n\n // 拉伸轴:找一对 |cos| ≈ 1 的反平行平面法向 → 带符号单位方向\n let axis: readonly [number, number, number] | undefined\n for (let i = 0; i < normals.length && !axis; i++) {\n const a = normals[i]\n if (!a) continue\n for (let j = i + 1; j < normals.length; j++) {\n const b = normals[j]\n if (!b) continue\n const lenA = Math.hypot(a[0], a[1], a[2])\n const lenB = Math.hypot(b[0], b[1], b[2])\n if (lenA < 1e-9 || lenB < 1e-9) continue\n const cos = (a[0] * b[0] + a[1] * b[1] + a[2] * b[2]) / (lenA * lenB)\n if (Math.abs(cos) > 0.999) {\n // b 反向即「从 i 面指向 j 面」的方向\n axis = [b[0] - a[0], b[1] - a[1], b[2] - a[2]] as const\n break\n }\n }\n }\n const axisLen = axis ? Math.hypot(axis[0], axis[1], axis[2]) : 0\n if (axis && axisLen > 1e-9) {\n const ax: readonly [number, number, number] = [axis[0] / axisLen, axis[1] / axisLen, axis[2] / axisLen]\n // 端面:沿轴投影最小者 = cap:bottom,最大者 = cap:top\n const capCandidates: { idx: number; t: number }[] = []\n for (let i = 0; i < normals.length; i++) {\n const n = normals[i]\n if (!n) continue\n const len = Math.hypot(n[0], n[1], n[2]) || 1\n const cos = Math.abs(n[0] * ax[0] + n[1] * ax[1] + n[2] * ax[2]) / len\n if (cos > 0.999) {\n capCandidates.push({ idx: i, t: centers[i]![0] * ax[0] + centers[i]![1] * ax[1] + centers[i]![2] * ax[2] })\n }\n }\n if (capCandidates.length >= 2) {\n capCandidates.sort((p, q) => p.t - q.t)\n const bottom = capCandidates[0]!\n const top = capCandidates[capCandidates.length - 1]!\n // 端面词汇用 semantic('bottom'/'top'——与 box 同形)。计划 §4.4 写的\n // `cap:<name>` 前缀形态与 RoleName 契约冲突(semantic 名不允许 ':',\n // role-name.ts SEMANTIC_NAME_RE),落地以契约为准:semantic 直名。\n if (hashes[bottom.idx] !== undefined) roles.set(formatRoleName(semantic('bottom')), [hashes[bottom.idx]!])\n if (hashes[top.idx] !== undefined) roles.set(formatRoleName(semantic('top')), [hashes[top.idx]!])\n }\n // 侧面:|cos| ≈ 0,按枚举序编号(= profile 边序)\n let wallIdx = 0\n for (let i = 0; i < normals.length; i++) {\n const n = normals[i]\n if (!n || hashes[i] === undefined) continue\n const len = Math.hypot(n[0], n[1], n[2]) || 1\n const cos = Math.abs(n[0] * ax[0] + n[1] * ax[1] + n[2] * ax[2]) / len\n if (cos < 0.001) {\n roles.set(formatRoleName(wall(wallIdx)), [hashes[i]!])\n wallIdx++\n }\n }\n }\n return roles\n } finally {\n for (const h of faceHandles) {\n try { kernel.release(h) } catch { /* 已释放 */ }\n }\n }\n}\n\n/** 显式平面目标(up-to 截断面):点 + 法向(点在平面上即可,无需共面于面边界)。 */\nexport interface UpToPlaneSpec {\n /** 平面上一点(世界坐标)。type:[x,y,z] */\n point: Vec3\n /** 平面法向(世界坐标,方向仅定半空间语义,截断取两侧之一)。type:[x,y,z] */\n normal: Vec3\n}\n\n/** up-to 目标:显式面引用 / 显式平面 / 支持体沿拉伸方向的远端(last)/近端(first)端面。 */\nexport type ExtrudeUpTo = FaceTopoRef | 'last' | 'first' | { plane: UpToPlaneSpec }\n\n/** `cad.extrude` 的对象形态参数(位置形态由 {@link normalizeExtrudeOptions} 归一到这里)。 */\nexport interface ExtrudeOptions {\n /** 拉伸量(mm,>0)。up-to 模式下无需给。 */\n length?: number\n /** 拉伸方向(世界坐标);缺省 [0,0,1]。 */\n normal?: Vec3\n /** 沿 normal 的前进方向;缺省 'forward'('backward' 等价于方向取反)。 */\n mode?: 'forward' | 'backward'\n /** 拉伸到面 / 到支持体端面;提供时忽略 length。 */\n upTo?: ExtrudeUpTo\n /** upTo 'last'/'first' 的支持体(累积支持体,由转换器显式传入)。 */\n baseFeature?: Shape\n /** 截断面沿其法向的偏移(mm);缺省 0。 */\n offset?: number\n}\n\n/** 判定是否为朴素对象(对象形态判别器,避免误吞 Shape / 数组)。 */\nfunction isPlainObject(v: unknown): v is Record<string, unknown> {\n return v !== null && typeof v === 'object' && !Array.isArray(v) && Object.getPrototypeOf(v) === Object.prototype\n}\n\n/**\n * 归一化 `cad.extrude` 的两种调用形态。\n *\n * - 位置形态(与生成投影同款,历史产物在用):`cad.extrude(face, 10)` /\n * `cad.extrude(face, [x,y,z])`——向量即「方向 × 长度」,恒为沿该方向前进。\n * - 对象形态(faijs 面):`cad.extrude(face, { length, normal, mode, upTo, ... })`。\n *\n * @param params - 调用点第二实参(数字 / 向量 / 对象)。\n * @returns 归一化后的对象形态参数。\n * @throws Error 参数既非数字 / 向量 / 朴素对象时(不猜)。\n */\nfunction normalizeExtrudeOptions(params: unknown): ExtrudeOptions {\n if (isPlainObject(params)) return params as ExtrudeOptions\n if (Array.isArray(params)) {\n const v = params as Vec3\n const len = Math.hypot(v[0] ?? 0, v[1] ?? 0, v[2] ?? 0)\n if (!Number.isFinite(len) || len < 1e-12) {\n throw new Error('E_EXTRUDE_ZERO_VECTOR: extrude direction vector has zero length')\n }\n return { length: len, normal: [v[0] / len, v[1] / len, v[2] / len], mode: 'forward' }\n }\n if (typeof params === 'number') return { length: params, normal: [0, 0, 1], mode: 'forward' }\n throw new Error('E_EXTRUDE_BAD_PARAMS: extrude expects (face, number | [x,y,z] | { length | upTo, ... })')\n}\n\n/**\n * 参数自校验:up-to 模式下无需 length;否则 length 必须为正数。\n *\n * @param o - 归一化后的参数。\n */\nfunction assertExtrudeOptions(o: ExtrudeOptions): void {\n if (o.upTo !== undefined) return // up-to 模式:长度由目标面决定\n assertPositiveNumber(o.length, 'extrude.length')\n}\n\n/** bbox 对角线长度(长试探的余量基数)。 */\nfunction bboxDiag(bbox: { min: Vec3; max: Vec3 }): number {\n return Math.hypot(bbox.max[0] - bbox.min[0], bbox.max[1] - bbox.min[1], bbox.max[2] - bbox.min[2])\n}\n\n/**\n * 目标面法向负侧的半空间覆盖盒(截断长拉伸用)——定向版。\n *\n * GOTCHA(PadTest Pad001 斜置基准面实测):轴对齐盒的边界不是斜面本身,\n * 截断呈台阶而非精确斜平面(体积 7076 vs 真值 4860)。正确做法:在局部基\n * (u, v, n) 里构造盒(深度沿 −n 伸出 R、横向 ±R),再用 kernel.transform\n * 旋到世界系——盒的 n=R 端面就是精确的目标平面。\n *\n * @param kernel - BREP 内核。\n * @param faceCenter - 目标面中心(世界坐标,盒的 n=0 端面过此点)。\n * @param faceNormal - 目标面法向(半空间保留 −n 侧…即盒占据 −n 侧深度)。\n * @param reach - 覆盖半径 R。\n * @returns 定向半空间盒的 brep 句柄。\n */\nfunction farSideBox(kernel: BrepEngineApi, faceCenter: Vec3, faceNormal: Vec3, reach: number): BrepHandle {\n const unit = new THREE.Vector3(...faceNormal).normalize()\n const center = new THREE.Vector3(...faceCenter)\n // 与 n 正交的正交基 u,v\n const aux = Math.abs(unit.y) < 0.9 ? new THREE.Vector3(0, 1, 0) : new THREE.Vector3(1, 0, 0)\n const u = new THREE.Vector3().crossVectors(unit, aux).normalize()\n const v = new THREE.Vector3().crossVectors(unit, u).normalize()\n const R = reach\n // 局部系盒:x∈[−R,R] (u), y∈[−R,R] (v), z∈[−R,0] (n 深度侧)\n const box = kernel.makeBoxFromCorners(\n { x: -R, y: -R, z: -R },\n { x: R, y: R, z: 0 },\n )\n // 旋转矩阵:列 = u, v, n;平移 = center(局部 z=0 端面落到过 center 的目标平面)\n const m = new THREE.Matrix4().makeBasis(u, v, unit).setPosition(center)\n return kernel.transform(box, matrixToArray(m))\n}\n\n/**\n * up-to 拉伸:occt-wasm 未暴露 `BRepFeat_MakePrism`,用「长拉伸 → 与目标面侧\n * 半空间盒求交」等价组合;长试探上限只作布尔构造辅助,不进入结果几何。\n *\n * @param kernel - BREP 内核。\n * @param inputSolid - 轮廓实体句柄。\n * @param o - 归一化参数(需带 upTo)。\n * @returns 截断后的实体句柄。\n * @throws Error E_UP_TO_* 系列:缺支持体 / 方向与目标面平行 / 不相交(禁静默)。\n */\nfunction extrudeUpToSolid(kernel: BrepEngineApi, inputSolid: BrepHandle, o: ExtrudeOptions): BrepHandle {\n const normal = new THREE.Vector3(...(o.normal ?? [0, 0, 1])).normalize()\n const offset = o.offset ?? 0\n const upTo = o.upTo as ExtrudeUpTo\n\n // 1) 方向目标:FaceTopoRef → 现场面几何;'last'/'first' → baseFeature 支持体\n // 沿拉伸方向的端面(远端 last / 近端 first)。\n let targetCenter: Vec3\n let targetNormal: Vec3\n if (typeof upTo === 'string') {\n const base = o.baseFeature\n const baseSolid = base ? (brepOf(base) as BrepHandle | undefined) : undefined\n if (!baseSolid) {\n throw new Error('E_UP_TO_NO_BASE: upTo \"last\"/\"first\" requires a baseFeature shape')\n }\n // 支持体 bbox 沿拉伸方向的远端/近端平面(R-C:baseFeature 显式传参)\n const bbox = getSolidBoundingBox(kernel, baseSolid)\n const pick = (which: 'max' | 'min'): Vec3 => {\n const c: Vec3 = [\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n ]\n const extent = which === 'max' ? 1 : -1\n const proj =\n (bbox.max[0] - bbox.min[0]) * Math.abs(normal.x) +\n (bbox.max[1] - bbox.min[1]) * Math.abs(normal.y) +\n (bbox.max[2] - bbox.min[2]) * Math.abs(normal.z)\n return [\n c[0] + ((normal.x * proj) / 2) * extent,\n c[1] + ((normal.y * proj) / 2) * extent,\n c[2] + ((normal.z * proj) / 2) * extent,\n ]\n }\n targetCenter = pick(upTo === 'last' ? 'max' : 'min')\n targetNormal = [normal.x, normal.y, normal.z]\n } else if (upTo && typeof upTo === 'object' && 'plane' in upTo) {\n // 显式平面目标(datum plane 等无限平面:截断面由平面方程决定,不受\n // 目标面边界限制——斜置基准面时顶面是斜的,定长路径语义错误)。\n targetCenter = [...upTo.plane.point] as Vec3\n targetNormal = [...upTo.plane.normal] as Vec3\n } else {\n // GOTCHA(探针实测):FaceTopoRef 携带的 hint 是 faceRef 现场捕获的\n // center/normal 快照,直接使用;不要对拉伸轮廓(sketch 面)做二次\n // resolveFaceGeometry——引用的面在目标体上、不在轮廓上,会 E_TOPO_NOT_FOUND。\n if (upTo.hint.center && upTo.hint.normal) {\n targetCenter = [...upTo.hint.center] as Vec3\n targetNormal = [...upTo.hint.normal] as Vec3\n } else {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'extrude upTo: face ref hint has no center/normal snapshot')\n }\n }\n\n // 2) 长试探长度:GOTCHA(探针实测)——不能按轮廓自身 bbox 对角线算(小轮廓够不到\n // 远处目标面);必须取「截断平面沿拉伸方向的投影距离」加余量,保证长拉伸至\n // 少穿过目标面。\n const bbox = getSolidBoundingBox(kernel, inputSolid)\n const shiftedCenter0: Vec3 = [\n targetCenter[0] + targetNormal[0] * offset,\n targetCenter[1] + targetNormal[1] * offset,\n targetCenter[2] + targetNormal[2] * offset,\n ]\n // 自动定向(仅 { plane } 目标):FreeCAD UpToFace 朝目标面所在方向拉伸。\n // GOTCHA(PadTest Pad001 实测,probe 探针):斜置基准面在草图局部坐标里\n // 位于轮廓的反方向(圆心处平面交点 t=−26 而非 +26),固定沿 +Z 拉截不到\n // 平面(体积 597 ≠ 真值 4860)。轮廓 bbox 中心到截断平面的有向投影与\n // 拉伸方向异号 → 翻转拉伸方向(就地翻转 Vector3,后续 tMax/keepSide 自洽)。\n if (upTo && typeof upTo === 'object' && 'plane' in upTo) {\n const c0: Vec3 = [\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n ]\n const tnAuto = new THREE.Vector3(...targetNormal).normalize()\n const dAuto =\n (c0[0] - shiftedCenter0[0]) * tnAuto.x +\n (c0[1] - shiftedCenter0[1]) * tnAuto.y +\n (c0[2] - shiftedCenter0[2]) * tnAuto.z\n // 沿拉伸方向到平面的有向交点参数:t = −((c0−plane)·n) / (dir·n)。\n // t<0 → 平面在行进反方向 → 翻转(FreeCAD UpToFace 朝平面拉伸)。\n const tAuto = -dAuto / normal.dot(tnAuto)\n if (tAuto < 0) {\n normal.multiplyScalar(-1)\n }\n }\n const cornerProjections = [\n [bbox.min[0], bbox.min[1], bbox.min[2]],\n [bbox.max[0], bbox.min[1], bbox.min[2]],\n [bbox.min[0], bbox.max[1], bbox.min[2]],\n [bbox.min[0], bbox.min[1], bbox.max[2]],\n [bbox.max[0], bbox.max[1], bbox.min[2]],\n [bbox.max[0], bbox.min[1], bbox.max[2]],\n [bbox.min[0], bbox.max[1], bbox.max[2]],\n [bbox.max[0], bbox.max[1], bbox.max[2]],\n ] as Vec3[]\n const planePoint0 = new THREE.Vector3(...shiftedCenter0)\n const tn0 = new THREE.Vector3(...targetNormal).normalize()\n const planeD = planePoint0.dot(tn0)\n const dirD = normal.dot(tn0)\n if (Math.abs(dirD) < 1e-9) {\n throw new Error('E_UP_TO_PARALLEL: extrude direction is parallel to the target face plane')\n }\n const tMax = cornerProjections\n .map((p) => (planeD - new THREE.Vector3(...p).dot(tn0)) / dirD)\n .reduce((a, b) => Math.max(a, b), 0)\n const L = tMax + Math.abs(offset) + bboxDiag(bbox) * 0.1 + 1\n const longSolid = kernel.extrude(inputSolid, normal.x * L, normal.y * L, normal.z * L)\n\n // 3) 截断平面 = 目标面 + offset(沿面法向)。GOTCHA(探针实测):半空间侧不能固定\n // 取「法向负侧」——目标面法向朝向与拉伸方向无必然关系。正确语义:保留「包含\n // 拉伸起点」的那一侧。farSideBox 覆盖「传入法向的反侧」,因此传 -keepSide。\n const tn = tn0\n const startCenter = new THREE.Vector3(\n (bbox.min[0] + bbox.max[0]) / 2,\n (bbox.min[1] + bbox.max[1]) / 2,\n (bbox.min[2] + bbox.max[2]) / 2,\n )\n const planePoint = new THREE.Vector3(...shiftedCenter0)\n const d = startCenter.sub(planePoint).dot(tn)\n // 保留侧法向:起点所在侧(d 与 tn 同号 → 正侧;异号 → 负侧);d≈0 时退化为\n // 拉伸方向(起点在面上时按拉伸方向截)\n const keepSide = Math.abs(d) < 1e-9 ? normal.clone() : tn.clone().multiplyScalar(Math.sign(d))\n // GOTCHA(PadTest Pad001 斜置基准面实测):targetCenter 可以是平面上离轮廓\n // 很远的任意一点(基准面 point 在草图局部坐标里横向偏 ~100),reach 若只取\n // L(按轮廓到截断面的投影距离)则半空间盒横向盖不住长拉伸体 → common 为空。\n // reach 必须 ≥ 平面点到拉伸体的距离 + 体对角线(全方向覆盖)。\n const reach =\n new THREE.Vector3(...shiftedCenter0).distanceTo(\n new THREE.Vector3((bbox.min[0] + bbox.max[0]) / 2, (bbox.min[1] + bbox.max[1]) / 2, (bbox.min[2] + bbox.max[2]) / 2),\n ) + bboxDiag(bbox) + Math.abs(offset) + 1\n const halfspace = farSideBox(kernel, shiftedCenter0, [-keepSide.x, -keepSide.y, -keepSide.z], reach)\n\n // 4) 求交:长拉伸 ∩ 半空间盒\n const clipped = kernel.common(longSolid, halfspace)\n kernel.release(longSolid)\n kernel.release(halfspace)\n\n // 预检:方向上不相交 → 显式报错(禁静默)\n const clippedBBox = getSolidBoundingBox(kernel, clipped)\n if (!Number.isFinite(bboxDiag(clippedBBox)) || bboxDiag(clippedBBox) < 1e-9) {\n kernel.release(clipped)\n throw new Error('E_UP_TO_NO_INTERSECTION: extrude direction does not reach the target face')\n }\n return clipped\n}\n\n/**\n * 沿 normal 拉伸几何(面 → 棱柱)。\n *\n * up-to 模式(`upTo`)与长度模式(`length`)二选一;长度模式委托生成投影\n * (vendored extrude 为唯一引擎),up-to 模式走半空间组合。\n *\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name extrude\n * @returns Shape 拉伸后的几何。\n * @param input - 目标几何(平面面)。type:Shape required:true\n * @param params.length - 总拉伸量(mm,>0)。up-to 模式下无需给。type:number\n * @param params.normal - 拉伸方向(世界坐标)。type:[x,y,z] 默认 [0,0,1]\n * @param params.mode - 沿 normal 的前进方向:forward 正向 / backward 反向。type:'forward' | 'backward' 默认 'forward'\n * @param params.upTo - 拉伸到面:FaceTopoRef 指定面 / 'last' 支持体远端面 / 'first' 近端面(需 baseFeature)。提供时忽略 length。type:'last' | 'first' | FaceTopoRef\n * @param params.baseFeature - upTo 'last'/'first' 的支持体几何(累积支持体)。type:Shape\n * @param params.offset - 截断面沿其法向的偏移(mm)。type:number 默认 0\n * @example\n * const p = await cad.extrude(part0, [0, 0, 10])\n * const p = await cad.extrude(part0, { length: 10 })\n * const p = await cad.extrude(sk, { upTo: cad.faceRef(part0, 3) })\n * const p = await cad.extrude(sk, { upTo: 'last', baseFeature: part0 })\n */\nexport const extrude = defineOp({\n name: 'extrude',\n brep: async (input: Shape, params: unknown): Promise<Shape> => {\n if (!input) throw new Error('[stdlib/extrude] no input geometry')\n const o = normalizeExtrudeOptions(params)\n assertExtrudeOptions(o)\n\n if (o.upTo !== undefined) {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/extrude] no OCCT kernel')\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/extrude] input is not BREP')\n const clipped = extrudeUpToSolid(kernel, inputSolid, o)\n // 3.2: inlined registerExtrudeRoles — origin = StmtId, roles from construct enumerator\n const origin = String(getCurrentStmt()?.id ?? '')\n return fromBrep(solidToShape(kernel, clipped), {\n solid: clipped,\n roleTable: new Map([[origin, extrudeConstructRoles(kernel, clipped)]]),\n })\n }\n\n // 长度形态:委托生成投影(生成投影自带借入 / Result 翻转 / 收养)\n const normal = new THREE.Vector3(...(o.normal ?? [0, 0, 1])).normalize()\n const sign = o.mode === 'backward' ? -1 : 1\n const v: Vec3 = [normal.x * o.length! * sign, normal.y * o.length! * sign, normal.z * o.length! * sign]\n const result = (await projectedExtrude(input, v)) as Shape\n // E3 后续:委托路径同样要建链根表(投影只给几何,命名是 faijs 语义)。\n // 3.2: inlined registerExtrudeRoles — origin = StmtId, roles from construct enumerator\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n const solid = kernel ? (brepOf(result) as BrepHandle | undefined) : undefined\n if (kernel && solid) {\n const origin = String(getCurrentStmt()?.id ?? '')\n return fromBrep(solidToShape(kernel, solid), {\n solid,\n roleTable: new Map([[origin, extrudeConstructRoles(kernel, solid)]]),\n })\n }\n return result\n },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'wall', index: 0 }] } } as Provenance,\n})\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"face-ref.d.ts","sourceRoot":"","sources":["../../src/api/face-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAK1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGrD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,
|
|
1
|
+
{"version":3,"file":"face-ref.d.ts","sourceRoot":"","sources":["../../src/api/face-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAK1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAGrD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,GAAG,WAAW,CAmCnE"}
|
package/dist/api/face-ref.js
CHANGED
|
@@ -40,10 +40,13 @@ export function faceRef(of, faceOrdinal) {
|
|
|
40
40
|
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `faceRef: faceOrdinal must be an integer >= 1 (got ${faceOrdinal})`);
|
|
41
41
|
}
|
|
42
42
|
const kernel = getBackends().kernel.brep;
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
43
|
+
// Phase 1.9(D6/§3):mesh 路径不支持拓扑引用——静态判定、显式抛错,不静默降级
|
|
44
|
+
if (!kernel) {
|
|
45
|
+
throw new TopoRefError('E_TOPO_MESH_UNSUPPORTED', 'face', 'faceRef: topology references are BREP-only (mesh path unsupported)');
|
|
46
|
+
}
|
|
47
|
+
if (!brepOf(of)) {
|
|
48
|
+
throw new TopoRefError('E_TOPO_MESH_UNSUPPORTED', 'face', 'faceRef: input shape has no BREP solid (mesh shapes do not carry topology identity)');
|
|
49
|
+
}
|
|
47
50
|
const ctx = buildEdgeResolutionContext(kernel, of);
|
|
48
51
|
if (!ctx)
|
|
49
52
|
throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'faceRef: input has no BREP naming context');
|
package/dist/api/face-ref.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"face-ref.js","sourceRoot":"","sources":["../../src/api/face-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAElF,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAA;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,OAAO,CAAC,EAAS,EAAE,WAAmB;IACpD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,YAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,qDAAqD,WAAW,GAAG,CAAC,CAAA;IACzH,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC,MAAM,CAAC,IAA4B,CAAA;IAChE,IAAI,CAAC,MAAM;
|
|
1
|
+
{"version":3,"file":"face-ref.js","sourceRoot":"","sources":["../../src/api/face-ref.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAEjC,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAElF,OAAO,EAAE,0BAA0B,EAAE,MAAM,gBAAgB,CAAA;AAE3D;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,UAAU,OAAO,CAAC,EAAS,EAAE,WAAmB;IACpD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,WAAW,CAAC,IAAI,WAAW,GAAG,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,YAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,qDAAqD,WAAW,GAAG,CAAC,CAAA;IACzH,CAAC;IACD,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC,MAAM,CAAC,IAA4B,CAAA;IAChE,mDAAmD;IACnD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,YAAY,CAAC,yBAAyB,EAAE,MAAM,EAAE,oEAAoE,CAAC,CAAA;IACjI,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,YAAY,CAAC,yBAAyB,EAAE,MAAM,EAAE,qFAAqF,CAAC,CAAA;IAClJ,CAAC;IAED,MAAM,GAAG,GAAG,0BAA0B,CAAC,MAAM,EAAE,EAAY,CAAC,CAAA;IAC5D,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,YAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,2CAA2C,CAAC,CAAA;IAEzG,MAAM,IAAI,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,KAAK,WAAW,CAAC,CAAA;IAC7D,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACvC,MAAM,IAAI,YAAY,CACpB,kBAAkB,EAClB,MAAM,EACN,yBAAyB,WAAW,qBAAqB,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAC7E,CAAA;IACH,CAAC;IAED,MAAM,KAAK,GAAG,GAAG,CAAC,SAAS,CAAA;IAC3B,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,YAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,yDAAyD,CAAC,CAAA;IAC/G,CAAC;IACD,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,EAAE,WAAW,CAAC,CAAA;IACnF,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,YAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,yBAAyB,WAAW,sBAAsB,CAAC,CAAA;IAChH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,eAAe,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,CAAA;AAC7G,CAAC","sourcesContent":["/**\n * stdlib face-ref — 面引用查询:把「面序号」解析成 `FaceTopoRef`(1 起)\n *\n * extrude 的 `upTo` 参数(拉伸到面,PadTest UpToFace 链路)需要指向\n * 「某个实体上第 N 张面」的引用。外部格式(FCStd 的 `UpToFace` LinkSub 等)\n * 只给序号,本模块与 `edge-ref.ts` 同构:在内核现场枚举里取第 N 张面,\n * 经输入 Shape 的命名槽(RoleTable + subShapeHashes)反查它的\n * `{origin, role}` 血统,合成 `FaceTopoRef`。\n *\n * 序号语义(GOTCHA):与 `edgeRef` 一致,1 起 == FreeCAD 的 `FaceN`\n * (`getSubShapes(solid,'face')` 用 TopExp::MapShapes + IndexedMap 枚举,\n * 与 `edge-ref.ts` 头注同源已记档)。\n *\n * 纯查询:同步、无副作用、不改 Shape;定不了案一律抛 `TopoRefError`,\n * 绝不静默拿序号硬取。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { getBackends } from '../runtime-state'\nimport { brepOf } from '../shape'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { captureFaceHint, findOriginRole, TopoRefError } from '../topology/naming'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { buildEdgeResolutionContext } from './topo-resolve'\n\n/**\n * 查询几何体第 N 张面的 `FaceTopoRef`,供 `cad.extrude` 的 `upTo` 等参数使用:\n * `cad.extrude(part0, { upTo: cad.faceRef(part0, 3) })`。\n *\n * 定不了案(无 BREP / 序号越界 / 面无 role 血统)抛 `TopoRefError`。\n * @group 查询\n * @inputs 1\n * @async false\n * @qual ok\n * @name faceRef\n * @returns FaceTopoRef 该面的拓扑引用(origin/role 血统 + 几何 hint)。\n * @param of - 目标几何(BREP 实体所在的 Shape)。type:Shape required:true\n * @param faceOrdinal - 面序号(1 起;等于 FreeCAD 的 `FaceN`)。type:number required:true\n * @note 序号 1 起,与命名层 `TopoRef.ordinal` 及 FreeCAD `FaceN` 同序(`getSubShapes(solid,'face')` 用 TopExp::MapShapes + IndexedMap 枚举)。\n * @example\n * const part1 = cad.extrude(sk, { upTo: cad.faceRef(part0, 3) })\n */\nexport function faceRef(of: Shape, faceOrdinal: number): FaceTopoRef {\n if (!Number.isInteger(faceOrdinal) || faceOrdinal < 1) {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `faceRef: faceOrdinal must be an integer >= 1 (got ${faceOrdinal})`)\n }\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n // Phase 1.9(D6/§3):mesh 路径不支持拓扑引用——静态判定、显式抛错,不静默降级\n if (!kernel) {\n throw new TopoRefError('E_TOPO_MESH_UNSUPPORTED', 'face', 'faceRef: topology references are BREP-only (mesh path unsupported)')\n }\n if (!brepOf(of)) {\n throw new TopoRefError('E_TOPO_MESH_UNSUPPORTED', 'face', 'faceRef: input shape has no BREP solid (mesh shapes do not carry topology identity)')\n }\n\n const ctx = buildEdgeResolutionContext(kernel, of as object)\n if (!ctx) throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'faceRef: input has no BREP naming context')\n\n const face = ctx.faces.find((f) => f.ordinal === faceOrdinal)\n if (!face || face.handle === undefined) {\n throw new TopoRefError(\n 'E_TOPO_NOT_FOUND',\n 'face',\n `faceRef: face ordinal ${faceOrdinal} out of range [1, ${ctx.faces.length}]`,\n )\n }\n\n const table = ctx.roleTable\n if (!table) {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', 'faceRef: input shape has no role table (nameless shape)')\n }\n const found = findOriginRole(table, ctx.faces.map((f) => f.hash ?? 0), faceOrdinal)\n if (!found) {\n throw new TopoRefError('E_TOPO_NOT_FOUND', 'face', `faceRef: face ordinal ${faceOrdinal} has no role lineage`)\n }\n\n return { kind: 'face', origin: found.origin, role: found.role, hint: captureFaceHint(kernel, face.handle) }\n}\n"]}
|
package/dist/api/fai_drill.d.ts
CHANGED
|
@@ -19,7 +19,7 @@ export declare function assertDrillParams(params: Record<string, unknown>): void
|
|
|
19
19
|
* @async true
|
|
20
20
|
* @qual ok
|
|
21
21
|
* @name fai_drill
|
|
22
|
-
* @deprecated `fai_` 前缀 op
|
|
22
|
+
* @deprecated **`../3d_editor` 消费面**(原 `@deprecated` 措辞已于 2026-09-22 校正):`fai_` 前缀 op 为编辑器应用提供,不属 faijs 平台面,但**不是废弃项**——它服务真实负载(3d_editor 38 个文件在用)。**变更其 API 形态必须同步更新 `../3d_editor`**(见 `docs/plans/2026-09-22-topology-identity-development-plan.md` §2)。faijs 平台面不提供等价 op(需要时须按平台需求另行设计,不得直接搬用本 op)。
|
|
23
23
|
* @note 键名以本表为准:`type: 'through'|'blind'` 与 `direction` 为向量的旧素材是无效写法——孔型由 `depth`(0=通孔)推导,`direction` 是 'normal'|'x'|'y'|'z' 枚举。
|
|
24
24
|
* @returns Shape 钻孔后的几何。
|
|
25
25
|
* @param input - 目标几何。type:Shape required:true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fai_drill.d.ts","sourceRoot":"","sources":["../../src/api/fai_drill.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"fai_drill.d.ts","sourceRoot":"","sources":["../../src/api/fai_drill.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAwBhD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAQvE;AAiMD;;;;;;;;;;;;;;;;;;;;;;;;;;;IA2BI;AACJ,eAAO,MAAM,SAAS;;CAYpB,CAAA"}
|
package/dist/api/fai_drill.js
CHANGED
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
* BREP 路径:OCCT cut(简单孔)或 threadBrep + cut(螺丝孔)。
|
|
7
7
|
*/
|
|
8
8
|
import { cad } from '../mesh/index.js';
|
|
9
|
-
import {
|
|
9
|
+
import { buildDrillToolSolid, computeDrillGeometry, solidToShape, matrixToArray, } from '../brep/brep-ops.js';
|
|
10
|
+
import { drillBrepWithRoleTable } from '../brep/face-evolution.js';
|
|
10
11
|
import { threadBrep } from './brep-mirror/threadFns.js';
|
|
11
12
|
import { getScrewSpec, threadToPitchMm } from '../primitives/screw/screw-db.js';
|
|
12
13
|
import * as THREE from 'three';
|
|
13
|
-
import { getBackends } from '../runtime-state.js';
|
|
14
|
-
import { fromBrep, brepOf } from '../shape.js';
|
|
14
|
+
import { getBackends, getCurrentStmt } from '../runtime-state.js';
|
|
15
|
+
import { fromBrep, brepOf, inputRoleTable } from '../shape.js';
|
|
15
16
|
import { defineOp } from '../sdk.js';
|
|
16
17
|
import { assertPositiveNumber, assertNumber, assertVec3 } from './assert.js';
|
|
17
18
|
import { resolveFaceGeometry } from './topo-resolve.js';
|
|
@@ -86,19 +87,21 @@ function faceNormalFrom(input, params) {
|
|
|
86
87
|
}
|
|
87
88
|
return [0, 0, 1];
|
|
88
89
|
}
|
|
89
|
-
/** BREP 螺丝孔:底孔(圆柱 cut)+ 内螺纹(threadBrep + cut
|
|
90
|
-
function screwHoleBrep(kernel, upstreamSolid, params, direction, faceNormal, localPosition) {
|
|
90
|
+
/** BREP 螺丝孔:底孔(圆柱 cut)+ 内螺纹(threadBrep + cut)。带 roleTable 传播。 */
|
|
91
|
+
function screwHoleBrep(kernel, upstreamSolid, params, direction, faceNormal, localPosition, inputRoleTable, outStmt) {
|
|
91
92
|
const diameter = params.diameter;
|
|
92
93
|
const depth = params.depth;
|
|
93
|
-
// 1. 底孔(圆柱 cut)
|
|
94
|
-
const
|
|
94
|
+
// 1. 底孔(圆柱 cut)→ roleTable(hole:0)
|
|
95
|
+
const baseGeom = computeDrillGeometry(kernel, upstreamSolid, {
|
|
95
96
|
diameter,
|
|
96
97
|
depth,
|
|
97
98
|
position: localPosition,
|
|
98
99
|
direction,
|
|
99
100
|
faceNormal,
|
|
100
|
-
holeType: 'simple',
|
|
101
101
|
});
|
|
102
|
+
const baseTool = buildDrillToolSolid(kernel, baseGeom);
|
|
103
|
+
const baseR = drillBrepWithRoleTable(kernel, upstreamSolid, baseTool, inputRoleTable, outStmt);
|
|
104
|
+
kernel.release(baseTool);
|
|
102
105
|
// 2. 螺纹(内螺纹 ridge,inward=true)
|
|
103
106
|
const screwSystem = params.screwSystem ?? 'metric';
|
|
104
107
|
const screwSpecIdx = params.screwSpecIdx ?? 4; // M5 default(与 mesh 路径一致)
|
|
@@ -123,14 +126,14 @@ function screwHoleBrep(kernel, upstreamSolid, params, direction, faceNormal, loc
|
|
|
123
126
|
const fullMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix);
|
|
124
127
|
const positionedThread = kernel.transform(threadSolid, matrixToArray(fullMatrix));
|
|
125
128
|
kernel.release(threadSolid);
|
|
126
|
-
const
|
|
127
|
-
kernel.release(result);
|
|
129
|
+
const finalR = drillBrepWithRoleTable(kernel, baseR.result, positionedThread, baseR.roleTable, outStmt);
|
|
128
130
|
kernel.release(positionedThread);
|
|
129
|
-
|
|
131
|
+
kernel.release(baseR.result);
|
|
132
|
+
return { result: finalR.result, roleTable: finalR.roleTable };
|
|
130
133
|
}
|
|
131
|
-
return result;
|
|
134
|
+
return { result: baseR.result, roleTable: baseR.roleTable };
|
|
132
135
|
}
|
|
133
|
-
/** BREP 路径:OCCT cut(简单孔)或 threadBrep + cut
|
|
136
|
+
/** BREP 路径:OCCT cut(简单孔)或 threadBrep + cut(螺丝孔)。带 roleTable 传播。 */
|
|
134
137
|
function drillBrepPath(input, params) {
|
|
135
138
|
const kernel = getBackends().kernel.brep;
|
|
136
139
|
if (!kernel)
|
|
@@ -144,21 +147,30 @@ function drillBrepPath(input, params) {
|
|
|
144
147
|
// 世界坐标 → 局部坐标(cad.load 返回的几何体在原始文件坐标系中)
|
|
145
148
|
const partTransform = getBackends().config.partTransform;
|
|
146
149
|
const localPosition = worldToLocalPosition(params.position, partTransform);
|
|
150
|
+
const inputTable = inputRoleTable(input);
|
|
151
|
+
const outStmt = String(getCurrentStmt()?.id ?? '');
|
|
147
152
|
let resultSolid;
|
|
153
|
+
let roleTable;
|
|
148
154
|
if (holeType === 'screw') {
|
|
149
|
-
|
|
155
|
+
const r = screwHoleBrep(kernel, inputSolid, params, direction, faceNormal, localPosition, inputTable ?? new Map(), outStmt);
|
|
156
|
+
resultSolid = r.result;
|
|
157
|
+
roleTable = r.roleTable;
|
|
150
158
|
}
|
|
151
159
|
else {
|
|
152
|
-
|
|
160
|
+
const geom = computeDrillGeometry(kernel, inputSolid, {
|
|
153
161
|
diameter: params.diameter,
|
|
154
162
|
depth: params.depth,
|
|
155
163
|
position: localPosition,
|
|
156
164
|
direction,
|
|
157
165
|
faceNormal,
|
|
158
|
-
holeType: 'simple',
|
|
159
166
|
});
|
|
167
|
+
const toolSolid = buildDrillToolSolid(kernel, geom);
|
|
168
|
+
const r = drillBrepWithRoleTable(kernel, inputSolid, toolSolid, inputTable ?? new Map(), outStmt);
|
|
169
|
+
kernel.release(toolSolid);
|
|
170
|
+
resultSolid = r.result;
|
|
171
|
+
roleTable = r.roleTable;
|
|
160
172
|
}
|
|
161
|
-
return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid });
|
|
173
|
+
return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable });
|
|
162
174
|
}
|
|
163
175
|
/** mesh 路径:manifold-3d mesh-CSG。 */
|
|
164
176
|
async function drillMeshPath(input, params) {
|
|
@@ -192,7 +204,7 @@ async function drillMeshPath(input, params) {
|
|
|
192
204
|
* @async true
|
|
193
205
|
* @qual ok
|
|
194
206
|
* @name fai_drill
|
|
195
|
-
* @deprecated `fai_` 前缀 op
|
|
207
|
+
* @deprecated **`../3d_editor` 消费面**(原 `@deprecated` 措辞已于 2026-09-22 校正):`fai_` 前缀 op 为编辑器应用提供,不属 faijs 平台面,但**不是废弃项**——它服务真实负载(3d_editor 38 个文件在用)。**变更其 API 形态必须同步更新 `../3d_editor`**(见 `docs/plans/2026-09-22-topology-identity-development-plan.md` §2)。faijs 平台面不提供等价 op(需要时须按平台需求另行设计,不得直接搬用本 op)。
|
|
196
208
|
* @note 键名以本表为准:`type: 'through'|'blind'` 与 `direction` 为向量的旧素材是无效写法——孔型由 `depth`(0=通孔)推导,`direction` 是 'normal'|'x'|'y'|'z' 枚举。
|
|
197
209
|
* @returns Shape 钻孔后的几何。
|
|
198
210
|
* @param input - 目标几何。type:Shape required:true
|
|
@@ -226,5 +238,6 @@ export const fai_drill = defineOp({
|
|
|
226
238
|
assertDrillParams(params);
|
|
227
239
|
return drillBrepPath(input, params);
|
|
228
240
|
},
|
|
241
|
+
naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
|
|
229
242
|
});
|
|
230
243
|
//# sourceMappingURL=fai_drill.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fai_drill.js","sourceRoot":"","sources":["../../src/api/fai_drill.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib drill — 钻孔库函数\n *\n *\n * dispatchPath 静态判定 brep/mesh。\n * BREP 路径:OCCT cut(简单孔)或 threadBrep + cut(螺丝孔)。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { cad } from '../mesh'\nimport {\n drillBrep,\n solidToShape,\n matrixToArray,\n} from '../brep/brep-ops'\nimport { threadBrep } from './brep-mirror/threadFns'\nimport { getScrewSpec, threadToPitchMm } from '../primitives/screw/screw-db'\nimport * as THREE from 'three'\nimport { getBackends } from '../runtime-state'\nimport { fromBrep, brepOf } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { BrepHandle } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { assertPositiveNumber, assertNumber, assertVec3 } from './assert'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { resolveFaceGeometry } from './topo-resolve'\n\n// ── per-op 参数自校验(Phase 2.2;stdlib 被直接 import 时的防御层) ──\n\n/**\n * Validate drill parameters: `diameter` must be a positive number, `position`\n * (if provided) a vec3, and `depth` (if provided) a number (<= 0 means a through hole).\n * @param params - the raw drill operation parameters.\n */\nexport function assertDrillParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.diameter, 'drill.diameter')\n if (params.position !== undefined && params.position !== null) {\n assertVec3(params.position, 'drill.position')\n }\n if (params.depth !== undefined && params.depth !== null) {\n assertNumber(params.depth, 'drill.depth')\n }\n}\n\n/** 世界坐标 → 几何体局部坐标(含单位缩放)。 */\nfunction worldToLocalPosition(\n worldPos: [number, number, number],\n partTransform: { position: [number, number, number]; scale?: [number, number, number] } | undefined,\n): [number, number, number] {\n const offset = partTransform?.position\n if (!offset) return worldPos\n const scale = partTransform?.scale\n if (scale && (scale[0] !== 1 || scale[1] !== 1 || scale[2] !== 1)) {\n return [\n (worldPos[0] - offset[0]) / scale[0],\n (worldPos[1] - offset[1]) / scale[1],\n (worldPos[2] - offset[2]) / scale[2],\n ]\n }\n return [\n worldPos[0] - offset[0],\n worldPos[1] - offset[1],\n worldPos[2] - offset[2],\n ]\n}\n\n/** 解析 direction 枚举 → 钻孔方向向量。 */\nfunction resolveDirection(params: Record<string, unknown>, faceNormal: Vec3): Vec3 {\n const directionEnum = (params.direction as string | undefined) ?? 'normal'\n if (directionEnum === 'normal') return faceNormal\n if (directionEnum === 'x') return [-1, 0, 0]\n if (directionEnum === 'y') return [0, -1, 0]\n if (directionEnum === 'z') return [0, 0, -1]\n return faceNormal\n}\n\n/**\n * 面法向派生(§6.2):钻孔轴向是「点击点的真实面法向」——曲面(圆柱面等)上\n * 仅凭 FaceTopoRef 的单一 hint 法向无法还原点击点的径向方向(引擎无 点→曲面\n * 投影 API),故轴向优先使用宿主捕获的 `faceNormal` 快照(与 position 同为点击\n * 快照);`face: FaceTopoRef` 作为持久化身份引用(跨重放追踪),仅在无\n * `faceNormal` 的历史/手写脚本时才按其派生的法向兜底。\n *\n * @param input - the target geometry (used to resolve the face ref).\n * @param params - raw drill params.\n * @returns the face normal the drill axis uses.\n */\nfunction faceNormalFrom(input: Shape, params: Record<string, unknown>): Vec3 {\n const faceNormal = params.faceNormal as Vec3 | undefined\n if (faceNormal && Array.isArray(faceNormal)) {\n return faceNormal\n }\n const face = params.face as FaceTopoRef | undefined\n if (face && typeof face === 'object' && face.kind === 'face') {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n const geom = resolveFaceGeometry(kernel, input, face)\n return geom.normal\n }\n return [0, 0, 1]\n}\n\n/** BREP 螺丝孔:底孔(圆柱 cut)+ 内螺纹(threadBrep + cut)。 */\nfunction screwHoleBrep(\n kernel: BrepEngineApi,\n upstreamSolid: BrepHandle,\n params: Record<string, unknown>,\n direction: Vec3,\n faceNormal: Vec3,\n localPosition: [number, number, number],\n): BrepHandle {\n const diameter = params.diameter as number\n const depth = params.depth as number\n // 1. 底孔(圆柱 cut)\n const result = drillBrep(kernel, upstreamSolid, {\n diameter,\n depth,\n position: localPosition,\n direction,\n faceNormal,\n holeType: 'simple',\n })\n\n // 2. 螺纹(内螺纹 ridge,inward=true)\n const screwSystem = (params.screwSystem as 'metric' | 'imperial') ?? 'metric'\n const screwSpecIdx = (params.screwSpecIdx as number) ?? 4 // M5 default(与 mesh 路径一致)\n const screwThread = (params.screwThread as 'coarse' | 'fine' | 'custom') ?? 'coarse'\n const spec = getScrewSpec(screwSystem, screwSpecIdx)\n const pitch = threadToPitchMm(screwSystem, spec, screwThread)\n\n if (pitch > 0) {\n const threadSolid = threadBrep(kernel, {\n radius: diameter / 2,\n pitch,\n height: depth > 0 ? depth : 20,\n inward: true,\n })\n const dir = new THREE.Vector3(...direction).normalize()\n const fn = new THREE.Vector3(...faceNormal)\n if (dir.dot(fn) > 0) dir.negate()\n\n const zAxis = new THREE.Vector3(0, 0, 1)\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, dir)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n const transMatrix = new THREE.Matrix4().makeTranslation(localPosition[0], localPosition[1], localPosition[2])\n const fullMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n const positionedThread = kernel.transform(threadSolid, matrixToArray(fullMatrix))\n kernel.release(threadSolid)\n\n const finalResult = kernel.cut(result, positionedThread)\n kernel.release(result)\n kernel.release(positionedThread)\n return finalResult\n }\n\n return result\n}\n\n/** BREP 路径:OCCT cut(简单孔)或 threadBrep + cut(螺丝孔)。 */\nfunction drillBrepPath(input: Shape, params: Record<string, unknown>): Shape {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/drill] no OCCT kernel')\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/drill] input is not BREP')\n\n const faceNormal = faceNormalFrom(input, params)\n const direction = resolveDirection(params, faceNormal)\n const holeType = params.holeType as 'simple' | 'screw' | undefined\n\n // 世界坐标 → 局部坐标(cad.load 返回的几何体在原始文件坐标系中)\n const partTransform = getBackends().config.partTransform\n const localPosition = worldToLocalPosition(params.position as [number, number, number], partTransform)\n\n let resultSolid: BrepHandle\n if (holeType === 'screw') {\n resultSolid = screwHoleBrep(kernel, inputSolid, params, direction, faceNormal, localPosition)\n } else {\n resultSolid = drillBrep(kernel, inputSolid, {\n diameter: params.diameter as number,\n depth: params.depth as number,\n position: localPosition,\n direction,\n faceNormal,\n holeType: 'simple',\n })\n }\n\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid })\n}\n\n/** mesh 路径:manifold-3d mesh-CSG。 */\nasync function drillMeshPath(input: Shape, params: Record<string, unknown>): Promise<Shape> {\n const faceNormal = faceNormalFrom(input, params)\n const direction = resolveDirection(params, faceNormal)\n const partTransform = getBackends().config.partTransform\n const localPos = worldToLocalPosition(params.position as [number, number, number], partTransform)\n\n const scale = partTransform?.scale\n const unitScale = scale && (scale[0] !== 1 || scale[1] !== 1 || scale[2] !== 1)\n ? scale[0]\n : 1\n\n return cad.fai_drill(input, {\n diameter: (params.diameter as number) / unitScale,\n depth: (params.depth as number) / unitScale,\n type: (params.depth as number) > 0 ? 'blind' : 'through',\n position: localPos,\n direction,\n faceNormal,\n tolerance: (params.tolerance as number | undefined) !== undefined ? (params.tolerance as number) / unitScale : undefined,\n holeType: params.holeType as 'simple' | 'screw' | undefined,\n screwSystem: params.screwSystem as string | undefined,\n screwSpecIdx: params.screwSpecIdx as number | undefined,\n screwThread: params.screwThread as string | undefined,\n screwHead: params.screwHead as string | undefined,\n })\n}\n\n/**\n * 在几何体上钻孔(CSG 减除)。depth=0 为通孔,>0 为盲孔。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name fai_drill\n * @deprecated `fai_` 前缀 op 是 ../3d_editor 项目特有的操作,不属于 faijs 平台面;将来会迁往该项目并从 faijs 删除。新代码请勿使用。\n * @note 键名以本表为准:`type: 'through'|'blind'` 与 `direction` 为向量的旧素材是无效写法——孔型由 `depth`(0=通孔)推导,`direction` 是 'normal'|'x'|'y'|'z' 枚举。\n * @returns Shape 钻孔后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param params.diameter - 孔径(mm)。type:number required:true\n * @param params.depth - 孔深(mm);0 = 通孔,> 0 = 盲孔。type:number 默认 0\n * @param params.holeType - 孔类型:simple 简单孔 / screw 螺丝孔。type:'simple' | 'screw' 默认 'simple'\n * @param params.direction - 钻孔轴向(normal 表示沿面法向)。type:'normal' | 'x' | 'y' | 'z' 默认 'normal'\n * @param params.position - 孔心位置。type:[x,y,z] 默认 原点\n * @param params.face - 面引用(§6.2 新形态:`FaceTopoRef`,执行期按输入 Shape 解析派生法向;优先于 `faceNormal`)。type:FaceTopoRef\n * @param params.faceNormal - 面法向(决定朝向;历史兜底,§6.2 起宿主不再写,改由 `face` 解析)。type:[x,y,z] 默认 [0,0,1]\n * @param params.tolerance - 公差(mm)。type:number 默认 0.3\n * @param params.screwSystem - 螺丝孔制式(holeType='screw' 时用)。type:'metric' | 'imperial' 默认 'metric'\n * @param params.screwSpecIdx - 螺丝规格索引(holeType='screw' 时用;4 → M5)。type:number 默认 4\n * @param params.screwThread - 螺丝螺纹类型。type:'coarse' | 'fine' | 'custom' 默认 'coarse'\n * @param params.screwHead - 螺丝头型。type:'hex' | 'chc' | 'none' 默认 'none'\n * @example\n * const p = await cad.fai_drill(part0, { diameter: 5 })\n * const p = await cad.fai_drill(part0, { diameter: 5, depth: 3 })\n * const p = await cad.fai_drill(part0, { diameter: 5.2, depth: 8, holeType: 'screw', screwSystem: 'metric', screwSpecIdx: 4, screwThread: 'coarse', screwHead: 'none' })\n */\nexport const fai_drill = defineOp({\n mesh: async (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[stdlib/drill] no input geometry')\n assertDrillParams(params)\n return drillMeshPath(input, params)\n },\n brep: (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[stdlib/drill] no input geometry')\n assertDrillParams(params)\n return drillBrepPath(input, params)\n },\n})\n"]}
|
|
1
|
+
{"version":3,"file":"fai_drill.js","sourceRoot":"","sources":["../../src/api/fai_drill.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib drill — 钻孔库函数\n *\n *\n * dispatchPath 静态判定 brep/mesh。\n * BREP 路径:OCCT cut(简单孔)或 threadBrep + cut(螺丝孔)。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { cad } from '../mesh'\nimport {\n buildDrillToolSolid,\n computeDrillGeometry,\n solidToShape,\n matrixToArray,\n} from '../brep/brep-ops'\nimport { drillBrepWithRoleTable } from '../brep/face-evolution'\nimport { threadBrep } from './brep-mirror/threadFns'\nimport { getScrewSpec, threadToPitchMm } from '../primitives/screw/screw-db'\nimport * as THREE from 'three'\nimport { getBackends, getCurrentStmt } from '../runtime-state'\nimport { fromBrep, brepOf, inputRoleTable } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { BrepHandle } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { assertPositiveNumber, assertNumber, assertVec3 } from './assert'\nimport type { FaceTopoRef } from '../topology/naming'\nimport { resolveFaceGeometry } from './topo-resolve'\n\n// ── per-op 参数自校验(Phase 2.2;stdlib 被直接 import 时的防御层) ──\n\n/**\n * Validate drill parameters: `diameter` must be a positive number, `position`\n * (if provided) a vec3, and `depth` (if provided) a number (<= 0 means a through hole).\n * @param params - the raw drill operation parameters.\n */\nexport function assertDrillParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.diameter, 'drill.diameter')\n if (params.position !== undefined && params.position !== null) {\n assertVec3(params.position, 'drill.position')\n }\n if (params.depth !== undefined && params.depth !== null) {\n assertNumber(params.depth, 'drill.depth')\n }\n}\n\n/** 世界坐标 → 几何体局部坐标(含单位缩放)。 */\nfunction worldToLocalPosition(\n worldPos: [number, number, number],\n partTransform: { position: [number, number, number]; scale?: [number, number, number] } | undefined,\n): [number, number, number] {\n const offset = partTransform?.position\n if (!offset) return worldPos\n const scale = partTransform?.scale\n if (scale && (scale[0] !== 1 || scale[1] !== 1 || scale[2] !== 1)) {\n return [\n (worldPos[0] - offset[0]) / scale[0],\n (worldPos[1] - offset[1]) / scale[1],\n (worldPos[2] - offset[2]) / scale[2],\n ]\n }\n return [\n worldPos[0] - offset[0],\n worldPos[1] - offset[1],\n worldPos[2] - offset[2],\n ]\n}\n\n/** 解析 direction 枚举 → 钻孔方向向量。 */\nfunction resolveDirection(params: Record<string, unknown>, faceNormal: Vec3): Vec3 {\n const directionEnum = (params.direction as string | undefined) ?? 'normal'\n if (directionEnum === 'normal') return faceNormal\n if (directionEnum === 'x') return [-1, 0, 0]\n if (directionEnum === 'y') return [0, -1, 0]\n if (directionEnum === 'z') return [0, 0, -1]\n return faceNormal\n}\n\n/**\n * 面法向派生(§6.2):钻孔轴向是「点击点的真实面法向」——曲面(圆柱面等)上\n * 仅凭 FaceTopoRef 的单一 hint 法向无法还原点击点的径向方向(引擎无 点→曲面\n * 投影 API),故轴向优先使用宿主捕获的 `faceNormal` 快照(与 position 同为点击\n * 快照);`face: FaceTopoRef` 作为持久化身份引用(跨重放追踪),仅在无\n * `faceNormal` 的历史/手写脚本时才按其派生的法向兜底。\n *\n * @param input - the target geometry (used to resolve the face ref).\n * @param params - raw drill params.\n * @returns the face normal the drill axis uses.\n */\nfunction faceNormalFrom(input: Shape, params: Record<string, unknown>): Vec3 {\n const faceNormal = params.faceNormal as Vec3 | undefined\n if (faceNormal && Array.isArray(faceNormal)) {\n return faceNormal\n }\n const face = params.face as FaceTopoRef | undefined\n if (face && typeof face === 'object' && face.kind === 'face') {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n const geom = resolveFaceGeometry(kernel, input, face)\n return geom.normal\n }\n return [0, 0, 1]\n}\n\n/** BREP 螺丝孔:底孔(圆柱 cut)+ 内螺纹(threadBrep + cut)。带 roleTable 传播。 */\nfunction screwHoleBrep(\n kernel: BrepEngineApi,\n upstreamSolid: BrepHandle,\n params: Record<string, unknown>,\n direction: Vec3,\n faceNormal: Vec3,\n localPosition: [number, number, number],\n inputRoleTable: ReadonlyMap<unknown, unknown>,\n outStmt: string,\n): { result: BrepHandle; roleTable: ReadonlyMap<unknown, unknown> } {\n const diameter = params.diameter as number\n const depth = params.depth as number\n // 1. 底孔(圆柱 cut)→ roleTable(hole:0)\n const baseGeom = computeDrillGeometry(kernel, upstreamSolid, {\n diameter,\n depth,\n position: localPosition,\n direction,\n faceNormal,\n })\n const baseTool = buildDrillToolSolid(kernel, baseGeom)\n const baseR = drillBrepWithRoleTable(kernel, upstreamSolid, baseTool, inputRoleTable, outStmt)\n kernel.release(baseTool)\n\n // 2. 螺纹(内螺纹 ridge,inward=true)\n const screwSystem = (params.screwSystem as 'metric' | 'imperial') ?? 'metric'\n const screwSpecIdx = (params.screwSpecIdx as number) ?? 4 // M5 default(与 mesh 路径一致)\n const screwThread = (params.screwThread as 'coarse' | 'fine' | 'custom') ?? 'coarse'\n const spec = getScrewSpec(screwSystem, screwSpecIdx)\n const pitch = threadToPitchMm(screwSystem, spec, screwThread)\n\n if (pitch > 0) {\n const threadSolid = threadBrep(kernel, {\n radius: diameter / 2,\n pitch,\n height: depth > 0 ? depth : 20,\n inward: true,\n })\n const dir = new THREE.Vector3(...direction).normalize()\n const fn = new THREE.Vector3(...faceNormal)\n if (dir.dot(fn) > 0) dir.negate()\n\n const zAxis = new THREE.Vector3(0, 0, 1)\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, dir)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n const transMatrix = new THREE.Matrix4().makeTranslation(localPosition[0], localPosition[1], localPosition[2])\n const fullMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n const positionedThread = kernel.transform(threadSolid, matrixToArray(fullMatrix))\n kernel.release(threadSolid)\n\n const finalR = drillBrepWithRoleTable(kernel, baseR.result, positionedThread, baseR.roleTable, outStmt)\n kernel.release(positionedThread)\n kernel.release(baseR.result)\n return { result: finalR.result, roleTable: finalR.roleTable }\n }\n\n return { result: baseR.result, roleTable: baseR.roleTable }\n}\n\n/** BREP 路径:OCCT cut(简单孔)或 threadBrep + cut(螺丝孔)。带 roleTable 传播。 */\nfunction drillBrepPath(input: Shape, params: Record<string, unknown>): Shape {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/drill] no OCCT kernel')\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/drill] input is not BREP')\n\n const faceNormal = faceNormalFrom(input, params)\n const direction = resolveDirection(params, faceNormal)\n const holeType = params.holeType as 'simple' | 'screw' | undefined\n\n // 世界坐标 → 局部坐标(cad.load 返回的几何体在原始文件坐标系中)\n const partTransform = getBackends().config.partTransform\n const localPosition = worldToLocalPosition(params.position as [number, number, number], partTransform)\n\n const inputTable = inputRoleTable(input) as ReadonlyMap<unknown, unknown> | undefined\n const outStmt = String(getCurrentStmt()?.id ?? '')\n\n let resultSolid: BrepHandle\n let roleTable: ReadonlyMap<unknown, unknown> | undefined\n if (holeType === 'screw') {\n const r = screwHoleBrep(\n kernel, inputSolid, params, direction, faceNormal, localPosition,\n inputTable ?? new Map(), outStmt,\n )\n resultSolid = r.result\n roleTable = r.roleTable\n } else {\n const geom = computeDrillGeometry(kernel, inputSolid, {\n diameter: params.diameter as number,\n depth: params.depth as number,\n position: localPosition,\n direction,\n faceNormal,\n })\n const toolSolid = buildDrillToolSolid(kernel, geom)\n const r = drillBrepWithRoleTable(kernel, inputSolid, toolSolid, inputTable ?? new Map(), outStmt)\n kernel.release(toolSolid)\n resultSolid = r.result\n roleTable = r.roleTable\n }\n\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n}\n\n/** mesh 路径:manifold-3d mesh-CSG。 */\nasync function drillMeshPath(input: Shape, params: Record<string, unknown>): Promise<Shape> {\n const faceNormal = faceNormalFrom(input, params)\n const direction = resolveDirection(params, faceNormal)\n const partTransform = getBackends().config.partTransform\n const localPos = worldToLocalPosition(params.position as [number, number, number], partTransform)\n\n const scale = partTransform?.scale\n const unitScale = scale && (scale[0] !== 1 || scale[1] !== 1 || scale[2] !== 1)\n ? scale[0]\n : 1\n\n return cad.fai_drill(input, {\n diameter: (params.diameter as number) / unitScale,\n depth: (params.depth as number) / unitScale,\n type: (params.depth as number) > 0 ? 'blind' : 'through',\n position: localPos,\n direction,\n faceNormal,\n tolerance: (params.tolerance as number | undefined) !== undefined ? (params.tolerance as number) / unitScale : undefined,\n holeType: params.holeType as 'simple' | 'screw' | undefined,\n screwSystem: params.screwSystem as string | undefined,\n screwSpecIdx: params.screwSpecIdx as number | undefined,\n screwThread: params.screwThread as string | undefined,\n screwHead: params.screwHead as string | undefined,\n })\n}\n\n/**\n * 在几何体上钻孔(CSG 减除)。depth=0 为通孔,>0 为盲孔。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name fai_drill\n * @deprecated **`../3d_editor` 消费面**(原 `@deprecated` 措辞已于 2026-09-22 校正):`fai_` 前缀 op 为编辑器应用提供,不属 faijs 平台面,但**不是废弃项**——它服务真实负载(3d_editor 38 个文件在用)。**变更其 API 形态必须同步更新 `../3d_editor`**(见 `docs/plans/2026-09-22-topology-identity-development-plan.md` §2)。faijs 平台面不提供等价 op(需要时须按平台需求另行设计,不得直接搬用本 op)。\n * @note 键名以本表为准:`type: 'through'|'blind'` 与 `direction` 为向量的旧素材是无效写法——孔型由 `depth`(0=通孔)推导,`direction` 是 'normal'|'x'|'y'|'z' 枚举。\n * @returns Shape 钻孔后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param params.diameter - 孔径(mm)。type:number required:true\n * @param params.depth - 孔深(mm);0 = 通孔,> 0 = 盲孔。type:number 默认 0\n * @param params.holeType - 孔类型:simple 简单孔 / screw 螺丝孔。type:'simple' | 'screw' 默认 'simple'\n * @param params.direction - 钻孔轴向(normal 表示沿面法向)。type:'normal' | 'x' | 'y' | 'z' 默认 'normal'\n * @param params.position - 孔心位置。type:[x,y,z] 默认 原点\n * @param params.face - 面引用(§6.2 新形态:`FaceTopoRef`,执行期按输入 Shape 解析派生法向;优先于 `faceNormal`)。type:FaceTopoRef\n * @param params.faceNormal - 面法向(决定朝向;历史兜底,§6.2 起宿主不再写,改由 `face` 解析)。type:[x,y,z] 默认 [0,0,1]\n * @param params.tolerance - 公差(mm)。type:number 默认 0.3\n * @param params.screwSystem - 螺丝孔制式(holeType='screw' 时用)。type:'metric' | 'imperial' 默认 'metric'\n * @param params.screwSpecIdx - 螺丝规格索引(holeType='screw' 时用;4 → M5)。type:number 默认 4\n * @param params.screwThread - 螺丝螺纹类型。type:'coarse' | 'fine' | 'custom' 默认 'coarse'\n * @param params.screwHead - 螺丝头型。type:'hex' | 'chc' | 'none' 默认 'none'\n * @example\n * const p = await cad.fai_drill(part0, { diameter: 5 })\n * const p = await cad.fai_drill(part0, { diameter: 5, depth: 3 })\n * const p = await cad.fai_drill(part0, { diameter: 5.2, depth: 8, holeType: 'screw', screwSystem: 'metric', screwSpecIdx: 4, screwThread: 'coarse', screwHead: 'none' })\n */\nexport const fai_drill = defineOp({\n mesh: async (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[stdlib/drill] no input geometry')\n assertDrillParams(params)\n return drillMeshPath(input, params)\n },\n brep: (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[stdlib/drill] no input geometry')\n assertDrillParams(params)\n return drillBrepPath(input, params)\n },\n naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } } as Provenance,\n})\n"]}
|
|
@@ -17,7 +17,7 @@ export declare function assertExtrudeParams(params: Record<string, unknown>): vo
|
|
|
17
17
|
* @async true
|
|
18
18
|
* @qual ok
|
|
19
19
|
* @name fai_extrude
|
|
20
|
-
* @deprecated `fai_` 前缀 op
|
|
20
|
+
* @deprecated **`../3d_editor` 消费面**(原 `@deprecated` 措辞已于 2026-09-22 校正):`fai_` 前缀 op 为编辑器应用提供,不属 faijs 平台面,但**不是废弃项**——它服务真实负载。**变更其 API 形态必须同步更新 `../3d_editor`**(见 `docs/plans/2026-09-22-topology-identity-development-plan.md` §2)。faijs 平台面不提供等价 op(需要时须按平台需求另行设计,不得直接搬用本 op)。
|
|
21
21
|
* @returns Shape 拉伸后的几何。
|
|
22
22
|
* @param input - 目标几何。type:Shape required:true
|
|
23
23
|
* @param params.length - 总拉伸量(mm)。type:number required:true
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fai_extrude.d.ts","sourceRoot":"","sources":["../../src/api/fai_extrude.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"fai_extrude.d.ts","sourceRoot":"","sources":["../../src/api/fai_extrude.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAahD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEzE;AAqBD;;;;;;;;;;;;;;;;;;;IAmBI;AACJ,eAAO,MAAM,WAAW;;CAiBtB,CAAA"}
|
package/dist/api/fai_extrude.js
CHANGED
|
@@ -43,7 +43,7 @@ function extrudeBrepPath(input, params) {
|
|
|
43
43
|
* @async true
|
|
44
44
|
* @qual ok
|
|
45
45
|
* @name fai_extrude
|
|
46
|
-
* @deprecated `fai_` 前缀 op
|
|
46
|
+
* @deprecated **`../3d_editor` 消费面**(原 `@deprecated` 措辞已于 2026-09-22 校正):`fai_` 前缀 op 为编辑器应用提供,不属 faijs 平台面,但**不是废弃项**——它服务真实负载。**变更其 API 形态必须同步更新 `../3d_editor`**(见 `docs/plans/2026-09-22-topology-identity-development-plan.md` §2)。faijs 平台面不提供等价 op(需要时须按平台需求另行设计,不得直接搬用本 op)。
|
|
47
47
|
* @returns Shape 拉伸后的几何。
|
|
48
48
|
* @param input - 目标几何。type:Shape required:true
|
|
49
49
|
* @param params.length - 总拉伸量(mm)。type:number required:true
|
|
@@ -74,5 +74,6 @@ export const fai_extrude = defineOp({
|
|
|
74
74
|
assertExtrudeParams(params);
|
|
75
75
|
return extrudeBrepPath(input, params);
|
|
76
76
|
},
|
|
77
|
+
naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }] } },
|
|
77
78
|
});
|
|
78
79
|
//# sourceMappingURL=fai_extrude.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fai_extrude.js","sourceRoot":"","sources":["../../src/api/fai_extrude.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"fai_extrude.js","sourceRoot":"","sources":["../../src/api/fai_extrude.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAI/C,wDAAwD;AAExD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,MAA+B;IACjE,oBAAoB,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAA;AACvD,CAAC;AAED,gDAAgD;AAChD,SAAS,eAAe,CAAC,KAAY,EAAE,MAA+B;IACpE,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC,MAAM,CAAC,IAA4B,CAAA;IAChE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;IAC/D,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IAC1D,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;IAEtE,MAAM,MAAM,GAAI,MAAM,CAAC,MAA2B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAC/D,MAAM,YAAY,GAAI,MAAM,CAAC,YAAmC,IAAI,CAAC,CAAA;IACrE,MAAM,WAAW,GAAG,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE;QAClD,MAAM;QACN,YAAY;QACZ,MAAM,EAAE,MAAM,CAAC,MAAgB;QAC/B,IAAI,EAAE,MAAM,CAAC,IAAuD;KACrE,CAAC,CAAA;IAEF,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,CAAC,CAAA;AAC5E,CAAC;AAED;;;;;;;;;;;;;;;;;;;IAmBI;AACJ,MAAM,CAAC,MAAM,WAAW,GAAG,QAAQ,CAAC;IAClC,IAAI,EAAE,KAAK,EAAE,KAAY,EAAE,MAA+B,EAAE,EAAE;QAC5D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;QACjE,mBAAmB,CAAC,MAAM,CAAC,CAAA;QAC3B,OAAO,GAAG,CAAC,WAAW,CAAC,KAAK,EAAE;YAC5B,MAAM,EAAG,MAAM,CAAC,MAA2B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;YACxD,YAAY,EAAG,MAAM,CAAC,YAAmC,IAAI,CAAC;YAC9D,MAAM,EAAE,MAAM,CAAC,MAAgB;YAC/B,IAAI,EAAE,MAAM,CAAC,IAAuD;SACrE,CAAC,CAAA;IACJ,CAAC;IACD,IAAI,EAAE,CAAC,KAAY,EAAE,MAA+B,EAAE,EAAE;QACtD,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAA;QACjE,mBAAmB,CAAC,MAAM,CAAC,CAAA;QAC3B,OAAO,eAAe,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;IACvC,CAAC;IACD,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,EAAE,EAAgB;CAC7J,CAAC,CAAA","sourcesContent":["/**\n * stdlib extrude — 拉伸库函数\n *\n *\n * dispatchPath 静态判定 brep/mesh,产物经 solid()/fromBrep() 构造器创建。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { extrudeBrep, solidToShape } from '../brep/brep-ops'\nimport { getBackends } from '../runtime-state'\nimport { fromBrep, brepOf } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { assertPositiveNumber } from './assert'\nimport type { BrepHandle } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\n\n// ── per-op 参数自校验(Phase 2.2;stdlib 被直接 import 时的防御层) ──\n\n/**\n * Validate extrude parameters: `length` must be a positive number.\n * @param params - the raw extrude operation parameters.\n */\nexport function assertExtrudeParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.length, 'extrude.length')\n}\n\n/** BREP 路径:OCCT extrude + 三角化 + fromBrep 登记。 */\nfunction extrudeBrepPath(input: Shape, params: Record<string, unknown>): Shape {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/extrude] no OCCT kernel')\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/extrude] input is not BREP')\n\n const normal = (params.normal as Vec3 | undefined) ?? [0, 0, 1]\n const originOffset = (params.originOffset as number | undefined) ?? 0\n const resultSolid = extrudeBrep(kernel, inputSolid, {\n normal,\n originOffset,\n length: params.length as number,\n mode: params.mode as 'centered' | 'forward' | 'backward' | undefined,\n })\n\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid })\n}\n\n/**\n * 沿法向拉伸几何。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual ok\n * @name fai_extrude\n * @deprecated **`../3d_editor` 消费面**(原 `@deprecated` 措辞已于 2026-09-22 校正):`fai_` 前缀 op 为编辑器应用提供,不属 faijs 平台面,但**不是废弃项**——它服务真实负载。**变更其 API 形态必须同步更新 `../3d_editor`**(见 `docs/plans/2026-09-22-topology-identity-development-plan.md` §2)。faijs 平台面不提供等价 op(需要时须按平台需求另行设计,不得直接搬用本 op)。\n * @returns Shape 拉伸后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param params.length - 总拉伸量(mm)。type:number required:true\n * @param params.mode - 拉伸方向:centered 双向各一半 / forward 正向 / backward 反向。type:'centered' | 'forward' | 'backward' 默认 'centered'\n * @param params.normal - 拉伸方向法向。type:[x,y,z] 默认 当前面法向 [0,0,1]\n * @param params.originOffset - 切面在法向上的偏移。type:number 默认 0\n * @param params.space - 坐标空间声明。type:'local' | 'world'\n * @example\n * const p = await cad.fai_extrude(part0, { length: 10 })\n * const p = await cad.fai_extrude(part0, { length: 10, mode: 'forward' })\n * const p = await cad.fai_extrude(part0, { length: 10, normal: [0,0,1], originOffset: 2 })\n */\nexport const fai_extrude = defineOp({\n mesh: async (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[stdlib/extrude] no input geometry')\n assertExtrudeParams(params)\n return cad.fai_extrude(input, {\n normal: (params.normal as Vec3 | undefined) ?? [0, 0, 1],\n originOffset: (params.originOffset as number | undefined) ?? 0,\n length: params.length as number,\n mode: params.mode as 'centered' | 'forward' | 'backward' | undefined,\n })\n },\n brep: (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[stdlib/extrude] no input geometry')\n assertExtrudeParams(params)\n return extrudeBrepPath(input, params)\n },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }] } } as Provenance,\n})\n"]}
|
package/dist/api/fai_split.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ import type { Shape } from '../mesh/types.js';
|
|
|
12
12
|
* @async true
|
|
13
13
|
* @qual warn
|
|
14
14
|
* @name fai_split
|
|
15
|
-
* @deprecated `fai_` 前缀 op
|
|
15
|
+
* @deprecated **`../3d_editor` 消费面**(原 `@deprecated` 措辞已于 2026-09-22 校正):`fai_` 前缀 op 为编辑器应用提供,不属 faijs 平台面,但**不是废弃项**——它服务真实负载。**变更其 API 形态必须同步更新 `../3d_editor`**(见 `docs/plans/2026-09-22-topology-identity-development-plan.md` §2)。faijs 平台面不提供等价 op(需要时须按平台需求另行设计,不得直接搬用本 op)。
|
|
16
16
|
* @returns { front: Shape; back: Shape } 必须用解构 `const { front: partA, back: partB } = await cad.fai_split(...)` 取出两个零件。
|
|
17
17
|
* @param input - 目标几何。type:Shape required:true
|
|
18
18
|
* @param params.cutMode - 切割模式。type:'plane' | 'dovetail' | 'dowel' | 'tenon' | 'straight-tenon' | 'straight' 默认 'plane'
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fai_split.d.ts","sourceRoot":"","sources":["../../src/api/fai_split.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"fai_split.d.ts","sourceRoot":"","sources":["../../src/api/fai_split.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAgOhD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAkCI;AACJ,eAAO,MAAM,SAAS;;CAiBpB,CAAA"}
|
package/dist/api/fai_split.js
CHANGED
|
@@ -203,7 +203,7 @@ async function splitMeshPath(input, params) {
|
|
|
203
203
|
* @async true
|
|
204
204
|
* @qual warn
|
|
205
205
|
* @name fai_split
|
|
206
|
-
* @deprecated `fai_` 前缀 op
|
|
206
|
+
* @deprecated **`../3d_editor` 消费面**(原 `@deprecated` 措辞已于 2026-09-22 校正):`fai_` 前缀 op 为编辑器应用提供,不属 faijs 平台面,但**不是废弃项**——它服务真实负载。**变更其 API 形态必须同步更新 `../3d_editor`**(见 `docs/plans/2026-09-22-topology-identity-development-plan.md` §2)。faijs 平台面不提供等价 op(需要时须按平台需求另行设计,不得直接搬用本 op)。
|
|
207
207
|
* @returns { front: Shape; back: Shape } 必须用解构 `const { front: partA, back: partB } = await cad.fai_split(...)` 取出两个零件。
|
|
208
208
|
* @param input - 目标几何。type:Shape required:true
|
|
209
209
|
* @param params.cutMode - 切割模式。type:'plane' | 'dovetail' | 'dowel' | 'tenon' | 'straight-tenon' | 'straight' 默认 'plane'
|
|
@@ -249,5 +249,6 @@ export const fai_split = defineOp({
|
|
|
249
249
|
return splitBrepPath(input, params);
|
|
250
250
|
},
|
|
251
251
|
outputs: ['front', 'back'],
|
|
252
|
+
naming: { kind: 'subdivide' },
|
|
252
253
|
});
|
|
253
254
|
//# sourceMappingURL=fai_split.js.map
|