okgeometry-api 1.16.0 → 1.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Brep.d.ts +84 -6
- package/dist/Brep.d.ts.map +1 -1
- package/dist/Brep.js +101 -4
- package/dist/Brep.js.map +1 -1
- package/dist/GeometryBoolean.d.ts +136 -0
- package/dist/GeometryBoolean.d.ts.map +1 -0
- package/dist/GeometryBoolean.js +632 -0
- package/dist/GeometryBoolean.js.map +1 -0
- package/dist/Mesh.d.ts +21 -1
- package/dist/Mesh.d.ts.map +1 -1
- package/dist/Mesh.js +66 -4
- package/dist/Mesh.js.map +1 -1
- package/dist/NurbsCurve.d.ts +66 -0
- package/dist/NurbsCurve.d.ts.map +1 -1
- package/dist/NurbsCurve.js +101 -0
- package/dist/NurbsCurve.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/wasm-base64.d.ts +1 -1
- package/dist/wasm-base64.d.ts.map +1 -1
- package/dist/wasm-base64.js +1 -1
- package/dist/wasm-base64.js.map +1 -1
- package/dist/wasm-bindings.d.ts +103 -1
- package/dist/wasm-bindings.d.ts.map +1 -1
- package/dist/wasm-bindings.js +164 -1
- package/dist/wasm-bindings.js.map +1 -1
- package/package.json +7 -3
- package/src/Brep.ts +130 -8
- package/src/GeometryBoolean.ts +863 -0
- package/src/Mesh.ts +3804 -3730
- package/src/NurbsCurve.ts +110 -0
- package/src/index.ts +88 -79
- package/src/wasm-base64.ts +1 -1
- package/src/wasm-bindings.d.ts +92 -1
- package/src/wasm-bindings.js +167 -1
package/src/Brep.ts
CHANGED
|
@@ -50,6 +50,21 @@ export interface BrepSplitSolidResult {
|
|
|
50
50
|
positive: Brep | null;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Both sides of a sheet split ({@link Brep.splitSheetBySolid} /
|
|
55
|
+
* {@link Brep.splitSheetBySheet}), each an OPEN Brep preserving the sheet's
|
|
56
|
+
* exact trimmed faces, pcurves and edges.
|
|
57
|
+
*
|
|
58
|
+
* `inside` follows the oriented-sheet convention ("inside" = FRONT, the side
|
|
59
|
+
* a sheet's normal points toward): pieces CONTAINED in the solid cutter, or
|
|
60
|
+
* pieces in FRONT of the sheet cutter's normal. A side is null when no
|
|
61
|
+
* material lands on it.
|
|
62
|
+
*/
|
|
63
|
+
export interface BrepSheetSplitResult {
|
|
64
|
+
inside: Brep | null;
|
|
65
|
+
outside: Brep | null;
|
|
66
|
+
}
|
|
67
|
+
|
|
53
68
|
/** Validation report for a BREP body. */
|
|
54
69
|
export interface BrepValidationReport {
|
|
55
70
|
isClosed: boolean;
|
|
@@ -770,14 +785,34 @@ export class Brep {
|
|
|
770
785
|
|
|
771
786
|
// ── Parametric booleans (BREP → BREP) ──
|
|
772
787
|
|
|
788
|
+
/**
|
|
789
|
+
* Resolve a parametric-boolean operand: Breps pass through; Meshes are
|
|
790
|
+
* converted via {@link Brep.fromMesh} (planar-faceted meshes only) so the
|
|
791
|
+
* EXACT pipeline can run. Curved/dense meshes fail conversion with
|
|
792
|
+
* guidance to use the tessellated union()/subtract()/intersect() instead.
|
|
793
|
+
*/
|
|
794
|
+
private static resolveParametricOperand(other: Brep | Mesh): Brep {
|
|
795
|
+
if (other instanceof Brep) return other;
|
|
796
|
+
try {
|
|
797
|
+
return Brep.fromMesh(other);
|
|
798
|
+
} catch (e) {
|
|
799
|
+
const reason = e instanceof Error ? e.message : String(e);
|
|
800
|
+
throw new Error(
|
|
801
|
+
`Parametric boolean operand mesh could not be converted to a BREP (${reason}); ` +
|
|
802
|
+
"use the tessellated union()/subtract()/intersect() for mesh operands instead",
|
|
803
|
+
);
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
|
|
773
807
|
private runParametricBoolean(
|
|
774
|
-
other: Brep,
|
|
808
|
+
other: Brep | Mesh,
|
|
775
809
|
op: "union" | "subtract" | "intersect",
|
|
776
810
|
options?: BrepParametricBooleanOptions,
|
|
777
811
|
): Brep {
|
|
778
812
|
ensureInit();
|
|
813
|
+
const rhs = Brep.resolveParametricOperand(other);
|
|
779
814
|
const tolerance = options?.tolerance ?? 1e-6;
|
|
780
|
-
const json = wasm.brep_boolean_op(this.json,
|
|
815
|
+
const json = wasm.brep_boolean_op(this.json, rhs.json, op, tolerance);
|
|
781
816
|
if (!json) throw new Error(`Brep.${op}Brep failed`);
|
|
782
817
|
if (json.startsWith('{"error"')) {
|
|
783
818
|
const parsed = JSON.parse(json) as { error: string };
|
|
@@ -791,7 +826,30 @@ export class Brep {
|
|
|
791
826
|
* trimmed-surface output. Result faces keep their parents' exact surfaces
|
|
792
827
|
* (planes/NURBS, untessellated); intersection edges are Newton-refined SSI
|
|
793
828
|
* curves stored as tolerant NURBS edges with matched pcurves on both
|
|
794
|
-
* adjacent faces.
|
|
829
|
+
* adjacent faces.
|
|
830
|
+
*
|
|
831
|
+
* Operands may be CLOSED solids or OPEN sheets — the kernel dispatches on
|
|
832
|
+
* closedness, following the oriented-sheet convention used across the API
|
|
833
|
+
* (a sheet's "inside" is the FRONT of its normal):
|
|
834
|
+
* - closed × closed — full volumetric boolean.
|
|
835
|
+
* - sheet × solid — `subtract` keeps the sheet's pieces OUTSIDE the solid,
|
|
836
|
+
* `intersect` the pieces INSIDE (open trimmed sheets).
|
|
837
|
+
* - solid × sheet — `subtract` keeps the capped half of the solid BEHIND
|
|
838
|
+
* the sheet normal, `intersect` the FRONT half (closed solids).
|
|
839
|
+
* - sheet × sheet — a sheet's material is its FRONT half-space, so
|
|
840
|
+
* `union` = ∂(matA ∪ matB): this sheet's BACK-of-other pieces joined
|
|
841
|
+
* with the other's BACK-of-this pieces into ONE open Brep stitched at
|
|
842
|
+
* the shared exact intersection edges (pieces in FRONT of the other
|
|
843
|
+
* sheet are interior to the union material and are dropped; faces the
|
|
844
|
+
* other operand never cuts are kept whole, coincident overlaps keep
|
|
845
|
+
* this sheet's copy); `subtract` keeps this sheet's BACK pieces;
|
|
846
|
+
* `intersect` its FRONT pieces.
|
|
847
|
+
* - `union` of a solid and a sheet (either order) is NOT defined and
|
|
848
|
+
* throws — trim the sheet with subtract/intersect instead.
|
|
849
|
+
*
|
|
850
|
+
* A Mesh operand is converted via {@link Brep.fromMesh} (planar-faceted
|
|
851
|
+
* meshes only); if conversion fails, use the tessellated
|
|
852
|
+
* union()/subtract()/intersect() instead.
|
|
795
853
|
*
|
|
796
854
|
* `options.tolerance` is the absolute geometric tolerance of intersection
|
|
797
855
|
* edges and coincident-face classification (default 1e-6).
|
|
@@ -800,17 +858,27 @@ export class Brep {
|
|
|
800
858
|
* cylinders touching along a line/point) is not resolved into pinch
|
|
801
859
|
* topology; transversal and coincident (coplanar) configurations are exact.
|
|
802
860
|
*/
|
|
803
|
-
unionBrep(other: Brep, options?: BrepParametricBooleanOptions): Brep {
|
|
861
|
+
unionBrep(other: Brep | Mesh, options?: BrepParametricBooleanOptions): Brep {
|
|
804
862
|
return this.runParametricBoolean(other, "union", options);
|
|
805
863
|
}
|
|
806
864
|
|
|
807
|
-
/**
|
|
808
|
-
|
|
865
|
+
/**
|
|
866
|
+
* PARAMETRIC boolean subtraction (this − other). See {@link unionBrep} for
|
|
867
|
+
* the full open/closed dispatch table: sheet − solid trims the sheet to
|
|
868
|
+
* the OUTSIDE of the solid; solid − sheet keeps the capped half BEHIND the
|
|
869
|
+
* sheet normal; sheet − sheet keeps this sheet's BACK pieces.
|
|
870
|
+
*/
|
|
871
|
+
subtractBrep(other: Brep | Mesh, options?: BrepParametricBooleanOptions): Brep {
|
|
809
872
|
return this.runParametricBoolean(other, "subtract", options);
|
|
810
873
|
}
|
|
811
874
|
|
|
812
|
-
/**
|
|
813
|
-
|
|
875
|
+
/**
|
|
876
|
+
* PARAMETRIC boolean intersection. See {@link unionBrep} for the full
|
|
877
|
+
* open/closed dispatch table: sheet ∩ solid trims the sheet to the INSIDE
|
|
878
|
+
* of the solid; solid ∩ sheet keeps the capped half in FRONT of the sheet
|
|
879
|
+
* normal; sheet ∩ sheet keeps this sheet's FRONT pieces.
|
|
880
|
+
*/
|
|
881
|
+
intersectBrep(other: Brep | Mesh, options?: BrepParametricBooleanOptions): Brep {
|
|
814
882
|
return this.runParametricBoolean(other, "intersect", options);
|
|
815
883
|
}
|
|
816
884
|
|
|
@@ -903,6 +971,60 @@ export class Brep {
|
|
|
903
971
|
return { negative: side(parsed.negative), positive: side(parsed.positive) };
|
|
904
972
|
}
|
|
905
973
|
|
|
974
|
+
/**
|
|
975
|
+
* PARAMETRIC split of this OPEN sheet by a CLOSED solid: the sheet's faces
|
|
976
|
+
* are imprinted with the exact intersection curves and every face piece is
|
|
977
|
+
* classified by containment in the solid. `inside` = the pieces contained
|
|
978
|
+
* in the solid (ON-boundary pieces count as inside), `outside` = the rest.
|
|
979
|
+
* Both sides are open Breps preserving the sheet's exact trimmed faces,
|
|
980
|
+
* pcurves and edges.
|
|
981
|
+
*
|
|
982
|
+
* The counterpart of {@link splitBySheet} with the roles swapped: use that
|
|
983
|
+
* one to split a closed solid BY a sheet (capped halves); use this one to
|
|
984
|
+
* split a sheet BY a solid (trimmed sheet pieces).
|
|
985
|
+
*/
|
|
986
|
+
splitSheetBySolid(
|
|
987
|
+
solid: Brep,
|
|
988
|
+
options?: BrepParametricBooleanOptions,
|
|
989
|
+
): BrepSheetSplitResult {
|
|
990
|
+
ensureInit();
|
|
991
|
+
const tolerance = options?.tolerance ?? 1e-6;
|
|
992
|
+
const json = wasm.brep_split_sheet_by_solid_op(this.json, solid.json, tolerance);
|
|
993
|
+
return Brep.parseSheetSplitResult(json, "Brep.splitSheetBySolid");
|
|
994
|
+
}
|
|
995
|
+
|
|
996
|
+
/**
|
|
997
|
+
* PARAMETRIC split of this OPEN sheet by another OPEN sheet (a sheet Brep
|
|
998
|
+
* or a NurbsSurface, converted via {@link Brep.fromSurface}): the mutual
|
|
999
|
+
* exact intersection curves are imprinted onto this sheet's faces and each
|
|
1000
|
+
* piece is assigned to the FRONT (`inside`) or BACK (`outside`) of the
|
|
1001
|
+
* other sheet's oriented normal — the same seam-vote classification as
|
|
1002
|
+
* {@link splitBySheet}. Faces the cutter never crosses classify wholesale
|
|
1003
|
+
* by their side of the cutter; coincident-overlap pieces land in `inside`.
|
|
1004
|
+
*/
|
|
1005
|
+
splitSheetBySheet(
|
|
1006
|
+
other: Brep | NurbsSurface,
|
|
1007
|
+
options?: BrepParametricBooleanOptions,
|
|
1008
|
+
): BrepSheetSplitResult {
|
|
1009
|
+
ensureInit();
|
|
1010
|
+
const cutter = other instanceof Brep ? other : Brep.fromSurface(other);
|
|
1011
|
+
const tolerance = options?.tolerance ?? 1e-6;
|
|
1012
|
+
const json = wasm.brep_split_sheet_by_sheet_op(this.json, cutter.json, tolerance);
|
|
1013
|
+
return Brep.parseSheetSplitResult(json, "Brep.splitSheetBySheet");
|
|
1014
|
+
}
|
|
1015
|
+
|
|
1016
|
+
private static parseSheetSplitResult(json: string, label: string): BrepSheetSplitResult {
|
|
1017
|
+
if (!json) throw new Error(`${label} failed`);
|
|
1018
|
+
if (json.startsWith('{"error"')) {
|
|
1019
|
+
const parsed = JSON.parse(json) as { error: string };
|
|
1020
|
+
throw new Error(`${label} failed: ${parsed.error}`);
|
|
1021
|
+
}
|
|
1022
|
+
const parsed = JSON.parse(json) as { inside: unknown; outside: unknown };
|
|
1023
|
+
const side = (v: unknown): Brep | null =>
|
|
1024
|
+
v == null ? null : new Brep(JSON.stringify(v));
|
|
1025
|
+
return { inside: side(parsed.inside), outside: side(parsed.outside) };
|
|
1026
|
+
}
|
|
1027
|
+
|
|
906
1028
|
/** JSON representation (persistence). */
|
|
907
1029
|
toJson(): string {
|
|
908
1030
|
return this.json;
|