@faicad/faijs 0.13.2 → 0.14.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (285) hide show
  1. package/dist/api/api-namespace.d.ts.map +1 -1
  2. package/dist/api/api-namespace.js +30 -4
  3. package/dist/api/api-namespace.js.map +1 -1
  4. package/dist/api/boolean.d.ts +19 -0
  5. package/dist/api/boolean.d.ts.map +1 -1
  6. package/dist/api/boolean.js +51 -10
  7. package/dist/api/boolean.js.map +1 -1
  8. package/dist/api/chamfer.d.ts.map +1 -1
  9. package/dist/api/chamfer.js +8 -7
  10. package/dist/api/chamfer.js.map +1 -1
  11. package/dist/api/compound-geom.d.ts +45 -0
  12. package/dist/api/compound-geom.d.ts.map +1 -0
  13. package/dist/api/compound-geom.js +85 -0
  14. package/dist/api/compound-geom.js.map +1 -0
  15. package/dist/api/compound.d.ts +2 -0
  16. package/dist/api/compound.d.ts.map +1 -1
  17. package/dist/api/compound.js +2 -0
  18. package/dist/api/compound.js.map +1 -1
  19. package/dist/api/copy.d.ts +1 -0
  20. package/dist/api/copy.d.ts.map +1 -1
  21. package/dist/api/copy.js +4 -2
  22. package/dist/api/copy.js.map +1 -1
  23. package/dist/api/edge-ref.d.ts.map +1 -1
  24. package/dist/api/edge-ref.js +7 -4
  25. package/dist/api/edge-ref.js.map +1 -1
  26. package/dist/api/engrave.d.ts.map +1 -1
  27. package/dist/api/engrave.js +1 -0
  28. package/dist/api/engrave.js.map +1 -1
  29. package/dist/api/extrude.d.ts.map +1 -1
  30. package/dist/api/extrude.js +131 -3
  31. package/dist/api/extrude.js.map +1 -1
  32. package/dist/api/face-ref.d.ts.map +1 -1
  33. package/dist/api/face-ref.js +7 -4
  34. package/dist/api/face-ref.js.map +1 -1
  35. package/dist/api/fai_drill.d.ts +1 -1
  36. package/dist/api/fai_drill.d.ts.map +1 -1
  37. package/dist/api/fai_drill.js +31 -18
  38. package/dist/api/fai_drill.js.map +1 -1
  39. package/dist/api/fai_extrude.d.ts +1 -1
  40. package/dist/api/fai_extrude.d.ts.map +1 -1
  41. package/dist/api/fai_extrude.js +2 -1
  42. package/dist/api/fai_extrude.js.map +1 -1
  43. package/dist/api/fai_split.d.ts +1 -1
  44. package/dist/api/fai_split.d.ts.map +1 -1
  45. package/dist/api/fai_split.js +2 -1
  46. package/dist/api/fai_split.js.map +1 -1
  47. package/dist/api/fillet.d.ts.map +1 -1
  48. package/dist/api/fillet.js +6 -5
  49. package/dist/api/fillet.js.map +1 -1
  50. package/dist/api/generated/operations.js +16 -16
  51. package/dist/api/generated/operations.js.map +1 -1
  52. package/dist/api/generated/script-face-manifest.d.ts.map +1 -1
  53. package/dist/api/generated/script-face-manifest.js +0 -1
  54. package/dist/api/generated/script-face-manifest.js.map +1 -1
  55. package/dist/api/generated/script-face.d.ts +1 -4
  56. package/dist/api/generated/script-face.d.ts.map +1 -1
  57. package/dist/api/generated/script-face.js +2 -3
  58. package/dist/api/generated/script-face.js.map +1 -1
  59. package/dist/api/generated/sketching.js +1 -1
  60. package/dist/api/generated/sketching.js.map +1 -1
  61. package/dist/api/generated/topology.d.ts +0 -48
  62. package/dist/api/generated/topology.d.ts.map +1 -1
  63. package/dist/api/generated/topology.js +20 -62
  64. package/dist/api/generated/topology.js.map +1 -1
  65. package/dist/api/import-brep.d.ts +36 -0
  66. package/dist/api/import-brep.d.ts.map +1 -0
  67. package/dist/api/import-brep.js +72 -0
  68. package/dist/api/import-brep.js.map +1 -0
  69. package/dist/api/import-step.d.ts +28 -0
  70. package/dist/api/import-step.d.ts.map +1 -0
  71. package/dist/api/import-step.js +57 -0
  72. package/dist/api/import-step.js.map +1 -0
  73. package/dist/api/index.d.ts +7 -2
  74. package/dist/api/index.d.ts.map +1 -1
  75. package/dist/api/index.js +19 -5
  76. package/dist/api/index.js.map +1 -1
  77. package/dist/api/internal/compat-op.d.ts.map +1 -1
  78. package/dist/api/internal/compat-op.js +2 -1
  79. package/dist/api/internal/compat-op.js.map +1 -1
  80. package/dist/api/knurl.d.ts.map +1 -1
  81. package/dist/api/knurl.js +1 -0
  82. package/dist/api/knurl.js.map +1 -1
  83. package/dist/api/load.d.ts +3 -1
  84. package/dist/api/load.d.ts.map +1 -1
  85. package/dist/api/load.js +3 -1
  86. package/dist/api/load.js.map +1 -1
  87. package/dist/api/pattern.d.ts +32 -0
  88. package/dist/api/pattern.d.ts.map +1 -0
  89. package/dist/api/pattern.js +121 -0
  90. package/dist/api/pattern.js.map +1 -0
  91. package/dist/api/place.d.ts +35 -0
  92. package/dist/api/place.d.ts.map +1 -0
  93. package/dist/api/place.js +113 -0
  94. package/dist/api/place.js.map +1 -0
  95. package/dist/api/primitives.d.ts.map +1 -1
  96. package/dist/api/primitives.js +10 -3
  97. package/dist/api/primitives.js.map +1 -1
  98. package/dist/api/screw.d.ts.map +1 -1
  99. package/dist/api/screw.js +1 -0
  100. package/dist/api/screw.js.map +1 -1
  101. package/dist/api/sdf.d.ts.map +1 -1
  102. package/dist/api/sdf.js +1 -0
  103. package/dist/api/sdf.js.map +1 -1
  104. package/dist/api/sketch.d.ts.map +1 -1
  105. package/dist/api/sketch.js +1 -0
  106. package/dist/api/sketch.js.map +1 -1
  107. package/dist/api/split.d.ts +31 -0
  108. package/dist/api/split.d.ts.map +1 -0
  109. package/dist/api/split.js +96 -0
  110. package/dist/api/split.js.map +1 -0
  111. package/dist/api/surface/arg-spec.d.ts +9 -0
  112. package/dist/api/surface/arg-spec.d.ts.map +1 -1
  113. package/dist/api/surface/arg-spec.js +49 -30
  114. package/dist/api/surface/arg-spec.js.map +1 -1
  115. package/dist/api/svgExtrude.d.ts.map +1 -1
  116. package/dist/api/svgExtrude.js +1 -0
  117. package/dist/api/svgExtrude.js.map +1 -1
  118. package/dist/api/text.d.ts.map +1 -1
  119. package/dist/api/text.js +1 -0
  120. package/dist/api/text.js.map +1 -1
  121. package/dist/api/topo-resolve.d.ts.map +1 -1
  122. package/dist/api/topo-resolve.js +65 -3
  123. package/dist/api/topo-resolve.js.map +1 -1
  124. package/dist/api/transform.d.ts +4 -0
  125. package/dist/api/transform.d.ts.map +1 -1
  126. package/dist/api/transform.js +44 -12
  127. package/dist/api/transform.js.map +1 -1
  128. package/dist/brep/brep-ops.d.ts +34 -1
  129. package/dist/brep/brep-ops.d.ts.map +1 -1
  130. package/dist/brep/brep-ops.js +62 -22
  131. package/dist/brep/brep-ops.js.map +1 -1
  132. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  133. package/dist/brep/engine/adapters/brep-mock.js +8 -0
  134. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  135. package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
  136. package/dist/brep/engine/adapters/brepkit.js +6 -1
  137. package/dist/brep/engine/adapters/brepkit.js.map +1 -1
  138. package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
  139. package/dist/brep/engine/adapters/occt.js +24 -1
  140. package/dist/brep/engine/adapters/occt.js.map +1 -1
  141. package/dist/brep/engine/primitives.d.ts +17 -0
  142. package/dist/brep/engine/primitives.d.ts.map +1 -1
  143. package/dist/brep/engine/primitives.js.map +1 -1
  144. package/dist/brep/engine/types.d.ts +49 -6
  145. package/dist/brep/engine/types.d.ts.map +1 -1
  146. package/dist/brep/engine/types.js.map +1 -1
  147. package/dist/brep/export/step.d.ts.map +1 -1
  148. package/dist/brep/export/step.js +6 -1
  149. package/dist/brep/export/step.js.map +1 -1
  150. package/dist/brep/face-evolution.d.ts +78 -8
  151. package/dist/brep/face-evolution.d.ts.map +1 -1
  152. package/dist/brep/face-evolution.js +130 -17
  153. package/dist/brep/face-evolution.js.map +1 -1
  154. package/dist/brepkit-kernel/brepkitKernel.d.ts +1 -1
  155. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  156. package/dist/brepkit-kernel/brepkitKernel.js +27 -1
  157. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  158. package/dist/cad-runtime/admit-compat-lib.d.ts +19 -1
  159. package/dist/cad-runtime/admit-compat-lib.d.ts.map +1 -1
  160. package/dist/cad-runtime/admit-compat-lib.js +21 -1
  161. package/dist/cad-runtime/admit-compat-lib.js.map +1 -1
  162. package/dist/cad-runtime/backend-dispatch.d.ts +44 -3
  163. package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
  164. package/dist/cad-runtime/backend-dispatch.js +46 -3
  165. package/dist/cad-runtime/backend-dispatch.js.map +1 -1
  166. package/dist/cad-runtime/browser-lib-loader.d.ts +2 -0
  167. package/dist/cad-runtime/browser-lib-loader.d.ts.map +1 -1
  168. package/dist/cad-runtime/browser-lib-loader.js +9 -1
  169. package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
  170. package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
  171. package/dist/cad-runtime/direct-executor.js +14 -4
  172. package/dist/cad-runtime/direct-executor.js.map +1 -1
  173. package/dist/cad-runtime/module-registry.d.ts +3 -1
  174. package/dist/cad-runtime/module-registry.d.ts.map +1 -1
  175. package/dist/cad-runtime/module-registry.js +13 -1
  176. package/dist/cad-runtime/module-registry.js.map +1 -1
  177. package/dist/cad-runtime/ports.d.ts +7 -0
  178. package/dist/cad-runtime/ports.d.ts.map +1 -1
  179. package/dist/cad-runtime/ports.js.map +1 -1
  180. package/dist/cad-runtime/runtime-concurrent-error.d.ts +38 -0
  181. package/dist/cad-runtime/runtime-concurrent-error.d.ts.map +1 -0
  182. package/dist/cad-runtime/runtime-concurrent-error.js +43 -0
  183. package/dist/cad-runtime/runtime-concurrent-error.js.map +1 -0
  184. package/dist/cad-runtime/runtime.d.ts +54 -2
  185. package/dist/cad-runtime/runtime.d.ts.map +1 -1
  186. package/dist/cad-runtime/runtime.js +186 -10
  187. package/dist/cad-runtime/runtime.js.map +1 -1
  188. package/dist/define-op.d.ts +22 -0
  189. package/dist/define-op.d.ts.map +1 -1
  190. package/dist/define-op.js +82 -12
  191. package/dist/define-op.js.map +1 -1
  192. package/dist/fcstd/attachment.d.ts +8 -1
  193. package/dist/fcstd/attachment.d.ts.map +1 -1
  194. package/dist/fcstd/attachment.js +7 -1
  195. package/dist/fcstd/attachment.js.map +1 -1
  196. package/dist/fcstd/build-fai-zip.d.ts.map +1 -1
  197. package/dist/fcstd/build-fai-zip.js +12 -7
  198. package/dist/fcstd/build-fai-zip.js.map +1 -1
  199. package/dist/fcstd/codegen.d.ts +10 -1
  200. package/dist/fcstd/codegen.d.ts.map +1 -1
  201. package/dist/fcstd/codegen.js +150 -48
  202. package/dist/fcstd/codegen.js.map +1 -1
  203. package/dist/fcstd/contour.d.ts.map +1 -1
  204. package/dist/fcstd/contour.js +23 -24
  205. package/dist/fcstd/contour.js.map +1 -1
  206. package/dist/fcstd/convert.d.ts +2 -18
  207. package/dist/fcstd/convert.d.ts.map +1 -1
  208. package/dist/fcstd/convert.js +35 -53
  209. package/dist/fcstd/convert.js.map +1 -1
  210. package/dist/fcstd/external-geo.d.ts +12 -1
  211. package/dist/fcstd/external-geo.d.ts.map +1 -1
  212. package/dist/fcstd/external-geo.js +15 -1
  213. package/dist/fcstd/external-geo.js.map +1 -1
  214. package/dist/fcstd/feature-translate.d.ts +21 -1
  215. package/dist/fcstd/feature-translate.d.ts.map +1 -1
  216. package/dist/fcstd/feature-translate.js +108 -6
  217. package/dist/fcstd/feature-translate.js.map +1 -1
  218. package/dist/fcstd/structural-types.d.ts +83 -0
  219. package/dist/fcstd/structural-types.d.ts.map +1 -0
  220. package/dist/fcstd/structural-types.js +116 -0
  221. package/dist/fcstd/structural-types.js.map +1 -0
  222. package/dist/index.d.ts +1 -0
  223. package/dist/index.d.ts.map +1 -1
  224. package/dist/index.js.map +1 -1
  225. package/dist/lang/determinism-scanner.d.ts +62 -0
  226. package/dist/lang/determinism-scanner.d.ts.map +1 -0
  227. package/dist/lang/determinism-scanner.js +619 -0
  228. package/dist/lang/determinism-scanner.js.map +1 -0
  229. package/dist/lang/symbol-table.generated.d.ts +7 -3
  230. package/dist/lang/symbol-table.generated.d.ts.map +1 -1
  231. package/dist/lang/symbol-table.generated.js +7 -3
  232. package/dist/lang/symbol-table.generated.js.map +1 -1
  233. package/dist/mesh/index.d.ts.map +1 -1
  234. package/dist/mesh/index.js +3 -2
  235. package/dist/mesh/index.js.map +1 -1
  236. package/dist/node-host/cli.d.ts.map +1 -1
  237. package/dist/node-host/cli.js +56 -2
  238. package/dist/node-host/cli.js.map +1 -1
  239. package/dist/runtime-state.d.ts +18 -6
  240. package/dist/runtime-state.d.ts.map +1 -1
  241. package/dist/runtime-state.js +9 -1
  242. package/dist/runtime-state.js.map +1 -1
  243. package/dist/shape.d.ts +15 -0
  244. package/dist/shape.d.ts.map +1 -1
  245. package/dist/shape.js +26 -3
  246. package/dist/shape.js.map +1 -1
  247. package/dist/topology/naming/build-naming.d.ts +14 -30
  248. package/dist/topology/naming/build-naming.d.ts.map +1 -1
  249. package/dist/topology/naming/build-naming.js +21 -54
  250. package/dist/topology/naming/build-naming.js.map +1 -1
  251. package/dist/topology/naming/capture-topo-ref.d.ts.map +1 -1
  252. package/dist/topology/naming/capture-topo-ref.js +5 -0
  253. package/dist/topology/naming/capture-topo-ref.js.map +1 -1
  254. package/dist/topology/naming/index.d.ts +3 -0
  255. package/dist/topology/naming/index.d.ts.map +1 -1
  256. package/dist/topology/naming/index.js +3 -0
  257. package/dist/topology/naming/index.js.map +1 -1
  258. package/dist/topology/naming/lineage-resolve.d.ts +80 -0
  259. package/dist/topology/naming/lineage-resolve.d.ts.map +1 -0
  260. package/dist/topology/naming/lineage-resolve.js +120 -0
  261. package/dist/topology/naming/lineage-resolve.js.map +1 -0
  262. package/dist/topology/naming/lineage.d.ts +349 -0
  263. package/dist/topology/naming/lineage.d.ts.map +1 -0
  264. package/dist/topology/naming/lineage.js +398 -0
  265. package/dist/topology/naming/lineage.js.map +1 -0
  266. package/dist/topology/naming/migrate.d.ts +41 -0
  267. package/dist/topology/naming/migrate.d.ts.map +1 -0
  268. package/dist/topology/naming/migrate.js +88 -0
  269. package/dist/topology/naming/migrate.js.map +1 -0
  270. package/dist/topology/naming/role-name.d.ts +176 -0
  271. package/dist/topology/naming/role-name.d.ts.map +1 -0
  272. package/dist/topology/naming/role-name.js +344 -0
  273. package/dist/topology/naming/role-name.js.map +1 -0
  274. package/dist/topology/naming/roles.d.ts +20 -22
  275. package/dist/topology/naming/roles.d.ts.map +1 -1
  276. package/dist/topology/naming/roles.js +51 -49
  277. package/dist/topology/naming/roles.js.map +1 -1
  278. package/dist/topology/naming/types.d.ts +65 -18
  279. package/dist/topology/naming/types.d.ts.map +1 -1
  280. package/dist/topology/naming/types.js.map +1 -1
  281. package/dist/weapp.d.ts +1 -1
  282. package/dist/weapp.d.ts.map +1 -1
  283. package/dist/weapp.js +1 -1
  284. package/dist/weapp.js.map +1 -1
  285. package/package.json +1 -1
