diff --git a/packages/chili-geo/src/utils.ts b/packages/chili-geo/src/utils.ts index c7eca5e3..707c112e 100644 --- a/packages/chili-geo/src/utils.ts +++ b/packages/chili-geo/src/utils.ts @@ -1,6 +1,6 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. -import { ICurve, IEdge, IWire, Precision, Result, ShapeType, XYZ } from "chili-core"; +import { ICurve, IEdge, IFace, IWire, Precision, Result, ShapeType, XYZ } from "chili-core"; export class GeoUtils { static nearestPoint(wire: IWire, point: XYZ): { edge: IEdge; point: XYZ } { @@ -56,7 +56,11 @@ export class GeoUtils { return Result.err("Cannot find next edge"); } - static normal(shape: IWire | IEdge): XYZ { + static normal(shape: IFace | IWire | IEdge): XYZ { + if (shape.shapeType === ShapeType.Face) { + return (shape as IFace).normal(0, 0)[1]; + } + if (shape.shapeType === ShapeType.Edge) { let curve = (shape as IEdge).asCurve().unwrap(); return this.curveNormal(curve); diff --git a/packages/chili/src/bodys/prism.ts b/packages/chili/src/bodys/prism.ts index 49c1b170..17885acc 100644 --- a/packages/chili/src/bodys/prism.ts +++ b/packages/chili/src/bodys/prism.ts @@ -10,18 +10,19 @@ import { Result, Serializer, } from "chili-core"; +import { GeoUtils } from "chili-geo"; -@Serializer.register("PrismBody", ["document", "face", "length"]) +@Serializer.register("PrismBody", ["document", "section", "length"]) export class PrismBody extends ParameterGeometry { override display: I18nKeys = "body.prism"; - private _face: IFace; + private _section: IShape; @Serializer.serialze() - get face(): IFace { - return this._face; + get section(): IShape { + return this._section; } - set face(value: IFace) { - this.setPropertyAndUpdate("face", value); + set section(value: IFace) { + this.setPropertyAndUpdate("section", value); } private _length: number; @@ -34,15 +35,15 @@ export class PrismBody extends ParameterGeometry { this.setPropertyAndUpdate("length", value); } - constructor(document: IDocument, face: IFace, length: number) { + constructor(document: IDocument, face: IShape, length: number) { super(document); - this._face = face; + this._section = face; this._length = length; } protected override generateShape(): Result { - let [_, normal] = this.face.normal(0, 0); + let normal = GeoUtils.normal(this.section as any); let vec = normal.multiply(this.length); - return this.document.application.shapeFactory.prism(this.face, vec); + return this.document.application.shapeFactory.prism(this.section, vec); } } diff --git a/packages/chili/src/commands/create/prism.ts b/packages/chili/src/commands/create/prism.ts index 3cb7ed72..8befc68d 100644 --- a/packages/chili/src/commands/create/prism.ts +++ b/packages/chili/src/commands/create/prism.ts @@ -1,6 +1,7 @@ // Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license. -import { GeometryModel, IFace, Precision, ShapeType, command } from "chili-core"; +import { GeometryModel, Precision, ShapeType, command } from "chili-core"; +import { GeoUtils } from "chili-geo"; import { PrismBody } from "../../bodys"; import { SnapLengthAtAxisData } from "../../snap"; import { IStep, LengthAtAxisStep } from "../../step"; @@ -16,8 +17,8 @@ let count = 1; }) export class Prism extends CreateCommand { protected override create(): GeometryModel { - let shape = this.stepDatas[0].shapes[0].shape as IFace; // todo assert - let [point, normal] = shape.normal(0, 0); + let shape = this.stepDatas[0].shapes[0].shape; + const { point, normal } = this.getAxis(); let dist = this.stepDatas[1].point!.sub(point).dot(normal); let body = new PrismBody(this.document, shape, dist); return new GeometryModel(this.document, `prism${count++}`, body); @@ -25,14 +26,17 @@ export class Prism extends CreateCommand { protected override getSteps(): IStep[] { return [ - new SelectShapeStep(ShapeType.Face, "prompt.select.faces", false), + new SelectShapeStep( + ShapeType.Face | ShapeType.Edge | ShapeType.Wire, + "prompt.select.shape", + false, + ), new LengthAtAxisStep("operate.pickNextPoint", this.getLengthStepData), ]; } private getLengthStepData = (): SnapLengthAtAxisData => { - let shape = this.stepDatas[0].shapes[0].shape as IFace; // todo assert - let [point, normal] = shape.normal(0, 0); + const { point, normal } = this.getAxis(); return { point, direction: normal, @@ -41,8 +45,16 @@ export class Prism extends CreateCommand { let dist = p.sub(point).dot(normal); if (Math.abs(dist) < Precision.Float) return []; let vec = normal.multiply(dist); + let shape = this.stepDatas[0].shapes[0].shape; return [this.application.shapeFactory.prism(shape, vec).unwrap().mesh.edges!]; }, }; }; + + private getAxis() { + let point = this.stepDatas[0].shapes[0].point!; + let shape = this.stepDatas[0].shapes[0].shape; + let normal = GeoUtils.normal(shape as any); + return { point, normal }; + } } diff --git a/packages/chili/src/document.ts b/packages/chili/src/document.ts index df3e757f..2f7106f7 100644 --- a/packages/chili/src/document.ts +++ b/packages/chili/src/document.ts @@ -28,7 +28,7 @@ import { } from "chili-core"; import { Selection } from "./selection"; -const FILE_VERSIOM = "0.1.2"; +const FILE_VERSIOM = "0.3.0"; export class Document extends Observable implements IDocument { readonly visual: IVisual;