brepjs 20.11.0 → 20.11.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.
Files changed (91) hide show
  1. package/dist/2d.cjs +6 -6
  2. package/dist/2d.js +6 -6
  3. package/dist/{adjacencyFns-CS62XPcQ.cjs → adjacencyFns-ChCZyiBA.cjs} +3 -3
  4. package/dist/{adjacencyFns-DG9R99LR.js → adjacencyFns-Cu9Zjjsv.js} +3 -3
  5. package/dist/{blueprint-B8tYa1RE.js → blueprint-CHmxRlJw.js} +5 -5
  6. package/dist/{blueprint-YK9OBMxh.cjs → blueprint-DxAD4jsT.cjs} +5 -5
  7. package/dist/{blueprintFns-DDiWI0Ol.cjs → blueprintFns-BxEYPNV5.cjs} +2 -2
  8. package/dist/{blueprintFns-C0x5vPm-.js → blueprintFns-CVjTOusS.js} +2 -2
  9. package/dist/{blueprintSketcher-DcyidOGa.js → blueprintSketcher-BECQIPIt.js} +3 -3
  10. package/dist/{blueprintSketcher-7v6ufdam.cjs → blueprintSketcher-Cy1atQHR.cjs} +3 -3
  11. package/dist/{boolean2D-DYAua9O_.js → boolean2D-Cf9l3KK0.js} +4 -4
  12. package/dist/{boolean2D-B21GheGE.cjs → boolean2D-DF0i9O9B.cjs} +4 -4
  13. package/dist/brepjs.cjs +397 -76
  14. package/dist/brepjs.js +397 -76
  15. package/dist/{cameraFns-CAjuoPKb.js → cameraFns-CkLHhFRs.js} +3 -3
  16. package/dist/{cameraFns-HpsMe1iL.cjs → cameraFns-nr0q89z5.cjs} +3 -3
  17. package/dist/core.cjs +2 -2
  18. package/dist/core.js +2 -2
  19. package/dist/{cornerFinder-DHg0ej_Q.js → cornerFinder-6S-UlbNA.js} +1 -1
  20. package/dist/{cornerFinder-DVHtBOzM.cjs → cornerFinder-CrceCNPv.cjs} +1 -1
  21. package/dist/{curveFns-DUSOe8uJ.cjs → curveFns-BBx04S8G.cjs} +1 -1
  22. package/dist/{curveFns-BdmSrGqT.js → curveFns-DdG-DkSs.js} +1 -1
  23. package/dist/{drawFns-Cy7P1Q-L.cjs → drawFns-COim8Ti4.cjs} +12 -12
  24. package/dist/{drawFns-X0cS9iAp.js → drawFns-Vb8LHeb-.js} +12 -12
  25. package/dist/{faceFns-DKEm5U-p.js → faceFns-3VaHLMb8.js} +2 -2
  26. package/dist/{faceFns-vVGf6osa.cjs → faceFns-DolWAvAu.cjs} +2 -2
  27. package/dist/{healingFns-CW0olP8u.cjs → healingFns-BZRF9VAs.cjs} +5 -5
  28. package/dist/{healingFns-C_3Zf9sr.js → healingFns-xog7HTv1.js} +5 -5
  29. package/dist/{helpers-CcZp3tLI.js → helpers-BhBnVALd.js} +6 -6
  30. package/dist/{helpers-BIpWypkW.cjs → helpers-BjVuQMLI.cjs} +6 -6
  31. package/dist/{importFns-D_tBVKl2.js → importFns-BExUbyad.js} +48 -11
  32. package/dist/{importFns-DI3Q8B0Q.cjs → importFns-Uz6iAurc.cjs} +48 -11
  33. package/dist/io/dxfExportFns.d.ts +2 -2
  34. package/dist/io/dxfImportFns.d.ts +4 -2
  35. package/dist/io.cjs +2 -2
  36. package/dist/io.js +2 -2
  37. package/dist/kernel/occtWasm/meshOps.d.ts +1 -1
  38. package/dist/kernel/occtWasm/occtWasmAdapter.cjs +1 -1
  39. package/dist/kernel/occtWasm/occtWasmAdapter.js +1 -1
  40. package/dist/kernel/occtWasm/occtWasmTypes.d.ts +2 -1
  41. package/dist/{loftFns-DIsFP0VL.js → loftFns-B7rgdvke.js} +1 -1
  42. package/dist/{loftFns-tGsV_hHY.cjs → loftFns-nWtrZfoY.cjs} +1 -1
  43. package/dist/{measureFns-eCuwj0im.js → measureFns-AxoHtJ3J.js} +3 -3
  44. package/dist/{measureFns-BoNCUOKe.cjs → measureFns-eOGL04SI.cjs} +3 -3
  45. package/dist/measurement.cjs +2 -2
  46. package/dist/measurement.js +2 -2
  47. package/dist/{meshFns-0W1-80zv.cjs → meshFns-BhOC8SuD.cjs} +3 -3
  48. package/dist/{meshFns-B9jPfcB2.js → meshFns-C1nJQkWC.js} +3 -3
  49. package/dist/{occtWasmAdapter-CsDULjij.cjs → occtWasmAdapter-D1EXktNq.cjs} +5 -2
  50. package/dist/{occtWasmAdapter-ClvPe3OJ.js → occtWasmAdapter-RBm-JLoN.js} +5 -2
  51. package/dist/operations.cjs +2 -2
  52. package/dist/operations.js +2 -2
  53. package/dist/{originTrackingFns-BW2BaJW8.js → originTrackingFns-4z3sWvOD.js} +2 -2
  54. package/dist/{originTrackingFns-cEKFxtia.cjs → originTrackingFns-DRRVoZxG.cjs} +2 -2
  55. package/dist/{primitiveFns-BJ-ehvvd.cjs → primitiveFns-BdSDbmhs.cjs} +4 -4
  56. package/dist/{primitiveFns-BOZ7Kx0M.js → primitiveFns-D-5rBhH4.js} +4 -4
  57. package/dist/{principalBoxFns-B6PZwxDM.js → principalBoxFns-BeOAlafI.js} +3 -3
  58. package/dist/{principalBoxFns-B1j2sNAc.cjs → principalBoxFns-CY98NNKz.cjs} +3 -3
  59. package/dist/projection.cjs +1 -1
  60. package/dist/projection.js +1 -1
  61. package/dist/query.cjs +2 -2
  62. package/dist/query.js +2 -2
  63. package/dist/{refResolveFns-DvDeMCVU.cjs → refResolveFns--VMNo9vf.cjs} +6 -6
  64. package/dist/{refResolveFns-BxvibZPu.js → refResolveFns-DB8FIWrZ.js} +6 -6
  65. package/dist/{shapeFns-De7CbEeQ.js → shapeFns-BTfhLPET.js} +2 -2
  66. package/dist/{shapeFns-CJrIL2CG.cjs → shapeFns-CREKqmcG.cjs} +2 -2
  67. package/dist/shapeRef.cjs +1 -1
  68. package/dist/shapeRef.js +1 -1
  69. package/dist/{shapeTypes-BCy8JI0O.js → shapeTypes-Db3yAgTO.js} +1 -1
  70. package/dist/{shapeTypes-CNQn1x5H.cjs → shapeTypes-HDVHzNk1.cjs} +1 -1
  71. package/dist/sketching.cjs +3 -3
  72. package/dist/sketching.js +3 -3
  73. package/dist/{solidBuilders-BN1p303l.cjs → solidBuilders-BeanhIbq.cjs} +5 -5
  74. package/dist/{solidBuilders-YbLOfWIp.js → solidBuilders-CSg8AUaL.js} +5 -5
  75. package/dist/{surfaceBuilders-CaN-lye8.js → surfaceBuilders-4F0VrN1_.js} +3 -3
  76. package/dist/{surfaceBuilders-C5lz2TNF.cjs → surfaceBuilders-BdOO4OJU.cjs} +3 -3
  77. package/dist/text.cjs +2 -2
  78. package/dist/text.js +2 -2
  79. package/dist/{textBlueprints-jlqCGG4p.cjs → textBlueprints-0pLR2X5a.cjs} +7 -7
  80. package/dist/{textBlueprints-BlfIkOUx.js → textBlueprints-BpituhGG.js} +7 -7
  81. package/dist/{textMetrics-B2KxCoHk.cjs → textMetrics-BhIL6fpo.cjs} +1 -1
  82. package/dist/{textMetrics-BjhB4Zur.js → textMetrics-DmgaIDzF.js} +1 -1
  83. package/dist/{threadFns-DWMumhmK.js → threadFns-C54cXKrZ.js} +7 -7
  84. package/dist/{threadFns-DO9SkBPb.cjs → threadFns-LGRpYJea.cjs} +7 -7
  85. package/dist/topology.cjs +9 -9
  86. package/dist/topology.js +9 -9
  87. package/dist/{topologyQueryFns-BwhwOtxv.cjs → topologyQueryFns-BJ5U4AmO.cjs} +1 -1
  88. package/dist/{topologyQueryFns-Clkdolgd.js → topologyQueryFns-BYXQ2Kkn.js} +1 -1
  89. package/dist/{validityTypes-B_6gRPPO.cjs → validityTypes-C2l1ryPq.cjs} +1 -1
  90. package/dist/{validityTypes-txYFYYN6.js → validityTypes-ClsRW650.js} +1 -1
  91. package/package.json +1 -1