@@ -145,5 +145,6 @@ export const sketch = defineOp({
145
145
  assertSketchParams(params);
146
146
  return sketchBrep(params);
147
147
  },
148
+ naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [] } },
148
149
  });
149
150
  //# sourceMappingURL=sketch.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sketch.js","sourceRoot":"","sources":["../../src/api/sketch.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * stdlib sketch — 从 2D 轮廓构面(creator 函数,无输入,brep-only)。\n *\n * 用途:faijs 此前没有「从 2D 轮廓构造 planar face」的能力,导致草图轮廓无法喂给\n * extrude/revolve。本 op 接收 2D 轮廓(线段 + 圆弧),在 z=0 平面用 OCCT 构面:\n * makeLineEdge/makeArcEdge → makeWire → makeFace(+ addHolesInFace)。\n *\n * 设计:\n * - 输入:{ contours: SketchLoop[] },每个 loop = 有序 segments(line / arc,z=0)。\n * - 外环 = 面积(shoelace)绝对值最大的 loop;其余 loop 作为孔。\n * - 圆弧:用起点/中点/终点三点的 makeArcEdge;整圆(sweep≈2π)拆成两段弧。\n * - 输出:Shape(mesh 三角化 + 句柄登记)。brep-only(下游 extrude/revolve 亦 brep-only)。\n *\n * 坐标系:输入 2D 点即 (x, y, 0),法向 +Z;草图在 Body 局部系内的定位由调用方(fcstd 端口)\n * 在轮廓坐标里预先变换,或由下游特征的 Placement 承担。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { getBackends } from '../runtime-state'\nimport { solidToShape } from '../brep/brep-ops'\nimport { fromBrep } from '../shape'\nimport { defineOp } from '../sdk'\n\n// ── 参数形状(与 fcstd Contour 结构相同,避免引擎依赖端口层)──\n\n/** 直线段(2D,z=0;端点为绝对坐标)。 */\nexport interface SketchLineSeg {\n kind: 'line'\n x1: number\n y1: number\n x2: number\n y2: number\n}\n\n/** 圆弧段(圆心 + 半径 + 起止角,弧度;z=0)。 */\nexport interface SketchArcSeg {\n kind: 'arc'\n cx: number\n cy: number\n radius: number\n /** 起始角(弧度) */\n startAngle: number\n /** 终止角(弧度) */\n endAngle: number\n ccw: boolean\n x1: number\n y1: number\n x2: number\n y2: number\n}\n\n/** 一条有序 2D 轮廓段(直线或圆弧)。 */\nexport type SketchSeg = SketchLineSeg | SketchArcSeg\n\n/** 单个轮廓环:有序段序列(首尾相接)。 */\nexport interface SketchLoop {\n segments: SketchSeg[]\n}\n\n/** `cad.sketch` 参数:轮廓环集合(第一个为外环,其余为孔)。 */\nexport interface SketchContoursParams {\n contours: SketchLoop[]\n}\n\n// ── 参数自校验 ──\n\n/**\n * Validate sketch parameters: `contours` must be a non-empty array of loops,\n * each with at least one segment.\n * @param params the raw sketch operation parameters.\n */\nexport function assertSketchParams(params: Record<string, unknown>): void {\n const contours = params.contours\n if (!Array.isArray(contours) || contours.length === 0) {\n throw new Error('E_SKETCH_NO_CONTOURS: sketch requires at least one contour')\n }\n for (const loop of contours) {\n if (!loop || typeof loop !== 'object' || !Array.isArray((loop as SketchLoop).segments)) {\n throw new Error('E_SKETCH_BAD_LOOP: each contour must have a segments array')\n }\n if ((loop as SketchLoop).segments.length === 0) {\n throw new Error('E_SKETCH_EMPTY_LOOP: a contour must have at least one segment')\n }\n }\n}\n\n/** 单环 shoelace 面积(带符号)。 */\nfunction loopSignedArea(loop: SketchLoop): number {\n const pts: Array<[number, number]> = []\n for (const seg of loop.segments) {\n pts.push([seg.x1, seg.y1])\n }\n let a = 0\n for (let i = 0; i < pts.length; i++) {\n const [x1, y1] = pts[i]!\n const [x2, y2] = pts[(i + 1) % pts.length]!\n a += x1 * y2 - x2 * y1\n }\n return a / 2\n}\n\n/** 圆弧 → 一条或两条 makeArcEdge(整圆拆分)。 */\nfunction arcToHandles(\n kernel: BrepEngineApi,\n seg: SketchArcSeg,\n): ReturnType<BrepEngineApi['makeArcEdge']>[] {\n const { cx, cy, radius, startAngle, endAngle } = seg\n let sweep = endAngle - startAngle\n // 归一化到 (0, 2π],处理角度回绕\n while (sweep <= 0) sweep += 2 * Math.PI\n while (sweep > 2 * Math.PI) sweep -= 2 * Math.PI\n\n const makeOne = (a0: number, a1: number): ReturnType<BrepEngineApi['makeArcEdge']> => {\n const mid = (a0 + a1) / 2\n const start = { x: cx + radius * Math.cos(a0), y: cy + radius * Math.sin(a0), z: 0 }\n const m = { x: cx + radius * Math.cos(mid), y: cy + radius * Math.sin(mid), z: 0 }\n const end = { x: cx + radius * Math.cos(a1), y: cy + radius * Math.sin(a1), z: 0 }\n return kernel.makeArcEdge(start, m, end)\n }\n\n // 整圆(sweep≈2π):拆成两段半圆,避免 makeArcEdge 起点≈终点退化\n if (sweep >= 2 * Math.PI - 1e-9) {\n const half = 2 * Math.PI / 2\n return [makeOne(startAngle, startAngle + half), makeOne(startAngle + half, startAngle + 2 * Math.PI)]\n }\n return [makeOne(startAngle, endAngle)]\n}\n\n/** 单环 → wire handle(仅构面,不释放中间句柄,遵循现有惯例)。 */\nfunction loopToWire(kernel: BrepEngineApi, loop: SketchLoop): ReturnType<BrepEngineApi['makeWire']> {\n const edges: ReturnType<BrepEngineApi['makeLineEdge']>[] = []\n for (const seg of loop.segments) {\n if (seg.kind === 'line') {\n edges.push(kernel.makeLineEdge({ x: seg.x1, y: seg.y1, z: 0 }, { x: seg.x2, y: seg.y2, z: 0 }))\n } else {\n // 极小扫角(退化弧)→ 退化为线段,避免构边失败\n let sweep = seg.endAngle - seg.startAngle\n while (sweep <= 0) sweep += 2 * Math.PI\n while (sweep > 2 * Math.PI) sweep -= 2 * Math.PI\n if (sweep < 1e-9) {\n edges.push(kernel.makeLineEdge({ x: seg.x1, y: seg.y1, z: 0 }, { x: seg.x2, y: seg.y2, z: 0 }))\n } else {\n edges.push(...arcToHandles(kernel, seg))\n }\n }\n }\n return kernel.makeWire(edges as ReturnType<BrepEngineApi['makeLineEdge']>[])\n}\n\n/** BREP 路径:2D 轮廓 → planar face(外环 + 孔)。 */\nfunction sketchBrep(params: Record<string, unknown>): Shape {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/sketch] no BREP kernel')\n\n const loops = (params.contours as SketchLoop[]).map((loop) => ({ loop, area: Math.abs(loopSignedArea(loop)) }))\n // 面积最大者为外环,其余为孔\n let outerIdx = 0\n for (let i = 1; i < loops.length; i++) {\n if (loops[i]!.area > loops[outerIdx]!.area) outerIdx = i\n }\n\n const outerWire = loopToWire(kernel, loops[outerIdx]!.loop)\n const face = kernel.makeFace(outerWire)\n\n const holeWires: ReturnType<BrepEngineApi['makeWire']>[] = []\n for (let i = 0; i < loops.length; i++) {\n if (i === outerIdx) continue\n holeWires.push(loopToWire(kernel, loops[i]!.loop))\n }\n if (holeWires.length > 0) {\n const faced = kernel.addHolesInFace(face, holeWires)\n kernel.release(face)\n return fromBrep(solidToShape(kernel, faced), { solid: faced })\n }\n\n kernel.release(outerWire)\n return fromBrep(solidToShape(kernel, face), { solid: face })\n}\n\n/**\n * 从 2D 轮廓构造平面(creator,无输入)。仅 BREP 可用。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name sketch\n * @returns Shape 平面几何(mesh 三角化 + BREP 句柄)。\n * @param params.contours - 有序 2D 轮廓(线段/圆弧;外环 + 孔)。type:SketchLoop[] required:true\n * @example\n * const f = cad.sketch({ contours: [{ segments: [{ kind:'line', x1:0,y1:0,x2:10,y2:0 }, ...] }] })\n */\nexport const sketch = defineOp({\n capabilities: ['directEdit'],\n brep(params: Record<string, unknown>) {\n assertSketchParams(params)\n return sketchBrep(params)\n },\n})\n"]}
