@faicad/faijs 0.19.0 → 0.22.2
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/brep-mirror/joinery-brep.d.ts.map +1 -1
- package/dist/api/brep-mirror/joinery-brep.js +3 -1
- package/dist/api/brep-mirror/joinery-brep.js.map +1 -1
- package/dist/api/generated/script-face-manifest.d.ts +4 -0
- package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
- package/dist/api/generated/script-face-manifest.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/primitives.d.ts +4 -3
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +9 -3
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/profile.d.ts +34 -5
- package/dist/api/profile.d.ts.map +1 -1
- package/dist/api/profile.js +60 -9
- package/dist/api/profile.js.map +1 -1
- package/dist/api/punch-hole.d.ts +3 -0
- package/dist/api/punch-hole.d.ts.map +1 -1
- package/dist/api/punch-hole.js.map +1 -1
- package/dist/api/sketch-on-plane.d.ts +12 -6
- package/dist/api/sketch-on-plane.d.ts.map +1 -1
- package/dist/api/sketch-on-plane.js +11 -8
- package/dist/api/sketch-on-plane.js.map +1 -1
- package/dist/api/surface/arg-spec.d.ts +8 -0
- package/dist/api/surface/arg-spec.d.ts.map +1 -1
- package/dist/api/surface/arg-spec.js.map +1 -1
- package/dist/api/transform.d.ts +5 -5
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +12 -10
- package/dist/api/transform.js.map +1 -1
- package/dist/api/xml-dom.d.ts +27 -0
- package/dist/api/xml-dom.d.ts.map +1 -0
- package/dist/api/xml-dom.js +45 -0
- package/dist/api/xml-dom.js.map +1 -0
- package/dist/brep/brep-ops.d.ts +4 -4
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +8 -6
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/brep-topology.d.ts.map +1 -1
- package/dist/brep/brep-topology.js +3 -1
- package/dist/brep/brep-topology.js.map +1 -1
- package/dist/brep/export/export-model.d.ts +79 -0
- package/dist/brep/export/export-model.d.ts.map +1 -0
- package/dist/brep/export/export-model.js +335 -0
- package/dist/brep/export/export-model.js.map +1 -0
- package/dist/brep/primitives-brep.d.ts.map +1 -1
- package/dist/brep/primitives-brep.js +3 -1
- package/dist/brep/primitives-brep.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +4 -2
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts +4 -0
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +17 -1
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +24 -1
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +53 -3
- 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 +15 -0
- package/dist/define-op.js.map +1 -1
- package/dist/env-agnostic.d.ts +7 -7
- package/dist/env-agnostic.d.ts.map +1 -1
- package/dist/env-agnostic.js +3 -3
- package/dist/env-agnostic.js.map +1 -1
- package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
- package/dist/geometry2d/bridge/lift-on-plane.js +6 -0
- package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
- package/dist/geometry2d/pen-sketcher.d.ts +25 -0
- package/dist/geometry2d/pen-sketcher.d.ts.map +1 -1
- package/dist/geometry2d/pen-sketcher.js +43 -0
- package/dist/geometry2d/pen-sketcher.js.map +1 -1
- package/dist/lang/code-to-args.d.ts +29 -3
- package/dist/lang/code-to-args.d.ts.map +1 -1
- package/dist/lang/code-to-args.js +41 -2
- package/dist/lang/code-to-args.js.map +1 -1
- package/dist/lang/codegen.d.ts +45 -1
- package/dist/lang/codegen.d.ts.map +1 -1
- package/dist/lang/codegen.js +135 -6
- package/dist/lang/codegen.js.map +1 -1
- package/dist/lang/host-arg.d.ts +6 -0
- package/dist/lang/host-arg.d.ts.map +1 -1
- package/dist/lang/host-arg.js.map +1 -1
- package/dist/lang/metadata-extractor.d.ts +25 -0
- package/dist/lang/metadata-extractor.d.ts.map +1 -1
- package/dist/lang/metadata-extractor.js +289 -25
- package/dist/lang/metadata-extractor.js.map +1 -1
- package/dist/lang/parse-error.d.ts +7 -1
- package/dist/lang/parse-error.d.ts.map +1 -1
- package/dist/lang/parse-error.js.map +1 -1
- package/dist/lang/security-scanner.d.ts +9 -1
- package/dist/lang/security-scanner.d.ts.map +1 -1
- package/dist/lang/security-scanner.js +38 -1
- package/dist/lang/security-scanner.js.map +1 -1
- package/dist/mesh/io.d.ts +62 -9
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +124 -17
- package/dist/mesh/io.js.map +1 -1
- package/dist/mesh/threemf-loader.d.ts +15 -0
- package/dist/mesh/threemf-loader.d.ts.map +1 -0
- package/dist/mesh/threemf-loader.js +163 -0
- package/dist/mesh/threemf-loader.js.map +1 -0
- package/dist/mesh/transform.d.ts +2 -2
- package/dist/mesh/transform.d.ts.map +1 -1
- package/dist/mesh/transform.js +3 -3
- package/dist/mesh/transform.js.map +1 -1
- package/dist/mesh/types.d.ts +1 -1
- package/dist/mesh/types.d.ts.map +1 -1
- package/dist/mesh/types.js.map +1 -1
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +53 -26
- package/dist/node-host/cli.js.map +1 -1
- package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
- package/dist/occt-kernel/occtKernel.js +4 -2
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
- package/dist/occt-kernel/topologyExt.js +4 -1
- package/dist/occt-kernel/topologyExt.js.map +1 -1
- package/dist/runtime-state.d.ts +18 -0
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +23 -0
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +1 -1
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +1 -1
- package/dist/sdk.js.map +1 -1
- package/dist/tolerance.d.ts +38 -0
- package/dist/tolerance.d.ts.map +1 -0
- package/dist/tolerance.js +40 -0
- package/dist/tolerance.js.map +1 -0
- package/dist/topology/naming/score.js +3 -3
- package/dist/topology/naming/score.js.map +1 -1
- package/dist/units.d.ts +248 -0
- package/dist/units.d.ts.map +1 -0
- package/dist/units.js +397 -0
- package/dist/units.js.map +1 -0
- package/package.json +11 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joinery-brep.d.ts","sourceRoot":"","sources":["../../../src/api/brep-mirror/joinery-brep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAA;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"joinery-brep.d.ts","sourceRoot":"","sources":["../../../src/api/brep-mirror/joinery-brep.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,8 @@
|
|
|
18
18
|
import * as THREE from 'three';
|
|
19
19
|
import { getSolidBoundingBox } from '../../brep/brep-utils.js';
|
|
20
20
|
import { splitBrep, matrixToArray } from '../../brep/brep-ops.js';
|
|
21
|
+
import { DEFAULT_LINEAR_DEFLECTION } from '../../tolerance.js';
|
|
22
|
+
import { mm } from '../../units.js';
|
|
21
23
|
// ─── Union-Find(与 csg-worker.ts SimpleUnionFind 一致) ───
|
|
22
24
|
class SimpleUnionFind {
|
|
23
25
|
parent;
|
|
@@ -170,7 +172,7 @@ function computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, widthDir,
|
|
|
170
172
|
/** 将 OCCT solid 三角化为 MeshData(用于截面分析) */
|
|
171
173
|
function solidToMeshData(kernel, solid) {
|
|
172
174
|
const mesh = kernel.meshShape(solid, {
|
|
173
|
-
linearDeflection:
|
|
175
|
+
linearDeflection: DEFAULT_LINEAR_DEFLECTION.as(mm),
|
|
174
176
|
angularDeflection: (2 * Math.PI) / 32,
|
|
175
177
|
});
|
|
176
178
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"joinery-brep.js","sourceRoot":"","sources":["../../../src/api/brep-mirror/joinery-brep.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * BREP 榫卯结构操作 — 用 OCCT 精确实体复刻 mesh 路径的榫卯布尔序列\n *\n * See docs/api-contract.md §8 (dual-path geometry contract) and §10.5 (split).\n *\n * 与 mesh 路径(joinery-shapes.ts + csg-worker.ts)对照:\n * - mesh 路径:buildWedgeGeometry/buildDowelGeometry/buildStraightTenonGeometry → Manifold CSG\n * - BREP 路径:buildWedgeSolid/buildDowelSolid/buildTenonSolid → OCCT fuse/cut/common\n *\n * 坐标框架与 mesh 路径完全一致:\n * - normal: 切割平面法线(单位向量,指向上方)\n * - widthDir: 挤出方向(单位向量)\n * - depthDir = normalize(cross(normal, widthDir))\n * - planeCenter: 切割平面中心\n *\n * 所有函数都是纯函数,输入输出均为 OCCT BrepHandle,调用方负责句柄生命周期。\n */\n\nimport * as THREE from 'three'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { Vec3 } from '../../mesh/types'\nimport { getSolidBoundingBox } from '../../brep/brep-utils'\nimport { splitBrep, matrixToArray } from '../../brep/brep-ops'\n\n// ─── 坐标框架 ───\n\n/** 榫卯操作的坐标框架(与 joinery-shapes.ts 一致) */\nexport interface JoineryBasis {\n /** 切割平面法线(单位向量) */\n normal: Vec3\n /** 宽度/挤出方向(单位向量) */\n widthDir: Vec3\n /** 深度方向 = normalize(cross(normal, widthDir)) */\n depthDir: Vec3\n /** 切割平面中心 */\n planeCenter: Vec3\n /** 平面原点偏移 = dot(normal, planeCenter) */\n planeDistance: number\n}\n\n// ─── Union-Find(与 csg-worker.ts SimpleUnionFind 一致) ───\n\nclass SimpleUnionFind {\n private parent: number[]\n private rank: number[]\n\n constructor(n: number) {\n this.parent = Array.from({ length: n }, (_, i) => i)\n this.rank = new Array(n).fill(0)\n }\n\n find(x: number): number {\n if (this.parent[x] !== x) {\n this.parent[x] = this.find(this.parent[x])\n }\n return this.parent[x]\n }\n\n union(x: number, y: number): void {\n const px = this.find(x)\n const py = this.find(y)\n if (px === py) return\n if (this.rank[px] < this.rank[py]) {\n this.parent[px] = py\n } else if (this.rank[px] > this.rank[py]) {\n this.parent[py] = px\n } else {\n this.parent[py] = px\n this.rank[px]++\n }\n }\n}\n\n// ─── 截面分析(从 mesh 三角化提取截面信息,与 csg-worker.ts 算法一致) ───\n\ninterface MeshData {\n positions: Float32Array\n indices: Uint32Array\n}\n\n/**\n * 检测切割平面上的帽面连通分量。\n *\n * 与 csg-worker.ts detectCapComponents 算法一致:\n * 1. 找到所有顶点在切割平面上的三角形\n * 2. 用 union-find 按共享顶点分组\n * 3. 返回每分量的顶点索引集合\n */\nfunction detectCapComponentsFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n): Set<number>[] {\n const eps = 0.001\n const { positions, indices } = mesh\n const vertCount = positions.length / 3\n if (indices.length === 0) return []\n\n // 找到所有帽面三角形\n const capVertSet = new Set<number>()\n interface CapTri { v0: number; v1: number; v2: number }\n const capTris: CapTri[] = []\n const triCount = indices.length / 3\n for (let t = 0; t < triCount; t++) {\n const i0 = indices[t * 3]\n const i1 = indices[t * 3 + 1]\n const i2 = indices[t * 3 + 2]\n const d0 = Math.abs(\n positions[i0 * 3] * normal[0] +\n positions[i0 * 3 + 1] * normal[1] +\n positions[i0 * 3 + 2] * normal[2] - planeDistance,\n )\n const d1 = Math.abs(\n positions[i1 * 3] * normal[0] +\n positions[i1 * 3 + 1] * normal[1] +\n positions[i1 * 3 + 2] * normal[2] - planeDistance,\n )\n const d2 = Math.abs(\n positions[i2 * 3] * normal[0] +\n positions[i2 * 3 + 1] * normal[1] +\n positions[i2 * 3 + 2] * normal[2] - planeDistance,\n )\n if (d0 < eps && d1 < eps && d2 < eps) {\n capTris.push({ v0: i0, v1: i1, v2: i2 })\n capVertSet.add(i0); capVertSet.add(i1); capVertSet.add(i2)\n }\n }\n if (capTris.length === 0) return []\n\n // Union-find 按共享顶点分组\n const uf = new SimpleUnionFind(vertCount)\n for (const tri of capTris) {\n uf.union(tri.v0, tri.v1)\n uf.union(tri.v1, tri.v2)\n uf.union(tri.v0, tri.v2)\n }\n\n // 按根节点分组\n const compMap = new Map<number, Set<number>>()\n for (const vi of capVertSet) {\n const root = uf.find(vi)\n if (!compMap.has(root)) compMap.set(root, new Set<number>())\n compMap.get(root)!.add(vi)\n }\n\n return Array.from(compMap.values())\n}\n\n/**\n * 计算切割平面上截面顶点的质心。\n *\n * 与 csg-worker.ts computeCrossSectionCentroid 算法一致。\n */\nfunction computeCrossSectionCentroidFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n fallback: Vec3,\n comp?: Set<number>,\n): Vec3 {\n const eps = 0.001\n const { positions } = mesh\n let cx = 0, cy = 0, cz = 0\n let count = 0\n\n const vertCount = positions.length / 3\n for (let i = 0; i < vertCount; i++) {\n if (comp && !comp.has(i)) continue\n\n const x = positions[i * 3]\n const y = positions[i * 3 + 1]\n const z = positions[i * 3 + 2]\n\n const dist = x * normal[0] + y * normal[1] + z * normal[2] - planeDistance\n if (Math.abs(dist) < eps) {\n cx += x\n cy += y\n cz += z\n count++\n }\n }\n\n if (count === 0) return fallback\n return [cx / count, cy / count, cz / count]\n}\n\n/**\n * 计算切割平面上截面沿指定方向的宽度。\n *\n * 与 csg-worker.ts computeCrossSectionWidth 算法一致。\n */\nfunction computeCrossSectionWidthFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n widthDir: Vec3,\n comp?: Set<number>,\n): number {\n const eps = 0.001\n const { positions } = mesh\n let minProj = Infinity\n let maxProj = -Infinity\n let found = false\n\n const vertCount = positions.length / 3\n for (let i = 0; i < vertCount; i++) {\n if (comp && !comp.has(i)) continue\n\n const x = positions[i * 3]\n const y = positions[i * 3 + 1]\n const z = positions[i * 3 + 2]\n\n const dist = x * normal[0] + y * normal[1] + z * normal[2] - planeDistance\n if (Math.abs(dist) < eps) {\n const proj = x * widthDir[0] + y * widthDir[1] + z * widthDir[2]\n if (proj < minProj) minProj = proj\n if (proj > maxProj) maxProj = proj\n found = true\n }\n }\n\n if (!found) return 0\n return maxProj - minProj\n}\n\n/** 将 OCCT solid 三角化为 MeshData(用于截面分析) */\nfunction solidToMeshData(kernel: BrepEngineApi, solid: BrepHandle): MeshData {\n const mesh = kernel.meshShape(solid, {\n linearDeflection: 0.1,\n angularDeflection: (2 * Math.PI) / 32,\n })\n return {\n positions: new Float32Array(mesh.positions),\n indices: new Uint32Array(mesh.indices),\n }\n}\n\n// ─── 基本体构造(BREP 等价物) ───\n\n/**\n * 构造局部的变换矩阵:local X → widthDir, Y → depthDir, Z → normal,再平移到 origin。\n */\nfunction makeBasisTransform(basis: JoineryBasis, origin: Vec3): THREE.Matrix4 {\n const basisMatrix = new THREE.Matrix4().makeBasis(\n new THREE.Vector3(...basis.widthDir),\n new THREE.Vector3(...basis.depthDir),\n new THREE.Vector3(...basis.normal),\n )\n const transMatrix = new THREE.Matrix4().makeTranslation(origin[0], origin[1], origin[2])\n return new THREE.Matrix4().multiplyMatrices(transMatrix, basisMatrix)\n}\n\n/**\n * 梯形棱柱(燕尾楔)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildWedgeGeometry 的 8 顶点拓扑:\n * - 梯形截面在 normal-depthDir 平面\n * - 底边(宽)在 planeCenter - normal*depth\n * - 顶边(窄)在 planeCenter\n * - 沿 widthDir 拉伸 extrudeLength,居中于 planeCenter\n *\n * 用 kernel.makeLineEdge + makeWire + makeFace + extrude 构造实体,\n * 然后用 transform 对齐到世界坐标系。\n * @param kernel - the BREP engine API.\n * @param basis - the joinery coordinate frame (normal/widthDir/depthDir/planeCenter).\n * @param depth - the wedge depth along the normal direction.\n * @param width - the wedge bottom width.\n * @param angleDeg - the dovetail flap angle in degrees.\n * @param extrudeLength - the extrusion length along the width direction.\n * @returns the constructed wedge solid handle.\n */\nexport function buildWedgeSolid(\n kernel: BrepEngineApi,\n basis: JoineryBasis,\n depth: number,\n width: number,\n angleDeg: number,\n extrudeLength: number,\n): BrepHandle {\n const { planeCenter } = basis\n const angleRad = (angleDeg * Math.PI) / 180\n\n const halfWidth = width / 2\n const halfTopWidth = Math.max(0, halfWidth - depth / Math.tan(angleRad))\n const halfExtrude = extrudeLength / 2\n\n // 在局部坐标系中构造梯形面(YZ 平面,X = -halfExtrude)\n // 局部: X → widthDir, Y → depthDir, Z → normal\n const xLocal = -halfExtrude\n const v0 = { x: xLocal, y: -halfWidth, z: -depth } // bottomLeft\n const v1 = { x: xLocal, y: halfWidth, z: -depth } // bottomRight\n const v2 = { x: xLocal, y: halfTopWidth, z: 0 } // topRight\n const v3 = { x: xLocal, y: -halfTopWidth, z: 0 } // topLeft\n\n // 构建梯形 wire\n const edges: BrepHandle[] = []\n edges.push(kernel.makeLineEdge(v0, v1))\n edges.push(kernel.makeLineEdge(v1, v2))\n edges.push(kernel.makeLineEdge(v2, v3))\n edges.push(kernel.makeLineEdge(v3, v0))\n\n const wire = kernel.makeWire(edges)\n const face = kernel.makeFace(wire)\n\n // 沿 X 轴(= widthDir)拉伸 extrudeLength\n const extruded = kernel.extrude(face, extrudeLength, 0, 0)\n\n // 释放中间句柄\n for (const e of edges) kernel.release(e)\n kernel.release(wire)\n kernel.release(face)\n\n // 变换到世界坐标系\n const fullMatrix = makeBasisTransform(basis, planeCenter)\n const result = kernel.transform(extruded, matrixToArray(fullMatrix))\n kernel.release(extruded)\n\n return result\n}\n\n/**\n * 圆柱(定位销)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildDowelGeometry:\n * - 圆截面在 widthDir-depthDir 平面,中心在 centroid\n * - 从切割平面向下延伸 height(沿 -normal)\n *\n * 用 kernel.makeCylinder + transform 对齐方向。\n * @param kernel - the BREP engine API.\n * @param centroid - the centroid where the dowel is placed.\n * @param basis - the joinery coordinate frame.\n * @param diameter - the dowel diameter.\n * @param height - the dowel height along the normal direction.\n * @returns the constructed dowel solid handle.\n */\nexport function buildDowelSolid(\n kernel: BrepEngineApi,\n centroid: Vec3,\n basis: JoineryBasis,\n diameter: number,\n height: number,\n): BrepHandle {\n const radius = diameter / 2\n const { normal } = basis\n\n // OCCT makeCylinder 创建 Z 轴方向圆柱(Z=0 → Z=height)\n // 需要旋转使 Z 轴对齐 -normal(圆柱向下延伸),且顶部在 centroid\n const cyl = kernel.makeCylinder(radius, height)\n\n // 旋转 Z → -normal\n const zAxis = new THREE.Vector3(0, 0, 1)\n const negNormal = new THREE.Vector3(-normal[0], -normal[1], -normal[2]).normalize()\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, negNormal)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n\n // 平移到 centroid(旋转后 Z=0 对应 centroid,即切割平面上的顶面)\n const transMatrix = new THREE.Matrix4().makeTranslation(centroid[0], centroid[1], centroid[2])\n const fullMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n const result = kernel.transform(cyl, matrixToArray(fullMatrix))\n kernel.release(cyl)\n\n return result\n}\n\n/**\n * 长方体(直榫)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildStraightTenonGeometry:\n * - 方截面在 widthDir-depthDir 平面,中心在 centroid\n * - 从切割平面向下延伸 height(沿 -normal)\n *\n * 用 kernel.makeBoxFromCorners + transform 对齐方向。\n * @param kernel - the BREP engine API.\n * @param centroid - the centroid where the tenon is placed.\n * @param basis - the joinery coordinate frame.\n * @param sideLength - the tenon square side length.\n * @param height - the tenon height along the normal direction.\n * @returns the constructed tenon solid handle.\n */\nexport function buildTenonSolid(\n kernel: BrepEngineApi,\n centroid: Vec3,\n basis: JoineryBasis,\n sideLength: number,\n height: number,\n): BrepHandle {\n const half = sideLength / 2\n\n // 在局部坐标系中创建盒子:X ∈ [-half, half], Y ∈ [-half, half], Z ∈ [-height, 0]\n // 局部: X → widthDir, Y → depthDir, Z → normal\n const localBox = kernel.makeBoxFromCorners(\n { x: -half, y: -half, z: -height },\n { x: half, y: half, z: 0 },\n )\n\n // 变换到世界坐标系\n const fullMatrix = makeBasisTransform(basis, centroid)\n const result = kernel.transform(localBox, matrixToArray(fullMatrix))\n kernel.release(localBox)\n\n return result\n}\n\n// ─── 截面质心 / 多截面检测 ───\n\n/** 截面分量信息 */\nexport interface CrossSectionComponent {\n /** 分量质心 */\n centroid: Vec3\n /** 分量面积(近似,用于排序) */\n area: number\n}\n\n/**\n * 检测上部实体在切割平面上的截面连通分量。\n *\n * BREP 等价物:将 upper solid 三角化后,用与 mesh 路径 detectCapComponents\n * 完全相同的算法(找帽面三角形 → union-find)检测连通分量。\n *\n * 与 csg-worker.ts detectCapComponents + computeCrossSectionCentroid 一致。\n * @param kernel - the BREP engine API.\n * @param upper - the upper solid whose cross section is analyzed.\n * @param basis - the joinery coordinate frame.\n * @returns the detected cross-section components (centroid + area).\n */\nexport function detectCrossSectionComponents(\n kernel: BrepEngineApi,\n upper: BrepHandle,\n basis: JoineryBasis,\n): CrossSectionComponent[] {\n const { normal, planeDistance, widthDir, depthDir, planeCenter } = basis\n const mesh = solidToMeshData(kernel, upper)\n const components = detectCapComponentsFromMesh(mesh, normal, planeDistance)\n\n if (components.length === 0) {\n // 无帽面 → 返回单个全局质心(planeCenter)作为回退\n return [{ centroid: planeCenter, area: 0 }]\n }\n\n return components.map(comp => {\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter, comp)\n const compWidth = computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, widthDir, comp)\n const compDepth = computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, depthDir, comp)\n return { centroid, area: compWidth * compDepth }\n })\n}\n\n// ─── 布尔序列(1:1 复刻 csg-worker.ts) ───\n\n/** dovetail 布尔分割的结果 */\nexport interface DovetailSplitBrepResult {\n /** 上部 + 楔(法线正方向半部分加燕尾榫) */\n front: BrepHandle\n /** 下部 - 凹腔(法线负方向半部分减燕尾槽) */\n back: BrepHandle\n}\n\n/** dowel/tenon 布尔分割的结果 */\nexport interface DowelOrTenonSplitBrepResult {\n /** 上部 + 销/榫(法线正方向半部分加圆柱/方柱) */\n front: BrepHandle\n /** 下部 - 孔(法线负方向半部分减圆柱/方柱) */\n back: BrepHandle\n}\n\n/** groove 参数 */\nexport interface GrooveParams {\n depth: number\n depthTolerance: number\n width: number\n widthTolerance: number\n flapsAngle: number\n}\n\n/**\n * Dovetail(燕尾)布尔分割 — BREP 等价物。\n *\n * 1:1 复刻 csg-worker.ts dovetailBooleanSplit:\n * 1. splitBrep → upper + lower\n * 2. 计算 crossSectionWidth(bbox 投影近似)\n * 3. buildWedgeSolid(overhang=20)→ common(wedge, lower) 裁剪贴合\n * 4. fuse(upper, wedgeTrimmed) → upper'\n * 5. buildWedgeSolid(公差)→ cut(lower, wedgeTol) → lower'\n * @param kernel - the BREP engine API.\n * @param original - the original solid to split.\n * @param basis - the joinery coordinate frame.\n * @param groove - the dovetail groove parameters.\n * @returns the split result with front (upper + wedge) and back (lower - cavity) handles.\n */\nexport function dovetailBooleanSplitBrep(\n kernel: BrepEngineApi,\n original: BrepHandle,\n basis: JoineryBasis,\n groove: GrooveParams,\n): DovetailSplitBrepResult {\n const { normal, widthDir, planeCenter, planeDistance } = basis\n\n // Step 1: 平面分割 → upper + lower\n const splitResult = splitBrep(kernel, original, { normal, planeDistance, planeCenter })\n let upper = splitResult.front\n let lower = splitResult.back\n\n // Step 2: 计算截面宽度(bbox 投影近似,后续 common 会裁回真实边界)\n const upperBbox = getSolidBoundingBox(kernel, upper)\n const upperSize: Vec3 = [\n upperBbox.max[0] - upperBbox.min[0],\n upperBbox.max[1] - upperBbox.min[1],\n upperBbox.max[2] - upperBbox.min[2],\n ]\n let crossSectionWidth =\n Math.abs(upperSize[0] * widthDir[0]) +\n Math.abs(upperSize[1] * widthDir[1]) +\n Math.abs(upperSize[2] * widthDir[2])\n if (crossSectionWidth <= 0) crossSectionWidth = 10 // 安全回退\n const extrudeLength = crossSectionWidth + 0.2\n const overhang = 20\n\n // Step 3: 构造楔(带 overhang)\n const wedgeW = buildWedgeSolid(kernel, basis, groove.depth, groove.width, groove.flapsAngle, extrudeLength + overhang)\n\n // Step 4: common(wedge, lower) → 裁剪楔贴合模型边界\n const wedgeTrimmed = kernel.common(wedgeW, lower)\n kernel.release(wedgeW)\n\n // Step 5: fuse(upper, wedgeTrimmed) → upper'\n const newUpper = kernel.fuse(upper, wedgeTrimmed)\n kernel.release(upper)\n kernel.release(wedgeTrimmed)\n upper = newUpper\n\n // Step 6: 构造公差楔\n const wedgeTol = buildWedgeSolid(\n kernel, basis,\n groove.depth + groove.depthTolerance,\n groove.width + groove.widthTolerance,\n groove.flapsAngle,\n extrudeLength + overhang,\n )\n\n // Step 7: cut(lower, wedgeTol) → lower'\n const newLower = kernel.cut(lower, wedgeTol)\n kernel.release(lower)\n kernel.release(wedgeTol)\n lower = newLower\n\n return { front: upper, back: lower }\n}\n\n/** dowel/tenon 参数 */\nexport interface DowelOrTenonParams {\n /** 直径(dowel)或边长(tenon) */\n size: number\n /** 尺寸公差 */\n sizeTolerance: number\n /** 高度 */\n height: number\n /** 高度公差 */\n heightTolerance: number\n}\n\n/**\n * Dowel(定位销)/ Tenon(直榫)布尔分割 — BREP 等价物。\n *\n * 1:1 复刻 csg-worker.ts dowelOrTenonBooleanSplit:\n * 1. splitBrep → upper + lower\n * 2. detectCrossSectionComponents → 截面质心列表\n * 3. 对每个质心:buildShapeSolid → fuse(upper, shape) → upper'\n * 4. 对每个质心:buildShapeSolid(公差)→ cut(lower, shapeTol) → lower'\n * @param kernel - the BREP engine API.\n * @param original - the original solid to split.\n * @param basis - the joinery coordinate frame.\n * @param shape - whether to build a dowel or a tenon.\n * @param params - the dowel/tenon size and tolerance parameters.\n * @param selectedSections - optional indices of cross-section components to place shapes on.\n * @returns the split result with front (upper + shape) and back (lower - hole) handles.\n */\nexport function dowelOrTenonBooleanSplitBrep(\n kernel: BrepEngineApi,\n original: BrepHandle,\n basis: JoineryBasis,\n shape: 'dowel' | 'tenon',\n params: DowelOrTenonParams,\n selectedSections?: number[] | null,\n): DowelOrTenonSplitBrepResult {\n const { normal, planeCenter, planeDistance } = basis\n\n // Step 1: 平面分割 → upper + lower\n const splitResult = splitBrep(kernel, original, { normal, planeDistance, planeCenter })\n let upper = splitResult.front\n let lower = splitResult.back\n\n // Step 2: 检测截面分量\n const components = detectCrossSectionComponents(kernel, upper, basis)\n\n // 构建放置位置列表\n interface Placement { centroid: Vec3 }\n let placements: Placement[]\n\n if (components.length <= 1 || !selectedSections || selectedSections.length === 0) {\n // 单截面或无选择 → 全局质心(向后兼容)\n const mesh = solidToMeshData(kernel, upper)\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter)\n placements = [{ centroid }]\n } else {\n // 多截面:按面积降序排,取选择的分量\n const sorted = [...components].sort((a, b) => b.area - a.area)\n placements = []\n for (const selId of selectedSections) {\n if (selId < sorted.length) {\n placements.push({ centroid: sorted[selId].centroid })\n }\n }\n if (placements.length === 0) {\n const mesh = solidToMeshData(kernel, upper)\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter)\n placements = [{ centroid }]\n }\n }\n\n // Step 3: 对每个质心构造基本体并 fuse 到 upper\n for (const { centroid } of placements) {\n let shapeC: BrepHandle\n if (shape === 'dowel') {\n shapeC = buildDowelSolid(kernel, centroid, basis, params.size, params.height)\n } else {\n shapeC = buildTenonSolid(kernel, centroid, basis, params.size, params.height)\n }\n\n const newUpper = kernel.fuse(upper, shapeC)\n kernel.release(upper)\n kernel.release(shapeC)\n upper = newUpper\n }\n\n // Step 4: 对每个质心构造公差体并 cut 从 lower\n const tolSize = params.size + params.sizeTolerance\n const tolHeight = params.height + params.heightTolerance\n\n for (const { centroid } of placements) {\n let shapeCTol: BrepHandle\n if (shape === 'dowel') {\n shapeCTol = buildDowelSolid(kernel, centroid, basis, tolSize, tolHeight)\n } else {\n shapeCTol = buildTenonSolid(kernel, centroid, basis, tolSize, tolHeight)\n }\n\n const newLower = kernel.cut(lower, shapeCTol)\n kernel.release(lower)\n kernel.release(shapeCTol)\n lower = newLower\n }\n\n return { front: upper, back: lower }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"joinery-brep.js","sourceRoot":"","sources":["../../../src/api/brep-mirror/joinery-brep.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAC9D,OAAO,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAA;AAC3D,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAA;AAkBhC,yDAAyD;AAEzD,MAAM,eAAe;IACX,MAAM,CAAU;IAChB,IAAI,CAAU;IAEtB,YAAY,CAAS;QACnB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAA;QACpD,IAAI,CAAC,IAAI,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;IAClC,CAAC;IAED,IAAI,CAAC,CAAS;QACZ,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;QAC5C,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;IACvB,CAAC;IAED,KAAK,CAAC,CAAS,EAAE,CAAS;QACxB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACvB,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;QACvB,IAAI,EAAE,KAAK,EAAE;YAAE,OAAM;QACrB,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YAClC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAA;QACtB,CAAC;aAAM,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAA;QACtB,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,EAAE,CAAA;YACpB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAA;QACjB,CAAC;IACH,CAAC;CACF;AASD;;;;;;;GAOG;AACH,SAAS,2BAA2B,CAClC,IAAc,EACd,MAAY,EACZ,aAAqB;IAErB,MAAM,GAAG,GAAG,KAAK,CAAA;IACjB,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IACnC,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA;IACtC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEnC,YAAY;IACZ,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;IAEpC,MAAM,OAAO,GAAa,EAAE,CAAA;IAC5B,MAAM,QAAQ,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAA;IACnC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QACzB,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAC7B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CACjB,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YAC7B,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YACjC,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,aAAa,CAClD,CAAA;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CACjB,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YAC7B,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YACjC,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,aAAa,CAClD,CAAA;QACD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CACjB,SAAS,CAAC,EAAE,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YAC7B,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC;YACjC,SAAS,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,aAAa,CAClD,CAAA;QACD,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG,IAAI,EAAE,GAAG,GAAG,EAAE,CAAC;YACrC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;YACxC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;QAC5D,CAAC;IACH,CAAC;IACD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAA;IAEnC,qBAAqB;IACrB,MAAM,EAAE,GAAG,IAAI,eAAe,CAAC,SAAS,CAAC,CAAA;IACzC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;QAC1B,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QACxB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;QACxB,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAA;IAC1B,CAAC;IAED,SAAS;IACT,MAAM,OAAO,GAAG,IAAI,GAAG,EAAuB,CAAA;IAC9C,KAAK,MAAM,EAAE,IAAI,UAAU,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,CAAA;QACxB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,GAAG,EAAU,CAAC,CAAA;QAC5D,OAAO,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC5B,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;AACrC,CAAC;AAED;;;;GAIG;AACH,SAAS,mCAAmC,CAC1C,IAAc,EACd,MAAY,EACZ,aAAqB,EACrB,QAAc,EACd,IAAkB;IAElB,MAAM,GAAG,GAAG,KAAK,CAAA;IACjB,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAC1B,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAA;IAC1B,IAAI,KAAK,GAAG,CAAC,CAAA;IAEb,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,SAAQ;QAElC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC1B,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAC9B,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAE9B,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,aAAa,CAAA;QAC1E,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;YACzB,EAAE,IAAI,CAAC,CAAA;YACP,EAAE,IAAI,CAAC,CAAA;YACP,EAAE,IAAI,CAAC,CAAA;YACP,KAAK,EAAE,CAAA;QACT,CAAC;IACH,CAAC;IAED,IAAI,KAAK,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAA;IAChC,OAAO,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,KAAK,CAAC,CAAA;AAC7C,CAAC;AAED;;;;GAIG;AACH,SAAS,gCAAgC,CACvC,IAAc,EACd,MAAY,EACZ,aAAqB,EACrB,QAAc,EACd,IAAkB;IAElB,MAAM,GAAG,GAAG,KAAK,CAAA;IACjB,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAA;IAC1B,IAAI,OAAO,GAAG,QAAQ,CAAA;IACtB,IAAI,OAAO,GAAG,CAAC,QAAQ,CAAA;IACvB,IAAI,KAAK,GAAG,KAAK,CAAA;IAEjB,MAAM,SAAS,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAA;IACtC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,IAAI,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,SAAQ;QAElC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAA;QAC1B,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAC9B,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAA;QAE9B,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,aAAa,CAAA;QAC1E,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC;YACzB,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;YAChE,IAAI,IAAI,GAAG,OAAO;gBAAE,OAAO,GAAG,IAAI,CAAA;YAClC,IAAI,IAAI,GAAG,OAAO;gBAAE,OAAO,GAAG,IAAI,CAAA;YAClC,KAAK,GAAG,IAAI,CAAA;QACd,CAAC;IACH,CAAC;IAED,IAAI,CAAC,KAAK;QAAE,OAAO,CAAC,CAAA;IACpB,OAAO,OAAO,GAAG,OAAO,CAAA;AAC1B,CAAC;AAED,yCAAyC;AACzC,SAAS,eAAe,CAAC,MAAqB,EAAE,KAAiB;IAC/D,MAAM,IAAI,GAAG,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE;QACnC,gBAAgB,EAAE,yBAAyB,CAAC,EAAE,CAAC,EAAE,CAAC;QAClD,iBAAiB,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE;KACtC,CAAC,CAAA;IACF,OAAO;QACL,SAAS,EAAE,IAAI,YAAY,CAAC,IAAI,CAAC,SAAS,CAAC;QAC3C,OAAO,EAAE,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC;KACvC,CAAA;AACH,CAAC;AAED,0BAA0B;AAE1B;;GAEG;AACH,SAAS,kBAAkB,CAAC,KAAmB,EAAE,MAAY;IAC3D,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,SAAS,CAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EACpC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,EACpC,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC,CACnC,CAAA;IACD,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAA;IACxF,OAAO,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,WAAW,CAAC,CAAA;AACvE,CAAC;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAqB,EACrB,KAAmB,EACnB,KAAa,EACb,KAAa,EACb,QAAgB,EAChB,aAAqB;IAErB,MAAM,EAAE,WAAW,EAAE,GAAG,KAAK,CAAA;IAC7B,MAAM,QAAQ,GAAG,CAAC,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAA;IAE3C,MAAM,SAAS,GAAG,KAAK,GAAG,CAAC,CAAA;IAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAA;IACxE,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC,CAAA;IAErC,uCAAuC;IACvC,6CAA6C;IAC7C,MAAM,MAAM,GAAG,CAAC,WAAW,CAAA;IAC3B,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAA,CAAI,aAAa;IACnE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAG,SAAS,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAA,CAAI,cAAc;IACpE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAG,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA,CAAM,WAAW;IACjE,MAAM,EAAE,GAAG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA,CAAM,UAAU;IAEhE,YAAY;IACZ,MAAM,KAAK,GAAiB,EAAE,CAAA;IAC9B,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IACvC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IACvC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IACvC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,CAAA;IAEvC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnC,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAElC,oCAAoC;IACpC,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IAE1D,SAAS;IACT,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAA;IACxC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IACpB,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAEpB,WAAW;IACX,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IACzD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,CAAA;IACpE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAExB,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAqB,EACrB,QAAc,EACd,KAAmB,EACnB,QAAgB,EAChB,MAAc;IAEd,MAAM,MAAM,GAAG,QAAQ,GAAG,CAAC,CAAA;IAC3B,MAAM,EAAE,MAAM,EAAE,GAAG,KAAK,CAAA;IAExB,+CAA+C;IAC/C,4CAA4C;IAC5C,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAE/C,iBAAiB;IACjB,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;IACxC,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,CAAA;IACnF,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,UAAU,EAAE,CAAC,kBAAkB,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;IACxE,MAAM,SAAS,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,CAAA;IAEtE,8CAA8C;IAC9C,MAAM,WAAW,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IAC9F,MAAM,UAAU,GAAG,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC,gBAAgB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAA;IAE/E,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,CAAA;IAC/D,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAEnB,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAqB,EACrB,QAAc,EACd,KAAmB,EACnB,UAAkB,EAClB,MAAc;IAEd,MAAM,IAAI,GAAG,UAAU,GAAG,CAAC,CAAA;IAE3B,qEAAqE;IACrE,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,kBAAkB,CACxC,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,EAClC,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,CAC3B,CAAA;IAED,WAAW;IACX,MAAM,UAAU,GAAG,kBAAkB,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,QAAQ,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC,CAAA;IACpE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAExB,OAAO,MAAM,CAAA;AACf,CAAC;AAYD;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,4BAA4B,CAC1C,MAAqB,EACrB,KAAiB,EACjB,KAAmB;IAEnB,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,KAAK,CAAA;IACxE,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IAC3C,MAAM,UAAU,GAAG,2BAA2B,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,CAAC,CAAA;IAE3E,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC5B,kCAAkC;QAClC,OAAO,CAAC,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAA;IAC7C,CAAC;IAED,OAAO,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;QAC3B,MAAM,QAAQ,GAAG,mCAAmC,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,IAAI,CAAC,CAAA;QACpG,MAAM,SAAS,GAAG,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC/F,MAAM,SAAS,GAAG,gCAAgC,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAA;QAC/F,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,GAAG,SAAS,EAAE,CAAA;IAClD,CAAC,CAAC,CAAA;AACJ,CAAC;AA6BD;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,wBAAwB,CACtC,MAAqB,EACrB,QAAoB,EACpB,KAAmB,EACnB,MAAoB;IAEpB,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,KAAK,CAAA;IAE9D,+BAA+B;IAC/B,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAA;IACvF,IAAI,KAAK,GAAG,WAAW,CAAC,KAAK,CAAA;IAC7B,IAAI,KAAK,GAAG,WAAW,CAAC,IAAI,CAAA;IAE5B,8CAA8C;IAC9C,MAAM,SAAS,GAAG,mBAAmB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IACpD,MAAM,SAAS,GAAS;QACtB,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACnC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;QACnC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;KACpC,CAAA;IACD,IAAI,iBAAiB,GACnB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACpC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,IAAI,iBAAiB,IAAI,CAAC;QAAE,iBAAiB,GAAG,EAAE,CAAA,CAAC,OAAO;IAC1D,MAAM,aAAa,GAAG,iBAAiB,GAAG,GAAG,CAAA;IAC7C,MAAM,QAAQ,GAAG,EAAE,CAAA;IAEnB,0BAA0B;IAC1B,MAAM,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,UAAU,EAAE,aAAa,GAAG,QAAQ,CAAC,CAAA;IAEtH,2CAA2C;IAC3C,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;IACjD,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAEtB,6CAA6C;IAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,YAAY,CAAC,CAAA;IACjD,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACrB,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;IAC5B,KAAK,GAAG,QAAQ,CAAA;IAEhB,gBAAgB;IAChB,MAAM,QAAQ,GAAG,eAAe,CAC9B,MAAM,EAAE,KAAK,EACb,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,cAAc,EACpC,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,cAAc,EACpC,MAAM,CAAC,UAAU,EACjB,aAAa,GAAG,QAAQ,CACzB,CAAA;IAED,wCAAwC;IACxC,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAA;IAC5C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;IACrB,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IACxB,KAAK,GAAG,QAAQ,CAAA;IAEhB,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AACtC,CAAC;AAcD;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,4BAA4B,CAC1C,MAAqB,EACrB,QAAoB,EACpB,KAAmB,EACnB,KAAwB,EACxB,MAA0B,EAC1B,gBAAkC;IAElC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,aAAa,EAAE,GAAG,KAAK,CAAA;IAEpD,+BAA+B;IAC/B,MAAM,WAAW,GAAG,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,EAAE,CAAC,CAAA;IACvF,IAAI,KAAK,GAAG,WAAW,CAAC,KAAK,CAAA;IAC7B,IAAI,KAAK,GAAG,WAAW,CAAC,IAAI,CAAA;IAE5B,iBAAiB;IACjB,MAAM,UAAU,GAAG,4BAA4B,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,CAAC,CAAA;IAIrE,IAAI,UAAuB,CAAA;IAE3B,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,IAAI,CAAC,gBAAgB,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjF,uBAAuB;QACvB,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QAC3C,MAAM,QAAQ,GAAG,mCAAmC,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAA;QAC9F,UAAU,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;IAC7B,CAAC;SAAM,CAAC;QACN,oBAAoB;QACpB,MAAM,MAAM,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;QAC9D,UAAU,GAAG,EAAE,CAAA;QACf,KAAK,MAAM,KAAK,IAAI,gBAAgB,EAAE,CAAC;YACrC,IAAI,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC;gBAC1B,UAAU,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAA;YACvD,CAAC;QACH,CAAC;QACD,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;YAC3C,MAAM,QAAQ,GAAG,mCAAmC,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,WAAW,CAAC,CAAA;YAC9F,UAAU,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;QAC7B,CAAC;IACH,CAAC;IAED,mCAAmC;IACnC,KAAK,MAAM,EAAE,QAAQ,EAAE,IAAI,UAAU,EAAE,CAAC;QACtC,IAAI,MAAkB,CAAA;QACtB,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QAC/E,CAAC;aAAM,CAAC;YACN,MAAM,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,CAAA;QAC/E,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAA;QAC3C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACrB,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QACtB,KAAK,GAAG,QAAQ,CAAA;IAClB,CAAC;IAED,kCAAkC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,GAAG,MAAM,CAAC,aAAa,CAAA;IAClD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,eAAe,CAAA;IAExD,KAAK,MAAM,EAAE,QAAQ,EAAE,IAAI,UAAU,EAAE,CAAC;QACtC,IAAI,SAAqB,CAAA;QACzB,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACtB,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;QAC1E,CAAC;aAAM,CAAC;YACN,SAAS,GAAG,eAAe,CAAC,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,CAAA;QAC1E,CAAC;QAED,MAAM,QAAQ,GAAG,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,SAAS,CAAC,CAAA;QAC7C,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAA;QACrB,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;QACzB,KAAK,GAAG,QAAQ,CAAA;IAClB,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,CAAA;AACtC,CAAC","sourcesContent":["/**\n * BREP 榫卯结构操作 — 用 OCCT 精确实体复刻 mesh 路径的榫卯布尔序列\n *\n * See docs/api-contract.md §8 (dual-path geometry contract) and §10.5 (split).\n *\n * 与 mesh 路径(joinery-shapes.ts + csg-worker.ts)对照:\n * - mesh 路径:buildWedgeGeometry/buildDowelGeometry/buildStraightTenonGeometry → Manifold CSG\n * - BREP 路径:buildWedgeSolid/buildDowelSolid/buildTenonSolid → OCCT fuse/cut/common\n *\n * 坐标框架与 mesh 路径完全一致:\n * - normal: 切割平面法线(单位向量,指向上方)\n * - widthDir: 挤出方向(单位向量)\n * - depthDir = normalize(cross(normal, widthDir))\n * - planeCenter: 切割平面中心\n *\n * 所有函数都是纯函数,输入输出均为 OCCT BrepHandle,调用方负责句柄生命周期。\n */\n\nimport * as THREE from 'three'\nimport type { BrepHandle } from '../../brep/engine/types'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { Vec3 } from '../../mesh/types'\nimport { getSolidBoundingBox } from '../../brep/brep-utils'\nimport { splitBrep, matrixToArray } from '../../brep/brep-ops'\nimport { DEFAULT_LINEAR_DEFLECTION } from '../../tolerance'\nimport { mm } from '../../units'\n\n// ─── 坐标框架 ───\n\n/** 榫卯操作的坐标框架(与 joinery-shapes.ts 一致) */\nexport interface JoineryBasis {\n /** 切割平面法线(单位向量) */\n normal: Vec3\n /** 宽度/挤出方向(单位向量) */\n widthDir: Vec3\n /** 深度方向 = normalize(cross(normal, widthDir)) */\n depthDir: Vec3\n /** 切割平面中心 */\n planeCenter: Vec3\n /** 平面原点偏移 = dot(normal, planeCenter) */\n planeDistance: number\n}\n\n// ─── Union-Find(与 csg-worker.ts SimpleUnionFind 一致) ───\n\nclass SimpleUnionFind {\n private parent: number[]\n private rank: number[]\n\n constructor(n: number) {\n this.parent = Array.from({ length: n }, (_, i) => i)\n this.rank = new Array(n).fill(0)\n }\n\n find(x: number): number {\n if (this.parent[x] !== x) {\n this.parent[x] = this.find(this.parent[x])\n }\n return this.parent[x]\n }\n\n union(x: number, y: number): void {\n const px = this.find(x)\n const py = this.find(y)\n if (px === py) return\n if (this.rank[px] < this.rank[py]) {\n this.parent[px] = py\n } else if (this.rank[px] > this.rank[py]) {\n this.parent[py] = px\n } else {\n this.parent[py] = px\n this.rank[px]++\n }\n }\n}\n\n// ─── 截面分析(从 mesh 三角化提取截面信息,与 csg-worker.ts 算法一致) ───\n\ninterface MeshData {\n positions: Float32Array\n indices: Uint32Array\n}\n\n/**\n * 检测切割平面上的帽面连通分量。\n *\n * 与 csg-worker.ts detectCapComponents 算法一致:\n * 1. 找到所有顶点在切割平面上的三角形\n * 2. 用 union-find 按共享顶点分组\n * 3. 返回每分量的顶点索引集合\n */\nfunction detectCapComponentsFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n): Set<number>[] {\n const eps = 0.001\n const { positions, indices } = mesh\n const vertCount = positions.length / 3\n if (indices.length === 0) return []\n\n // 找到所有帽面三角形\n const capVertSet = new Set<number>()\n interface CapTri { v0: number; v1: number; v2: number }\n const capTris: CapTri[] = []\n const triCount = indices.length / 3\n for (let t = 0; t < triCount; t++) {\n const i0 = indices[t * 3]\n const i1 = indices[t * 3 + 1]\n const i2 = indices[t * 3 + 2]\n const d0 = Math.abs(\n positions[i0 * 3] * normal[0] +\n positions[i0 * 3 + 1] * normal[1] +\n positions[i0 * 3 + 2] * normal[2] - planeDistance,\n )\n const d1 = Math.abs(\n positions[i1 * 3] * normal[0] +\n positions[i1 * 3 + 1] * normal[1] +\n positions[i1 * 3 + 2] * normal[2] - planeDistance,\n )\n const d2 = Math.abs(\n positions[i2 * 3] * normal[0] +\n positions[i2 * 3 + 1] * normal[1] +\n positions[i2 * 3 + 2] * normal[2] - planeDistance,\n )\n if (d0 < eps && d1 < eps && d2 < eps) {\n capTris.push({ v0: i0, v1: i1, v2: i2 })\n capVertSet.add(i0); capVertSet.add(i1); capVertSet.add(i2)\n }\n }\n if (capTris.length === 0) return []\n\n // Union-find 按共享顶点分组\n const uf = new SimpleUnionFind(vertCount)\n for (const tri of capTris) {\n uf.union(tri.v0, tri.v1)\n uf.union(tri.v1, tri.v2)\n uf.union(tri.v0, tri.v2)\n }\n\n // 按根节点分组\n const compMap = new Map<number, Set<number>>()\n for (const vi of capVertSet) {\n const root = uf.find(vi)\n if (!compMap.has(root)) compMap.set(root, new Set<number>())\n compMap.get(root)!.add(vi)\n }\n\n return Array.from(compMap.values())\n}\n\n/**\n * 计算切割平面上截面顶点的质心。\n *\n * 与 csg-worker.ts computeCrossSectionCentroid 算法一致。\n */\nfunction computeCrossSectionCentroidFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n fallback: Vec3,\n comp?: Set<number>,\n): Vec3 {\n const eps = 0.001\n const { positions } = mesh\n let cx = 0, cy = 0, cz = 0\n let count = 0\n\n const vertCount = positions.length / 3\n for (let i = 0; i < vertCount; i++) {\n if (comp && !comp.has(i)) continue\n\n const x = positions[i * 3]\n const y = positions[i * 3 + 1]\n const z = positions[i * 3 + 2]\n\n const dist = x * normal[0] + y * normal[1] + z * normal[2] - planeDistance\n if (Math.abs(dist) < eps) {\n cx += x\n cy += y\n cz += z\n count++\n }\n }\n\n if (count === 0) return fallback\n return [cx / count, cy / count, cz / count]\n}\n\n/**\n * 计算切割平面上截面沿指定方向的宽度。\n *\n * 与 csg-worker.ts computeCrossSectionWidth 算法一致。\n */\nfunction computeCrossSectionWidthFromMesh(\n mesh: MeshData,\n normal: Vec3,\n planeDistance: number,\n widthDir: Vec3,\n comp?: Set<number>,\n): number {\n const eps = 0.001\n const { positions } = mesh\n let minProj = Infinity\n let maxProj = -Infinity\n let found = false\n\n const vertCount = positions.length / 3\n for (let i = 0; i < vertCount; i++) {\n if (comp && !comp.has(i)) continue\n\n const x = positions[i * 3]\n const y = positions[i * 3 + 1]\n const z = positions[i * 3 + 2]\n\n const dist = x * normal[0] + y * normal[1] + z * normal[2] - planeDistance\n if (Math.abs(dist) < eps) {\n const proj = x * widthDir[0] + y * widthDir[1] + z * widthDir[2]\n if (proj < minProj) minProj = proj\n if (proj > maxProj) maxProj = proj\n found = true\n }\n }\n\n if (!found) return 0\n return maxProj - minProj\n}\n\n/** 将 OCCT solid 三角化为 MeshData(用于截面分析) */\nfunction solidToMeshData(kernel: BrepEngineApi, solid: BrepHandle): MeshData {\n const mesh = kernel.meshShape(solid, {\n linearDeflection: DEFAULT_LINEAR_DEFLECTION.as(mm),\n angularDeflection: (2 * Math.PI) / 32,\n })\n return {\n positions: new Float32Array(mesh.positions),\n indices: new Uint32Array(mesh.indices),\n }\n}\n\n// ─── 基本体构造(BREP 等价物) ───\n\n/**\n * 构造局部的变换矩阵:local X → widthDir, Y → depthDir, Z → normal,再平移到 origin。\n */\nfunction makeBasisTransform(basis: JoineryBasis, origin: Vec3): THREE.Matrix4 {\n const basisMatrix = new THREE.Matrix4().makeBasis(\n new THREE.Vector3(...basis.widthDir),\n new THREE.Vector3(...basis.depthDir),\n new THREE.Vector3(...basis.normal),\n )\n const transMatrix = new THREE.Matrix4().makeTranslation(origin[0], origin[1], origin[2])\n return new THREE.Matrix4().multiplyMatrices(transMatrix, basisMatrix)\n}\n\n/**\n * 梯形棱柱(燕尾楔)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildWedgeGeometry 的 8 顶点拓扑:\n * - 梯形截面在 normal-depthDir 平面\n * - 底边(宽)在 planeCenter - normal*depth\n * - 顶边(窄)在 planeCenter\n * - 沿 widthDir 拉伸 extrudeLength,居中于 planeCenter\n *\n * 用 kernel.makeLineEdge + makeWire + makeFace + extrude 构造实体,\n * 然后用 transform 对齐到世界坐标系。\n * @param kernel - the BREP engine API.\n * @param basis - the joinery coordinate frame (normal/widthDir/depthDir/planeCenter).\n * @param depth - the wedge depth along the normal direction.\n * @param width - the wedge bottom width.\n * @param angleDeg - the dovetail flap angle in degrees.\n * @param extrudeLength - the extrusion length along the width direction.\n * @returns the constructed wedge solid handle.\n */\nexport function buildWedgeSolid(\n kernel: BrepEngineApi,\n basis: JoineryBasis,\n depth: number,\n width: number,\n angleDeg: number,\n extrudeLength: number,\n): BrepHandle {\n const { planeCenter } = basis\n const angleRad = (angleDeg * Math.PI) / 180\n\n const halfWidth = width / 2\n const halfTopWidth = Math.max(0, halfWidth - depth / Math.tan(angleRad))\n const halfExtrude = extrudeLength / 2\n\n // 在局部坐标系中构造梯形面(YZ 平面,X = -halfExtrude)\n // 局部: X → widthDir, Y → depthDir, Z → normal\n const xLocal = -halfExtrude\n const v0 = { x: xLocal, y: -halfWidth, z: -depth } // bottomLeft\n const v1 = { x: xLocal, y: halfWidth, z: -depth } // bottomRight\n const v2 = { x: xLocal, y: halfTopWidth, z: 0 } // topRight\n const v3 = { x: xLocal, y: -halfTopWidth, z: 0 } // topLeft\n\n // 构建梯形 wire\n const edges: BrepHandle[] = []\n edges.push(kernel.makeLineEdge(v0, v1))\n edges.push(kernel.makeLineEdge(v1, v2))\n edges.push(kernel.makeLineEdge(v2, v3))\n edges.push(kernel.makeLineEdge(v3, v0))\n\n const wire = kernel.makeWire(edges)\n const face = kernel.makeFace(wire)\n\n // 沿 X 轴(= widthDir)拉伸 extrudeLength\n const extruded = kernel.extrude(face, extrudeLength, 0, 0)\n\n // 释放中间句柄\n for (const e of edges) kernel.release(e)\n kernel.release(wire)\n kernel.release(face)\n\n // 变换到世界坐标系\n const fullMatrix = makeBasisTransform(basis, planeCenter)\n const result = kernel.transform(extruded, matrixToArray(fullMatrix))\n kernel.release(extruded)\n\n return result\n}\n\n/**\n * 圆柱(定位销)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildDowelGeometry:\n * - 圆截面在 widthDir-depthDir 平面,中心在 centroid\n * - 从切割平面向下延伸 height(沿 -normal)\n *\n * 用 kernel.makeCylinder + transform 对齐方向。\n * @param kernel - the BREP engine API.\n * @param centroid - the centroid where the dowel is placed.\n * @param basis - the joinery coordinate frame.\n * @param diameter - the dowel diameter.\n * @param height - the dowel height along the normal direction.\n * @returns the constructed dowel solid handle.\n */\nexport function buildDowelSolid(\n kernel: BrepEngineApi,\n centroid: Vec3,\n basis: JoineryBasis,\n diameter: number,\n height: number,\n): BrepHandle {\n const radius = diameter / 2\n const { normal } = basis\n\n // OCCT makeCylinder 创建 Z 轴方向圆柱(Z=0 → Z=height)\n // 需要旋转使 Z 轴对齐 -normal(圆柱向下延伸),且顶部在 centroid\n const cyl = kernel.makeCylinder(radius, height)\n\n // 旋转 Z → -normal\n const zAxis = new THREE.Vector3(0, 0, 1)\n const negNormal = new THREE.Vector3(-normal[0], -normal[1], -normal[2]).normalize()\n const quat = new THREE.Quaternion().setFromUnitVectors(zAxis, negNormal)\n const rotMatrix = new THREE.Matrix4().makeRotationFromQuaternion(quat)\n\n // 平移到 centroid(旋转后 Z=0 对应 centroid,即切割平面上的顶面)\n const transMatrix = new THREE.Matrix4().makeTranslation(centroid[0], centroid[1], centroid[2])\n const fullMatrix = new THREE.Matrix4().multiplyMatrices(transMatrix, rotMatrix)\n\n const result = kernel.transform(cyl, matrixToArray(fullMatrix))\n kernel.release(cyl)\n\n return result\n}\n\n/**\n * 长方体(直榫)— BREP 等价物。\n *\n * 复刻 joinery-shapes.ts buildStraightTenonGeometry:\n * - 方截面在 widthDir-depthDir 平面,中心在 centroid\n * - 从切割平面向下延伸 height(沿 -normal)\n *\n * 用 kernel.makeBoxFromCorners + transform 对齐方向。\n * @param kernel - the BREP engine API.\n * @param centroid - the centroid where the tenon is placed.\n * @param basis - the joinery coordinate frame.\n * @param sideLength - the tenon square side length.\n * @param height - the tenon height along the normal direction.\n * @returns the constructed tenon solid handle.\n */\nexport function buildTenonSolid(\n kernel: BrepEngineApi,\n centroid: Vec3,\n basis: JoineryBasis,\n sideLength: number,\n height: number,\n): BrepHandle {\n const half = sideLength / 2\n\n // 在局部坐标系中创建盒子:X ∈ [-half, half], Y ∈ [-half, half], Z ∈ [-height, 0]\n // 局部: X → widthDir, Y → depthDir, Z → normal\n const localBox = kernel.makeBoxFromCorners(\n { x: -half, y: -half, z: -height },\n { x: half, y: half, z: 0 },\n )\n\n // 变换到世界坐标系\n const fullMatrix = makeBasisTransform(basis, centroid)\n const result = kernel.transform(localBox, matrixToArray(fullMatrix))\n kernel.release(localBox)\n\n return result\n}\n\n// ─── 截面质心 / 多截面检测 ───\n\n/** 截面分量信息 */\nexport interface CrossSectionComponent {\n /** 分量质心 */\n centroid: Vec3\n /** 分量面积(近似,用于排序) */\n area: number\n}\n\n/**\n * 检测上部实体在切割平面上的截面连通分量。\n *\n * BREP 等价物:将 upper solid 三角化后,用与 mesh 路径 detectCapComponents\n * 完全相同的算法(找帽面三角形 → union-find)检测连通分量。\n *\n * 与 csg-worker.ts detectCapComponents + computeCrossSectionCentroid 一致。\n * @param kernel - the BREP engine API.\n * @param upper - the upper solid whose cross section is analyzed.\n * @param basis - the joinery coordinate frame.\n * @returns the detected cross-section components (centroid + area).\n */\nexport function detectCrossSectionComponents(\n kernel: BrepEngineApi,\n upper: BrepHandle,\n basis: JoineryBasis,\n): CrossSectionComponent[] {\n const { normal, planeDistance, widthDir, depthDir, planeCenter } = basis\n const mesh = solidToMeshData(kernel, upper)\n const components = detectCapComponentsFromMesh(mesh, normal, planeDistance)\n\n if (components.length === 0) {\n // 无帽面 → 返回单个全局质心(planeCenter)作为回退\n return [{ centroid: planeCenter, area: 0 }]\n }\n\n return components.map(comp => {\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter, comp)\n const compWidth = computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, widthDir, comp)\n const compDepth = computeCrossSectionWidthFromMesh(mesh, normal, planeDistance, depthDir, comp)\n return { centroid, area: compWidth * compDepth }\n })\n}\n\n// ─── 布尔序列(1:1 复刻 csg-worker.ts) ───\n\n/** dovetail 布尔分割的结果 */\nexport interface DovetailSplitBrepResult {\n /** 上部 + 楔(法线正方向半部分加燕尾榫) */\n front: BrepHandle\n /** 下部 - 凹腔(法线负方向半部分减燕尾槽) */\n back: BrepHandle\n}\n\n/** dowel/tenon 布尔分割的结果 */\nexport interface DowelOrTenonSplitBrepResult {\n /** 上部 + 销/榫(法线正方向半部分加圆柱/方柱) */\n front: BrepHandle\n /** 下部 - 孔(法线负方向半部分减圆柱/方柱) */\n back: BrepHandle\n}\n\n/** groove 参数 */\nexport interface GrooveParams {\n depth: number\n depthTolerance: number\n width: number\n widthTolerance: number\n flapsAngle: number\n}\n\n/**\n * Dovetail(燕尾)布尔分割 — BREP 等价物。\n *\n * 1:1 复刻 csg-worker.ts dovetailBooleanSplit:\n * 1. splitBrep → upper + lower\n * 2. 计算 crossSectionWidth(bbox 投影近似)\n * 3. buildWedgeSolid(overhang=20)→ common(wedge, lower) 裁剪贴合\n * 4. fuse(upper, wedgeTrimmed) → upper'\n * 5. buildWedgeSolid(公差)→ cut(lower, wedgeTol) → lower'\n * @param kernel - the BREP engine API.\n * @param original - the original solid to split.\n * @param basis - the joinery coordinate frame.\n * @param groove - the dovetail groove parameters.\n * @returns the split result with front (upper + wedge) and back (lower - cavity) handles.\n */\nexport function dovetailBooleanSplitBrep(\n kernel: BrepEngineApi,\n original: BrepHandle,\n basis: JoineryBasis,\n groove: GrooveParams,\n): DovetailSplitBrepResult {\n const { normal, widthDir, planeCenter, planeDistance } = basis\n\n // Step 1: 平面分割 → upper + lower\n const splitResult = splitBrep(kernel, original, { normal, planeDistance, planeCenter })\n let upper = splitResult.front\n let lower = splitResult.back\n\n // Step 2: 计算截面宽度(bbox 投影近似,后续 common 会裁回真实边界)\n const upperBbox = getSolidBoundingBox(kernel, upper)\n const upperSize: Vec3 = [\n upperBbox.max[0] - upperBbox.min[0],\n upperBbox.max[1] - upperBbox.min[1],\n upperBbox.max[2] - upperBbox.min[2],\n ]\n let crossSectionWidth =\n Math.abs(upperSize[0] * widthDir[0]) +\n Math.abs(upperSize[1] * widthDir[1]) +\n Math.abs(upperSize[2] * widthDir[2])\n if (crossSectionWidth <= 0) crossSectionWidth = 10 // 安全回退\n const extrudeLength = crossSectionWidth + 0.2\n const overhang = 20\n\n // Step 3: 构造楔(带 overhang)\n const wedgeW = buildWedgeSolid(kernel, basis, groove.depth, groove.width, groove.flapsAngle, extrudeLength + overhang)\n\n // Step 4: common(wedge, lower) → 裁剪楔贴合模型边界\n const wedgeTrimmed = kernel.common(wedgeW, lower)\n kernel.release(wedgeW)\n\n // Step 5: fuse(upper, wedgeTrimmed) → upper'\n const newUpper = kernel.fuse(upper, wedgeTrimmed)\n kernel.release(upper)\n kernel.release(wedgeTrimmed)\n upper = newUpper\n\n // Step 6: 构造公差楔\n const wedgeTol = buildWedgeSolid(\n kernel, basis,\n groove.depth + groove.depthTolerance,\n groove.width + groove.widthTolerance,\n groove.flapsAngle,\n extrudeLength + overhang,\n )\n\n // Step 7: cut(lower, wedgeTol) → lower'\n const newLower = kernel.cut(lower, wedgeTol)\n kernel.release(lower)\n kernel.release(wedgeTol)\n lower = newLower\n\n return { front: upper, back: lower }\n}\n\n/** dowel/tenon 参数 */\nexport interface DowelOrTenonParams {\n /** 直径(dowel)或边长(tenon) */\n size: number\n /** 尺寸公差 */\n sizeTolerance: number\n /** 高度 */\n height: number\n /** 高度公差 */\n heightTolerance: number\n}\n\n/**\n * Dowel(定位销)/ Tenon(直榫)布尔分割 — BREP 等价物。\n *\n * 1:1 复刻 csg-worker.ts dowelOrTenonBooleanSplit:\n * 1. splitBrep → upper + lower\n * 2. detectCrossSectionComponents → 截面质心列表\n * 3. 对每个质心:buildShapeSolid → fuse(upper, shape) → upper'\n * 4. 对每个质心:buildShapeSolid(公差)→ cut(lower, shapeTol) → lower'\n * @param kernel - the BREP engine API.\n * @param original - the original solid to split.\n * @param basis - the joinery coordinate frame.\n * @param shape - whether to build a dowel or a tenon.\n * @param params - the dowel/tenon size and tolerance parameters.\n * @param selectedSections - optional indices of cross-section components to place shapes on.\n * @returns the split result with front (upper + shape) and back (lower - hole) handles.\n */\nexport function dowelOrTenonBooleanSplitBrep(\n kernel: BrepEngineApi,\n original: BrepHandle,\n basis: JoineryBasis,\n shape: 'dowel' | 'tenon',\n params: DowelOrTenonParams,\n selectedSections?: number[] | null,\n): DowelOrTenonSplitBrepResult {\n const { normal, planeCenter, planeDistance } = basis\n\n // Step 1: 平面分割 → upper + lower\n const splitResult = splitBrep(kernel, original, { normal, planeDistance, planeCenter })\n let upper = splitResult.front\n let lower = splitResult.back\n\n // Step 2: 检测截面分量\n const components = detectCrossSectionComponents(kernel, upper, basis)\n\n // 构建放置位置列表\n interface Placement { centroid: Vec3 }\n let placements: Placement[]\n\n if (components.length <= 1 || !selectedSections || selectedSections.length === 0) {\n // 单截面或无选择 → 全局质心(向后兼容)\n const mesh = solidToMeshData(kernel, upper)\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter)\n placements = [{ centroid }]\n } else {\n // 多截面:按面积降序排,取选择的分量\n const sorted = [...components].sort((a, b) => b.area - a.area)\n placements = []\n for (const selId of selectedSections) {\n if (selId < sorted.length) {\n placements.push({ centroid: sorted[selId].centroid })\n }\n }\n if (placements.length === 0) {\n const mesh = solidToMeshData(kernel, upper)\n const centroid = computeCrossSectionCentroidFromMesh(mesh, normal, planeDistance, planeCenter)\n placements = [{ centroid }]\n }\n }\n\n // Step 3: 对每个质心构造基本体并 fuse 到 upper\n for (const { centroid } of placements) {\n let shapeC: BrepHandle\n if (shape === 'dowel') {\n shapeC = buildDowelSolid(kernel, centroid, basis, params.size, params.height)\n } else {\n shapeC = buildTenonSolid(kernel, centroid, basis, params.size, params.height)\n }\n\n const newUpper = kernel.fuse(upper, shapeC)\n kernel.release(upper)\n kernel.release(shapeC)\n upper = newUpper\n }\n\n // Step 4: 对每个质心构造公差体并 cut 从 lower\n const tolSize = params.size + params.sizeTolerance\n const tolHeight = params.height + params.heightTolerance\n\n for (const { centroid } of placements) {\n let shapeCTol: BrepHandle\n if (shape === 'dowel') {\n shapeCTol = buildDowelSolid(kernel, centroid, basis, tolSize, tolHeight)\n } else {\n shapeCTol = buildTenonSolid(kernel, centroid, basis, tolSize, tolHeight)\n }\n\n const newLower = kernel.cut(lower, shapeCTol)\n kernel.release(lower)\n kernel.release(shapeCTol)\n lower = newLower\n }\n\n return { front: upper, back: lower }\n}\n"]}
|
|
@@ -11,6 +11,10 @@ export interface ScriptFaceOp {
|
|
|
11
11
|
module: string;
|
|
12
12
|
/** Phase 5(D11):平台 op 的平台身份(中立 op 缺省)。 */
|
|
13
13
|
engines?: readonly string[];
|
|
14
|
+
/** P26 (unit-system D8):参数量纲声明(参数名 → DimName)。 */
|
|
15
|
+
paramDims?: Record<string, string>;
|
|
16
|
+
/** P26 (unit-system D8):返回值量纲。 */
|
|
17
|
+
retDim?: string;
|
|
14
18
|
}
|
|
15
19
|
/** Cad script-face op manifest (B1: single source for cad namespace, check() symbol table). */
|
|
16
20
|
export declare const SCRIPT_FACE_OPS: readonly ScriptFaceOp[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-face-manifest.d.ts","sourceRoot":"","sources":["../../../src/api/generated/script-face-manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,uBAAuB;AACvB,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"script-face-manifest.d.ts","sourceRoot":"","sources":["../../../src/api/generated/script-face-manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,uBAAuB;AACvB,MAAM,WAAW,YAAY;IAC3B,gCAAgC;IAChC,IAAI,EAAE,MAAM,CAAA;IACZ,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAA;IACd,0CAA0C;IAC1C,OAAO,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC3B,kDAAkD;IAClD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAClC,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,+FAA+F;AAC/F,eAAO,MAAM,eAAe,EAAE,SAAS,YAAY,EAyClD,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"script-face-manifest.js","sourceRoot":"","sources":["../../../src/api/generated/script-face-manifest.ts"],"names":[],"mappings":"AAAA;;;;GAIG;
|
|
1
|
+
{"version":3,"file":"script-face-manifest.js","sourceRoot":"","sources":["../../../src/api/generated/script-face-manifest.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * generated/script-face-manifest.ts — 生成文件,禁手改。\n * 由 packages/core/scripts/gen-l3-surface.ts 依据 api/surface/arg-spec.ts 生成。\n * cad 脚本面新增 op 清单(P23 B1 三源一致:导出面 ≡ cad 面 ≡ check() 符号表)。\n */\n\n/** 一条 cad 脚本面新增 op。 */\nexport interface ScriptFaceOp {\n /** faijs 面导出名(= brepjs 符号名)。 */\n name: string\n /** 所属分片模块(生成文件名)。 */\n module: string\n /** Phase 5(D11):平台 op 的平台身份(中立 op 缺省)。 */\n engines?: readonly string[]\n /** P26 (unit-system D8):参数量纲声明(参数名 → DimName)。 */\n paramDims?: Record<string, string>\n /** P26 (unit-system D8):返回值量纲。 */\n retDim?: string\n}\n\n/** Cad script-face op manifest (B1: single source for cad namespace, check() symbol table). */\nexport const SCRIPT_FACE_OPS: readonly ScriptFaceOp[] = [\n { name: 'torus', module: 'topology' },\n { name: 'fuse', module: 'topology', engines: [\"occt\"] },\n { name: 'inspectMassProps', module: 'measurement', engines: [\"occt\"] },\n { name: 'area', module: 'measurement' },\n { name: 'length', module: 'measurement' },\n { name: 'volume', module: 'measurement' },\n { name: 'centerOfMass', module: 'measurement' },\n { name: 'viewCamera', module: 'view' },\n { name: 'projectView', module: 'view' },\n { name: 'projectSheet', module: 'view' },\n { name: 'complexExtrude', module: 'operations', engines: [\"occt\"] },\n { name: 'twistExtrude', module: 'operations', engines: [\"occt\"] },\n { name: 'linearPattern', module: 'operations', engines: [\"occt\"] },\n { name: 'circularPattern', module: 'operations', engines: [\"occt\"] },\n { name: 'gridPattern', module: 'operations', engines: [\"occt\"] },\n { name: 'roof', module: 'operations' },\n { name: 'drill', module: 'operations' },\n { name: 'pocket', module: 'operations' },\n { name: 'boss', module: 'operations' },\n { name: 'mirrorJoin', module: 'operations' },\n { name: 'rectangularPattern', module: 'operations', engines: [\"occt\"] },\n { name: 'thread', module: 'operations', engines: [\"occt\"] },\n { name: 'convexHull', module: 'operations' },\n { name: 'makeBaseBox', module: 'sketching' },\n { name: 'ellipsoid', module: 'topology' },\n { name: 'rotate', module: 'topology' },\n { name: 'mirror', module: 'topology' },\n { name: 'clone', module: 'topology' },\n { name: 'applyMatrix', module: 'topology' },\n { name: 'locate', module: 'topology' },\n { name: 'split', module: 'topology', engines: [\"occt\"] },\n { name: 'offset', module: 'topology', engines: [\"occt\"] },\n { name: 'heal', module: 'topology', engines: [\"occt\"] },\n { name: 'simplify', module: 'topology', engines: [\"occt\"] },\n { name: 'isValid', module: 'topology' },\n { name: 'isSameShape', module: 'topology' },\n { name: 'autoHeal', module: 'topology', engines: [\"occt\"] },\n { name: 'fixShape', module: 'topology' },\n { name: 'healSolid', module: 'topology' },\n { name: 'fixSelfIntersection', module: 'topology', engines: [\"occt\"] },\n]\n"]}
|
package/dist/api/knurl.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knurl.d.ts","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAOhD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvE;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,eAAO,MAAM,KAAK;;
|
|
1
|
+
{"version":3,"file":"knurl.d.ts","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAQ,MAAM,eAAe,CAAA;AAOhD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEvE;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,eAAO,MAAM,KAAK;;CAsBhB,CAAA"}
|
package/dist/api/knurl.js
CHANGED
|
@@ -58,6 +58,7 @@ export const knurl = defineOp({
|
|
|
58
58
|
knurlMappingMode: params.knurlMappingMode ?? 5,
|
|
59
59
|
});
|
|
60
60
|
},
|
|
61
|
+
paramDims: { knurlTextureHeight: 'length', knurlRefineLength: 'length' },
|
|
61
62
|
naming: { kind: 'unmodeled', reason: 'knurl is mesh-only, no BREP face identity' },
|
|
62
63
|
});
|
|
63
64
|
//# sourceMappingURL=knurl.js.map
|
package/dist/api/knurl.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knurl.js","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE/C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,oBAAoB,CAAC,MAAM,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAA;AAC7E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,KAAK,EAAE,KAAY,EAAE,MAA+B,EAAE,EAAE;QAC5D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;QAC/D,iBAAiB,CAAC,MAAM,CAAC,CAAA;QACzB,+CAA+C;QAC/C,iEAAiE;QACjE,MAAM,CAAC,SAAS,CAAC,GAAG,mBAAmB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAChD,OAAO,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE;YAC1B,IAAI,EAAE;gBACJ,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;gBAC5E,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;aAC7D;YACD,kBAAkB,EAAG,MAAM,CAAC,kBAAyC,IAAI,GAAG;YAC5E,uBAAuB,EAAG,MAAM,CAAC,uBAA+C,IAAI,KAAK;YACzF,iBAAiB,EAAG,MAAM,CAAC,iBAAwC,IAAI,GAAG;YAC1E,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,gBAAgB,EAAG,MAAM,CAAC,gBAAuC,IAAI,CAAC;SACvE,CAAC,CAAA;IACJ,CAAC;IACD,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,2CAA2C,EAAgB;CACjG,CAAC,CAAA","sourcesContent":["/**\n * stdlib knurl — 滚花库函数(mesh-only)\n *\n *\n * knurl 无 BREP 实现(mesh-only)——dispatchPath 在 brep 模式下调用前抛错。\n * part-brep-lost 事件由引擎统一发(P4,库不再 emit)。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { reconcileBrepInputs } from './reconcile'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { assertPositiveNumber } from './assert'\n\n/**\n * Validate knurl parameters: `knurlTextureHeight` must be a positive number.\n * @param params - the raw knurl operation parameters.\n */\nexport function assertKnurlParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.knurlTextureHeight, 'knurl.knurlTextureHeight')\n}\n\n/**\n * 施加滚花(顶点位移,非布尔)。mesh-only。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual warn\n * @name knurl\n * @note knurl 无 BREP 实现(mesh-only),本质是顶点位移(网格操作),网格参数可接受;brep 模式下调用前抛 BrepUnsupportedError。面锚定建议用几何引用。\n * @returns Shape 滚花后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param params.knurlTextureHeight - 纹路高度(mm)。type:number 默认 0.5\n * @param params.knurlScaleU - 纹路 U 向频率。type:number 默认 0.15\n * @param params.knurlScaleV - 纹路 V 向频率。type:number 默认 0.15\n * @param params.knurlInvertDisplacement - 反向位移。type:boolean 默认 false\n * @param params.knurlRefineLength - 细分长度(mm)。type:number 默认 1.0\n * @param params.knurlMappingMode - UV 映射模式。type:number 默认 5\n * @param params.faceCenter - 面锚点中心。type:[x,y,z] 默认 bboxCenter\n * @param params.faceNormal - 面法向。type:[x,y,z] 默认 [0,0,1]\n * @example\n * const p = await cad.knurl(part0, { knurlTextureHeight: 0.5, knurlScaleU: 0.15, knurlScaleV: 0.15, knurlInvertDisplacement: false, knurlRefineLength: 1.0, knurlMappingMode: 5 })\n */\nexport const knurl = defineOp({\n mesh: async (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[stdlib/knurl] no input geometry')\n assertKnurlParams(params)\n // 断链时刻(用户点名场景):BREP 建模的模型最后做滚花 → BREP 输入必须先归约为\n // 合法 2-manifold 网格再进 mesh 路径(reconcileBrepInputs 对 mesh 侧输入原样透传)\n const [meshInput] = reconcileBrepInputs([input])\n return cad.knurl(meshInput, {\n face: {\n center: (params.faceCenter as Vec3 | undefined) ?? cad.bboxCenter(meshInput),\n normal: (params.faceNormal as Vec3 | undefined) ?? [0, 0, 1],\n },\n knurlTextureHeight: (params.knurlTextureHeight as number | undefined) ?? 0.5,\n knurlInvertDisplacement: (params.knurlInvertDisplacement as boolean | undefined) ?? false,\n knurlRefineLength: (params.knurlRefineLength as number | undefined) ?? 1.0,\n knurlScaleU: (params.knurlScaleU as number | undefined) ?? 0.15,\n knurlScaleV: (params.knurlScaleV as number | undefined) ?? 0.15,\n knurlMappingMode: (params.knurlMappingMode as number | undefined) ?? 5,\n })\n },\n naming: { kind: 'unmodeled', reason: 'knurl is mesh-only, no BREP face identity' } as Provenance,\n})\n"]}
|
|
1
|
+
{"version":3,"file":"knurl.js","sourceRoot":"","sources":["../../src/api/knurl.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,OAAO,EAAE,GAAG,EAAE,MAAM,SAAS,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAA;AAE/C;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,MAA+B;IAC/D,oBAAoB,CAAC,MAAM,CAAC,kBAAkB,EAAE,0BAA0B,CAAC,CAAA;AAC7E,CAAC;AAED;;;;;;;;;;;;;;;;;;;;IAoBI;AACJ,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,EAAE,KAAK,EAAE,KAAY,EAAE,MAA+B,EAAE,EAAE;QAC5D,IAAI,CAAC,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;QAC/D,iBAAiB,CAAC,MAAM,CAAC,CAAA;QACzB,+CAA+C;QAC/C,iEAAiE;QACjE,MAAM,CAAC,SAAS,CAAC,GAAG,mBAAmB,CAAC,CAAC,KAAK,CAAC,CAAC,CAAA;QAChD,OAAO,GAAG,CAAC,KAAK,CAAC,SAAS,EAAE;YAC1B,IAAI,EAAE;gBACJ,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,GAAG,CAAC,UAAU,CAAC,SAAS,CAAC;gBAC5E,MAAM,EAAG,MAAM,CAAC,UAA+B,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;aAC7D;YACD,kBAAkB,EAAG,MAAM,CAAC,kBAAyC,IAAI,GAAG;YAC5E,uBAAuB,EAAG,MAAM,CAAC,uBAA+C,IAAI,KAAK;YACzF,iBAAiB,EAAG,MAAM,CAAC,iBAAwC,IAAI,GAAG;YAC1E,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,WAAW,EAAG,MAAM,CAAC,WAAkC,IAAI,IAAI;YAC/D,gBAAgB,EAAG,MAAM,CAAC,gBAAuC,IAAI,CAAC;SACvE,CAAC,CAAA;IACJ,CAAC;IACD,SAAS,EAAE,EAAE,kBAAkB,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE;IACxE,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,MAAM,EAAE,2CAA2C,EAAgB;CACjG,CAAC,CAAA","sourcesContent":["/**\n * stdlib knurl — 滚花库函数(mesh-only)\n *\n *\n * knurl 无 BREP 实现(mesh-only)——dispatchPath 在 brep 模式下调用前抛错。\n * part-brep-lost 事件由引擎统一发(P4,库不再 emit)。\n */\n\nimport type { Shape, Vec3 } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { reconcileBrepInputs } from './reconcile'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { assertPositiveNumber } from './assert'\n\n/**\n * Validate knurl parameters: `knurlTextureHeight` must be a positive number.\n * @param params - the raw knurl operation parameters.\n */\nexport function assertKnurlParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.knurlTextureHeight, 'knurl.knurlTextureHeight')\n}\n\n/**\n * 施加滚花(顶点位移,非布尔)。mesh-only。\n * @group 特征\n * @inputs 1\n * @async true\n * @qual warn\n * @name knurl\n * @note knurl 无 BREP 实现(mesh-only),本质是顶点位移(网格操作),网格参数可接受;brep 模式下调用前抛 BrepUnsupportedError。面锚定建议用几何引用。\n * @returns Shape 滚花后的几何。\n * @param input - 目标几何。type:Shape required:true\n * @param params.knurlTextureHeight - 纹路高度(mm)。type:number 默认 0.5\n * @param params.knurlScaleU - 纹路 U 向频率。type:number 默认 0.15\n * @param params.knurlScaleV - 纹路 V 向频率。type:number 默认 0.15\n * @param params.knurlInvertDisplacement - 反向位移。type:boolean 默认 false\n * @param params.knurlRefineLength - 细分长度(mm)。type:number 默认 1.0\n * @param params.knurlMappingMode - UV 映射模式。type:number 默认 5\n * @param params.faceCenter - 面锚点中心。type:[x,y,z] 默认 bboxCenter\n * @param params.faceNormal - 面法向。type:[x,y,z] 默认 [0,0,1]\n * @example\n * const p = await cad.knurl(part0, { knurlTextureHeight: 0.5, knurlScaleU: 0.15, knurlScaleV: 0.15, knurlInvertDisplacement: false, knurlRefineLength: 1.0, knurlMappingMode: 5 })\n */\nexport const knurl = defineOp({\n mesh: async (input: Shape, params: Record<string, unknown>) => {\n if (!input) throw new Error('[stdlib/knurl] no input geometry')\n assertKnurlParams(params)\n // 断链时刻(用户点名场景):BREP 建模的模型最后做滚花 → BREP 输入必须先归约为\n // 合法 2-manifold 网格再进 mesh 路径(reconcileBrepInputs 对 mesh 侧输入原样透传)\n const [meshInput] = reconcileBrepInputs([input])\n return cad.knurl(meshInput, {\n face: {\n center: (params.faceCenter as Vec3 | undefined) ?? cad.bboxCenter(meshInput),\n normal: (params.faceNormal as Vec3 | undefined) ?? [0, 0, 1],\n },\n knurlTextureHeight: (params.knurlTextureHeight as number | undefined) ?? 0.5,\n knurlInvertDisplacement: (params.knurlInvertDisplacement as boolean | undefined) ?? false,\n knurlRefineLength: (params.knurlRefineLength as number | undefined) ?? 1.0,\n knurlScaleU: (params.knurlScaleU as number | undefined) ?? 0.15,\n knurlScaleV: (params.knurlScaleV as number | undefined) ?? 0.15,\n knurlMappingMode: (params.knurlMappingMode as number | undefined) ?? 5,\n })\n },\n paramDims: { knurlTextureHeight: 'length', knurlRefineLength: 'length' },\n naming: { kind: 'unmodeled', reason: 'knurl is mesh-only, no BREP face identity' } as Provenance,\n})\n"]}
|
package/dist/api/primitives.d.ts
CHANGED
|
@@ -56,10 +56,11 @@ export declare function assertWedgeParams(params: Record<string, unknown>): void
|
|
|
56
56
|
* @param params.centered - 无 at 时是否居中到原点(type:boolean 默认 false,角点在原点)。
|
|
57
57
|
* @param params.segments - 细分度(影响三角化)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)
|
|
58
58
|
* @example
|
|
59
|
-
* const part0 = cad.box(10, 20, 30)
|
|
60
|
-
* const part1 = cad.box(30, 20, 10, { centered: true, at: [1, 2, 3], segments: 64 })
|
|
59
|
+
* const part0 = cad.box(10 * MM, 20 * MM, 30 * MM)
|
|
60
|
+
* const part1 = cad.box(30 * MM, 20 * MM, 10 * MM, { centered: true, at: [1, 2, 3], segments: 64 })
|
|
61
61
|
*
|
|
62
|
-
* 位置原生(§4.1/§6.2):`box(width, depth, height)` 与 `box(10, 20, 30, {centered:true})`
|
|
62
|
+
* 位置原生(§4.1/§6.2):`box(width, depth, height)` 与 `box(10 * MM, 20 * MM, 30 * MM, {centered:true})`
|
|
63
|
+
* 有量纲位必须写单位字面量(基准单位亦然,`10` 裸数字被 D8 R2 拒)。
|
|
63
64
|
* 归一到同一对象(D11 位置→对象 + 尾参 options 合并)。旧 `{ size }` 对象形态已废弃(裁决 3),
|
|
64
65
|
* 传入会抛 `E_ARGS_FORM`(错误提示 ≠ 兼容,§4.1)。
|
|
65
66
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/api/primitives.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAgB1C;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAS1E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUtE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKvE;AAmBD
|
|
1
|
+
{"version":3,"file":"primitives.d.ts","sourceRoot":"","sources":["../../src/api/primitives.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAgB1C;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUrE;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAExE;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAS1E;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAUtE;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAKvE;AAmBD;;;;;;;;;;;;;;;;;;;;;;KAsBK;AACL,eAAO,MAAM,GAAG;;CAwBd,CAAA;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,MAAM;;CAgBjB,CAAA;AAWF;;;;;;;;;;;;;;;;;;;;;;IAsBI;AACJ,eAAO,MAAM,QAAQ;;CAgBnB,CAAA;AAEF;;;;;;;;;;;;;;;;;;;;;;IAsBI;AACJ,eAAO,MAAM,IAAI;;CAuBf,CAAA;AAEF;;;;;;;;;;;;;;;;IAgBI;AACJ,eAAO,MAAM,KAAK;;CAchB,CAAA"}
|
package/dist/api/primitives.js
CHANGED
|
@@ -110,10 +110,11 @@ function primitiveBrep(op, params) {
|
|
|
110
110
|
* @param params.centered - 无 at 时是否居中到原点(type:boolean 默认 false,角点在原点)。
|
|
111
111
|
* @param params.segments - 细分度(影响三角化)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)
|
|
112
112
|
* @example
|
|
113
|
-
* const part0 = cad.box(10, 20, 30)
|
|
114
|
-
* const part1 = cad.box(30, 20, 10, { centered: true, at: [1, 2, 3], segments: 64 })
|
|
113
|
+
* const part0 = cad.box(10 * MM, 20 * MM, 30 * MM)
|
|
114
|
+
* const part1 = cad.box(30 * MM, 20 * MM, 10 * MM, { centered: true, at: [1, 2, 3], segments: 64 })
|
|
115
115
|
*
|
|
116
|
-
* 位置原生(§4.1/§6.2):`box(width, depth, height)` 与 `box(10, 20, 30, {centered:true})`
|
|
116
|
+
* 位置原生(§4.1/§6.2):`box(width, depth, height)` 与 `box(10 * MM, 20 * MM, 30 * MM, {centered:true})`
|
|
117
|
+
* 有量纲位必须写单位字面量(基准单位亦然,`10` 裸数字被 D8 R2 拒)。
|
|
117
118
|
* 归一到同一对象(D11 位置→对象 + 尾参 options 合并)。旧 `{ size }` 对象形态已废弃(裁决 3),
|
|
118
119
|
* 传入会抛 `E_ARGS_FORM`(错误提示 ≠ 兼容,§4.1)。
|
|
119
120
|
*/
|
|
@@ -139,6 +140,7 @@ export const box = defineOp({
|
|
|
139
140
|
// D11 位置→对象(§4.1/§6.2):三个标量装箱成 { width, depth, height },尾参
|
|
140
141
|
// options 经 dual-form-args 的尾参合并(§6.2)并入。
|
|
141
142
|
slotMap: { keys: ['width', 'depth', 'height'] },
|
|
143
|
+
paramDims: { width: 'length', depth: 'length', height: 'length' },
|
|
142
144
|
naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'front' }, { kind: 'semantic', name: 'back' }, { kind: 'semantic', name: 'left' }, { kind: 'semantic', name: 'right' }] } },
|
|
143
145
|
});
|
|
144
146
|
/**
|
|
@@ -172,6 +174,7 @@ export const sphere = defineOp({
|
|
|
172
174
|
// D11: `sphere(10)` == `sphere({ radius: 10 })`; 尾参 options({at, segments})
|
|
173
175
|
// 经 dual-form-args 的尾参合并规则归一(裁决 4,§6.2)。
|
|
174
176
|
slotMap: { keys: ['radius'] },
|
|
177
|
+
paramDims: { radius: 'length' },
|
|
175
178
|
naming: { kind: 'unmodeled', reason: 'sphere face vocabulary pending Phase 3' },
|
|
176
179
|
});
|
|
177
180
|
/**
|
|
@@ -220,6 +223,7 @@ export const cylinder = defineOp({
|
|
|
220
223
|
// D11(§4.1/§6.2):`cylinder(5, 40)` 两个标量装箱成 { radius, height };尾参 options
|
|
221
224
|
// 经 dual-form-args 尾参合并并入。
|
|
222
225
|
slotMap: { keys: ['radius', 'height'] },
|
|
226
|
+
paramDims: { radius: 'length', height: 'length' },
|
|
223
227
|
naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'lateral' }] } },
|
|
224
228
|
});
|
|
225
229
|
/**
|
|
@@ -266,6 +270,7 @@ export const cone = defineOp({
|
|
|
266
270
|
// D11(§4.1/§6.2): `cone(10, 4, 30)` 三个标量装箱成 { radiusBottom, radiusTop, height }。
|
|
267
271
|
// 尾参 options({at, centered, segments})经 dual-form-args 尾参合并并入。
|
|
268
272
|
slotMap: { keys: ['radiusBottom', 'radiusTop', 'height'] },
|
|
273
|
+
paramDims: { radiusBottom: 'length', radiusTop: 'length', height: 'length' },
|
|
269
274
|
naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'lateral' }] } },
|
|
270
275
|
});
|
|
271
276
|
/**
|
|
@@ -297,6 +302,7 @@ export const wedge = defineOp({
|
|
|
297
302
|
},
|
|
298
303
|
// D11: `wedge(30, 20, 45, 10)` == `wedge({ width: 30, height: 20, angle: 45, length: 10 })`.
|
|
299
304
|
slotMap: { keys: ['width', 'height', 'angle', 'length'] },
|
|
305
|
+
paramDims: { width: 'length', height: 'length', angle: 'angle', length: 'length' },
|
|
300
306
|
naming: { kind: 'unmodeled', reason: 'wedge face vocabulary pending Phase 3' },
|
|
301
307
|
});
|
|
302
308
|
//# sourceMappingURL=primitives.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/api/primitives.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib primitives — 基本体创建库函数(box/sphere/cylinder/cone/wedge)\n *\n *\n * dispatchPath 静态判定 brep/mesh,产物经 solid()/fromBrep() 构造器创建。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { clampNRad } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { primitiveToBrepSolid } from '../primitives/brep-primitives'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getCurrentStmt } from '../runtime-state'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep } from '../shape'\nimport { assignRoles } from '../topology/naming/roles'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { asPartName } from '../identity'\nimport { defineOp } from '../sdk'\nimport { assertPositiveNumber, assertNonNegativeNumber } from './assert'\n\n// ── per-op 参数自校验(Phase 2.2;stdlib 被直接 import 时的防御层) ──\n\n/**\n * Validate box parameters (brepjs contract, §4.1 A 决策): `width`, `depth` and\n * `height` must be positive numbers. The legacy `{ size }` object form is\n * removed — any call still passing `size` throws an explicit `E_ARGS_FORM`\n * error pointing at the new signature (error hint ≠ compatibility).\n * @param params - the raw box operation parameters.\n */\nexport function assertBoxParams(params: Record<string, unknown>): void {\n if (params.size !== undefined) {\n throw new Error(\n '[faijs/args] box: E_ARGS_FORM: the `box({ size })` object form is removed. ' +\n 'box now uses `box(width, depth, height, { at?, centered?, segments? })`.',\n )\n }\n assertPositiveNumber(params.width, 'box.width')\n assertPositiveNumber(params.depth, 'box.depth')\n assertPositiveNumber(params.height, 'box.height')\n}\n\n/**\n * Validate sphere parameters: `radius` must be a positive number.\n * @param params - the raw sphere operation parameters.\n */\nexport function assertSphereParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.radius, 'sphere.radius')\n}\n\n/**\n * Validate cylinder parameters (brepjs contract, §4.3 A 决策): `radius` and\n * `height` must be positive. The legacy `{ center }` object key is removed — any\n * call still passing `center` throws an explicit `E_ARGS_FORM` error pointing at\n * the new signature (error hint ≠ compatibility, 裁决 3).\n * @param params - the raw cylinder operation parameters.\n */\nexport function assertCylinderParams(params: Record<string, unknown>): void {\n if (params.center !== undefined || params.size !== undefined) {\n throw new Error(\n '[faijs/args] cylinder: E_ARGS_FORM: the legacy object form is removed. ' +\n 'cylinder now uses `cylinder(radius, height, { at?, centered?, segments? })`.',\n )\n }\n assertPositiveNumber(params.radius, 'cylinder.radius')\n assertPositiveNumber(params.height, 'cylinder.height')\n}\n\n/**\n * Validate cone parameters (brepjs contract, §4.1 P 决策): `radiusBottom` and\n * `height` must be positive, `radiusTop` must be non-negative. The legacy\n * `{ center }` object key is removed — any call still passing `center` throws an\n * explicit `E_ARGS_FORM` error pointing at the new signature (error hint ≠\n * compatibility, 裁决 3).\n * @param params - the raw cone operation parameters.\n */\nexport function assertConeParams(params: Record<string, unknown>): void {\n if (params.center !== undefined || params.size !== undefined) {\n throw new Error(\n '[faijs/args] cone: E_ARGS_FORM: the legacy object form is removed. ' +\n 'cone now uses `cone(bottomRadius, topRadius, height, { at?, centered?, segments? })`.',\n )\n }\n assertPositiveNumber(params.radiusBottom, 'cone.radiusBottom')\n assertNonNegativeNumber(params.radiusTop, 'cone.radiusTop')\n assertPositiveNumber(params.height, 'cone.height')\n}\n\n/**\n * Validate wedge parameters: `width`, `height`, `angle`, and `length` must be\n * positive numbers.\n * @param params - the raw wedge operation parameters.\n */\nexport function assertWedgeParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.width, 'wedge.width')\n assertPositiveNumber(params.height, 'wedge.height')\n assertPositiveNumber(params.angle, 'wedge.angle')\n assertPositiveNumber(params.length, 'wedge.length')\n}\n\n/** BREP 路径:OCCT 精确构造 + 三角化 + fromBrep 登记(基本体无面演化;链根建 roleTable)。 */\nfunction primitiveBrep(op: string, params: Record<string, unknown>): Shape {\n const kernel = getBrepApi()\n const type = op === 'box' ? 'cube' : op\n const result = primitiveToBrepSolid(kernel, type as 'cube' | 'sphere' | 'cylinder' | 'cone' | 'wedge', params as never)\n // §3.2:链根建表——语义命名器按 op 类型给面命名(semantic 'top'/'lateral' 等,\n // Phase 1.7 已删 'box:' 前缀与位置兜底)。\n // Phase 1.6:origin 用链根语句的 StmtId(当前语句 id,§2.2/§4.1)——变量名会被\n // 改名/复用,StmtId 全局唯一,保证多个同类型 primitive 不撞 origin。\n const origin = String(getCurrentStmt()?.id ?? op)\n const roles = assignRoles(kernel, result.solid, op)\n return fromBrep(\n solidToShape(kernel, result.solid, clampNRad((params.nRad ?? params.segments) as number)),\n { solid: result.solid, roleTable: new Map([[asPartName(origin), roles]]) },\n )\n}\n\n/**\n * 创建长方体(brepjs 契约,§4.1 A 决策)。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name box\n * @returns Shape 长方体几何,可作为后续 op 的输入。\n * @param params.width - X 方向边长(mm)。type:number required:true\n * @param params.depth - Y 方向边长(mm)。type:number required:true\n * @param params.height - Z 方向边长(mm)。type:number required:true\n * @param params.at - 中心点(CENTER 语义,优先于 centered)。type:[x,y,z] 可选\n * @param params.centered - 无 at 时是否居中到原点(type:boolean 默认 false,角点在原点)。\n * @param params.segments - 细分度(影响三角化)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)\n * @example\n * const part0 = cad.box(10, 20, 30)\n * const part1 = cad.box(30, 20, 10, { centered: true, at: [1, 2, 3], segments: 64 })\n *\n * 位置原生(§4.1/§6.2):`box(width, depth, height)` 与 `box(10, 20, 30, {centered:true})`\n * 归一到同一对象(D11 位置→对象 + 尾参 options 合并)。旧 `{ size }` 对象形态已废弃(裁决 3),\n * 传入会抛 `E_ARGS_FORM`(错误提示 ≠ 兼容,§4.1)。\n */\nexport const box = defineOp({\n name: 'box',\n mesh: (params: Record<string, unknown>) => {\n assertBoxParams(params)\n return cad.box(params as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertBoxParams(params)\n return primitiveBrep('box', params)\n },\n // schema feeds codegen/UI parameter panels.\n schema: {\n width: 'number',\n depth: 'number',\n height: 'number',\n at: 'vec3?',\n centered: 'boolean?',\n segments: 'number?',\n },\n // D11 位置→对象(§4.1/§6.2):三个标量装箱成 { width, depth, height },尾参\n // options 经 dual-form-args 的尾参合并(§6.2)并入。\n slotMap: { keys: ['width', 'depth', 'height'] },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'front' }, { kind: 'semantic', name: 'back' }, { kind: 'semantic', name: 'left' }, { kind: 'semantic', name: 'right' }] } } as Provenance,\n})\n\n/**\n * 创建球体。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name sphere\n * @returns Shape 球体几何,可作为后续 op 的输入。\n * @param params.radius - 半径(mm)。type:number required:true\n * @param params.segments - 细分度(影响面数)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)\n * @param params.center - 球心位置(at 的同义别名)。type:[x,y,z] 默认 [0,0,0](原点)。\n * @param params.at - 球心位置(center 的同义别名,brepjs 契约;裁决 4 双形态合法)。\n * @example\n * const r = cad.sphere({ radius: 10 })\n * const r = cad.sphere(10, { at: [0, 0, 10], segments: 64 })\n * const r = cad.sphere({ radius: 10, segments: 64, center: [0,0,10] })\n */\nexport const sphere = defineOp({\n name: 'sphere',\n mesh: (params: Record<string, unknown>) => {\n assertSphereParams(params)\n return cad.sphere(centerParams(params) as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertSphereParams(params)\n return primitiveBrep('sphere', centerParams(params))\n },\n schema: { radius: 'number', segments: 'number?', center: 'vec3?', at: 'vec3?' },\n // D11: `sphere(10)` == `sphere({ radius: 10 })`; 尾参 options({at, segments})\n // 经 dual-form-args 的尾参合并规则归一(裁决 4,§6.2)。\n slotMap: { keys: ['radius'] },\n naming: { kind: 'unmodeled', reason: 'sphere face vocabulary pending Phase 3' } as Provenance,\n})\n\n/**\n * 位置归一:把 brepjs 契约的 `at`(= faijs 的 `center`,球心语义)归一为一个\n * `center` 输入,mesh/brep 两条消费路径共用(裁决 1/4,§4.2)。\n */\nfunction centerParams(params: Record<string, unknown>): Record<string, unknown> {\n if (params.at !== undefined) return { ...params, center: params.at }\n return params\n}\n\n/**\n * 创建圆柱体(brepjs 契约,§4.3 A 决策)。\n * 锚点:`at` 是**底面轴心**(BASE 语义,默认 [0,0,0],底面在原点、+Z 延伸);`centered:true`\n * 指底面落到 −h/2(无 at 时居中到原点;与 `at` 同给时以 `at` 为中心)。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name cylinder\n * @returns Shape 圆柱体几何,可作为后续 op 的输入。\n * @param params.radius - 底面半径(mm)。type:number required:true\n * @param params.height - 高度(mm),沿 +Z 轴。type:number required:true\n * @param params.at - 底面中心(BASE 语义)。type:[x,y,z] 可选\n * @param params.centered - 是否居中(底面 −h/2;与 at 同给时以 at 为中心)。type:boolean 默认 false\n * @param params.segments - 细分度(影响三角化)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)\n * @example\n * const c = cad.cylinder(5, 40)\n * const c = cad.cylinder(5, 40, { centered: true, at: [0, 0, 20], segments: 64 })\n *\n * 位置原生(§4.1/§6.2):`cylinder(5, 40)` 与 `cylinder(5, 40, {centered:true})`\n * 归一到同一对象(D11 位置→装箱 + 尾参 options 合并)。旧 `{ center }` 对象形态已废弃\n * (裁决 3),传入会抛 `E_ARGS_FORM`(错误提示 ≠ 兼容,§4.3)。\n */\nexport const cylinder = defineOp({\n name: 'cylinder',\n mesh: (params: Record<string, unknown>) => {\n assertCylinderParams(params)\n return cad.cylinder(params as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertCylinderParams(params)\n return primitiveBrep('cylinder', params)\n },\n schema: { radius: 'number', height: 'number', at: 'vec3?', centered: 'boolean?', segments: 'number?' },\n // D11(§4.1/§6.2):`cylinder(5, 40)` 两个标量装箱成 { radius, height };尾参 options\n // 经 dual-form-args 尾参合并并入。\n slotMap: { keys: ['radius', 'height'] },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'lateral' }] } } as Provenance,\n})\n\n/**\n * 创建圆锥体(brepjs 契约,§4.1 P 决策)。radiusTop 等于 radiusBottom 时即圆柱,0 为尖锥。\n * 锚点:`at` 是**底面轴心**(BASE 语义,默认 [0,0,0],底面在原点、+Z 延伸);`centered:true`\n * 指底面落到 −h/2(无 at 时居中到原点;与 `at` 同给时以 `at` 为中心)。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name cone\n * @returns Shape 圆锥体几何,可作为后续 op 的输入。\n * @param params.radiusBottom - 底半径(mm)。type:number required:true\n * @param params.radiusTop - 顶半径(mm),0 为尖锥,非负,等于 radiusBottom 得圆柱。type:number required:true\n * @param params.height - 高度(mm),沿 +Z 轴。type:number required:true\n * @param params.at - 底面轴心(BASE 语义)。type:[x,y,z] 可选\n * @param params.centered - 是否居中(底面 −h/2;与 at 同给时以 at 为中心)。type:boolean 默认 false\n * @param params.segments - 细分度(影响三角化)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)\n * @example\n * const c = cad.cone(10, 4, 30)\n * const c = cad.cone(10, 0, 30, { centered: true, at: [0, 0, 20], segments: 64 })\n * 位置原生(§4.1/§6.2):`cone(10, 4, 30)` 与 `cone(10, 4, 30, { centered: true })`\n * 归一到同一对象(D11 位置→装箱 + 尾参 options 合并)。旧 `{ center }`/`{ size }` 对象形态\n * 已废弃(裁决 3),传入会抛 E_ARGS_FORM(错误提示 ≠ 兼容)。\n */\nexport const cone = defineOp({\n name: 'cone',\n mesh: (params: Record<string, unknown>) => {\n assertConeParams(params)\n return cad.cone(params as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertConeParams(params)\n return primitiveBrep('cone', params)\n },\n schema: {\n radiusBottom: 'number',\n radiusTop: 'number',\n height: 'number',\n at: 'vec3?',\n centered: 'boolean?',\n segments: 'number?',\n },\n // D11(§4.1/§6.2): `cone(10, 4, 30)` 三个标量装箱成 { radiusBottom, radiusTop, height }。\n // 尾参 options({at, centered, segments})经 dual-form-args 尾参合并并入。\n slotMap: { keys: ['radiusBottom', 'radiusTop', 'height'] },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'lateral' }] } } as Provenance,\n})\n\n/**\n * 创建楔形体。唯一契约是 width/height/angle/length(width/height/angle 为正数,length 沿切割方向),\n * 旧文档的 size 形态已废弃,传 { size } 会抛错。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name wedge\n * @note 曾与 UI 面板的 `size` 形态并存并写入文档,但断言层确认唯一合法契约是 width/height/angle/length;传 `{ size }` 直接抛错。已按真源收敛。\n * @returns Shape 楔形体几何,可作为后续 op 的输入。\n * @param params.width - 底面宽度(mm)。type:number required:true\n * @param params.height - 高度(mm)。type:number required:true\n * @param params.angle - 楔形角度(度)。type:number required:true\n * @param params.length - 沿切割方向的长度(mm)。type:number required:true\n * @example\n * const w = cad.wedge({ width: 30, height: 20, angle: 45, length: 10 })\n */\nexport const wedge = defineOp({\n name: 'wedge',\n mesh: (params: Record<string, unknown>) => {\n assertWedgeParams(params)\n return cad.wedge(params as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertWedgeParams(params)\n return primitiveBrep('wedge', params)\n },\n // D11: `wedge(30, 20, 45, 10)` == `wedge({ width: 30, height: 20, angle: 45, length: 10 })`.\n slotMap: { keys: ['width', 'height', 'angle', 'length'] },\n naming: { kind: 'unmodeled', reason: 'wedge face vocabulary pending Phase 3' } as Provenance,\n})\n"]}
|
|
1
|
+
{"version":3,"file":"primitives.js","sourceRoot":"","sources":["../../src/api/primitives.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib primitives — 基本体创建库函数(box/sphere/cylinder/cone/wedge)\n *\n *\n * dispatchPath 静态判定 brep/mesh,产物经 solid()/fromBrep() 构造器创建。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { clampNRad } from '../mesh/types'\nimport { cad } from '../mesh'\nimport { primitiveToBrepSolid } from '../primitives/brep-primitives'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getCurrentStmt } from '../runtime-state'\nimport { getBrepApi } from '../brep/handle-bridge'\nimport { fromBrep } from '../shape'\nimport { assignRoles } from '../topology/naming/roles'\nimport type { Provenance } from '../topology/naming/lineage'\nimport { asPartName } from '../identity'\nimport { defineOp } from '../sdk'\nimport { assertPositiveNumber, assertNonNegativeNumber } from './assert'\n\n// ── per-op 参数自校验(Phase 2.2;stdlib 被直接 import 时的防御层) ──\n\n/**\n * Validate box parameters (brepjs contract, §4.1 A 决策): `width`, `depth` and\n * `height` must be positive numbers. The legacy `{ size }` object form is\n * removed — any call still passing `size` throws an explicit `E_ARGS_FORM`\n * error pointing at the new signature (error hint ≠ compatibility).\n * @param params - the raw box operation parameters.\n */\nexport function assertBoxParams(params: Record<string, unknown>): void {\n if (params.size !== undefined) {\n throw new Error(\n '[faijs/args] box: E_ARGS_FORM: the `box({ size })` object form is removed. ' +\n 'box now uses `box(width, depth, height, { at?, centered?, segments? })`.',\n )\n }\n assertPositiveNumber(params.width, 'box.width')\n assertPositiveNumber(params.depth, 'box.depth')\n assertPositiveNumber(params.height, 'box.height')\n}\n\n/**\n * Validate sphere parameters: `radius` must be a positive number.\n * @param params - the raw sphere operation parameters.\n */\nexport function assertSphereParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.radius, 'sphere.radius')\n}\n\n/**\n * Validate cylinder parameters (brepjs contract, §4.3 A 决策): `radius` and\n * `height` must be positive. The legacy `{ center }` object key is removed — any\n * call still passing `center` throws an explicit `E_ARGS_FORM` error pointing at\n * the new signature (error hint ≠ compatibility, 裁决 3).\n * @param params - the raw cylinder operation parameters.\n */\nexport function assertCylinderParams(params: Record<string, unknown>): void {\n if (params.center !== undefined || params.size !== undefined) {\n throw new Error(\n '[faijs/args] cylinder: E_ARGS_FORM: the legacy object form is removed. ' +\n 'cylinder now uses `cylinder(radius, height, { at?, centered?, segments? })`.',\n )\n }\n assertPositiveNumber(params.radius, 'cylinder.radius')\n assertPositiveNumber(params.height, 'cylinder.height')\n}\n\n/**\n * Validate cone parameters (brepjs contract, §4.1 P 决策): `radiusBottom` and\n * `height` must be positive, `radiusTop` must be non-negative. The legacy\n * `{ center }` object key is removed — any call still passing `center` throws an\n * explicit `E_ARGS_FORM` error pointing at the new signature (error hint ≠\n * compatibility, 裁决 3).\n * @param params - the raw cone operation parameters.\n */\nexport function assertConeParams(params: Record<string, unknown>): void {\n if (params.center !== undefined || params.size !== undefined) {\n throw new Error(\n '[faijs/args] cone: E_ARGS_FORM: the legacy object form is removed. ' +\n 'cone now uses `cone(bottomRadius, topRadius, height, { at?, centered?, segments? })`.',\n )\n }\n assertPositiveNumber(params.radiusBottom, 'cone.radiusBottom')\n assertNonNegativeNumber(params.radiusTop, 'cone.radiusTop')\n assertPositiveNumber(params.height, 'cone.height')\n}\n\n/**\n * Validate wedge parameters: `width`, `height`, `angle`, and `length` must be\n * positive numbers.\n * @param params - the raw wedge operation parameters.\n */\nexport function assertWedgeParams(params: Record<string, unknown>): void {\n assertPositiveNumber(params.width, 'wedge.width')\n assertPositiveNumber(params.height, 'wedge.height')\n assertPositiveNumber(params.angle, 'wedge.angle')\n assertPositiveNumber(params.length, 'wedge.length')\n}\n\n/** BREP 路径:OCCT 精确构造 + 三角化 + fromBrep 登记(基本体无面演化;链根建 roleTable)。 */\nfunction primitiveBrep(op: string, params: Record<string, unknown>): Shape {\n const kernel = getBrepApi()\n const type = op === 'box' ? 'cube' : op\n const result = primitiveToBrepSolid(kernel, type as 'cube' | 'sphere' | 'cylinder' | 'cone' | 'wedge', params as never)\n // §3.2:链根建表——语义命名器按 op 类型给面命名(semantic 'top'/'lateral' 等,\n // Phase 1.7 已删 'box:' 前缀与位置兜底)。\n // Phase 1.6:origin 用链根语句的 StmtId(当前语句 id,§2.2/§4.1)——变量名会被\n // 改名/复用,StmtId 全局唯一,保证多个同类型 primitive 不撞 origin。\n const origin = String(getCurrentStmt()?.id ?? op)\n const roles = assignRoles(kernel, result.solid, op)\n return fromBrep(\n solidToShape(kernel, result.solid, clampNRad((params.nRad ?? params.segments) as number)),\n { solid: result.solid, roleTable: new Map([[asPartName(origin), roles]]) },\n )\n}\n\n/**\n * 创建长方体(brepjs 契约,§4.1 A 决策)。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name box\n * @returns Shape 长方体几何,可作为后续 op 的输入。\n * @param params.width - X 方向边长(mm)。type:number required:true\n * @param params.depth - Y 方向边长(mm)。type:number required:true\n * @param params.height - Z 方向边长(mm)。type:number required:true\n * @param params.at - 中心点(CENTER 语义,优先于 centered)。type:[x,y,z] 可选\n * @param params.centered - 无 at 时是否居中到原点(type:boolean 默认 false,角点在原点)。\n * @param params.segments - 细分度(影响三角化)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)\n * @example\n * const part0 = cad.box(10 * MM, 20 * MM, 30 * MM)\n * const part1 = cad.box(30 * MM, 20 * MM, 10 * MM, { centered: true, at: [1, 2, 3], segments: 64 })\n *\n * 位置原生(§4.1/§6.2):`box(width, depth, height)` 与 `box(10 * MM, 20 * MM, 30 * MM, {centered:true})`\n * 有量纲位必须写单位字面量(基准单位亦然,`10` 裸数字被 D8 R2 拒)。\n * 归一到同一对象(D11 位置→对象 + 尾参 options 合并)。旧 `{ size }` 对象形态已废弃(裁决 3),\n * 传入会抛 `E_ARGS_FORM`(错误提示 ≠ 兼容,§4.1)。\n */\nexport const box = defineOp({\n name: 'box',\n mesh: (params: Record<string, unknown>) => {\n assertBoxParams(params)\n return cad.box(params as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertBoxParams(params)\n return primitiveBrep('box', params)\n },\n // schema feeds codegen/UI parameter panels.\n schema: {\n width: 'number',\n depth: 'number',\n height: 'number',\n at: 'vec3?',\n centered: 'boolean?',\n segments: 'number?',\n },\n // D11 位置→对象(§4.1/§6.2):三个标量装箱成 { width, depth, height },尾参\n // options 经 dual-form-args 的尾参合并(§6.2)并入。\n slotMap: { keys: ['width', 'depth', 'height'] },\n paramDims: { width: 'length', depth: 'length', height: 'length' },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'front' }, { kind: 'semantic', name: 'back' }, { kind: 'semantic', name: 'left' }, { kind: 'semantic', name: 'right' }] } } as Provenance,\n})\n\n/**\n * 创建球体。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name sphere\n * @returns Shape 球体几何,可作为后续 op 的输入。\n * @param params.radius - 半径(mm)。type:number required:true\n * @param params.segments - 细分度(影响面数)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)\n * @param params.center - 球心位置(at 的同义别名)。type:[x,y,z] 默认 [0,0,0](原点)。\n * @param params.at - 球心位置(center 的同义别名,brepjs 契约;裁决 4 双形态合法)。\n * @example\n * const r = cad.sphere({ radius: 10 })\n * const r = cad.sphere(10, { at: [0, 0, 10], segments: 64 })\n * const r = cad.sphere({ radius: 10, segments: 64, center: [0,0,10] })\n */\nexport const sphere = defineOp({\n name: 'sphere',\n mesh: (params: Record<string, unknown>) => {\n assertSphereParams(params)\n return cad.sphere(centerParams(params) as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertSphereParams(params)\n return primitiveBrep('sphere', centerParams(params))\n },\n schema: { radius: 'number', segments: 'number?', center: 'vec3?', at: 'vec3?' },\n // D11: `sphere(10)` == `sphere({ radius: 10 })`; 尾参 options({at, segments})\n // 经 dual-form-args 的尾参合并规则归一(裁决 4,§6.2)。\n slotMap: { keys: ['radius'] },\n paramDims: { radius: 'length' },\n naming: { kind: 'unmodeled', reason: 'sphere face vocabulary pending Phase 3' } as Provenance,\n})\n\n/**\n * 位置归一:把 brepjs 契约的 `at`(= faijs 的 `center`,球心语义)归一为一个\n * `center` 输入,mesh/brep 两条消费路径共用(裁决 1/4,§4.2)。\n */\nfunction centerParams(params: Record<string, unknown>): Record<string, unknown> {\n if (params.at !== undefined) return { ...params, center: params.at }\n return params\n}\n\n/**\n * 创建圆柱体(brepjs 契约,§4.3 A 决策)。\n * 锚点:`at` 是**底面轴心**(BASE 语义,默认 [0,0,0],底面在原点、+Z 延伸);`centered:true`\n * 指底面落到 −h/2(无 at 时居中到原点;与 `at` 同给时以 `at` 为中心)。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name cylinder\n * @returns Shape 圆柱体几何,可作为后续 op 的输入。\n * @param params.radius - 底面半径(mm)。type:number required:true\n * @param params.height - 高度(mm),沿 +Z 轴。type:number required:true\n * @param params.at - 底面中心(BASE 语义)。type:[x,y,z] 可选\n * @param params.centered - 是否居中(底面 −h/2;与 at 同给时以 at 为中心)。type:boolean 默认 false\n * @param params.segments - 细分度(影响三角化)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)\n * @example\n * const c = cad.cylinder(5, 40)\n * const c = cad.cylinder(5, 40, { centered: true, at: [0, 0, 20], segments: 64 })\n *\n * 位置原生(§4.1/§6.2):`cylinder(5, 40)` 与 `cylinder(5, 40, {centered:true})`\n * 归一到同一对象(D11 位置→装箱 + 尾参 options 合并)。旧 `{ center }` 对象形态已废弃\n * (裁决 3),传入会抛 `E_ARGS_FORM`(错误提示 ≠ 兼容,§4.3)。\n */\nexport const cylinder = defineOp({\n name: 'cylinder',\n mesh: (params: Record<string, unknown>) => {\n assertCylinderParams(params)\n return cad.cylinder(params as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertCylinderParams(params)\n return primitiveBrep('cylinder', params)\n },\n schema: { radius: 'number', height: 'number', at: 'vec3?', centered: 'boolean?', segments: 'number?' },\n // D11(§4.1/§6.2):`cylinder(5, 40)` 两个标量装箱成 { radius, height };尾参 options\n // 经 dual-form-args 尾参合并并入。\n slotMap: { keys: ['radius', 'height'] },\n paramDims: { radius: 'length', height: 'length' },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'lateral' }] } } as Provenance,\n})\n\n/**\n * 创建圆锥体(brepjs 契约,§4.1 P 决策)。radiusTop 等于 radiusBottom 时即圆柱,0 为尖锥。\n * 锚点:`at` 是**底面轴心**(BASE 语义,默认 [0,0,0],底面在原点、+Z 延伸);`centered:true`\n * 指底面落到 −h/2(无 at 时居中到原点;与 `at` 同给时以 `at` 为中心)。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name cone\n * @returns Shape 圆锥体几何,可作为后续 op 的输入。\n * @param params.radiusBottom - 底半径(mm)。type:number required:true\n * @param params.radiusTop - 顶半径(mm),0 为尖锥,非负,等于 radiusBottom 得圆柱。type:number required:true\n * @param params.height - 高度(mm),沿 +Z 轴。type:number required:true\n * @param params.at - 底面轴心(BASE 语义)。type:[x,y,z] 可选\n * @param params.centered - 是否居中(底面 −h/2;与 at 同给时以 at 为中心)。type:boolean 默认 false\n * @param params.segments - 细分度(影响三角化)。type:number 默认 64(= brepjs standard 等效,P0 §5.0/§5.1)\n * @example\n * const c = cad.cone(10, 4, 30)\n * const c = cad.cone(10, 0, 30, { centered: true, at: [0, 0, 20], segments: 64 })\n * 位置原生(§4.1/§6.2):`cone(10, 4, 30)` 与 `cone(10, 4, 30, { centered: true })`\n * 归一到同一对象(D11 位置→装箱 + 尾参 options 合并)。旧 `{ center }`/`{ size }` 对象形态\n * 已废弃(裁决 3),传入会抛 E_ARGS_FORM(错误提示 ≠ 兼容)。\n */\nexport const cone = defineOp({\n name: 'cone',\n mesh: (params: Record<string, unknown>) => {\n assertConeParams(params)\n return cad.cone(params as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertConeParams(params)\n return primitiveBrep('cone', params)\n },\n schema: {\n radiusBottom: 'number',\n radiusTop: 'number',\n height: 'number',\n at: 'vec3?',\n centered: 'boolean?',\n segments: 'number?',\n },\n // D11(§4.1/§6.2): `cone(10, 4, 30)` 三个标量装箱成 { radiusBottom, radiusTop, height }。\n // 尾参 options({at, centered, segments})经 dual-form-args 尾参合并并入。\n slotMap: { keys: ['radiusBottom', 'radiusTop', 'height'] },\n paramDims: { radiusBottom: 'length', radiusTop: 'length', height: 'length' },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'semantic', name: 'lateral' }] } } as Provenance,\n})\n\n/**\n * 创建楔形体。唯一契约是 width/height/angle/length(width/height/angle 为正数,length 沿切割方向),\n * 旧文档的 size 形态已废弃,传 { size } 会抛错。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name wedge\n * @note 曾与 UI 面板的 `size` 形态并存并写入文档,但断言层确认唯一合法契约是 width/height/angle/length;传 `{ size }` 直接抛错。已按真源收敛。\n * @returns Shape 楔形体几何,可作为后续 op 的输入。\n * @param params.width - 底面宽度(mm)。type:number required:true\n * @param params.height - 高度(mm)。type:number required:true\n * @param params.angle - 楔形角度(度)。type:number required:true\n * @param params.length - 沿切割方向的长度(mm)。type:number required:true\n * @example\n * const w = cad.wedge({ width: 30, height: 20, angle: 45, length: 10 })\n */\nexport const wedge = defineOp({\n name: 'wedge',\n mesh: (params: Record<string, unknown>) => {\n assertWedgeParams(params)\n return cad.wedge(params as never)\n },\n brep: (params: Record<string, unknown>) => {\n assertWedgeParams(params)\n return primitiveBrep('wedge', params)\n },\n // D11: `wedge(30, 20, 45, 10)` == `wedge({ width: 30, height: 20, angle: 45, length: 10 })`.\n slotMap: { keys: ['width', 'height', 'angle', 'length'] },\n paramDims: { width: 'length', height: 'length', angle: 'angle', length: 'length' },\n naming: { kind: 'unmodeled', reason: 'wedge face vocabulary pending Phase 3' } as Provenance,\n})\n"]}
|
package/dist/api/profile.d.ts
CHANGED
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
* 在轮廓坐标里预先变换,或由下游特征的 Placement 承担。
|
|
16
16
|
*/
|
|
17
17
|
import type { Shape } from '../mesh/types.js';
|
|
18
|
+
import { Blueprint } from '../geometry2d/blueprint.js';
|
|
18
19
|
/** 直线段(2D,z=0;端点为绝对坐标)。 */
|
|
19
20
|
export interface ProfileLineSeg {
|
|
20
21
|
kind: 'line';
|
|
@@ -45,9 +46,26 @@ export type ProfileSeg = ProfileLineSeg | ProfileArcSeg;
|
|
|
45
46
|
export interface ProfileLoop {
|
|
46
47
|
segments: ProfileSeg[];
|
|
47
48
|
}
|
|
49
|
+
/**
|
|
50
|
+
* A 2D contour that is already DRAWN — i.e. `cad.draw`'s product (a
|
|
51
|
+
* `Blueprint`), or an array of them (one per contour).
|
|
52
|
+
*
|
|
53
|
+
* Why the 2D entries accept this: `cad.draw` returns a pure-data contour with no
|
|
54
|
+
* OCCT handle, and without this path NO op can turn it into a Shape. Measured
|
|
55
|
+
* 2026-09-28 — feeding a `cad.draw` product straight to `cad.extrude` fails with
|
|
56
|
+
* `E_BREP_INPUT: argument carries no BREP handle`, and to `cad.sweep` with
|
|
57
|
+
* `INVALID_SHAPE_ID`. The plan's "draw → `sketchOnPlane` → `extrude`" pipeline
|
|
58
|
+
* therefore needs this bridge; `cad.profile` takes it too, because both entries
|
|
59
|
+
* share {@link toContourBlueprints} and a split acceptance rule would be a trap.
|
|
60
|
+
*/
|
|
61
|
+
export type DrawnContours = Blueprint | Blueprint[];
|
|
48
62
|
/** `cad.profile` 参数:轮廓环集合。语义见 {@link buildProfileShape}(嵌套=孔,不相交=独立岛)。 */
|
|
49
63
|
export interface ProfileParams {
|
|
50
|
-
|
|
64
|
+
/**
|
|
65
|
+
* 轮廓来源,两种等价形态:段环数据(`{segments: […]}`)或已绘制轮廓
|
|
66
|
+
* (`cad.draw` 产物 / 其数组)。
|
|
67
|
+
*/
|
|
68
|
+
contours: ProfileLoop[] | DrawnContours;
|
|
51
69
|
/**
|
|
52
70
|
* 产物形态:'face'(默认)构面;'wire' 只交出不带面的最大岛外环 wire(1D 曲线),
|
|
53
71
|
* 供扫掠族(sweep/loft/…)直接作 spine。'wire' 形态丢弃孔环(扫掠脊柱为单闭合轮廓)。
|
|
@@ -55,8 +73,19 @@ export interface ProfileParams {
|
|
|
55
73
|
as?: 'face' | 'wire';
|
|
56
74
|
}
|
|
57
75
|
/**
|
|
58
|
-
*
|
|
59
|
-
*
|
|
76
|
+
* Normalize a `contours` argument to `Blueprint[]`.
|
|
77
|
+
*
|
|
78
|
+
* Accepts the segment-loop data form, a single drawn contour, or an array of
|
|
79
|
+
* drawn contours. The two forms are never mixed — a mixed array is a caller bug
|
|
80
|
+
* and is rejected rather than half-interpreted.
|
|
81
|
+
*
|
|
82
|
+
* @param contours - the raw `contours` argument (`ProfileLoop[]` | `Blueprint` | `Blueprint[]`).
|
|
83
|
+
* @returns one `Blueprint` per contour, in input order.
|
|
84
|
+
*/
|
|
85
|
+
export declare function toContourBlueprints(contours: unknown): Blueprint[];
|
|
86
|
+
/**
|
|
87
|
+
* Validate profile parameters: `contours` must be a non-empty contour set —
|
|
88
|
+
* either segment loops (each with at least one segment) or drawn contours.
|
|
60
89
|
* @param params the raw profile operation parameters.
|
|
61
90
|
*/
|
|
62
91
|
export declare function assertProfileParams(params: Record<string, unknown>): void;
|
|
@@ -69,7 +98,7 @@ export declare function assertProfileParams(params: Record<string, unknown>): vo
|
|
|
69
98
|
* (7 面、volume 0)。多岛产物 = compound(每岛一面、各带自己的孔),下游
|
|
70
99
|
* `cad.extrude` 对 compound 输入逐面挤出(kernel MakePrism 收复合形状)。
|
|
71
100
|
*
|
|
72
|
-
* @param params -
|
|
101
|
+
* @param params - 轮廓来源(段环数据或 `cad.draw` 产物)与产物形态。
|
|
73
102
|
* @returns Shape(单岛为 face;多岛为 face 的 compound;`as:'wire'` 为 1D 曲线)。
|
|
74
103
|
*/
|
|
75
104
|
export declare function buildProfileShape(params: ProfileParams): Shape;
|
|
@@ -81,7 +110,7 @@ export declare function buildProfileShape(params: ProfileParams): Shape;
|
|
|
81
110
|
* @qual ok
|
|
82
111
|
* @name profile
|
|
83
112
|
* @returns Shape 平面几何(mesh 三角化 + BREP 句柄);`as:'wire'` 时返回 1D 曲线(kind:'curve')。
|
|
84
|
-
* @param params.contours - 有序 2D 轮廓(线段/圆弧;外环 +
|
|
113
|
+
* @param params.contours - 有序 2D 轮廓(线段/圆弧;外环 + 孔),或已绘制轮廓(`cad.draw` 产物:单个 Blueprint 或其数组)。type:ProfileLoop[]|Blueprint|Blueprint[] required:true
|
|
85
114
|
* @param params.as - 产物形态:'face'(默认)构面;'wire' 只交外环 wire(1D 曲线)。type:'face'|'wire' required:false
|
|
86
115
|
* @example
|
|
87
116
|
* const f = cad.profile({ contours: [{ segments: [{ kind:'line', x1:0,y1:0,x2:10,y2:0 }, ...] }] })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/api/profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"profile.d.ts","sourceRoot":"","sources":["../../src/api/profile.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAO1C,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAQnD,2BAA2B;AAC3B,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED,iCAAiC;AACjC,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,KAAK,CAAA;IACX,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,CAAA;IACd,cAAc;IACd,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc;IACd,QAAQ,EAAE,MAAM,CAAA;IAChB,GAAG,EAAE,OAAO,CAAA;IACZ,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;CACX;AAED,0BAA0B;AAC1B,MAAM,MAAM,UAAU,GAAG,cAAc,GAAG,aAAa,CAAA;AAEvD,yBAAyB;AACzB,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,UAAU,EAAE,CAAA;CACvB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,EAAE,CAAA;AAEnD,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B;;;OAGG;IACH,QAAQ,EAAE,WAAW,EAAE,GAAG,aAAa,CAAA;IACvC;;;OAGG;IACH,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;CACrB;AAeD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,EAAE,CAsBlE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CA2BzE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,aAAa,GAAG,KAAK,CAiD9D;AA+ED;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,OAAO;;CAOlB,CAAA"}
|