package/dist/brepjs.cjs CHANGED
@@ -1,42 +1,42 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./rolldown-runtime-BW-eSwOZ.cjs");
3
- const require_shapeTypes = require("./shapeTypes-CNQn1x5H.cjs");
4
- const require_occtWasmAdapter = require("./occtWasmAdapter-CsDULjij.cjs");
3
+ const require_shapeTypes = require("./shapeTypes-HDVHzNk1.cjs");
4
+ const require_occtWasmAdapter = require("./occtWasmAdapter-D1EXktNq.cjs");
5
5
  const require_bug = require("./bug-CBcpIPuf.cjs");
6
6
  const require_errors = require("./errors-B9r_Dzs1.cjs");
7
- const require_topologyQueryFns = require("./topologyQueryFns-BwhwOtxv.cjs");
8
- const require_validityTypes = require("./validityTypes-B_6gRPPO.cjs");
7
+ const require_topologyQueryFns = require("./topologyQueryFns-BJ5U4AmO.cjs");
8
+ const require_validityTypes = require("./validityTypes-C2l1ryPq.cjs");
9
9
  const require_constants = require("./constants-oee0S_x6.cjs");
10
10
  const require_types = require("./types-CjF9Rofr.cjs");
11
11
  const require_vecOps = require("./vecOps-CrGEPPQM.cjs");