1
+ {"version":3,"file":"sketch.js","sourceRoot":"","sources":["../../src/api/sketch.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACnC,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AA4CjC,cAAc;AAEd;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,MAA+B;IAChE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAA;IAChC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtD,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;IAC/E,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAE,IAAmB,CAAC,QAAQ,CAAC,EAAE,CAAC;YACvF,MAAM,IAAI,KAAK,CAAC,4DAA4D,CAAC,CAAA;QAC/E,CAAC;QACD,IAAK,IAAmB,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,+DAA+D,CAAC,CAAA;QAClF,CAAC;IACH,CAAC;AACH,CAAC;AAED,2BAA2B;AAC3B,SAAS,cAAc,CAAC,IAAgB;IACtC,MAAM,GAAG,GAA4B,EAAE,CAAA;IACvC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAA;IAC5B,CAAC;IACD,IAAI,CAAC,GAAG,CAAC,CAAA;IACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAE,CAAA;QACxB,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,CAAE,CAAA;QAC3C,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,CAAA;IACxB,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,CAAA;AACd,CAAC;AAED,oCAAoC;AACpC,SAAS,YAAY,CACnB,MAAqB,EACrB,GAAiB;IAEjB,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAA;IACpD,IAAI,KAAK,GAAG,QAAQ,GAAG,UAAU,CAAA;IACjC,sBAAsB;IACtB,OAAO,KAAK,IAAI,CAAC;QAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAA;IACvC,OAAO,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE;QAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAA;IAEhD,MAAM,OAAO,GAAG,CAAC,EAAU,EAAE,EAAU,EAA4C,EAAE;QACnF,MAAM,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,CAAA;QACzB,MAAM,KAAK,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;QACpF,MAAM,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;QAClF,MAAM,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,GAAG,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAA;QAClF,OAAO,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;IAC1C,CAAC,CAAA;IAED,6CAA6C;IAC7C,IAAI,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,IAAI,EAAE,CAAC;QAChC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,CAAC,CAAA;QAC5B,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC,EAAE,OAAO,CAAC,UAAU,GAAG,IAAI,EAAE,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAA;IACvG,CAAC;IACD,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAA;AACxC,CAAC;AAED,4CAA4C;AAC5C,SAAS,UAAU,CAAC,MAAqB,EAAE,IAAgB;IACzD,MAAM,KAAK,GAAgD,EAAE,CAAA;IAC7D,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;QAChC,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;QACjG,CAAC;aAAM,CAAC;YACN,0BAA0B;YAC1B,IAAI,KAAK,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAA;YACzC,OAAO,KAAK,IAAI,CAAC;gBAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAA;YACvC,OAAO,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,EAAE;gBAAE,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAA;YAChD,IAAI,KAAK,GAAG,IAAI,EAAE,CAAC;gBACjB,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAA;YACjG,CAAC;iBAAM,CAAC;gBACN,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAA;YAC1C,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC,QAAQ,CAAC,KAAoD,CAAC,CAAA;AAC9E,CAAC;AAED,2CAA2C;AAC3C,SAAS,UAAU,CAAC,MAA+B;IACjD,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC,MAAM,CAAC,IAA4B,CAAA;IAChE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,gCAAgC,CAAC,CAAA;IAE9D,MAAM,KAAK,GAAI,MAAM,CAAC,QAAyB,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC/G,gBAAgB;IAChB,IAAI,QAAQ,GAAG,CAAC,CAAA;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAE,CAAC,IAAI;YAAE,QAAQ,GAAG,CAAC,CAAA;IAC1D,CAAC;IAED,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,QAAQ,CAAE,CAAC,IAAI,CAAC,CAAA;IAC3D,MAAM,IAAI,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;IAEvC,MAAM,SAAS,GAA4C,EAAE,CAAA;IAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,IAAI,CAAC,KAAK,QAAQ;YAAE,SAAQ;QAC5B,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IACpD,CAAC;IACD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,SAAS,CAAC,CAAA;QACpD,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;QACpB,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAA;IAChE,CAAC;IAED,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IACzB,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAA;AAC9D,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG,QAAQ,CAAC;IAC7B,YAAY,EAAE,CAAC,YAAY,CAAC;IAC5B,IAAI,CAAC,MAA+B;QAClC,kBAAkB,CAAC,MAAM,CAAC,CAAA;QAC1B,OAAO,UAAU,CAAC,MAAM,CAAC,CAAA;IAC3B,CAAC;IACD,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,EAAE,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,EAAE,EAAE,EAAgB;CACtF,CAAC,CAAA","sourcesContent":["/**\n * stdlib sketch — 从 2D 轮廓构面(creator 函数,无输入,brep-only)。\n *\n * 用途:faijs 此前没有「从 2D 轮廓构造 planar face」的能力,导致草图轮廓无法喂给\n * extrude/revolve。本 op 接收 2D 轮廓(线段 + 圆弧),在 z=0 平面用 OCCT 构面:\n * makeLineEdge/makeArcEdge → makeWire → makeFace(+ addHolesInFace)。\n *\n * 设计:\n * - 输入:{ contours: SketchLoop[] },每个 loop = 有序 segments(line / arc,z=0)。\n * - 外环 = 面积(shoelace)绝对值最大的 loop;其余 loop 作为孔。\n * - 圆弧:用起点/中点/终点三点的 makeArcEdge;整圆(sweep≈2π)拆成两段弧。\n * - 输出:Shape(mesh 三角化 + 句柄登记)。brep-only(下游 extrude/revolve 亦 brep-only)。\n *\n * 坐标系:输入 2D 点即 (x, y, 0),法向 +Z;草图在 Body 局部系内的定位由调用方(fcstd 端口)\n * 在轮廓坐标里预先变换,或由下游特征的 Placement 承担。\n */\n\nimport type { Shape } from '../mesh/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\nimport { getBackends } from '../runtime-state'\nimport { solidToShape } from '../brep/brep-ops'\nimport { fromBrep } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\n\n// ── 参数形状(与 fcstd Contour 结构相同,避免引擎依赖端口层)──\n\n/** 直线段(2D,z=0;端点为绝对坐标)。 */\nexport interface SketchLineSeg {\n kind: 'line'\n x1: number\n y1: number\n x2: number\n y2: number\n}\n\n/** 圆弧段(圆心 + 半径 + 起止角,弧度;z=0)。 */\nexport interface SketchArcSeg {\n kind: 'arc'\n cx: number\n cy: number\n radius: number\n /** 起始角(弧度) */\n startAngle: number\n /** 终止角(弧度) */\n endAngle: number\n ccw: boolean\n x1: number\n y1: number\n x2: number\n y2: number\n}\n\n/** 一条有序 2D 轮廓段(直线或圆弧)。 */\nexport type SketchSeg = SketchLineSeg | SketchArcSeg\n\n/** 单个轮廓环:有序段序列(首尾相接)。 */\nexport interface SketchLoop {\n segments: SketchSeg[]\n}\n\n/** `cad.sketch` 参数:轮廓环集合(第一个为外环,其余为孔)。 */\nexport interface SketchContoursParams {\n contours: SketchLoop[]\n}\n\n// ── 参数自校验 ──\n\n/**\n * Validate sketch parameters: `contours` must be a non-empty array of loops,\n * each with at least one segment.\n * @param params the raw sketch operation parameters.\n */\nexport function assertSketchParams(params: Record<string, unknown>): void {\n const contours = params.contours\n if (!Array.isArray(contours) || contours.length === 0) {\n throw new Error('E_SKETCH_NO_CONTOURS: sketch requires at least one contour')\n }\n for (const loop of contours) {\n if (!loop || typeof loop !== 'object' || !Array.isArray((loop as SketchLoop).segments)) {\n throw new Error('E_SKETCH_BAD_LOOP: each contour must have a segments array')\n }\n if ((loop as SketchLoop).segments.length === 0) {\n throw new Error('E_SKETCH_EMPTY_LOOP: a contour must have at least one segment')\n }\n }\n}\n\n/** 单环 shoelace 面积(带符号)。 */\nfunction loopSignedArea(loop: SketchLoop): number {\n const pts: Array<[number, number]> = []\n for (const seg of loop.segments) {\n pts.push([seg.x1, seg.y1])\n }\n let a = 0\n for (let i = 0; i < pts.length; i++) {\n const [x1, y1] = pts[i]!\n const [x2, y2] = pts[(i + 1) % pts.length]!\n a += x1 * y2 - x2 * y1\n }\n return a / 2\n}\n\n/** 圆弧 → 一条或两条 makeArcEdge(整圆拆分)。 */\nfunction arcToHandles(\n kernel: BrepEngineApi,\n seg: SketchArcSeg,\n): ReturnType<BrepEngineApi['makeArcEdge']>[] {\n const { cx, cy, radius, startAngle, endAngle } = seg\n let sweep = endAngle - startAngle\n // 归一化到 (0, 2π],处理角度回绕\n while (sweep <= 0) sweep += 2 * Math.PI\n while (sweep > 2 * Math.PI) sweep -= 2 * Math.PI\n\n const makeOne = (a0: number, a1: number): ReturnType<BrepEngineApi['makeArcEdge']> => {\n const mid = (a0 + a1) / 2\n const start = { x: cx + radius * Math.cos(a0), y: cy + radius * Math.sin(a0), z: 0 }\n const m = { x: cx + radius * Math.cos(mid), y: cy + radius * Math.sin(mid), z: 0 }\n const end = { x: cx + radius * Math.cos(a1), y: cy + radius * Math.sin(a1), z: 0 }\n return kernel.makeArcEdge(start, m, end)\n }\n\n // 整圆(sweep≈2π):拆成两段半圆,避免 makeArcEdge 起点≈终点退化\n if (sweep >= 2 * Math.PI - 1e-9) {\n const half = 2 * Math.PI / 2\n return [makeOne(startAngle, startAngle + half), makeOne(startAngle + half, startAngle + 2 * Math.PI)]\n }\n return [makeOne(startAngle, endAngle)]\n}\n\n/** 单环 → wire handle(仅构面,不释放中间句柄,遵循现有惯例)。 */\nfunction loopToWire(kernel: BrepEngineApi, loop: SketchLoop): ReturnType<BrepEngineApi['makeWire']> {\n const edges: ReturnType<BrepEngineApi['makeLineEdge']>[] = []\n for (const seg of loop.segments) {\n if (seg.kind === 'line') {\n edges.push(kernel.makeLineEdge({ x: seg.x1, y: seg.y1, z: 0 }, { x: seg.x2, y: seg.y2, z: 0 }))\n } else {\n // 极小扫角(退化弧)→ 退化为线段,避免构边失败\n let sweep = seg.endAngle - seg.startAngle\n while (sweep <= 0) sweep += 2 * Math.PI\n while (sweep > 2 * Math.PI) sweep -= 2 * Math.PI\n if (sweep < 1e-9) {\n edges.push(kernel.makeLineEdge({ x: seg.x1, y: seg.y1, z: 0 }, { x: seg.x2, y: seg.y2, z: 0 }))\n } else {\n edges.push(...arcToHandles(kernel, seg))\n }\n }\n }\n return kernel.makeWire(edges as ReturnType<BrepEngineApi['makeLineEdge']>[])\n}\n\n/** BREP 路径:2D 轮廓 → planar face(外环 + 孔)。 */\nfunction sketchBrep(params: Record<string, unknown>): Shape {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/sketch] no BREP kernel')\n\n const loops = (params.contours as SketchLoop[]).map((loop) => ({ loop, area: Math.abs(loopSignedArea(loop)) }))\n // 面积最大者为外环,其余为孔\n let outerIdx = 0\n for (let i = 1; i < loops.length; i++) {\n if (loops[i]!.area > loops[outerIdx]!.area) outerIdx = i\n }\n\n const outerWire = loopToWire(kernel, loops[outerIdx]!.loop)\n const face = kernel.makeFace(outerWire)\n\n const holeWires: ReturnType<BrepEngineApi['makeWire']>[] = []\n for (let i = 0; i < loops.length; i++) {\n if (i === outerIdx) continue\n holeWires.push(loopToWire(kernel, loops[i]!.loop))\n }\n if (holeWires.length > 0) {\n const faced = kernel.addHolesInFace(face, holeWires)\n kernel.release(face)\n return fromBrep(solidToShape(kernel, faced), { solid: faced })\n }\n\n kernel.release(outerWire)\n return fromBrep(solidToShape(kernel, face), { solid: face })\n}\n\n/**\n * 从 2D 轮廓构造平面(creator,无输入)。仅 BREP 可用。\n * @group 创建\n * @inputs 0\n * @async false\n * @qual ok\n * @name sketch\n * @returns Shape 平面几何(mesh 三角化 + BREP 句柄)。\n * @param params.contours - 有序 2D 轮廓(线段/圆弧;外环 + 孔)。type:SketchLoop[] required:true\n * @example\n * const f = cad.sketch({ contours: [{ segments: [{ kind:'line', x1:0,y1:0,x2:10,y2:0 }, ...] }] })\n */\nexport const sketch = defineOp({\n capabilities: ['directEdit'],\n brep(params: Record<string, unknown>) {\n assertSketchParams(params)\n return sketchBrep(params)\n },\n naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [] } } as Provenance,\n})\n"]}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * stdlib split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)
3
+ *
4
+ * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径
5
+ * 用内核原生 split(BRepAlgoAPI_Splitter)切分,存活面(hash 逐字不变)回投原
6
+ * role,新造面(截面 + 被切细的侧面片)记 `splinter(#j)`,片序按质心排序保证跨
7
+ * 重放稳定。
8
+ *
9
+ * 机制(无 splitWithHistory,纯 hash 比对 + 几何排序):`subdivide` 类零声明,
10
+ * 新造面不对应任何输入面的因果坐标,故挂消费它的那条语句、用稳定的片序 `#j` 区分。
11
+ */
12
+ import type { Shape } from '../mesh/types.js';
13
+ /**
14
+ * 用工具几何切分目标几何(BRepAlgoAPI_Splitter),返回所有碎片组成的几何。
15
+ * @group 特征
16
+ * @inputs 2
17
+ * @async true
18
+ * @qual ok
19
+ * @name split
20
+ * @note BREP-only:非 BREP 输入抛 E_MESH_UNSUPPORTED。切分产生的截面 / 被切细的侧面
21
+ * 片记 `splinter(#j)`(Phase 3 L4 抗重放词汇)。
22
+ * @returns Shape 切分后的几何(compound of pieces)。
23
+ * @param input - 目标几何。type:Shape required:true
24
+ * @param tools - 切刀几何(数组)。type:Shape[] required:true
25
+ * @example
26
+ * const pieces = await cad.split(part0, [part1])
27
+ */
28
+ export declare const split: ((input: Shape, tools: Shape[]) => Promise<Shape>) & {
29
+ __faijs__dualOp?: import("../define-op.js").DualOpMeta;
30
+ };
31
+ //# sourceMappingURL=split.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.d.ts","sourceRoot":"","sources":["../../src/api/split.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AAwE1C;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,KAAK;;CAKhB,CAAA"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * stdlib split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)
3
+ *
4
+ * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径
5
+ * 用内核原生 split(BRepAlgoAPI_Splitter)切分,存活面(hash 逐字不变)回投原
6
+ * role,新造面(截面 + 被切细的侧面片)记 `splinter(#j)`,片序按质心排序保证跨
7
+ * 重放稳定。
8
+ *
9
+ * 机制(无 splitWithHistory,纯 hash 比对 + 几何排序):`subdivide` 类零声明,
10
+ * 新造面不对应任何输入面的因果坐标,故挂消费它的那条语句、用稳定的片序 `#j` 区分。
11
+ */
12
+ import { solidToShape } from '../brep/brep-ops.js';
13
+ import { getFaceHashes } from '../brep/face-evolution.js';
14
+ import { getBackends, getCurrentStmt } from '../runtime-state.js';
15
+ import { fromBrep, brepOf, inputRoleTable } from '../shape.js';
16
+ import { defineOp } from '../sdk.js';
17
+ /** BREP 路径:用 tools 切分 input,存活面回投、新造面记 `splinter(#j)`。 */
18
+ function splitBrep(input, tools) {
19
+ const kernel = getBackends().kernel.brep;
20
+ if (!kernel)
21
+ throw new Error('[stdlib/split] no OCCT kernel');
22
+ const inputSolid = brepOf(input);
23
+ if (!inputSolid)
24
+ throw new Error('[stdlib/split] input is not BREP');
25
+ const toolSolids = tools
26
+ .map((t) => brepOf(t))
27
+ .filter((s) => !!s);
28
+ if (toolSolids.length === 0)
29
+ return input;
30
+ // Phase 1.6:origin = 本次语句 StmtId。
31
+ const outStmt = String(getCurrentStmt()?.id ?? '');
32
+ const inputTable = inputRoleTable(input);
33
+ const inputHashes = getFaceHashes(kernel, inputSolid);
34
+ const inputHashSet = new Set(inputHashes);
35
+ const inputHashToRole = new Map();
36
+ if (inputTable) {
37
+ for (const roles of inputTable.values()) {
38
+ for (const [role, hashes] of roles)
39
+ for (const h of hashes)
40
+ inputHashToRole.set(h, role);
41
+ }
42
+ }
43
+ // 内核原生 split(BRepAlgoAPI_Splitter)返回包含所有碎片的 compound
44
+ const resultSolid = kernel.split(inputSolid, toolSolids);
45
+ const resultHashes = getFaceHashes(kernel, resultSolid);
46
+ const resultFaces = kernel.getSubShapes(resultSolid, 'face');
47
+ const resultCentroids = resultFaces.map((f) => kernel.getSurfaceCenterOfMass(f));
48
+ const roleTable = new Map();
49
+ const inner = new Map();
50
+ // 存活面(hash 逐字不变)→ 回投原 role;其余 = 新造面 → splinter(#j)
51
+ const newFaces = [];
52
+ for (let i = 0; i < resultHashes.length; i++) {
53
+ const h = resultHashes[i];
54
+ if (inputHashSet.has(h)) {
55
+ const role = inputHashToRole.get(h);
56
+ if (role) {
57
+ if (!inner.has(role))
58
+ inner.set(role, []);
59
+ inner.get(role).push(h);
60
+ }
61
+ }
62
+ else {
63
+ newFaces.push({ hash: h, c: resultCentroids[i] });
64
+ }
65
+ }
66
+ // 按质心 (x,y,z) 排序保证片序跨重放稳定
67
+ newFaces.sort((a, b) => a.c.x - b.c.x || a.c.y - b.c.y || a.c.z - b.c.z);
68
+ for (let j = 0; j < newFaces.length; j++) {
69
+ const role = `splinter(#${j})`;
70
+ inner.set(role, [newFaces[j].hash]);
71
+ }
72
+ roleTable.set(outStmt, inner);
73
+ return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable });
74
+ }
75
+ /**
76
+ * 用工具几何切分目标几何(BRepAlgoAPI_Splitter),返回所有碎片组成的几何。
77
+ * @group 特征
78
+ * @inputs 2
79
+ * @async true
80
+ * @qual ok
81
+ * @name split
82
+ * @note BREP-only:非 BREP 输入抛 E_MESH_UNSUPPORTED。切分产生的截面 / 被切细的侧面
83
+ * 片记 `splinter(#j)`(Phase 3 L4 抗重放词汇)。
84
+ * @returns Shape 切分后的几何(compound of pieces)。
85
+ * @param input - 目标几何。type:Shape required:true
86
+ * @param tools - 切刀几何(数组)。type:Shape[] required:true
87
+ * @example
88
+ * const pieces = await cad.split(part0, [part1])
89
+ */
90
+ export const split = defineOp({
91
+ brep(input, tools) {
92
+ return splitBrep(input, tools);
93
+ },
94
+ naming: { kind: 'subdivide' },
95
+ });
96
+ //# sourceMappingURL=split.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"split.js","sourceRoot":"","sources":["../../src/api/split.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAA;AACtD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAC9D,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAMjC,0DAA0D;AAC1D,SAAS,SAAS,CAAC,KAAY,EAAE,KAAc;IAC7C,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC,MAAM,CAAC,IAA4B,CAAA;IAChE,IAAI,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAA;IAC7D,MAAM,UAAU,GAAG,MAAM,CAAC,KAAK,CAA2B,CAAA;IAC1D,IAAI,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,kCAAkC,CAAC,CAAA;IACpE,MAAM,UAAU,GAAG,KAAK;SACrB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAA2B,CAAC;SAC/C,MAAM,CAAC,CAAC,CAAC,EAAmB,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACtC,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAA;IAEzC,kCAAkC;IAClC,MAAM,OAAO,GAAG,MAAM,CAAC,cAAc,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAA;IAClD,MAAM,UAAU,GAAG,cAAc,CAAC,KAAK,CAA0B,CAAA;IAEjE,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;IACrD,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAA;IACzC,MAAM,eAAe,GAAG,IAAI,GAAG,EAAkB,CAAA;IACjD,IAAI,UAAU,EAAE,CAAC;QACf,KAAK,MAAM,KAAK,IAAI,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YACxC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,KAAK;gBAAE,KAAK,MAAM,CAAC,IAAI,MAAM;oBAAE,eAAe,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;QAC1F,CAAC;IACH,CAAC;IAED,qDAAqD;IACrD,MAAM,WAAW,GAAI,MAEnB,CAAC,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,CAAA;IAEhC,MAAM,YAAY,GAAG,aAAa,CAAC,MAAM,EAAE,WAAW,CAAC,CAAA;IACvD,MAAM,WAAW,GAAG,MAAM,CAAC,YAAY,CAAC,WAAW,EAAE,MAAM,CAAC,CAAA;IAC5D,MAAM,eAAe,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC,CAAA;IAEhF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAiC,CAAA;IAC1D,MAAM,KAAK,GAAG,IAAI,GAAG,EAAoB,CAAA;IAEzC,mDAAmD;IACnD,MAAM,QAAQ,GAA+D,EAAE,CAAA;IAC/E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7C,MAAM,CAAC,GAAG,YAAY,CAAC,CAAC,CAAE,CAAA;QAC1B,IAAI,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;YACnC,IAAI,IAAI,EAAE,CAAC;gBACT,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;oBAAE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC,CAAA;gBACzC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YAC1B,CAAC;QACH,CAAC;aAAM,CAAC;YACN,QAAQ,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,EAAE,eAAe,CAAC,CAAC,CAAE,EAAE,CAAC,CAAA;QACpD,CAAC;IACH,CAAC;IACD,0BAA0B;IAC1B,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAA;IACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,CAAA;QAC9B,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IACrC,CAAC;IACD,SAAS,CAAC,GAAG,CAAC,OAAO,EAAE,KAAK,CAAC,CAAA;IAE7B,OAAO,QAAQ,CAAC,YAAY,CAAC,MAAM,EAAE,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC,CAAA;AACvF,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,MAAM,KAAK,GAAG,QAAQ,CAAC;IAC5B,IAAI,CAAC,KAAY,EAAE,KAAc;QAC/B,OAAO,SAAS,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IAChC,CAAC;IACD,MAAM,EAAE,EAAE,IAAI,EAAE,WAAW,EAAgB;CAC5C,CAAC,CAAA","sourcesContent":["/**\n * stdlib split — split(手写覆盖生成投影,Phase 3: L4 `splinter(#j)` 角色表)\n *\n * 生成投影是 brep-only compatOp,不带角色表;本文件手写 defineOp,BREP 路径\n * 用内核原生 split(BRepAlgoAPI_Splitter)切分,存活面(hash 逐字不变)回投原\n * role,新造面(截面 + 被切细的侧面片)记 `splinter(#j)`,片序按质心排序保证跨\n * 重放稳定。\n *\n * 机制(无 splitWithHistory,纯 hash 比对 + 几何排序):`subdivide` 类零声明,\n * 新造面不对应任何输入面的因果坐标,故挂消费它的那条语句、用稳定的片序 `#j` 区分。\n */\n\nimport type { Shape } from '../mesh/types'\nimport { solidToShape } from '../brep/brep-ops'\nimport { getFaceHashes } from '../brep/face-evolution'\nimport { getBackends, getCurrentStmt } from '../runtime-state'\nimport { fromBrep, brepOf, inputRoleTable } from '../shape'\nimport { defineOp } from '../sdk'\nimport type { Provenance } from '../topology/naming/lineage'\nimport type { RoleTable } from '../topology/naming/types'\nimport type { BrepHandle } from '../brep/engine/types'\nimport type { BrepEngineApi } from '../brep/engine/primitives'\n\n/** BREP 路径:用 tools 切分 input,存活面回投、新造面记 `splinter(#j)`。 */\nfunction splitBrep(input: Shape, tools: Shape[]): Shape {\n const kernel = getBackends().kernel.brep as BrepEngineApi | null\n if (!kernel) throw new Error('[stdlib/split] no OCCT kernel')\n const inputSolid = brepOf(input) as BrepHandle | undefined\n if (!inputSolid) throw new Error('[stdlib/split] input is not BREP')\n const toolSolids = tools\n .map((t) => brepOf(t) as BrepHandle | undefined)\n .filter((s): s is BrepHandle => !!s)\n if (toolSolids.length === 0) return input\n\n // Phase 1.6:origin = 本次语句 StmtId。\n const outStmt = String(getCurrentStmt()?.id ?? '')\n const inputTable = inputRoleTable(input) as RoleTable | undefined\n\n const inputHashes = getFaceHashes(kernel, inputSolid)\n const inputHashSet = new Set(inputHashes)\n const inputHashToRole = new Map<number, string>()\n if (inputTable) {\n for (const roles of inputTable.values()) {\n for (const [role, hashes] of roles) for (const h of hashes) inputHashToRole.set(h, role)\n }\n }\n\n // 内核原生 split(BRepAlgoAPI_Splitter)返回包含所有碎片的 compound\n const resultSolid = (kernel as unknown as {\n split(s: BrepHandle, tools: BrepHandle[]): BrepHandle\n }).split(inputSolid, toolSolids)\n\n const resultHashes = getFaceHashes(kernel, resultSolid)\n const resultFaces = kernel.getSubShapes(resultSolid, 'face')\n const resultCentroids = resultFaces.map((f) => kernel.getSurfaceCenterOfMass(f))\n\n const roleTable = new Map<string, Map<string, number[]>>()\n const inner = new Map<string, number[]>()\n\n // 存活面(hash 逐字不变)→ 回投原 role;其余 = 新造面 → splinter(#j)\n const newFaces: { hash: number; c: { x: number; y: number; z: number } }[] = []\n for (let i = 0; i < resultHashes.length; i++) {\n const h = resultHashes[i]!\n if (inputHashSet.has(h)) {\n const role = inputHashToRole.get(h)\n if (role) {\n if (!inner.has(role)) inner.set(role, [])\n inner.get(role)!.push(h)\n }\n } else {\n newFaces.push({ hash: h, c: resultCentroids[i]! })\n }\n }\n // 按质心 (x,y,z) 排序保证片序跨重放稳定\n newFaces.sort((a, b) => a.c.x - b.c.x || a.c.y - b.c.y || a.c.z - b.c.z)\n for (let j = 0; j < newFaces.length; j++) {\n const role = `splinter(#${j})`\n inner.set(role, [newFaces[j].hash])\n }\n roleTable.set(outStmt, inner)\n\n return fromBrep(solidToShape(kernel, resultSolid), { solid: resultSolid, roleTable })\n}\n\n/**\n * 用工具几何切分目标几何(BRepAlgoAPI_Splitter),返回所有碎片组成的几何。\n * @group 特征\n * @inputs 2\n * @async true\n * @qual ok\n * @name split\n * @note BREP-only:非 BREP 输入抛 E_MESH_UNSUPPORTED。切分产生的截面 / 被切细的侧面\n * 片记 `splinter(#j)`(Phase 3 L4 抗重放词汇)。\n * @returns Shape 切分后的几何(compound of pieces)。\n * @param input - 目标几何。type:Shape required:true\n * @param tools - 切刀几何(数组)。type:Shape[] required:true\n * @example\n * const pieces = await cad.split(part0, [part1])\n */\nexport const split = defineOp({\n brep(input: Shape, tools: Shape[]) {\n return splitBrep(input, tools)\n },\n naming: { kind: 'subdivide' } as Provenance,\n})\n"]}
@@ -28,6 +28,8 @@
28
28
  */
