Skip to content

Commit

Permalink
✨ feat: add Bezier
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangechen committed May 21, 2024
1 parent bdf1d2c commit 234c527
Show file tree
Hide file tree
Showing 24 changed files with 368 additions and 98 deletions.
1 change: 1 addition & 0 deletions packages/chili-core/src/command/commandKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type CommandKeys =
| "file.export.iges"
| "file.export.stp"
| "create.arc"
| "create.bezier"
| "create.box"
| "create.line"
| "create.circle"
Expand Down
1 change: 1 addition & 0 deletions packages/chili-core/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default {
"line.end": "End",
"polygon.points": "Points",
"command.arc": "Arc",
"command.bezier": "Bezier",
"command.boolean.common": "Common",
"command.boolean.cut": "Cut",
"command.boolean.fuse": "Fuse",
Expand Down
1 change: 1 addition & 0 deletions packages/chili-core/src/i18n/keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export type I18nKeys =
| "command.line"
| "command.line.isConnected"
| "command.box"
| "command.bezier"
| "command.circle"
| "command.rect"
| "command.move"
Expand Down
1 change: 1 addition & 0 deletions packages/chili-core/src/i18n/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export default {
"line.end": "终点",
"polygon.points": "点",
"command.arc": "圆弧",
"command.bezier": "贝塞尔",
"command.boolean.common": "相交",
"command.boolean.cut": "剪切",
"command.boolean.fuse": "融合",
Expand Down
29 changes: 28 additions & 1 deletion packages/chili-core/src/shape/curve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ export interface ICurve {
firstParameter(): number;
lastParameter(): number;
point(parameter: number): XYZ;
trim(start: number, end: number): void;
project(point: XYZ): XYZ[];
isCN(n: number): boolean;
d0(u: number): XYZ;
Expand All @@ -33,6 +32,34 @@ export interface ICircle extends IConic {
radius: number;
}

export interface IBoundedCurve extends ICurve {
startPoint(): XYZ;
endPoint(): XYZ;
}

export interface IBezierCurve extends IBoundedCurve {
degree(): number;
weight(index: number): number;
insertPoleAfter(index: number, point: XYZ, weight: number | undefined): void;
insertPoleBefore(index: number, point: XYZ, weight: number | undefined): void;
removePole(index: number): void;
setPole(index: number, point: XYZ, weight: number | undefined): void;
setWeight(index: number, weight: number): void;
nbPoles(): number;
pole(index: number): XYZ;
poles(): XYZ[];
}

export interface ITrimmedCurve extends IBoundedCurve {
basisCurve(): ICurve;
}

export interface IOffsetCurve extends ICurve {
basisCurve(): ICurve;
offset(): number;
direction(): XYZ;
}

export namespace ICurve {
export function isConic(curve: ICurve): curve is IConic {
let conic = curve as IConic;
Expand Down
5 changes: 3 additions & 2 deletions packages/chili-core/src/shape/shape.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import { Result } from "../foundation";
import { Matrix4, Ray, XYZ } from "../math";
import { ICurve } from "./curve";
import { ICurve, ITrimmedCurve } from "./curve";
import { IShapeMeshData } from "./meshData";
import { ShapeType } from "./shapeType";

Expand All @@ -16,6 +16,7 @@ export enum CurveType {
BSplineCurve,
OffsetCurve,
OtherCurve,
TrimmedCurve,
}

export enum SurfaceType {
Expand Down Expand Up @@ -67,7 +68,7 @@ export interface IVertex extends IShape {}
export interface IEdge extends IShape {
intersect(other: IEdge | Ray): XYZ[];
length(): number;
asCurve(): Result<ICurve>;
asCurve(): ITrimmedCurve;
offset(distance: number, dir: XYZ): Result<IEdge>;
}

Expand Down
2 changes: 2 additions & 0 deletions packages/chili-core/src/shape/shapeFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

import { Result } from "../foundation";
import { Plane, Ray, XYZ } from "../math";
import { IBezierCurve } from "./curve";
import { ICompound, IEdge, IFace, IShape, ISolid, IVertex, IWire } from "./shape";
import { IShapeConverter } from "./shapeConverter";

export interface IShapeFactory {
readonly converter: IShapeConverter;
face(...wire: IWire[]): Result<IFace>;
bezier(points: XYZ[], weights?: number[]): Result<IEdge>;
point(point: XYZ): Result<IVertex>;
line(start: XYZ, end: XYZ): Result<IEdge>;
arc(normal: XYZ, center: XYZ, start: XYZ, angle: number): Result<IEdge>;
Expand Down
10 changes: 5 additions & 5 deletions packages/chili-geo/src/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export class GeoUtils {
let res: { edge: IEdge; point: XYZ } | undefined = undefined;
let minDistance = Number.MAX_VALUE;
for (const edge of wire.findSubShapes(ShapeType.Edge) as IEdge[]) {
let tempPoint = edge.asCurve().unwrap().nearestPoint(point);
let tempPoint = edge.asCurve().nearestPoint(point);
let tempDistance = tempPoint.distanceTo(point);
if (tempDistance < minDistance) {
res = { edge, point: tempPoint };
Expand Down Expand Up @@ -37,15 +37,15 @@ export class GeoUtils {
firstEdge = edge as IEdge;
break;
}
return this.curveNormal(firstEdge!.asCurve().unwrap());
return this.curveNormal(firstEdge!.asCurve());
};

static findNextEdge(wire: IWire, edge: IEdge): Result<IEdge> {
let curve = edge.asCurve().unwrap();
let curve = edge.asCurve();
let point = curve.point(curve.lastParameter());
for (const e of wire.iterSubShapes(ShapeType.Edge, true)) {
if (e.isEqual(edge)) continue;
let testCurve = (e as IEdge).asCurve().unwrap();
let testCurve = (e as IEdge).asCurve();
if (
point.distanceTo(testCurve.point(testCurve.firstParameter())) < Precision.Distance ||
point.distanceTo(testCurve.point(testCurve.lastParameter())) < Precision.Distance
Expand All @@ -62,7 +62,7 @@ export class GeoUtils {
}

if (shape.shapeType === ShapeType.Edge) {
let curve = (shape as IEdge).asCurve().unwrap();
let curve = (shape as IEdge).asCurve();
return this.curveNormal(curve);
}

Expand Down
167 changes: 136 additions & 31 deletions packages/chili-occ/src/occGeometry.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,35 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { CurveType, ICircle, ICurve, IDisposable, ILine, Plane, XYZ } from "chili-core";
import { Geom_Circle, Geom_Curve, Geom_Line, Geom_TrimmedCurve } from "../occ-wasm/chili_occ";
import {
CurveType,
IBezierCurve,
IBoundedCurve,
ICircle,
ICurve,
IDisposable,
ILine,
IOffsetCurve,
ITrimmedCurve,
Plane,
XYZ,
} from "chili-core";
import {
Geom_BezierCurve,
Geom_BoundedCurve,
Geom_Circle,
Geom_Curve,
Geom_Line,
Geom_OffsetCurve,
Geom_TrimmedCurve,
} from "../occ-wasm/chili_occ";

import { OccHelps } from "./occHelps";

export class OccCurve implements ICurve, IDisposable {
readonly curve: Geom_TrimmedCurve;
readonly curveType: CurveType;

constructor(curve: Geom_Curve, start: number, end: number) {
let curveHandle = new occ.Handle_Geom_Curve_2(curve);
constructor(readonly curve: Geom_Curve) {
this.curveType = OccHelps.getCurveType(curve);
this.curve = new occ.Geom_TrimmedCurve(curveHandle, start, end, true, true);
}

nearestPoint(point: XYZ): XYZ {
Expand Down Expand Up @@ -46,14 +63,13 @@ export class OccCurve implements ICurve, IDisposable {
}

parameter(point: XYZ): number {
let api = new occ.GeomAPI_ProjectPointOnCurve_2(OccHelps.toPnt(point), this.curve.BasisCurve());
let api = new occ.GeomAPI_ProjectPointOnCurve_2(
OccHelps.toPnt(point),
new occ.Handle_Geom_Curve_2(this.curve),
);
return api.LowerDistanceParameter();
}

trim(start: number, end: number) {
this.curve.SetTrim(start, end, true, true);
}

project(point: XYZ): XYZ[] {
let result = new Array<XYZ>();
let api = new occ.GeomAPI_ProjectPointOnCurve_2(
Expand Down Expand Up @@ -125,20 +141,8 @@ export class OccCurve implements ICurve, IDisposable {
}

export class OccLine extends OccCurve implements ILine {
constructor(
private line: Geom_Line,
start: number,
end: number,
) {
super(line, start, end);
}

get start(): XYZ {
return OccHelps.toXYZ(this.curve.StartPoint());
}

get endPoint(): XYZ {
return OccHelps.toXYZ(this.curve.EndPoint());
constructor(private line: Geom_Line) {
super(line);
}

get direction(): XYZ {
Expand Down Expand Up @@ -170,12 +174,8 @@ export class OccCircle extends OccCurve implements ICircle {
this.circle.SetPosition(OccHelps.toAx2(value));
}

constructor(
private circle: Geom_Circle,
start: number,
end: number,
) {
super(circle, start, end);
constructor(private circle: Geom_Circle) {
super(circle);
}

get center(): XYZ {
Expand All @@ -194,3 +194,108 @@ export class OccCircle extends OccCurve implements ICircle {
this.circle.SetRadius(value);
}
}

export class OccBoundedCurve extends OccCurve implements IBoundedCurve {
constructor(private boundedCurve: Geom_BoundedCurve) {
super(boundedCurve);
}

startPoint(): XYZ {
return OccHelps.toXYZ(this.boundedCurve.StartPoint());
}

endPoint(): XYZ {
return OccHelps.toXYZ(this.boundedCurve.EndPoint());
}
}

export class OccTrimmedCurve extends OccBoundedCurve implements ITrimmedCurve {
constructor(private trimmedCurve: Geom_TrimmedCurve) {
super(trimmedCurve);
}

basisCurve(): ICurve {
return OccHelps.wrapCurve(this.trimmedCurve.BasisCurve().get());
}
}

export class OccOffsetCurve extends OccCurve implements IOffsetCurve {
constructor(private offsetCurve: Geom_OffsetCurve) {
super(offsetCurve);
}

basisCurve(): ICurve {
return OccHelps.wrapCurve(this.offsetCurve.BasisCurve().get());
}

offset(): number {
return this.offsetCurve.Offset();
}

direction(): XYZ {
return OccHelps.toXYZ(this.offsetCurve.Direction());
}
}

export class OccBezierCurve extends OccBoundedCurve implements IBezierCurve {
constructor(private bezier: Geom_BezierCurve) {
super(bezier);
}

weight(index: number): number {
return this.bezier.Weight(index);
}

insertPoleAfter(index: number, point: XYZ, weight: number | undefined): void {
if (weight === undefined) {
this.bezier.InsertPoleAfter_1(index, OccHelps.toPnt(point));
} else {
this.bezier.InsertPoleAfter_2(index, OccHelps.toPnt(point), weight);
}
}

insertPoleBefore(index: number, point: XYZ, weight: number | undefined): void {
if (weight === undefined) {
this.bezier.InsertPoleBefore_1(index, OccHelps.toPnt(point));
} else {
this.bezier.InsertPoleBefore_2(index, OccHelps.toPnt(point), weight);
}
}

removePole(index: number): void {
this.bezier.RemovePole(index);
}

setPole(index: number, point: XYZ, weight: number | undefined): void {
if (weight === undefined) {
this.bezier.SetPole_1(index, OccHelps.toPnt(point));
} else {
this.bezier.SetPole_2(index, OccHelps.toPnt(point), weight);
}
}

setWeight(index: number, weight: number): void {
this.setWeight(index, weight);
}

nbPoles(): number {
return this.bezier.NbPoles();
}

pole(index: number): XYZ {
return OccHelps.toXYZ(this.bezier.Pole(index));
}

degree(): number {
return this.bezier.Degree();
}

poles(): XYZ[] {
let result: XYZ[] = [];
let pls = this.bezier.Poles_2();
for (let i = 1; i <= pls.Length(); i++) {
result.push(OccHelps.toXYZ(pls.Value(i)));
}
return result;
}
}
Loading

0 comments on commit 234c527

Please sign in to comment.