12
12
  const require_planeOps = require("./planeOps-C7sRqzno.cjs");
13
- const require_faceFns = require("./faceFns-vVGf6osa.cjs");
14
- const require_originTrackingFns = require("./originTrackingFns-cEKFxtia.cjs");
15
- const require_solidBuilders = require("./solidBuilders-BN1p303l.cjs");
16
- const require_primitiveFns = require("./primitiveFns-BJ-ehvvd.cjs");
17
- const require_shapeFns = require("./shapeFns-CJrIL2CG.cjs");
18
- const require_curveFns = require("./curveFns-DUSOe8uJ.cjs");
19
- const require_meshFns = require("./meshFns-0W1-80zv.cjs");
13
+ const require_faceFns = require("./faceFns-DolWAvAu.cjs");
14
+ const require_originTrackingFns = require("./originTrackingFns-DRRVoZxG.cjs");
15
+ const require_solidBuilders = require("./solidBuilders-BeanhIbq.cjs");
16
+ const require_primitiveFns = require("./primitiveFns-BdSDbmhs.cjs");
17
+ const require_shapeFns = require("./shapeFns-CREKqmcG.cjs");
18
+ const require_curveFns = require("./curveFns-BBx04S8G.cjs");
19
+ const require_meshFns = require("./meshFns-BhOC8SuD.cjs");
20
20
  const require_arrayAccess = require("./arrayAccess-DpJYARwv.cjs");
21
- const require_surfaceBuilders = require("./surfaceBuilders-C5lz2TNF.cjs");
22
- const require_healingFns = require("./healingFns-CW0olP8u.cjs");
23
- const require_threadFns = require("./threadFns-DO9SkBPb.cjs");
24
- const require_blueprintSketcher = require("./blueprintSketcher-7v6ufdam.cjs");
25
- const require_helpers = require("./helpers-BIpWypkW.cjs");
26
- const require_blueprint = require("./blueprint-YK9OBMxh.cjs");
27
- const require_drawFns = require("./drawFns-Cy7P1Q-L.cjs");
28
- const require_measureFns = require("./measureFns-BoNCUOKe.cjs");
29
- const require_cornerFinder = require("./cornerFinder-DVHtBOzM.cjs");
30
- const require_boolean2D = require("./boolean2D-B21GheGE.cjs");
31
- const require_blueprintFns = require("./blueprintFns-DDiWI0Ol.cjs");
32
- const require_importFns = require("./importFns-DI3Q8B0Q.cjs");
33
- const require_textBlueprints = require("./textBlueprints-jlqCGG4p.cjs");
34
- const require_loftFns = require("./loftFns-tGsV_hHY.cjs");
35
- const require_refResolveFns = require("./refResolveFns-DvDeMCVU.cjs");
36
- const require_adjacencyFns = require("./adjacencyFns-CS62XPcQ.cjs");
37
- const require_cameraFns = require("./cameraFns-HpsMe1iL.cjs");
38
- const require_textMetrics = require("./textMetrics-B2KxCoHk.cjs");
39
- const require_principalBoxFns = require("./principalBoxFns-B1j2sNAc.cjs");
21
+ const require_surfaceBuilders = require("./surfaceBuilders-BdOO4OJU.cjs");
22
+ const require_healingFns = require("./healingFns-BZRF9VAs.cjs");
23
+ const require_threadFns = require("./threadFns-LGRpYJea.cjs");
24
+ const require_blueprintSketcher = require("./blueprintSketcher-Cy1atQHR.cjs");
25
+ const require_helpers = require("./helpers-BjVuQMLI.cjs");
26
+ const require_blueprint = require("./blueprint-DxAD4jsT.cjs");
27
+ const require_drawFns = require("./drawFns-COim8Ti4.cjs");
28
+ const require_measureFns = require("./measureFns-eOGL04SI.cjs");
29
+ const require_cornerFinder = require("./cornerFinder-CrceCNPv.cjs");
30
+ const require_boolean2D = require("./boolean2D-DF0i9O9B.cjs");
31
+ const require_blueprintFns = require("./blueprintFns-BxEYPNV5.cjs");
32
+ const require_importFns = require("./importFns-Uz6iAurc.cjs");
33
+ const require_textBlueprints = require("./textBlueprints-0pLR2X5a.cjs");
34
+ const require_loftFns = require("./loftFns-nWtrZfoY.cjs");
35
+ const require_refResolveFns = require("./refResolveFns--VMNo9vf.cjs");
36
+ const require_adjacencyFns = require("./adjacencyFns-ChCZyiBA.cjs");
37
+ const require_cameraFns = require("./cameraFns-nr0q89z5.cjs");
38
+ const require_textMetrics = require("./textMetrics-BhIL6fpo.cjs");
39
+ const require_principalBoxFns = require("./principalBoxFns-CY98NNKz.cjs");
40
40
  const require_workerPool = require("./workerPool-D5tiNXrI.cjs");