29
29
  /** 生成器可用的投影方式。 */
30
30
  export type ProjectionKind = 'brep-op' | 'query' | 'pure' | 'type' | 'skip' | 'faijs';
31
+ import type { Provenance } from '../../topology/naming/lineage.js';
32
+ export type { Provenance } from '../../topology/naming/lineage.js';
31
33
  /** brep-op / query 的时间线消费声明(透传 defineOp 元数据,G3/G4)。 */
32
34
  /**
33
35
  * faijs 面 query 形参描述(P14 机器签名:生成器按此产出函数签名 + JSDoc @param)。
@@ -101,6 +103,13 @@ export interface ArgSpecEntry {
101
103
  * 生成器据此产出 api/generated/script-face.ts + script-face-manifest.ts。
102
104
  */
103
105
  scriptFace?: boolean;
106
+ /**
107
+ * Topology identity provenance declaration (plan §4.4 / Phase 2.1).
108
+ * Required for `kind==='brep-op' && scriptFace===true` (generator guard, 2.2);
109
+ * encodes the op's face-mapping category + new-face vocabulary.
110
+ * `import type` from lineage.ts — pure type, no runtime circular dep.
111
+ */
112
+ naming?: Provenance;
104
113
  }
105
114
  /**
106
115
  * 首批机制验证样本(P13a)。每个样本都选了 faijs 无同名、brepjs 有完整实现的符号,
@@ -1 +1 @@
1
- {"version":3,"file":"arg-spec.d.ts","sourceRoot":"","sources":["../../../src/api/surface/arg-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,kBAAkB;AAClB,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAErF,uDAAuD;AAEvD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kBAAkB;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAA;AAEzC;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,cAAc,CAAA;IACpB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAA;IACjC,8GAA8G;IAC9G,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,yFAAyF;IACzF,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;IAC1B,uNAAuN;IACvN,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,iDAAiD;IACjD,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;CACrB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,YAAY,EAs+GlC,CAAA"}
1
+ {"version":3,"file":"arg-spec.d.ts","sourceRoot":"","sources":["../../../src/api/surface/arg-spec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,kBAAkB;AAClB,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAA;AAErF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAE/D,YAAY,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAA;AAE/D,uDAAuD;AAEvD;;;GAGG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,8CAA8C;IAC9C,IAAI,EAAE,MAAM,CAAA;IACZ,iDAAiD;IACjD,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,kBAAkB;IAClB,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,IAAI,GAAG,IAAI,CAAA;AAEzC;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,cAAc,CAAA;IACpB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,qDAAqD;IACrD,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qEAAqE;IACrE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf;;;;;;OAMG;IACH,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;IACvB;;OAEG;IACH,sBAAsB,CAAC,EAAE,MAAM,EAAE,CAAA;IACjC,8GAA8G;IAC9G,aAAa,CAAC,EAAE,OAAO,CAAA;IACvB,yFAAyF;IACzF,WAAW,CAAC,EAAE,UAAU,EAAE,CAAA;IAC1B,uNAAuN;IACvN,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,iDAAiD;IACjD,SAAS,CAAC,EAAE,SAAS,CAAA;IACrB;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB;;;;;OAKG;IACH,MAAM,CAAC,EAAE,UAAU,CAAA;CACpB;AAED;;;;GAIG;AACH,eAAO,MAAM,QAAQ,EAAE,YAAY,EAy/GlC,CAAA"}
@@ -48,6 +48,7 @@ export const ARG_SPEC = [
48
48
  params: ['majorRadius', 'minorRadius', 'options'],
49
49
  formClass: 'A',
50
50
  scriptFace: true,
51
+ naming: { kind: 'unmodeled', reason: 'construct vocabulary pending Phase 3' },
51
52
  },
52
53
  {
53
54
  name: 'fuse',
@@ -60,6 +61,7 @@ export const ARG_SPEC = [
60
61
  params: ['a', 'b', 'options'],
61
62
  formClass: 'A',
62
63
  scriptFace: true,
64
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
63
65
  },
64
66
  {
65
67
  name: 'getBounds',
@@ -1425,30 +1427,35 @@ export const ARG_SPEC = [
1425
1427
  reason: 'faijs 侧 cad.extrude 由手写平台 op 覆盖(api/extrude.ts:对象形态 + upTo 拉伸到面/到支持体端面)。本投影只作为「长度形态」的引擎被手写 op 委托调用(vendored 是唯一拉伸引擎,既有 cad.extrude(face,[x,y,z]) 语义零漂移),生成模块符号不直接进 cad 命名空间 by design(同 fillet 口径)。',
1426
1428
  args: 'extrude(face: Shape, height: number|Vec3) → Shape|extrude(face: Shape, params: { length? | upTo, normal?, mode?, baseFeature?, offset? }) → Shape',
1427
1429
  params: ['face', 'height'], formClass: 'A',
1430
+ naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }] } },
1428
1431
  },
1429
1432
  {
1430
1433
  name: 'revolve', source: 'operations/api.js#revolve', kind: 'brep-op', module: 'operations',
1431
1434
  geometryArgs: [0], reason: 'shapeable 面 → Result(Shape3D),brep-op',
1432
1435
  args: 'revolve(face: Shape, options?: RevolveOptions): Shape',
1433
1436
  params: ['face', 'options'], formClass: 'A',
1437
+ naming: { kind: 'construct', newFaces: { via: 'explicit', vocab: [{ kind: 'semantic', name: 'top' }, { kind: 'semantic', name: 'bottom' }, { kind: 'wall', index: 0 }] } },
1434
1438
  },
1435
1439
  {
1436
1440
  name: 'sweep', source: 'operations/extrudeFns.js#sweep', kind: 'brep-op', module: 'operations',
1437
1441
  geometryArgs: [0, 1], reason: 'wire + spine → Result(Shape3D|tuple),默认单产物,brep-op',
1438
1442
  args: 'sweep(wire: Shape, spine: Shape, config?: SweepOptions, shellMode?: boolean): Shape',
1439
1443
  params: ['wire', 'spine', 'config', 'shellMode'], formClass: 'A',
1444
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
1440
1445
  },
1441
1446
  {
1442
1447
  name: 'complexExtrude', source: 'operations/extrudeFns.js#complexExtrude', kind: 'brep-op', module: 'operations',
1443
1448
  geometryArgs: [0], reason: 'wire → Result(Shape3D),brep-op',
1444
1449
  args: 'complexExtrude(wire: Shape, center: Vec3, normal: Vec3, profile?: ExtrusionProfile): Shape',
1445
1450
  params: ['wire', 'center', 'normal', 'profile'], formClass: 'A',
1451
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
1446
1452
  },
1447
1453
  {
1448
1454
  name: 'twistExtrude', source: 'operations/extrudeFns.js#twistExtrude', kind: 'brep-op', module: 'operations',
1449
1455
  geometryArgs: [0], reason: 'wire → Result(Shape3D),brep-op',
1450
1456
  args: 'twistExtrude(wire: Shape, angleDegrees: number, center: Vec3, normal: Vec3): Shape',
1451
1457
  params: ['wire', 'angleDegrees', 'center', 'normal'], formClass: 'A',
1458
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
1452
1459
  },
1453
1460
  {
1454
1461
  name: 'linearPattern', source: 'operations/patternFns.js#linearPattern', kind: 'brep-op', module: 'operations',
@@ -1456,6 +1463,7 @@ export const ARG_SPEC = [
1456
1463
  args: 'linearPattern(shape: Shape, direction: Vec3, count: number, spacing: number): Shape',
1457
1464
  params: ['shape', 'direction', 'count', 'spacing'], formClass: 'A',
1458
1465
  scriptFace: true,
1466
+ naming: { kind: 'replicate', k: 0 },
1459
1467
  },
1460
1468
  {
1461
1469
  name: 'circularPattern', source: 'operations/patternFns.js#circularPattern', kind: 'brep-op', module: 'operations',
@@ -1463,6 +1471,7 @@ export const ARG_SPEC = [
1463
1471
  args: 'circularPattern(shape: Shape, axis: Vec3, count: number, fullAngle?: number, center?: Vec3): Shape',
1464
1472
  params: ['shape', 'axis', 'count', 'fullAngle', 'center'], formClass: 'A',
1465
1473
  scriptFace: true,
1474
+ naming: { kind: 'replicate', k: 0 },
1466
1475
  },
1467
1476
  {
1468
1477
  name: 'gridPattern', source: 'operations/patternFns.js#gridPattern', kind: 'brep-op', module: 'operations',
@@ -1470,12 +1479,14 @@ export const ARG_SPEC = [
1470
1479
  args: 'gridPattern(shape: Shape, directionX: Vec3, directionY: Vec3, countX: number, countY: number, spacingX: number, spacingY: number): Shape',
1471
1480
  params: ['shape', 'directionX', 'directionY', 'countX', 'countY', 'spacingX', 'spacingY'], formClass: 'A',
1472
1481
  scriptFace: true,
1482
+ naming: { kind: 'replicate', k: 0 },
1473
1483
  },
1474
1484
  {
1475
1485
  name: 'roof', source: 'operations/roofFns.js#roof', kind: 'brep-op', module: 'operations',
1476
1486
  geometryArgs: [0], reason: 'wire → Result(ValidSolid)→solid,brep-op',
1477
1487
  args: 'roof(wire: Shape, options?: RoofOptions): Shape',
1478
1488
  params: ['wire', 'options'], formClass: 'A',
1489
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
1479
1490
  },
1480
1491
  {
1481
1492
  name: 'drill', source: 'operations/compoundOpsFns.js#drill', kind: 'brep-op', module: 'operations',
@@ -1483,6 +1494,7 @@ export const ARG_SPEC = [
1483
1494
  args: 'drill(shape: Shape, options: DrillOptions): Shape',
1484
1495
  params: ['shape', 'options'], formClass: 'A',
1485
1496
  scriptFace: true,
1497
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
1486
1498
  },
1487
1499
  {
1488
1500
  name: 'pocket', source: 'operations/compoundOpsFns.js#pocket', kind: 'brep-op', module: 'operations',
@@ -1490,6 +1502,7 @@ export const ARG_SPEC = [
1490
1502
  args: 'pocket(shape: Shape, options: PocketOptions): Shape',
1491
1503
  params: ['shape', 'options'], formClass: 'A',
1492
1504
  scriptFace: true,
1505
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
1493
1506
  },
1494
1507
  {
1495
1508
  name: 'boss', source: 'operations/compoundOpsFns.js#boss', kind: 'brep-op', module: 'operations',
@@ -1497,6 +1510,7 @@ export const ARG_SPEC = [
1497
1510
  args: 'boss(shape: Shape, options: BossOptions): Shape',
1498
1511
  params: ['shape', 'options'], formClass: 'A',
1499
1512
  scriptFace: true,
1513
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
1500
1514
  },
1501
1515
  {
1502
1516
  name: 'mirrorJoin', source: 'operations/compoundOpsFns.js#mirrorJoin', kind: 'brep-op', module: 'operations',
@@ -1504,6 +1518,7 @@ export const ARG_SPEC = [
1504
1518
  args: 'mirrorJoin(shape: Shape, options?: MirrorJoinOptions): Shape',
1505
1519
  params: ['shape', 'options'], formClass: 'A',
1506
1520
  scriptFace: true,
1521
+ naming: { kind: 'replicate', k: 2 },
1507
1522
  },
1508
1523
  {
1509
1524
  name: 'rectangularPattern', source: 'operations/compoundOpsFns.js#rectangularPattern', kind: 'brep-op', module: 'operations',
@@ -1511,12 +1526,14 @@ export const ARG_SPEC = [
1511
1526
  args: 'rectangularPattern(shape: Shape, options: RectangularPatternOptions): Shape',
1512
1527
  params: ['shape', 'options'], formClass: 'A',
1513
1528
  scriptFace: true,
1529
+ naming: { kind: 'replicate', k: 0 },
1514
1530
  },
1515
1531
  {
1516
1532
  name: 'thread', source: 'operations/threadFns.js#thread', kind: 'brep-op', module: 'operations',
1517
1533
  geometryArgs: [], reason: '仅参数构造 → Result(Shape3D),单产物,brep-op',
1518
1534
  args: 'thread(options: ThreadOptions): Shape',
1519
1535
  params: ['options'], formClass: 'B1',
1536
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
1520
1537
  },
1521
1538
  {
1522
1539
  name: 'convexHull', source: 'operations/convexHullFns.js#convexHull', kind: 'brep-op', module: 'operations',
@@ -1524,6 +1541,7 @@ export const ARG_SPEC = [
1524
1541
  args: 'convexHull(points: Vec3[]): Shape',
1525
1542
  params: ['points'], formClass: 'A',
1526
1543
  scriptFace: true,
1544
+ naming: { kind: 'unmodeled', reason: 'construct vocabulary pending Phase 3' },
1527
1545
  },
1528
1546
  {
1529
1547
  // ---- skip:状态 DSL/多产物/数组入参/host IO/kernel 入参 ----
@@ -2215,6 +2233,7 @@ export const ARG_SPEC = [
2215
2233
  returnsResult: false,
2216
2234
  params: ['xLength', 'yLength', 'zLength'], formClass: 'A',
2217
2235
  scriptFace: true,
2236
+ naming: { kind: 'unmodeled', reason: 'construct vocabulary pending Phase 3' },
2218
2237
  },
2219
2238
  // 47 × skip(状态化草图/绘图 DSL 族)
2220
2239
  {
@@ -2472,32 +2491,23 @@ export const ARG_SPEC = [
2472
2491
  // 投影到 brepjs 契约,但**不投 scriptFace**(faijs 侧由手写 dual-op 覆盖,生成模块
2473
2492
  // 符号为孤儿 by design)。
2474
2493
  {
2475
- name: 'box', source: 'topology/primitiveFns.js#box', kind: 'brep-op',
2476
- geometryArgs: [], returnsResult: false,
2494
+ name: 'box', source: 'topology/primitiveFns.js#box', kind: 'skip',
2477
2495
  args: 'box(width: number, depth: number, height: number, options?: BoxOptions): Shape',
2478
- reason: 'faijs 侧由手写 dual-op 覆盖(§4.1 A 决策,mesh+brep 双实现);本条目仅投影到 vendored 盒契约,生成模块符号为孤儿 by design,scriptFace 不投(避免与手写 box 撞名)。',
2479
- params: ['width', 'depth', 'height', 'options'], formClass: 'A',
2480
- scriptFace: false,
2496
+ reason: 'overridden by handwritten api/primitives.ts (box dual-op, mesh+brep)',
2481
2497
  },
2482
2498
  {
2483
2499
  name: 'sphere', source: 'topology/primitiveFns.js#sphere', kind: 'skip',
2484
2500
  reason: 'faijs 同名 sphere(§5.1 双形态同 box),生成层不重复投影',
2485
2501
  },
2486
2502
  {
2487
- name: 'cylinder', source: 'topology/primitiveFns.js#cylinder', kind: 'brep-op',
2488
- geometryArgs: [], returnsResult: false,
2503
+ name: 'cylinder', source: 'topology/primitiveFns.js#cylinder', kind: 'skip',
2489
2504
  args: 'cylinder(radius: number, height: number, options?: CylinderOptions): Shape',
2490
- reason: 'faijs 侧由手写 dual-op 覆盖(§4.3 A 决策,mesh+brep 双实现,at/centered BASE 语义);本条目仅投影到 vendored 圆柱契约,生成模块符号为孤儿 by design,scriptFace 不投(避免与手写 cylinder 撞名)。',
2491
- params: ['radius', 'height', 'options'], formClass: 'A',
2492
- scriptFace: false,
2505
+ reason: 'overridden by handwritten api/primitives.ts (cylinder dual-op, mesh+brep)',
2493
2506
  },
2494
2507
  {
2495
- name: 'cone', source: 'topology/primitiveFns.js#cone', kind: 'brep-op',
2496
- geometryArgs: [], returnsResult: false,
2508
+ name: 'cone', source: 'topology/primitiveFns.js#cone', kind: 'skip',
2497
2509
  args: 'cone(radiusBottom: number, radiusTop: number, height: number, options?: ConeOptions): Shape',
2498
- reason: 'faijs 侧由手写 dual-op 覆盖(§4.1 P 决策,mesh+brep 双实现,at/centered BASE 语义);本条目仅投影到 vendored 圆锥契约,生成模块符号为孤儿 by design,scriptFace 不投(避免与手写 cone 撞名)。',
2499
- params: ['radiusBottom', 'radiusTop', 'height', 'options'], formClass: 'A',
2500
- scriptFace: false,
2510
+ reason: 'overridden by handwritten api/primitives.ts (cone dual-op, mesh+brep)',
2501
2511
  },
2502
2512
  {
2503
2513
  name: 'ellipsoid', source: 'topology/primitiveFns.js#ellipsoid', kind: 'brep-op',
@@ -2506,6 +2516,7 @@ export const ARG_SPEC = [
2506
2516
  reason: '纯数值整件构造(rx/ry/rz → ValidSolid),brep-op',
2507
2517
  params: ['rx', 'ry', 'rz', 'options'], formClass: 'A',
2508
2518
  scriptFace: true,
2519
+ naming: { kind: 'unmodeled', reason: 'construct vocabulary pending Phase 3' },
2509
2520
  },
2510
2521
  {
2511
2522
  name: 'addHoles', source: 'topology/primitiveFns.js#addHoles', kind: 'skip',
@@ -2606,14 +2617,12 @@ export const ARG_SPEC = [
2606
2617
  + '3d_editor UI 不得暴露;将来暴露前必须先补 mesh 实现。',
2607
2618
  params: ['shape', 'angle', 'options'], formClass: 'A',
2608
2619
  scriptFace: true,
2620
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
2609
2621
  },
2610
2622
  {
2611
- name: 'scale', source: 'topology/api.js#scale', kind: 'brep-op',
2612
- geometryArgs: [0], returnsResult: false,
2623
+ name: 'scale', source: 'topology/api.js#scale', kind: 'skip',
2613
2624
  args: 'scale(shape: Shape, factor: number, options?: { center?: Vec3 }): Shape',
2614
- reason: 'faijs 侧由手写 dual-op 覆盖(§4.6 裁决 4/2:scale = vendored 等比 + center 不动点,mesh+brep 双实现);本条目仅投影到 vendored scale 契约,生成模块符号为孤儿 by design,scriptFace 不投(避免与手写 scale 撞名)。',
2615
- params: ['shape', 'factor', 'options'], formClass: 'A',
2616
- scriptFace: false,
2625
+ reason: 'overridden by handwritten api/transform.ts (scale dual-op, mesh+brep)',
2617
2626
  },
2618
2627
  {
2619
2628
  name: 'mirror', source: 'topology/api.js#mirror', kind: 'brep-op',
@@ -2622,6 +2631,7 @@ export const ARG_SPEC = [
2622
2631
  reason: 'faijs 无同名 mirror,整件反射 → brep-op',
2623
2632
  params: ['shape', 'options'], formClass: 'A',
2624
2633
  scriptFace: true,
2634
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
2625
2635
  },
2626
2636
  {
2627
2637
  name: 'clone', source: 'topology/api.js#clone', kind: 'brep-op',
@@ -2630,6 +2640,7 @@ export const ARG_SPEC = [
2630
2640
  reason: 'faijs 用 copy(不同名),整件克隆(Result<T>)→ brep-op',
2631
2641
  params: ['shape'], formClass: 'A',
2632
2642
  scriptFace: true,
2643
+ naming: { kind: 'identity' },
2633
2644
  },
2634
2645
  {
2635
2646
  name: 'applyMatrix', source: 'topology/api.js#applyMatrix', kind: 'brep-op',
@@ -2638,6 +2649,7 @@ export const ARG_SPEC = [
2638
2649
  reason: 'faijs 用 applyTransform(不同名),整件矩阵变换 → brep-op',
2639
2650
  params: ['shape', 'matrix'], formClass: 'A',
2640
2651
  scriptFace: true,
2652
+ naming: { kind: 'identity' },
2641
2653
  },
2642
2654
  {
2643
2655
  name: 'transformCopy', source: 'topology/api.js#transformCopy', kind: 'brep-op',
@@ -2646,6 +2658,7 @@ export const ARG_SPEC = [
2646
2658
  reason: 'faijs 无同名,克隆+复合变换 → brep-op',
2647
2659
  params: ['shape', 'composed'], formClass: 'A',
2648
2660
  scriptFace: true,
2661
+ naming: { kind: 'identity' },
2649
2662
  },
2650
2663
  {
2651
2664
  name: 'locate', source: 'topology/api.js#locate', kind: 'brep-op',
@@ -2654,18 +2667,20 @@ export const ARG_SPEC = [
2654
2667
  reason: 'faijs 无同名,整件定位变换 → brep-op',
2655
2668
  params: ['shape', 'placement'], formClass: 'A',
2656
2669
  scriptFace: true,
2670
+ naming: { kind: 'identity' },
2657
2671
  },
2658
2672
  {
2659
2673
  name: 'composeTransforms', source: 'topology/api.js#composeTransforms', kind: 'pure',
2660
2674
  reason: '变换函数组合器(纯数据,无 Shape 参数)',
2661
2675
  },
2662
2676
  {
2663
- name: 'cut', source: 'topology/api.js#cut', kind: 'brep-op',
2677
+ name: 'cut', source: 'topology/api.js#cut', kind: 'skip',
2664
2678
  geometryArgs: [0, 1], returnsResult: true,
2665
2679
  args: 'cut(base: Shape, tool: Shape, options?: BooleanOptions): Shape',
2666
- reason: 'faijs 用 subtract(不同名),布尔减 → brep-op',
2680
+ reason: 'overridden by handwritten boolean.ts:cut (Phase 3 roleTable propagation)',
2667
2681
  params: ['base', 'tool', 'options'], formClass: 'A',
2668
2682
  scriptFace: true,
2683
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
2669
2684
  },
2670
2685
  {
2671
2686
  name: 'fuseAll', source: 'topology/api.js#fuseAll', kind: 'skip',
@@ -2686,8 +2701,8 @@ export const ARG_SPEC = [
2686
2701
  name: 'section', source: 'topology/api.js#section', kind: 'brep-op',
2687
2702
  geometryArgs: [0], returnsResult: true,
2688
2703
  args: 'section(shape: Shape, plane: PlaneInput): Shape',
2689
- reason: 'faijs 无同名截面查询(平面入参非几何)→ brep-op',
2690
2704
  params: ['shape', 'plane'], formClass: 'A',
2705
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
2691
2706
  },
2692
2707
  {
2693
2708
  name: 'sectionToFace', source: 'topology/api.js#sectionToFace', kind: 'skip',
@@ -2700,18 +2715,16 @@ export const ARG_SPEC = [
2700
2715
  reason: 'faijs split 已更名 fai_split,上游工具切件 split 空出 → brep-op(§5.1 D-SPLIT;tools 暂登记几何首参,数组切件经 faijs 侧适配)',
2701
2716
  params: ['shape', 'tools'], formClass: 'A',
2702
2717
  scriptFace: true,
2718
+ naming: { kind: 'subdivide' },
2703
2719
  },
2704
2720
  {
2705
2721
  name: 'slice', source: 'topology/api.js#slice', kind: 'skip',
2706
2722
  reason: 'planes 数组入参且返回 AnyShape[](多产物),skip',
2707
2723
  },
2708
2724
  {
2709
- name: 'fillet', source: 'topology/api.js#fillet', kind: 'brep-op',
2710
- geometryArgs: [0], returnsResult: true,
2725
+ name: 'fillet', source: 'topology/api.js#fillet', kind: 'skip',
2711
2726
  args: 'fillet(shape: Shape, edges?, radius | [r1,r2]): Shape',
2712
- reason: 'D-FILLET:faijs 侧由手写 dual-op 覆盖(§2.1 等半径 + filletWithHistory roleTable 传播);本条目仅投影到 vendored fillet 契约,生成模块符号为孤儿 by design,scriptFace 不投(避免与手写 fillet 撞名)。',
2713
- params: ['shape', 'edges', 'radius'], formClass: 'A',
2714
- scriptFace: false,
2727
+ reason: 'overridden by handwritten api/fillet.ts (fillet dual-op, roleTable propagation)',
2715
2728
  },
2716
2729
  {
2717
2730
  name: 'chamfer', source: 'topology/api.js#chamfer', kind: 'skip',
@@ -2721,8 +2734,8 @@ export const ARG_SPEC = [
2721
2734
  name: 'shell', source: 'topology/api.js#shell', kind: 'brep-op',
2722
2735
  geometryArgs: [0], returnsResult: true,
2723
2736
  args: 'shell(shape: Shape, faces?: Shape[], thickness: number): Shape',
2724
- reason: 'faijs 无同名抽壳 → brep-op(faces 可选,整件抽壳可表达)',
2725
2737
  params: ['shape', 'faces', 'thickness'], formClass: 'A',
2738
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
2726
2739
  },
2727
2740
  {
2728
2741
  name: 'offset', source: 'topology/api.js#offset', kind: 'brep-op',
@@ -2731,6 +2744,7 @@ export const ARG_SPEC = [
2731
2744
  reason: 'faijs 无同名偏置 → brep-op',
2732
2745
  params: ['shape', 'distance'], formClass: 'A',
2733
2746
  scriptFace: true,
2747
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
2734
2748
  },
2735
2749
  {
2736
2750
  name: 'thicken', source: 'topology/api.js#thicken', kind: 'skip',
@@ -2747,6 +2761,7 @@ export const ARG_SPEC = [
2747
2761
  reason: 'faijs 无同名整件修复 → brep-op',
2748
2762
  params: ['shape'], formClass: 'A',
2749
2763
  scriptFace: true,
2764
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
2750
2765
  },
2751
2766
  {
2752
2767
  name: 'simplify', source: 'topology/api.js#simplify', kind: 'brep-op',
@@ -2755,6 +2770,7 @@ export const ARG_SPEC = [
2755
2770
  reason: 'faijs 无同名整件简化 → brep-op',
2756
2771
  params: ['shape'], formClass: 'A',
2757
2772
  scriptFace: true,
2773
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
2758
2774
  },
2759
2775
  {
2760
2776
  name: 'mesh', source: 'topology/api.js#mesh', kind: 'skip',
@@ -3050,6 +3066,7 @@ export const ARG_SPEC = [
3050
3066
  reason: '整件自动修复(Result<Shape>),brep-op',
3051
3067
  params: ['shape', 'options'], formClass: 'A',
3052
3068
  scriptFace: true,
3069
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
3053
3070
  },
3054
3071
  {
3055
3072
  name: 'fixShape', source: 'topology/healingFns.js#fixShape', kind: 'brep-op',
@@ -3058,6 +3075,7 @@ export const ARG_SPEC = [
3058
3075
  reason: '整件修复(Result<Shape>),brep-op',
3059
3076
  params: ['shape'], formClass: 'A',
3060
3077
  scriptFace: true,
3078
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
3061
3079
  },
3062
3080
  {
3063
3081
  name: 'healSolid', source: 'topology/healingFns.js#healSolid', kind: 'brep-op',
@@ -3066,13 +3084,14 @@ export const ARG_SPEC = [
3066
3084
  reason: 'Solid 修复(Result<ValidSolid>),brep-op',
3067
3085
  params: ['solid'], formClass: 'A',
3068
3086
  scriptFace: true,
3087
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
3069
3088
  },
3070
3089
  {
3071
3090
  name: 'fixSelfIntersection', source: 'topology/healingFns.js#fixSelfIntersection', kind: 'brep-op',
3072
3091
  geometryArgs: [0], returnsResult: true,
3073
3092
  args: 'fixSelfIntersection(shape: Shape): Shape',
3074
- reason: '整件自交修复(Result<Shape>),brep-op',
3075
3093
  params: ['shape'], formClass: 'A',
3094
+ naming: { kind: 'kernel', newFaces: { via: 'byAdjacency' } },
3076
3095
  },
3077
3096
  {
3078
3097
  name: 'healFace', source: 'topology/healingFns.js#healFace', kind: 'skip',