diff --git a/packages/chili-core/src/shape/curve.ts b/packages/chili-core/src/shape/curve.ts index 04f02fc3..fef36bec 100644 --- a/packages/chili-core/src/shape/curve.ts +++ b/packages/chili-core/src/shape/curve.ts @@ -1,22 +1,37 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. -import { Plane, XYZ } from "../math"; +import { Plane, Ray, XYZ } from "../math"; import { CurveType } from "./shape"; +export enum Continuity { + C0, + G1, + C1, + G2, + C2, + C3, + CN, +} + export interface ICurve { get curveType(): CurveType; parameter(point: XYZ): number; firstParameter(): number; lastParameter(): number; - point(parameter: number): XYZ; project(point: XYZ): XYZ[]; + value(parameter: number): XYZ; isCN(n: number): boolean; d0(u: number): XYZ; d1(u: number): { point: XYZ; vec: XYZ }; d2(u: number): { point: XYZ; vec1: XYZ; vec2: XYZ }; d3(u: number): { point: XYZ; vec1: XYZ; vec2: XYZ; vec3: XYZ }; dn(u: number, n: number): XYZ; + reversed(): ICurve; nearestPoint(point: XYZ): XYZ; + isClosed(): boolean; + period(): number; + isPeriodic(): boolean; + continutity(): Continuity; } export interface ILine extends ICurve { @@ -24,7 +39,10 @@ export interface ILine extends ICurve { } export interface IConic extends ICurve { - plane: Plane; + axis: XYZ; + xAxis: XYZ; + yAxis: XYZ; + eccentricity(): number; } export interface ICircle extends IConic { @@ -32,6 +50,30 @@ export interface ICircle extends IConic { radius: number; } +export interface IEllipse extends IConic { + area(): number; + center: XYZ; + get focus1(): XYZ; + get focus2(): XYZ; + majorRadius: number; + minorRadius: number; +} + +export interface IHyperbola extends IConic { + focal(): number; + location: XYZ; + get focus1(): XYZ; + get focus2(): XYZ; + majorRadius: number; + minorRadius: number; +} + +export interface IParabola extends IConic { + focal(): number; + get focus(): XYZ; + get directrix(): XYZ; +} + export interface IBoundedCurve extends ICurve { startPoint(): XYZ; endPoint(): XYZ; @@ -50,6 +92,18 @@ export interface IBezierCurve extends IBoundedCurve { poles(): XYZ[]; } +export interface IBSplineCurve extends IBoundedCurve { + degree(): number; + nbKnots(): number; + knot(index: number): number; + setKnot(index: number, value: number): void; + nbPoles(): number; + pole(index: number): XYZ; + poles(): XYZ[]; + weight(index: number): number; + setWeight(index: number, value: number): void; +} + export interface ITrimmedCurve extends IBoundedCurve { basisCurve(): ICurve; } @@ -60,10 +114,15 @@ export interface IOffsetCurve extends ICurve { direction(): XYZ; } +export interface IComplexCurve { + nbCurves(): number; + curve(index: number): ICurve; +} + export namespace ICurve { export function isConic(curve: ICurve): curve is IConic { let conic = curve as IConic; - return conic.plane !== undefined; + return conic.axis !== undefined; } export function isCircle(curve: ICurve): curve is ICircle { diff --git a/packages/chili-core/src/shape/shape.ts b/packages/chili-core/src/shape/shape.ts index 8f3e5aef..553eb84b 100644 --- a/packages/chili-core/src/shape/shape.ts +++ b/packages/chili-core/src/shape/shape.ts @@ -1,7 +1,7 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. import { Result } from "../foundation"; -import { Matrix4, Ray, XYZ } from "../math"; +import { Matrix4, Plane, Ray, XYZ } from "../math"; import { ITrimmedCurve } from "./curve"; import { IShapeMeshData } from "./meshData"; import { ShapeType } from "./shapeType"; @@ -61,6 +61,10 @@ export interface IShape { findAncestor(ancestorType: ShapeType, fromShape: IShape): IShape[]; findSubShapes(subshapeType: ShapeType): IShape[]; iterSubShapes(shapeType: ShapeType, unique: boolean): IterableIterator; + section(shape: IShape | Plane): IShape; + split(edges: (IEdge | IWire)[]): IShape; + splitWithFace(onFace: IFace, edges: IEdge | IWire): IShape; + splitWithEdge(onEdge: IEdge, edge: IEdge): IShape; } export interface IVertex extends IShape {} diff --git a/packages/chili-geo/src/utils.ts b/packages/chili-geo/src/utils.ts index 9f0de3d0..31179a85 100644 --- a/packages/chili-geo/src/utils.ts +++ b/packages/chili-geo/src/utils.ts @@ -19,7 +19,7 @@ export class GeoUtils { private static curveNormal = (curve: ICurve) => { if (ICurve.isConic(curve)) { - return curve.plane.normal; + return curve.axis; } let vec = curve.dn(0, 1); if (vec.isParallelTo(XYZ.unitX)) return XYZ.unitZ; @@ -42,13 +42,13 @@ export class GeoUtils { static findNextEdge(wire: IWire, edge: IEdge): Result { let curve = edge.asCurve(); - let point = curve.point(curve.lastParameter()); + let point = curve.value(curve.lastParameter()); for (const e of wire.iterSubShapes(ShapeType.Edge, true)) { if (e.isEqual(edge)) continue; let testCurve = (e as IEdge).asCurve(); if ( - point.distanceTo(testCurve.point(testCurve.firstParameter())) < Precision.Distance || - point.distanceTo(testCurve.point(testCurve.lastParameter())) < Precision.Distance + point.distanceTo(testCurve.value(testCurve.firstParameter())) < Precision.Distance || + point.distanceTo(testCurve.value(testCurve.lastParameter())) < Precision.Distance ) { return Result.ok(e as IEdge); } diff --git a/packages/chili-occ/occ-wasm/build_config.yml b/packages/chili-occ/occ-wasm/build_config.yml index 6ee6e3e6..a87e9354 100644 --- a/packages/chili-occ/occ-wasm/build_config.yml +++ b/packages/chili-occ/occ-wasm/build_config.yml @@ -74,6 +74,7 @@ mainBuild: - symbol: BRepPrimAPI_MakeTorus - symbol: BRepTools - symbol: BRepTools_ReShape + - symbol: BRepTools_Quilt - symbol: ChFi3d_FilletShape - symbol: ChFiDS_ChamfMode - symbol: Convert_ParameterisationType @@ -94,6 +95,9 @@ mainBuild: - symbol: Geom_Conic - symbol: Geom_CylindricalSurface - symbol: Geom_ElementarySurface + - symbol: Geom_Ellipse + - symbol: Geom_Hyperbola + - symbol: Geom_Parabola - symbol: GeomFill_Trihedron - symbol: Geom_Geometry - symbol: Geom_Line @@ -160,6 +164,7 @@ mainBuild: - symbol: MoniTool_TypedValue - symbol: NCollection_BaseList - symbol: NCollection_BaseMap + - symbol: NCollection_BaseSequence - symbol: Poly_Array1OfTriangle - symbol: Poly_Connect - symbol: Poly_PolygonOnTriangulation @@ -209,6 +214,7 @@ mainBuild: - symbol: TopoDS_Vertex - symbol: TopoDS_Wire - symbol: TopTools_ListOfShape + - symbol: TopTools_SequenceOfShape - symbol: TopTools_IndexedMapOfShape - symbol: TopTools_IndexedDataMapOfShapeListOfShape - symbol: XSControl_Reader diff --git a/packages/chili-occ/occ-wasm/chili_occ.d.ts b/packages/chili-occ/occ-wasm/chili_occ.d.ts index 9e835aad..e6292020 100644 --- a/packages/chili-occ/occ-wasm/chili_occ.d.ts +++ b/packages/chili-occ/occ-wasm/chili_occ.d.ts @@ -2077,6 +2077,17 @@ export declare class BRepTools { delete(): void; } +export declare class BRepTools_Quilt { + constructor() + Bind_1(Eold: TopoDS_Edge, Enew: TopoDS_Edge): void; + Bind_2(Vold: TopoDS_Vertex, Vnew: TopoDS_Vertex): void; + Add(S: TopoDS_Shape): void; + IsCopied(S: TopoDS_Shape): Standard_Boolean; + Copy(S: TopoDS_Shape): TopoDS_Shape; + Shells(): TopoDS_Shape; + delete(): void; +} + export declare class BRepTools_ReShape extends Standard_Transient { constructor() Clear(): void; @@ -2989,6 +3000,47 @@ export declare class Geom_ElementarySurface extends Geom_Surface { delete(): void; } +export declare class Geom_Ellipse extends Geom_Conic { + SetElips(E: gp_Elips): void; + SetMajorRadius(MajorRadius: Standard_Real): void; + SetMinorRadius(MinorRadius: Standard_Real): void; + Elips(): gp_Elips; + ReversedParameter(U: Standard_Real): Standard_Real; + Directrix1(): gp_Ax1; + Directrix2(): gp_Ax1; + Eccentricity(): Standard_Real; + Focal(): Standard_Real; + Focus1(): gp_Pnt; + Focus2(): gp_Pnt; + MajorRadius(): Standard_Real; + MinorRadius(): Standard_Real; + Parameter(): Standard_Real; + FirstParameter(): Standard_Real; + LastParameter(): Standard_Real; + IsClosed(): Standard_Boolean; + IsPeriodic(): Standard_Boolean; + D0(U: Standard_Real, P: gp_Pnt): void; + D1(U: Standard_Real, P: gp_Pnt, V1: gp_Vec): void; + D2(U: Standard_Real, P: gp_Pnt, V1: gp_Vec, V2: gp_Vec): void; + D3(U: Standard_Real, P: gp_Pnt, V1: gp_Vec, V2: gp_Vec, V3: gp_Vec): void; + DN(U: Standard_Real, N: Graphic3d_ZLayerId): gp_Vec; + Transform(T: gp_Trsf): void; + Copy(): Handle_Geom_Geometry; + DumpJson(theOStream: Standard_OStream, theDepth: Graphic3d_ZLayerId): void; + static get_type_name(): Standard_Character; + static get_type_descriptor(): Handle_Standard_Type; + DynamicType(): Handle_Standard_Type; + delete(): void; +} + + export declare class Geom_Ellipse_1 extends Geom_Ellipse { + constructor(E: gp_Elips); + } + + export declare class Geom_Ellipse_2 extends Geom_Ellipse { + constructor(A2: gp_Ax2, MajorRadius: Standard_Real, MinorRadius: Standard_Real); + } + export declare class Geom_Geometry extends Standard_Transient { Mirror_1(P: gp_Pnt): void; Mirror_2(A1: gp_Ax1): void; @@ -3014,6 +3066,52 @@ export declare class Geom_Geometry extends Standard_Transient { delete(): void; } +export declare class Geom_Hyperbola extends Geom_Conic { + SetHypr(H: gp_Hypr): void; + SetMajorRadius(MajorRadius: Standard_Real): void; + SetMinorRadius(MinorRadius: Standard_Real): void; + Hypr(): gp_Hypr; + ReversedParameter(U: Standard_Real): Standard_Real; + FirstParameter(): Standard_Real; + LastParameter(): Standard_Real; + IsClosed(): Standard_Boolean; + IsPeriodic(): Standard_Boolean; + Asymptote1(): gp_Ax1; + Asymptote2(): gp_Ax1; + ConjugateBranch1(): gp_Hypr; + ConjugateBranch2(): gp_Hypr; + Directrix1(): gp_Ax1; + Directrix2(): gp_Ax1; + Eccentricity(): Standard_Real; + Focal(): Standard_Real; + Focus1(): gp_Pnt; + Focus2(): gp_Pnt; + MajorRadius(): Standard_Real; + MinorRadius(): Standard_Real; + OtherBranch(): gp_Hypr; + Parameter(): Standard_Real; + D0(U: Standard_Real, P: gp_Pnt): void; + D1(U: Standard_Real, P: gp_Pnt, V1: gp_Vec): void; + D2(U: Standard_Real, P: gp_Pnt, V1: gp_Vec, V2: gp_Vec): void; + D3(U: Standard_Real, P: gp_Pnt, V1: gp_Vec, V2: gp_Vec, V3: gp_Vec): void; + DN(U: Standard_Real, N: Graphic3d_ZLayerId): gp_Vec; + Transform(T: gp_Trsf): void; + Copy(): Handle_Geom_Geometry; + DumpJson(theOStream: Standard_OStream, theDepth: Graphic3d_ZLayerId): void; + static get_type_name(): Standard_Character; + static get_type_descriptor(): Handle_Standard_Type; + DynamicType(): Handle_Standard_Type; + delete(): void; +} + + export declare class Geom_Hyperbola_1 extends Geom_Hyperbola { + constructor(H: gp_Hypr); + } + + export declare class Geom_Hyperbola_2 extends Geom_Hyperbola { + constructor(A2: gp_Ax2, MajorRadius: Standard_Real, MinorRadius: Standard_Real); + } + export declare class Geom_Line extends Geom_Curve { SetLin(L: gp_Lin): void; SetDirection(V: gp_Dir): void; @@ -3158,6 +3256,48 @@ export declare class Geom_OffsetSurface extends Geom_Surface { delete(): void; } +export declare class Geom_Parabola extends Geom_Conic { + SetFocal(Focal: Standard_Real): void; + SetParab(Prb: gp_Parab): void; + Parab(): gp_Parab; + ReversedParameter(U: Standard_Real): Standard_Real; + FirstParameter(): Standard_Real; + LastParameter(): Standard_Real; + IsClosed(): Standard_Boolean; + IsPeriodic(): Standard_Boolean; + Directrix(): gp_Ax1; + Eccentricity(): Standard_Real; + Focus(): gp_Pnt; + Focal(): Standard_Real; + Parameter(): Standard_Real; + D0(U: Standard_Real, P: gp_Pnt): void; + D1(U: Standard_Real, P: gp_Pnt, V1: gp_Vec): void; + D2(U: Standard_Real, P: gp_Pnt, V1: gp_Vec, V2: gp_Vec): void; + D3(U: Standard_Real, P: gp_Pnt, V1: gp_Vec, V2: gp_Vec, V3: gp_Vec): void; + DN(U: Standard_Real, N: Graphic3d_ZLayerId): gp_Vec; + Transform(T: gp_Trsf): void; + TransformedParameter(U: Standard_Real, T: gp_Trsf): Standard_Real; + ParametricTransformation(T: gp_Trsf): Standard_Real; + Copy(): Handle_Geom_Geometry; + DumpJson(theOStream: Standard_OStream, theDepth: Graphic3d_ZLayerId): void; + static get_type_name(): Standard_Character; + static get_type_descriptor(): Handle_Standard_Type; + DynamicType(): Handle_Standard_Type; + delete(): void; +} + + export declare class Geom_Parabola_1 extends Geom_Parabola { + constructor(Prb: gp_Parab); + } + + export declare class Geom_Parabola_2 extends Geom_Parabola { + constructor(A2: gp_Ax2, Focal: Standard_Real); + } + + export declare class Geom_Parabola_3 extends Geom_Parabola { + constructor(D: gp_Ax1, F: gp_Pnt); + } + export declare class Geom_Surface extends Geom_Geometry { UReverse(): void; UReversed(): Handle_Geom_Surface; @@ -3843,6 +3983,13 @@ export declare class NCollection_BaseMap { delete(): void; } +export declare class NCollection_BaseSequence { + IsEmpty(): Standard_Boolean; + Length(): Graphic3d_ZLayerId; + Allocator(): Handle_NCollection_BaseAllocator; + delete(): void; +} + export declare class Poly_Array1OfTriangle { begin(): any; end(): any; @@ -5112,6 +5259,54 @@ export declare class TopTools_ListOfShape extends NCollection_BaseList { constructor(theOther: TopTools_ListOfShape); } +export declare class TopTools_SequenceOfShape extends NCollection_BaseSequence { + begin(): any; + end(): any; + cbegin(): any; + cend(): any; + Size(): Standard_Integer; + Length(): Standard_Integer; + Lower(): Standard_Integer; + Upper(): Standard_Integer; + IsEmpty(): Standard_Boolean; + Reverse(): void; + Exchange(I: Standard_Integer, J: Standard_Integer): void; + static delNode(theNode: NCollection_SeqNode, theAl: Handle_NCollection_BaseAllocator): void; + Clear(theAllocator: Handle_NCollection_BaseAllocator): void; + Assign(theOther: TopTools_SequenceOfShape): TopTools_SequenceOfShape; + Remove_2(theIndex: Standard_Integer): void; + Remove_3(theFromIndex: Standard_Integer, theToIndex: Standard_Integer): void; + Append_1(theItem: TopoDS_Shape): void; + Append_2(theSeq: TopTools_SequenceOfShape): void; + Prepend_1(theItem: TopoDS_Shape): void; + Prepend_2(theSeq: TopTools_SequenceOfShape): void; + InsertBefore_1(theIndex: Standard_Integer, theItem: TopoDS_Shape): void; + InsertBefore_2(theIndex: Standard_Integer, theSeq: TopTools_SequenceOfShape): void; + InsertAfter_2(theIndex: Standard_Integer, theSeq: TopTools_SequenceOfShape): void; + InsertAfter_3(theIndex: Standard_Integer, theItem: TopoDS_Shape): void; + Split(theIndex: Standard_Integer, theSeq: TopTools_SequenceOfShape): void; + First(): TopoDS_Shape; + ChangeFirst(): TopoDS_Shape; + Last(): TopoDS_Shape; + ChangeLast(): TopoDS_Shape; + Value(theIndex: Standard_Integer): TopoDS_Shape; + ChangeValue(theIndex: Standard_Integer): TopoDS_Shape; + SetValue(theIndex: Standard_Integer, theItem: TopoDS_Shape): void; + delete(): void; +} + + export declare class TopTools_SequenceOfShape_1 extends TopTools_SequenceOfShape { + constructor(); + } + + export declare class TopTools_SequenceOfShape_2 extends TopTools_SequenceOfShape { + constructor(theAllocator: Handle_NCollection_BaseAllocator); + } + + export declare class TopTools_SequenceOfShape_3 extends TopTools_SequenceOfShape { + constructor(theOther: TopTools_SequenceOfShape); + } + export declare class TopoDS { constructor(); static Vertex_1(S: TopoDS_Shape): TopoDS_Vertex; @@ -6691,6 +6886,7 @@ export type OpenCascadeInstance = {FS: typeof FS} & { BRepPrimAPI_MakeTorus_7: typeof BRepPrimAPI_MakeTorus_7; BRepPrimAPI_MakeTorus_8: typeof BRepPrimAPI_MakeTorus_8; BRepTools: typeof BRepTools; + BRepTools_Quilt: typeof BRepTools_Quilt; BRepTools_ReShape: typeof BRepTools_ReShape; Bnd_Box: typeof Bnd_Box; Bnd_Box_1: typeof Bnd_Box_1; @@ -6786,7 +6982,13 @@ export type OpenCascadeInstance = {FS: typeof FS} & { Geom_CylindricalSurface_1: typeof Geom_CylindricalSurface_1; Geom_CylindricalSurface_2: typeof Geom_CylindricalSurface_2; Geom_ElementarySurface: typeof Geom_ElementarySurface; + Geom_Ellipse: typeof Geom_Ellipse; + Geom_Ellipse_1: typeof Geom_Ellipse_1; + Geom_Ellipse_2: typeof Geom_Ellipse_2; Geom_Geometry: typeof Geom_Geometry; + Geom_Hyperbola: typeof Geom_Hyperbola; + Geom_Hyperbola_1: typeof Geom_Hyperbola_1; + Geom_Hyperbola_2: typeof Geom_Hyperbola_2; Geom_Line: typeof Geom_Line; Geom_Line_1: typeof Geom_Line_1; Geom_Line_2: typeof Geom_Line_2; @@ -6798,6 +7000,10 @@ export type OpenCascadeInstance = {FS: typeof FS} & { Handle_Geom_Line_4: typeof Handle_Geom_Line_4; Geom_OffsetCurve: typeof Geom_OffsetCurve; Geom_OffsetSurface: typeof Geom_OffsetSurface; + Geom_Parabola: typeof Geom_Parabola; + Geom_Parabola_1: typeof Geom_Parabola_1; + Geom_Parabola_2: typeof Geom_Parabola_2; + Geom_Parabola_3: typeof Geom_Parabola_3; Geom_Surface: typeof Geom_Surface; Handle_Geom_Surface: typeof Handle_Geom_Surface; Handle_Geom_Surface_1: typeof Handle_Geom_Surface_1; @@ -6877,6 +7083,7 @@ export type OpenCascadeInstance = {FS: typeof FS} & { MoniTool_TypedValue_2: typeof MoniTool_TypedValue_2; NCollection_BaseList: typeof NCollection_BaseList; NCollection_BaseMap: typeof NCollection_BaseMap; + NCollection_BaseSequence: typeof NCollection_BaseSequence; Poly_Array1OfTriangle: typeof Poly_Array1OfTriangle; Poly_Array1OfTriangle_1: typeof Poly_Array1OfTriangle_1; Poly_Array1OfTriangle_2: typeof Poly_Array1OfTriangle_2; @@ -7014,6 +7221,10 @@ export type OpenCascadeInstance = {FS: typeof FS} & { TopTools_ListOfShape_1: typeof TopTools_ListOfShape_1; TopTools_ListOfShape_2: typeof TopTools_ListOfShape_2; TopTools_ListOfShape_3: typeof TopTools_ListOfShape_3; + TopTools_SequenceOfShape: typeof TopTools_SequenceOfShape; + TopTools_SequenceOfShape_1: typeof TopTools_SequenceOfShape_1; + TopTools_SequenceOfShape_2: typeof TopTools_SequenceOfShape_2; + TopTools_SequenceOfShape_3: typeof TopTools_SequenceOfShape_3; TopoDS: typeof TopoDS; TopoDS_Builder: typeof TopoDS_Builder; TopoDS_CompSolid: typeof TopoDS_CompSolid; diff --git a/packages/chili-occ/occ-wasm/chili_occ.wasm b/packages/chili-occ/occ-wasm/chili_occ.wasm index 05470350..51481f9c 100755 Binary files a/packages/chili-occ/occ-wasm/chili_occ.wasm and b/packages/chili-occ/occ-wasm/chili_occ.wasm differ diff --git a/packages/chili-occ/src/occGeometry.ts b/packages/chili-occ/src/occGeometry.ts index d996754c..e5237de7 100644 --- a/packages/chili-occ/src/occGeometry.ts +++ b/packages/chili-occ/src/occGeometry.ts @@ -1,29 +1,39 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. import { + Continuity, CurveType, + IBSplineCurve, IBezierCurve, IBoundedCurve, ICircle, + IConic, ICurve, IDisposable, + IEllipse, + IHyperbola, ILine, IOffsetCurve, + IParabola, ITrimmedCurve, - Plane, XYZ, } from "chili-core"; import { + Geom_BSplineCurve, Geom_BezierCurve, Geom_BoundedCurve, Geom_Circle, + Geom_Conic, Geom_Curve, + Geom_Hyperbola, Geom_Line, Geom_OffsetCurve, + Geom_Parabola, Geom_TrimmedCurve, } from "../occ-wasm/chili_occ"; import { OccHelps } from "./occHelps"; +import { Geom_Ellipse } from "opencascade.js/dist/opencascade.full"; export class OccCurve implements ICurve, IDisposable { readonly curveType: CurveType; @@ -32,14 +42,52 @@ export class OccCurve implements ICurve, IDisposable { this.curveType = OccHelps.getCurveType(curve); } + reversed(): ICurve { + return OccHelps.wrapCurve(this.curve.Reversed().get()); + } + + isClosed(): boolean { + return this.curve.IsClosed(); + } + + period(): number { + return this.curve.Period(); + } + + isPeriodic(): boolean { + return this.curve.IsPeriodic(); + } + + continutity(): Continuity { + let cni = this.curve.Continuity(); + switch (cni) { + case occ.GeomAbs_Shape.GeomAbs_C0: + return Continuity.C0; + case occ.GeomAbs_Shape.GeomAbs_G1: + return Continuity.G1; + case occ.GeomAbs_Shape.GeomAbs_C1: + return Continuity.C1; + case occ.GeomAbs_Shape.GeomAbs_G2: + return Continuity.G2; + case occ.GeomAbs_Shape.GeomAbs_C2: + return Continuity.C2; + case occ.GeomAbs_Shape.GeomAbs_C3: + return Continuity.C3; + case occ.GeomAbs_Shape.GeomAbs_CN: + return Continuity.CN; + default: + throw new Error("unknown continuity"); + } + } + nearestPoint(point: XYZ): XYZ { let api = new occ.GeomAPI_ProjectPointOnCurve_2( OccHelps.toPnt(point), new occ.Handle_Geom_Curve_2(this.curve), ); if (api.NbPoints() == 0) { - let start = this.point(this.curve.FirstParameter()); - let end = this.point(this.curve.LastParameter()); + let start = this.value(this.curve.FirstParameter()); + let end = this.value(this.curve.LastParameter()); let distStart = point.distanceTo(start); let distEnd = point.distanceTo(end); return distStart < distEnd ? start : end; @@ -49,7 +97,7 @@ export class OccCurve implements ICurve, IDisposable { return OccHelps.toXYZ(pnt); } - point(parameter: number): XYZ { + value(parameter: number): XYZ { let p = this.curve.Value(parameter); return OccHelps.toXYZ(p); } @@ -166,14 +214,25 @@ export class OccLine extends OccCurve implements ILine { } } -export class OccCircle extends OccCurve implements ICircle { - get plane(): Plane { - return OccHelps.fromAx2(this.circle.Position()); +export class OccConic extends OccCurve implements IConic { + constructor(private conion: Geom_Conic) { + super(conion); } - set plane(value: Plane) { - this.circle.SetPosition(OccHelps.toAx2(value)); + get axis(): XYZ { + return OccHelps.toXYZ(this.conion.Axis().Direction()); } + get xAxis(): XYZ { + return OccHelps.toXYZ(this.conion.XAxis().Direction()); + } + get yAxis(): XYZ { + return OccHelps.toXYZ(this.conion.YAxis().Direction()); + } + eccentricity(): number { + return this.conion.Eccentricity(); + } +} +export class OccCircle extends OccConic implements ICircle { constructor(private circle: Geom_Circle) { super(circle); } @@ -195,6 +254,96 @@ export class OccCircle extends OccCurve implements ICircle { } } +export class OccEllipse extends OccConic implements IEllipse { + constructor(private ellipse: Geom_Ellipse) { + super(ellipse); + } + + get center(): XYZ { + return OccHelps.toXYZ(this.ellipse.Location()); + } + set center(value: XYZ) { + this.ellipse.SetLocation(OccHelps.toPnt(value)); + } + + get focus1(): XYZ { + return OccHelps.toXYZ(this.ellipse.Focus1()); + } + get focus2(): XYZ { + return OccHelps.toXYZ(this.ellipse.Focus2()); + } + + get majorRadius(): number { + return this.ellipse.MajorRadius(); + } + set majorRadius(value: number) { + this.ellipse.SetMajorRadius(value); + } + + get minorRadius(): number { + return this.ellipse.MinorRadius(); + } + set minorRadius(value: number) { + this.ellipse.SetMinorRadius(value); + } + + area(): number { + return this.ellipse.Elips().Area(); + } +} + +export class OccHyperbola extends OccConic implements IHyperbola { + constructor(private hyperbola: Geom_Hyperbola) { + super(hyperbola); + } + focal(): number { + return this.hyperbola.Focal(); + } + get location(): XYZ { + return OccHelps.toXYZ(this.hyperbola.Location()); + } + set location(value: XYZ) { + this.hyperbola.SetLocation(OccHelps.toPnt(value)); + } + + get focus1(): XYZ { + return OccHelps.toXYZ(this.hyperbola.Focus1()); + } + get focus2(): XYZ { + return OccHelps.toXYZ(this.hyperbola.Focus2()); + } + get majorRadius(): number { + return this.hyperbola.MajorRadius(); + } + set majorRadius(value: number) { + this.hyperbola.SetMajorRadius(value); + } + + get minorRadius(): number { + return this.hyperbola.MinorRadius(); + } + set minorRadius(value: number) { + this.hyperbola.SetMinorRadius(value); + } +} + +export class OccParabola extends OccConic implements IParabola { + constructor(private parabola: Geom_Parabola) { + super(parabola); + } + focal(): number { + return this.parabola.Focal(); + } + + get focus(): XYZ { + return OccHelps.toXYZ(this.parabola.Focus()); + } + + get directrix() { + return OccHelps.toXYZ(this.parabola.Directrix().Direction()); + } +} + export class OccBoundedCurve extends OccCurve implements IBoundedCurve { constructor(private boundedCurve: Geom_BoundedCurve) { super(boundedCurve); @@ -299,3 +448,42 @@ export class OccBezierCurve extends OccBoundedCurve implements IBezierCurve { return result; } } + +export class OccBSplineCurve extends OccBoundedCurve implements IBSplineCurve { + constructor(private bspline: Geom_BSplineCurve) { + super(bspline); + } + nbKnots(): number { + return this.bspline.NbKnots(); + } + knot(index: number): number { + return this.bspline.Knot(index); + } + setKnot(index: number, value: number): void { + this.bspline.SetKnot_1(index, value); + } + nbPoles(): number { + return this.bspline.NbPoles(); + } + pole(index: number): XYZ { + return OccHelps.toXYZ(this.bspline.Pole(index)); + } + poles(): XYZ[] { + let result: XYZ[] = []; + let pls = this.bspline.Poles_2(); + for (let i = 1; i <= pls.Length(); i++) { + result.push(OccHelps.toXYZ(pls.Value(i))); + } + return result; + } + weight(index: number): number { + return this.bspline.Weight(index); + } + setWeight(index: number, value: number): void { + this.bspline.SetWeight(index, value); + } + + degree(): number { + return this.bspline.Degree(); + } +} diff --git a/packages/chili-occ/src/occHelps.ts b/packages/chili-occ/src/occHelps.ts index 12320fdf..46805202 100644 --- a/packages/chili-occ/src/occHelps.ts +++ b/packages/chili-occ/src/occHelps.ts @@ -14,13 +14,18 @@ import { } from "chili-core"; import { GeomAbs_JoinType, + Geom_BSplineCurve, Geom_BezierCurve, Geom_Circle, Geom_Curve, + Geom_Ellipse, + Geom_Hyperbola, Geom_Line, Geom_OffsetCurve, + Geom_Parabola, Geom_TrimmedCurve, TopAbs_ShapeEnum, + TopTools_ListOfShape, TopoDS_Shape, gp_Ax2, gp_Ax3, @@ -42,7 +47,17 @@ import { OccVertex, OccWire, } from "./occShape"; -import { OccBezierCurve, OccCircle, OccLine, OccOffsetCurve, OccTrimmedCurve } from "./occGeometry"; +import { + OccBSplineCurve, + OccBezierCurve, + OccCircle, + OccEllipse, + OccHyperbola, + OccLine, + OccOffsetCurve, + OccParabola, + OccTrimmedCurve, +} from "./occGeometry"; export class OccHelps { static toXYZ(p: gp_Pnt | gp_Dir | gp_Vec): XYZ { @@ -253,15 +268,15 @@ export class OccHelps { let isType = (type: string) => curve.IsInstance_2(type); if (isType("Geom_Line")) return new OccLine(curve as Geom_Line); else if (isType("Geom_Circle")) return new OccCircle(curve as Geom_Circle); - // else if (isType("Geom_Ellipse")) return new OccLine(curve as Geom_Line); - // else if (isType("Geom_Hyperbola")) return new OccLine(curve as Geom_Line); - // else if (isType("Geom_Parabola")) return new OccLine(curve as Geom_Line); + else if (isType("Geom_Ellipse")) return new OccEllipse(curve as Geom_Ellipse); + else if (isType("Geom_Hyperbola")) return new OccHyperbola(curve as Geom_Hyperbola); + else if (isType("Geom_Parabola")) return new OccParabola(curve as Geom_Parabola); else if (isType("Geom_BezierCurve")) return new OccBezierCurve(curve as Geom_BezierCurve); - // else if (isType("Geom_BSplineCurve")) return new OccLine(curve as Geom_Line); + else if (isType("Geom_BSplineCurve")) return new OccBSplineCurve(curve as Geom_BSplineCurve); else if (isType("Geom_OffsetCurve")) return new OccOffsetCurve(curve as Geom_OffsetCurve); else if (isType("Geom_TrimmedCurve")) return new OccTrimmedCurve(curve as Geom_TrimmedCurve); - throw new Error("Unknown curve type"); + throw new Error("Unknown curve type: " + curve.DynamicType().Name); } static getActualShape(shape: TopoDS_Shape): TopoDS_Shape { @@ -287,6 +302,16 @@ export class OccHelps { } } + static toArray(shapes: TopTools_ListOfShape): IShape[] { + const arr: IShape[] = []; + while (!shapes.IsEmpty()) { + let first = shapes.First_1(); + arr.push(this.wrapShape(first)); + shapes.RemoveFirst(); + } + return arr; + } + static *mapShapes(shape: TopoDS_Shape, shapeType: TopAbs_ShapeEnum) { let indexShape = new occ.TopTools_IndexedMapOfShape_1(); occ.TopExp.MapShapes_1(shape, shapeType, indexShape); diff --git a/packages/chili-occ/src/occShape.ts b/packages/chili-occ/src/occShape.ts index ed3a24c9..6bc280f1 100644 --- a/packages/chili-occ/src/occShape.ts +++ b/packages/chili-occ/src/occShape.ts @@ -16,6 +16,7 @@ import { JoinType, Matrix4, Orientation, + Plane, Ray, Result, SerializedProperties, @@ -58,6 +59,19 @@ export class OccShape implements IShape { this.shapeType = OccHelps.getShapeType(shape); } + section(shape: IShape | Plane): IShape { + if (shape instanceof OccShape) { + let s = new occ.BRepAlgoAPI_Section_3(this.shape, shape.shape, true); + return OccHelps.wrapShape(s.Shape()); + } else if (shape instanceof Plane) { + let pln = OccHelps.toPln(shape); + let s = new occ.BRepAlgoAPI_Section_5(this.shape, pln, true); + return OccHelps.wrapShape(s.Shape()); + } + + throw new Error("Invalid section"); + } + get matrix() { return OccHelps.convertToMatrix(this.shape.Location_1().Transformation()); } @@ -126,6 +140,39 @@ export class OccShape implements IShape { if (other instanceof OccShape) return this.shape.IsEqual(other.shape); return false; } + + split(edges: (IEdge | IWire)[]): IShape { + let shapes = new occ.TopTools_SequenceOfShape_1(); + edges.forEach((shape) => { + shapes.Append_1((shape as unknown as OccShape).shape); + }); + + let spliter = new occ.BRepFeat_SplitShape_2(this.shape); + spliter.Add_1(shapes); + let message = new occ.Message_ProgressRange_1(); + spliter.Build(message); + if (!spliter.IsDone()) { + throw new Error("Failed to split shape"); + } + return OccHelps.wrapShape(spliter.Shape()); + } + + splitWithFace(onFace: IFace, edges: IEdge | IWire): IShape { + let face = onFace as OccFace; + let spliter = new occ.BRepFeat_SplitShape_2(this.shape); + if (edges instanceof OccEdge) { + spliter.Add_3(edges.shape, face.shape); + } else if (edges instanceof OccWire) { + spliter.Add_2(edges.shape, face.shape); + } + return OccHelps.wrapShape(spliter.Shape()); + } + + splitWithEdge(onEdge: IEdge, edge: IEdge): IShape { + let spliter = new occ.BRepFeat_SplitShape_2(this.shape); + spliter.Add_5((onEdge as OccEdge).shape, (edge as OccEdge).shape); + return OccHelps.wrapShape(spliter.Shape()); + } } @Serializer.register("Vertex", ["shape", "id"], OccShape.deserialize, OccShape.serialize) diff --git a/packages/chili-occ/test/occ.test.ts b/packages/chili-occ/test/occ.test.ts index c4443710..54194331 100644 --- a/packages/chili-occ/test/occ.test.ts +++ b/packages/chili-occ/test/occ.test.ts @@ -93,10 +93,10 @@ describe("geometry test", () => { let curve = edge.asCurve(); expect(curve instanceof OccCurve).toBe(true); expect(edge.length()).toBe(20); - expect(curve.point(curve.firstParameter()).x).toBe(-10); - expect(curve.point(curve.lastParameter()).x).toBe(10); + expect(curve.value(curve.firstParameter()).x).toBe(-10); + expect(curve.value(curve.lastParameter()).x).toBe(10); expect(curve.curveType).toBe(CurveType.TrimmedCurve); - expect(curve.point(0).x).toBe(-10); + expect(curve.value(0).x).toBe(-10); expect(curve.firstParameter()).toBe(0); expect(curve.lastParameter()).toBe(20); }); @@ -205,9 +205,9 @@ describe("curve test", () => { let shape = new OccEdge(e1); shape.matrix = Matrix4.createTranslation(10, 20, 30); let edge = shape.mesh.edges?.groups.at(0)?.shape as OccEdge; - let p2 = shape.asCurve().point(0); + let p2 = shape.asCurve().value(0); expect(p2?.x).toBeCloseTo(20); - expect(edge.asCurve().point(0).x).toBeCloseTo(20); + expect(edge.asCurve().value(0).x).toBeCloseTo(20); }); }); }); diff --git a/packages/chili-three/test/testEdge.ts b/packages/chili-three/test/testEdge.ts index 04e65b04..221fe04a 100644 --- a/packages/chili-three/test/testEdge.ts +++ b/packages/chili-three/test/testEdge.ts @@ -2,13 +2,16 @@ import { I18nKeys, IDocument, IEdge, + IFace, IShape, IShapeMeshData, ITrimmedCurve, + IWire, LineType, Matrix4, Orientation, ParameterBody, + Plane, Ray, Result, Serialized, @@ -21,6 +24,18 @@ export class TestEdge implements IEdge { readonly start: XYZ, readonly end: XYZ, ) {} + section(shape: IShape | Plane): IShape { + throw new Error("Method not implemented."); + } + split(edges: (IEdge | IWire)[]): IShape { + throw new Error("Method not implemented."); + } + splitWithFace(onFace: IFace, edges: IEdge | IWire): IShape { + throw new Error("Method not implemented."); + } + splitWithEdge(onEdge: IEdge, edge: IEdge): IShape { + throw new Error("Method not implemented."); + } findAncestor(ancestorType: ShapeType, fromShape: IShape): IShape[] { throw new Error("Method not implemented."); diff --git a/packages/chili/src/commands/create/revolve.ts b/packages/chili/src/commands/create/revolve.ts index 68199423..c6a751d0 100644 --- a/packages/chili/src/commands/create/revolve.ts +++ b/packages/chili/src/commands/create/revolve.ts @@ -36,7 +36,7 @@ export class Revolve extends CreateCommand { protected override geometryEntity(): GeometryEntity { let shape = this.stepDatas[0].shapes[0].shape; // todo assert let edge = (this.stepDatas[1].shapes[0].shape as IEdge).asCurve().basisCurve() as ILine; - let axis = new Ray(edge.point(0), edge.direction); + let axis = new Ray(edge.value(0), edge.direction); let body = new RevolveBody(this.document, shape, axis, this._angle); return new ParameterGeometryEntity(this.document, body); } diff --git a/packages/chili/src/snap/objectSnap.ts b/packages/chili/src/snap/objectSnap.ts index 0b26b328..05536a6d 100644 --- a/packages/chili/src/snap/objectSnap.ts +++ b/packages/chili/src/snap/objectSnap.ts @@ -2,7 +2,6 @@ import { Config, - CurveType, I18n, ICircle, ICurve, @@ -270,8 +269,8 @@ export class ObjectSnap implements ISnapper { private getEdgeFeaturePoints(view: IView, shape: VisualShapeData, infos: SnapedData[]) { let curve = (shape.shape as IEdge).asCurve(); - let start = curve.point(curve.firstParameter()); - let end = curve.point(curve.lastParameter()); + let start = curve.value(curve.firstParameter()); + let end = curve.value(curve.lastParameter()); let addPoint = (point: XYZ, info: string) => infos.push({ view, point: point, info, shapes: [shape] }); if (ObjectSnapType.has(this._snapType, ObjectSnapType.endPoint)) { @@ -279,7 +278,7 @@ export class ObjectSnap implements ISnapper { addPoint(end, I18n.translate("snap.end")); } if (ObjectSnapType.has(this._snapType, ObjectSnapType.midPoint)) { - let mid = curve.point((curve.firstParameter() + curve.lastParameter()) * 0.5); + let mid = curve.value((curve.firstParameter() + curve.lastParameter()) * 0.5); addPoint(mid, I18n.translate("snap.mid")); } }