41
41
  // src/kernel/types.ts
42
42
  /** Check if the kernel supports hidden-line-removal projection. */
@@ -6181,7 +6181,7 @@ function sub(a, b) {
6181
6181
  function dot(a, b) {
6182
6182
  return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
6183
6183
  }
6184
- function cross(a, b) {
6184
+ function cross$1(a, b) {
6185
6185
  return [
6186
6186
  a[1] * b[2] - a[2] * b[1],
6187
6187
  a[2] * b[0] - a[0] * b[2],
@@ -6205,7 +6205,7 @@ function normalize(a) {
6205
6205
  }
6206
6206
  /** A unit vector perpendicular to `v` (for the parallel-normals degenerate case). */
6207
6207
  function anyPerpendicular(v) {
6208
- return normalize(cross(v, Math.abs(v[0]) < .9 ? [
6208
+ return normalize(cross$1(v, Math.abs(v[0]) < .9 ? [
6209
6209
  1,
6210
6210
  0,
6211
6211
  0
@@ -6285,7 +6285,7 @@ function solveAngle(ref, dep, angleRad) {
6285
6285
  1
6286
6286
  ]);
6287
6287
  const phi = Math.acos(Math.max(-1, Math.min(1, dot(nDep, nRef))));
6288
- const c = cross(nDep, nRef);
6288
+ const c = cross$1(nDep, nRef);
6289
6289
  const axis = Math.hypot(c[0], c[1], c[2]) < 1e-9 ? anyPerpendicular(nDep) : c;
6290
6290
  return {
6291
6291
  position: [
@@ -6792,63 +6792,378 @@ function parseEntities(text) {
6792
6792
  current = {
6793
6793
  type: value,
6794
6794
  layer: "0",
6795
- data: /* @__PURE__ */ new Map()
6795
+ data: /* @__PURE__ */ new Map(),
6796
+ pairs: []
6796
6797
  };
6797
6798
  continue;
6798
6799
  }
6799
6800
  if (current) {
6801
+ current.pairs.push([code, value]);
6800
6802
  if (code === 8) current.layer = value;
6801
6803
  else current.data.set(code, value);
6802
6804
  }
6803
6805
  }
6804
6806
  return entities;
6805
6807
  }
6806
- function getNum(data, code, fallback = 0) {
6807
- const v = data.get(code);
6808
- if (v === void 0) return fallback;
6809
- const n = parseFloat(v);
6808
+ function num(value, fallback = 0) {
6809
+ if (value === void 0) return fallback;
6810
+ const n = parseFloat(value);
6810
6811
  return isNaN(n) ? fallback : n;
6811
6812
  }
6812
- function entityToEdge(entity) {
6813
- const { type, data } = entity;
6814
- const kernel = require_shapeTypes.getKernel();
6815
- if (type === "LINE") return kernel.makeLineEdge([
6816
- getNum(data, 10),
6817
- getNum(data, 20),
6818
- getNum(data, 30)
6819
- ], [
6820
- getNum(data, 11),
6821
- getNum(data, 21),
6822
- getNum(data, 31)
6813
+ function getNum(data, code, fallback = 0) {
6814
+ return num(data.get(code), fallback);
6815
+ }
6816
+ /** LWPOLYLINE vertices: each 10 starts one and its 20 and 42 follow; 38 is the elevation. */
6817
+ function lwVertices(entity) {
6818
+ const z = getNum(entity.data, 38);
6819
+ const out = [];
6820
+ for (const [code, value] of entity.pairs) {
6821
+ const last = out[out.length - 1];
6822
+ if (code === 10) out.push({
6823
+ point: [
6824
+ num(value),
6825
+ 0,
6826
+ z
6827
+ ],
6828
+ bulge: 0
6829
+ });
6830
+ else if (code === 20 && last) last.point[1] = num(value);
6831
+ else if (code === 42 && last) last.bulge = num(value);
6832
+ }
6833
+ return out;
6834
+ }
6835
+ /**
6836
+ * The DXF R12 polyline: a POLYLINE header, its VERTEX entities, then SEQEND. They arrive as
6837
+ * separate entities, so the header gathers the vertices that follow it.
6838
+ */
6839
+ function gatherPolylines(entities) {
6840
+ const out = [];
6841
+ for (let i = 0; i < entities.length; i++) {
6842
+ const e = entities[i];
6843
+ if (e === void 0) continue;
6844
+ if (e.type !== "POLYLINE") {
6845
+ if (e.type !== "VERTEX" && e.type !== "SEQEND") out.push(e);
6846
+ continue;
6847
+ }
6848
+ const vertices = [];
6849
+ let j = i + 1;
6850
+ for (; j < entities.length && entities[j]?.type === "VERTEX"; j++) {
6851
+ const v = entities[j];
6852
+ if (v === void 0) continue;
6853
+ vertices.push([10, v.data.get(10) ?? "0"], [20, v.data.get(20) ?? "0"], [30, v.data.get(30) ?? "0"], [42, v.data.get(42) ?? "0"]);
6854
+ }
6855
+ if (entities[j]?.type === "SEQEND") j++;
6856
+ const own = e.pairs.filter(([code]) => code !== 10 && code !== 20 && code !== 30);
6857
+ out.push({
6858
+ ...e,
6859
+ pairs: [...own, ...vertices]
6860
+ });
6861
+ i = j - 1;
6862
+ }
6863
+ return out;
6864
+ }
6865
+ function polyVertices(entity) {
6866
+ if (entity.type === "LWPOLYLINE") return lwVertices(entity);
6867
+ const out = [];
6868
+ const p = entity.pairs;
6869
+ for (let k = 0; k < p.length; k++) {
6870
+ if (p[k]?.[0] !== 10) continue;
6871
+ out.push({
6872
+ point: [
6873
+ num(p[k]?.[1]),
6874
+ num(p[k + 1]?.[1]),
6875
+ num(p[k + 2]?.[1])
6876
+ ],
6877
+ bulge: num(p[k + 3]?.[1])
6878
+ });
6879
+ }
6880
+ return out;
6881
+ }
6882
+ var JOIN_TOL = 1e-7;
6883
+ var TURN = 2 * Math.PI;
6884
+ function cross(a, b) {
6885
+ return [
6886
+ a[1] * b[2] - a[2] * b[1],
6887
+ a[2] * b[0] - a[0] * b[2],
6888
+ a[0] * b[1] - a[1] * b[0]
6889
+ ];
6890
+ }
6891
+ function unit(v) {
6892
+ const l = Math.hypot(v[0], v[1], v[2]) || 1;
6893
+ return [
6894
+ v[0] / l,
6895
+ v[1] / l,
6896
+ v[2] / l
6897
+ ];
6898
+ }
6899
+ /**
6900
+ * The entity's object coordinate system, from its extrusion direction (210/220/230), by DXF's
6901
+ * arbitrary axis algorithm. Planar entities (circles, arcs, 2D polylines) store their points in
6902
+ * it; the default extrusion +Z makes it the world frame.
6903
+ */
6904
+ function ocsOf(data) {
6905
+ const normal = unit([
6906
+ getNum(data, 210),
6907
+ getNum(data, 220),
6908
+ getNum(data, 230, 1)
6823
6909
  ]);
6824
- if (type === "CIRCLE") return kernel.makeCircleEdge([
6825
- getNum(data, 10),
6826
- getNum(data, 20),
6827
- getNum(data, 30)
6828
- ], [
6910
+ if (normal[0] === 0 && normal[1] === 0 && normal[2] > 0) return {
6911
+ normal: [
6912
+ 0,
6913
+ 0,
6914
+ 1
6915
+ ],
6916
+ identity: true,
6917
+ toWorld: (p) => p
6918
+ };
6919
+ const ax = unit(cross(Math.abs(normal[0]) < 1 / 64 && Math.abs(normal[1]) < 1 / 64 ? [
6920
+ 0,
6921
+ 1,
6922
+ 0
6923
+ ] : [
6829
6924
  0,
6830
6925
  0,
6831
6926
  1
6832
- ], getNum(data, 40));
6833
- if (type === "ARC") {
6834
- const startAngle = getNum(data, 50) * Math.PI / 180;
6835
- const endAngle = getNum(data, 51) * Math.PI / 180;
6836
- return kernel.makeCircleArc([
6837
- getNum(data, 10),
6838
- getNum(data, 20),
6839
- getNum(data, 30)
6840
- ], [
6927
+ ], normal));
6928
+ const ay = unit(cross(normal, ax));
6929
+ return {
6930
+ normal,
6931
+ identity: false,
6932
+ toWorld: ([x, y, z]) => [
6933
+ ax[0] * x + ay[0] * y + normal[0] * z,
6934
+ ax[1] * x + ay[1] * y + normal[1] * z,
6935
+ ax[2] * x + ay[2] * y + normal[2] * z
6936
+ ]
6937
+ };
6938
+ }
6939
+ function apart(a, b) {
6940
+ return Math.hypot(a[0] - b[0], a[1] - b[1], a[2] - b[2]) > JOIN_TOL;
6941
+ }
6942
+ function linePiece(a, b) {
6943
+ return {
6944
+ start: a,
6945
+ end: b,
6946
+ build: () => require_shapeTypes.getKernel().makeLineEdge(a, b)
6947
+ };
6948
+ }
6949
+ /**
6950
+ * An ARC entity about OCS center `c`, counterclockwise from angle `from` through `sweep` (0, 2π].
6951
+ * In the default OCS, which is most files, it's built from its center and angles, which stays
6952
+ * exact for a shallow arc. In a rotated OCS, whose in-plane axes the kernel doesn't share, it goes
6953
+ * through three points on it, or is a line when its sagitta is under the tolerance.
6954
+ */
6955
+ function arcPiece(c, r, from, sweep, ocs) {
6956
+ const on = (t) => ocs.toWorld([
6957
+ c[0] + r * Math.cos(t),
6958
+ c[1] + r * Math.sin(t),
6959
+ c[2]
6960
+ ]);
6961
+ const start = on(from);
6962
+ const end = on(from + sweep);
6963
+ if (ocs.identity) return {
6964
+ start,
6965
+ end,
6966
+ build: () => require_shapeTypes.getKernel().makeCircleArc(c, [
6967
+ 0,
6968
+ 0,
6969
+ 1
6970
+ ], r, from, from + sweep)
6971
+ };
6972
+ if (r * (1 - Math.cos(sweep / 2)) <= JOIN_TOL) return linePiece(start, end);
6973
+ const mid = on(from + sweep / 2);
6974
+ return {
6975
+ start,
6976
+ end,
6977
+ build: () => require_shapeTypes.getKernel().makeArcEdge(start, mid, end)
6978
+ };
6979
+ }
6980
+ /**
6981
+ * A polyline segment in its OCS: straight, or the arc a bulge describes. A bulge is tan(θ/4) of
6982
+ * the arc's included angle, counterclockwise when positive, so the arc's midpoint lies the sagitta
6983
+ * (bulge × half the chord) off the chord's midpoint, to its right for a positive bulge. The arc
6984
+ * goes through the supplied vertices exactly, so it meets its neighbours; one whose sagitta is
6985
+ * under the tolerance is a line to the kernel and is built as one.
6986
+ */
6987
+ function segment(a, b, bulge, ocs) {
6988
+ const dx = b[0] - a[0];
6989
+ const dy = b[1] - a[1];
6990
+ const d = Math.hypot(dx, dy);
6991
+ const s = bulge * d / 2;
6992
+ if (Math.abs(s) <= JOIN_TOL) return linePiece(ocs.toWorld(a), ocs.toWorld(b));
6993
+ const mid = [
6994
+ (a[0] + b[0]) / 2 + dy / d * s,
6995
+ (a[1] + b[1]) / 2 - dx / d * s,
6996
+ a[2]
6997
+ ];
6998
+ const [wa, wm, wb] = [
6999
+ ocs.toWorld(a),
7000
+ ocs.toWorld(mid),
7001
+ ocs.toWorld(b)
7002
+ ];
7003
+ return {
7004
+ start: wa,
7005
+ end: wb,
7006
+ build: () => require_shapeTypes.getKernel().makeArcEdge(wa, wm, wb)
7007
+ };
7008
+ }
7009
+ var CLOSED = 1;
7010
+ var POLYLINE_3D = 8;
7011
+ var MESH_FORMS = 80;
7012
+ function polylinePieces(entity) {
7013
+ const flags = getNum(entity.data, 70);
7014
+ if (entity.type === "POLYLINE" && (flags & MESH_FORMS) !== 0) return [];
7015
+ const is3d = entity.type === "POLYLINE" && (flags & POLYLINE_3D) !== 0;
7016
+ const ocs = is3d ? {
7017
+ normal: [
6841
7018
  0,
6842
7019
  0,
6843
7020
  1
6844
- ], getNum(data, 40), startAngle, endAngle);
7021
+ ],
7022
+ identity: true,
7023
+ toWorld: (p) => p
7024
+ } : ocsOf(entity.data);
7025
+ const elevation = entity.type === "POLYLINE" && !is3d ? getNum(entity.data, 30) : void 0;
7026
+ const vertices = polyVertices(entity).map((v) => elevation === void 0 ? v : {
7027
+ ...v,
7028
+ point: [
7029
+ v.point[0],
7030
+ v.point[1],
7031
+ elevation
7032
+ ]
7033
+ });
7034
+ const closed = (flags & CLOSED) === CLOSED;
7035
+ const pieces = [];
7036
+ const count = closed ? vertices.length : vertices.length - 1;
7037
+ for (let k = 0; k < count; k++) {
7038
+ const a = vertices[k];
7039
+ const b = vertices[(k + 1) % vertices.length];
7040
+ if (!a || !b || !apart(a.point, b.point)) continue;
7041
+ pieces.push(segment(a.point, b.point, is3d ? 0 : a.bulge, ocs));
7042
+ }
7043
+ return pieces;
7044
+ }
7045
+ function entityToPieces(entity) {
7046
+ const { type, data } = entity;
7047
+ if (type === "LINE") {
7048
+ const start = [
7049
+ getNum(data, 10),
7050
+ getNum(data, 20),
7051
+ getNum(data, 30)
7052
+ ];
7053
+ const end = [
7054
+ getNum(data, 11),
7055
+ getNum(data, 21),
7056
+ getNum(data, 31)
7057
+ ];
7058
+ return apart(start, end) ? [linePiece(start, end)] : [];
6845
7059
  }
7060
+ if (type === "CIRCLE" || type === "ARC") {
7061
+ const ocs = ocsOf(data);
7062
+ const c = [
7063
+ getNum(data, 10),
7064
+ getNum(data, 20),
7065
+ getNum(data, 30)
7066
+ ];
7067
+ const r = getNum(data, 40);
7068
+ if (!(r > 0) || !Number.isFinite(r)) return [];
7069
+ if (type === "CIRCLE") {
7070
+ const center = ocs.toWorld(c);
7071
+ const at = ocs.toWorld([
7072
+ c[0] + r,
7073
+ c[1],
7074
+ c[2]
7075
+ ]);
7076
+ return [{
7077
+ start: at,
7078
+ end: at,
7079
+ build: () => require_shapeTypes.getKernel().makeCircleEdge(center, ocs.normal, r)
7080
+ }];
7081
+ }
7082
+ const from = getNum(data, 50) * Math.PI / 180;
7083
+ const to = getNum(data, 51) * Math.PI / 180;
7084
+ if (!Number.isFinite(from) || !Number.isFinite(to)) return [];
7085
+ let sweep = (to - from) % TURN;
7086
+ if (sweep <= 0) sweep += TURN;
7087
+ return [arcPiece(c, r, from % TURN, sweep, ocs)];
7088
+ }
7089
+ if (type === "LWPOLYLINE" || type === "POLYLINE") return polylinePieces(entity);
7090
+ return [];
7091
+ }
7092
+ /** Gives endpoints within JOIN_TOL of each other one id, by a grid of JOIN_TOL cells. */
7093
+ function pointIds() {
7094
+ const cells = /* @__PURE__ */ new Map();
7095
+ let next = 0;
7096
+ return (p) => {
7097
+ const c = p.map((v) => Math.floor(v / JOIN_TOL));
7098
+ for (let dx = -1; dx <= 1; dx++) for (let dy = -1; dy <= 1; dy++) for (let dz = -1; dz <= 1; dz++) {
7099
+ const hit = cells.get(`${(c[0] ?? 0) + dx},${(c[1] ?? 0) + dy},${(c[2] ?? 0) + dz}`)?.find((e) => !apart(e.p, p));
7100
+ if (hit) return hit.id;
7101
+ }
7102
+ const key = c.join(",");
7103
+ const id = next++;
7104
+ const cell = cells.get(key);
7105
+ if (cell) cell.push({
7106
+ p,
7107
+ id
7108
+ });
7109
+ else cells.set(key, [{
7110
+ p,
7111
+ id
7112
+ }]);
7113
+ return id;
7114
+ };
7115
+ }
7116
+ /** The pieces in connected chains, each in walking order, so every chain makes one wire. */
7117
+ function chainPieces(pieces) {
7118
+ const idOf = pointIds();
7119
+ const ends = pieces.map((p) => [idOf(p.start), idOf(p.end)]);
7120
+ const at = /* @__PURE__ */ new Map();
7121
+ ends.forEach(([s, e], i) => {
7122
+ for (const id of s === e ? [s] : [s, e]) {
7123
+ const list = at.get(id);
7124
+ if (list) list.push(i);
7125
+ else at.set(id, [i]);
7126
+ }
7127
+ });
7128
+ const used = /* @__PURE__ */ new Set();
7129
+ const cursor = /* @__PURE__ */ new Map();
7130
+ const step = (tip) => {
7131
+ const list = at.get(tip) ?? [];
7132
+ let c = cursor.get(tip) ?? 0;
7133
+ while (c < list.length && used.has(list[c] ?? -1)) c++;
7134
+ cursor.set(tip, c + 1);
7135
+ const i = list[c];
7136
+ if (i === void 0) return void 0;
7137
+ used.add(i);
7138
+ const [s, e] = ends[i] ?? [tip, tip];
7139
+ return {
7140
+ i,
7141
+ tip: s === tip ? e : s
7142
+ };
7143
+ };
7144
+ const chains = [];
7145
+ pieces.forEach((first, i) => {
7146
+ if (used.has(i)) return;
7147
+ used.add(i);
7148
+ const chain = [first];
7149
+ const [s, e] = ends[i] ?? [0, 0];
7150
+ for (const [dir, from] of [[1, e], [-1, s]]) for (let hop = step(from); hop; hop = step(hop.tip)) {
7151
+ const piece = pieces[hop.i];
7152
+ if (!piece) continue;
7153
+ if (dir === 1) chain.push(piece);
7154
+ else chain.unshift(piece);
7155
+ }
7156
+ chains.push(chain);
7157
+ });
7158
+ return chains;
6846
7159
  }
6847
7160
  /**
6848
7161
  * Import a DXF file from a Blob, returning kernel wires.
6849
7162
  *
6850
- * Parses ASCII DXF LINE, CIRCLE, and ARC entities.
6851
- * Edges are assembled into wires using `BRepBuilderAPI_MakeWire`.
7163
+ * Parses ASCII DXF LINE, CIRCLE, ARC, LWPOLYLINE and R12 POLYLINE entities, polyline bulges
7164
+ * included, in world coordinates (planar entities are mapped out of their object coordinate
7165
+ * system). Polygon and polyface meshes are skipped. Edges that meet end to end become one wire,
7166
+ * so disconnected outlines come back as separate wires.
6852
7167
  *
6853
7168
  * @param blob - A Blob containing ASCII DXF data.
6854
7169
  * @param options - Optional import settings (layer filter).
@@ -6861,22 +7176,28 @@ async function importDXF(blob, options) {
6861
7176
  } catch (cause) {
6862
7177
  return require_errors.err(require_errors.ioError(require_errors.BrepErrorCode.DXF_IMPORT_FAILED, "Failed to read DXF blob", cause));
6863
7178
  }
6864
- const allEntities = parseEntities(text);
6865
- const entities = options?.layer !== void 0 ? allEntities.filter((e) => e.layer === options.layer) : allEntities;
6866
- if (entities.length === 0) return require_errors.ok([]);
7179
+ const allEntities = gatherPolylines(parseEntities(text));
7180
+ const pieces = (options?.layer !== void 0 ? allEntities.filter((e) => e.layer === options.layer) : allEntities).flatMap(entityToPieces);
7181
+ if (pieces.length === 0) return require_errors.ok([]);
7182
+ const kernel = require_shapeTypes.getKernel();
6867
7183
  const edges = [];
7184
+ const wires = [];
6868
7185
  try {
6869
- for (const entity of entities) {
6870
- const edge = entityToEdge(entity);
6871
- if (edge !== void 0) edges.push(edge);
7186
+ for (const chain of chainPieces(pieces)) {
7187
+ const chainEdges = [];
7188
+ for (const p of chain) {
7189
+ const edge = p.build();
7190
+ edges.push(edge);
7191
+ chainEdges.push(edge);
7192
+ }
7193
+ wires.push(require_shapeTypes.createWire(kernel.makeWire(chainEdges)));
6872
7194
  }
6873
- if (edges.length === 0) return require_errors.ok([]);
6874
- const wire = require_shapeTypes.getKernel().makeWire(edges);
6875
- return require_errors.ok([require_shapeTypes.createWire(wire)]);
7195
+ return require_errors.ok(wires);
6876
7196
  } catch (cause) {
7197
+ for (const w of wires) w[Symbol.dispose]();
6877
7198
  return require_errors.err(require_errors.ioError(require_errors.BrepErrorCode.DXF_IMPORT_FAILED, "Failed to convert DXF entities to geometry", cause));
6878
7199
  } finally {
6879
- for (const edge of edges) edge.delete();
7200
+ for (const edge of edges) kernel.dispose(edge);
6880
7201
  }
6881
7202
  }
6882
7203
  // src/io/ioUtils.ts