Skip to content

Commit

Permalink
🐞 fix: Fixed the bug where the shape could not update automatically
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangechen committed Oct 28, 2024
1 parent 71d9be4 commit 77f9dd7
Show file tree
Hide file tree
Showing 14 changed files with 116 additions and 52 deletions.
55 changes: 55 additions & 0 deletions packages/chili-core/src/math/boundingBox.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

export type PointLike = { x: number; y: number; z: number };

export class BoundingBox {
public min: PointLike;
public max: PointLike;

constructor(min: PointLike, max: PointLike) {
this.min = min;
this.max = max;
}

static expandByPoint(box: BoundingBox, point: PointLike) {
box.min.x = Math.min(box.min.x, point.x);
box.min.y = Math.min(box.min.y, point.y);
box.min.z = Math.min(box.min.z, point.z);

box.max.x = Math.max(box.max.x, point.x);
box.max.y = Math.max(box.max.y, point.y);
box.max.z = Math.max(box.max.z, point.z);
}

public static fromNumbers(points: number[]): BoundingBox {
let min = { x: Number.MAX_VALUE, y: Number.MAX_VALUE, z: Number.MAX_VALUE };
let max = { x: Number.MIN_VALUE, y: Number.MIN_VALUE, z: Number.MIN_VALUE };

for (let i = 0; i < points.length; i += 3) {
min.x = Math.min(min.x, points[i]);
min.y = Math.min(min.y, points[i + 1]);
min.z = Math.min(min.z, points[i + 2]);

max.x = Math.max(max.x, points[i]);
max.y = Math.max(max.y, points[i + 1]);
max.z = Math.max(max.z, points[i + 2]);
}
return new BoundingBox(min, max);
}

public static fromPoints(points: PointLike[]): BoundingBox {
let min = { x: Number.MAX_VALUE, y: Number.MAX_VALUE, z: Number.MAX_VALUE };
let max = { x: Number.MIN_VALUE, y: Number.MIN_VALUE, z: Number.MIN_VALUE };
for (let point of points) {
min.x = Math.min(min.x, point.x);
min.y = Math.min(min.y, point.y);
min.z = Math.min(min.z, point.z);

max.x = Math.max(max.x, point.x);
max.y = Math.max(max.y, point.y);
max.z = Math.max(max.z, point.z);
}

return new BoundingBox(min, max);
}
}
67 changes: 38 additions & 29 deletions packages/chili-core/src/model/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ import {
Id,
PubSub,
Result,
debounce,
} from "../foundation";
import { I18n, I18nKeys } from "../i18n";
import { Matrix4 } from "../math";
import { BoundingBox } from "../math/boundingBox";
import { Property } from "../property";
import { Serialized, Serializer } from "../serialize";
import { IShape, IShapeMeshData } from "../shape";
Expand Down Expand Up @@ -223,6 +225,7 @@ export namespace INode {
export interface IMeshObject extends IPropertyChanged {
materialId: string;
matrix: Matrix4;
boundingBox(): BoundingBox;
get mesh(): IShapeMeshData;
}

Expand All @@ -246,6 +249,7 @@ export abstract class GeometryNode extends Node implements IMeshObject {
value,
(_p, oldMatrix) => {
this.onMatrixChanged(value, oldMatrix);
this._boundingBox = undefined;
},
{
equals: (left, right) => left.equals(right),
Expand All @@ -258,6 +262,16 @@ export abstract class GeometryNode extends Node implements IMeshObject {
this.setPrivateValue("materialId", materialId ?? document.materials.at(0)?.id ?? "");
}

protected _boundingBox: BoundingBox | undefined;
boundingBox(): BoundingBox {
if (this._boundingBox === undefined) {
let points = this.mesh.faces?.positions ?? this.mesh.edges?.positions ?? [];
points = this.matrix.ofPoints(points);
this._boundingBox = BoundingBox.fromNumbers(points);
}
return this._boundingBox;
}

protected onMatrixChanged(newMatrix: Matrix4, oldMatrix: Matrix4): void {}

protected onVisibleChanged(): void {
Expand All @@ -280,7 +294,28 @@ export abstract class GeometryNode extends Node implements IMeshObject {
}

export abstract class ShapeNode extends GeometryNode {
abstract get shape(): Result<IShape>;
protected _shape: Result<IShape> = Result.err(SHAPE_UNDEFINED);
get shape(): Result<IShape> {
return this._shape;
}

protected setShape(shape: Result<IShape>) {
if (this._shape.isOk && this._shape.isOk && this._shape.value.isEqual(shape.value)) {
return;
}

if (!shape.isOk) {
PubSub.default.pub("displayError", shape.error);
return;
}

let oldShape = this._shape;
this._shape = shape;
this._mesh = undefined;
this._boundingBox = undefined;
this._shape.value.matrix = this.matrix;
this.emitPropertyChanged("shape", oldShape);
}

protected override onMatrixChanged(newMatrix: Matrix4): void {
if (this.shape.isOk) this.shape.value.matrix = newMatrix;
Expand All @@ -301,24 +336,12 @@ export abstract class ShapeNode extends GeometryNode {

const SHAPE_UNDEFINED = "Shape not initialized";
export abstract class ParameterShapeNode extends ShapeNode {
protected _shape: Result<IShape> = Result.err(SHAPE_UNDEFINED);
override get shape(): Result<IShape> {
if (!this._shape.isOk && this._shape.error === SHAPE_UNDEFINED) {
this._shape = this.generateShape();
}
return this._shape;
}
override set shape(shape: Result<IShape>) {
if (shape.isOk && this._shape.isOk && this._shape.value.isEqual(shape.value)) {
return;
}

let oldShape = this._shape;
this._shape = shape;
this._mesh = undefined;
this._shape.value.matrix = this.matrix;
this.emitPropertyChanged("shape", oldShape);
}

protected setPropertyEmitShapeChanged<K extends keyof this>(
property: K,
Expand All @@ -327,7 +350,7 @@ export abstract class ParameterShapeNode extends ShapeNode {
equals?: IEqualityComparer<this[K]> | undefined,
): boolean {
if (this.setProperty(property, newValue, onPropertyChanged, equals)) {
this.shape = this.generateShape();
this.setShape(this.generateShape());
return true;
}

Expand All @@ -345,26 +368,12 @@ export abstract class ParameterShapeNode extends ShapeNode {

@Serializer.register(["document", "name", "shape", "materialId", "id"])
export class EditableShapeNode extends ShapeNode {
protected _shape: Result<IShape>;
@Serializer.serialze()
override get shape(): Result<IShape> {
return this._shape;
}
override set shape(shape: Result<IShape>) {
if (this._shape.isOk && this._shape.unchecked() === shape.unchecked()) {
return;
}

if (!shape.isOk) {
PubSub.default.pub("displayError", shape.error);
return;
}

let oldShape = this._shape;
this._shape = shape;
this._mesh = undefined;
this._shape.value.matrix = this.matrix;
this.emitPropertyChanged("shape", oldShape);
this.setShape(shape);
}

constructor(document: IDocument, name: string, shape: IShape, materialId?: string, id?: string) {
Expand Down
4 changes: 2 additions & 2 deletions packages/chili/src/bodys/arc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class ArcNode extends ParameterShapeNode {
return this.getPrivateValue("center");
}
set center(center: XYZ) {
this.setProperty("center", center);
this.setPropertyEmitShapeChanged("center", center);
}

@Serializer.serialze()
Expand All @@ -43,7 +43,7 @@ export class ArcNode extends ParameterShapeNode {
return this.getPrivateValue("angle");
}
set angle(value: number) {
this.setProperty("angle", value);
this.setPropertyEmitShapeChanged("angle", value);
}

constructor(document: IDocument, normal: XYZ, center: XYZ, start: XYZ, angle: number) {
Expand Down
6 changes: 3 additions & 3 deletions packages/chili/src/bodys/box.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class BoxNode extends ParameterShapeNode {
return this.getPrivateValue("dx");
}
set dx(dx: number) {
this.setProperty("dx", dx);
this.setPropertyEmitShapeChanged("dx", dx);
}

@Serializer.serialze()
Expand All @@ -32,7 +32,7 @@ export class BoxNode extends ParameterShapeNode {
return this.getPrivateValue("dy");
}
set dy(dy: number) {
this.setProperty("dy", dy);
this.setPropertyEmitShapeChanged("dy", dy);
}

@Serializer.serialze()
Expand All @@ -41,7 +41,7 @@ export class BoxNode extends ParameterShapeNode {
return this.getPrivateValue("dz");
}
set dz(dz: number) {
this.setProperty("dz", dz);
this.setPropertyEmitShapeChanged("dz", dz);
}

@Serializer.serialze()
Expand Down
4 changes: 2 additions & 2 deletions packages/chili/src/bodys/circle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class CircleNode extends FacebaseNode {
return this.getPrivateValue("center");
}
set center(center: XYZ) {
this.setProperty("center", center);
this.setPropertyEmitShapeChanged("center", center);
}

@Serializer.serialze()
Expand All @@ -23,7 +23,7 @@ export class CircleNode extends FacebaseNode {
return this.getPrivateValue("radius");
}
set radius(radius: number) {
this.setProperty("radius", radius);
this.setPropertyEmitShapeChanged("radius", radius);
}

@Serializer.serialze()
Expand Down
2 changes: 1 addition & 1 deletion packages/chili/src/bodys/face.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class FaceNode extends ParameterShapeNode {
return this.getPrivateValue("shapes");
}
set shapes(values: IEdge[] | IWire[]) {
this.setProperty("shapes", values);
this.setPropertyEmitShapeChanged("shapes", values);
}

constructor(document: IDocument, shapes: IEdge[] | IWire[]) {
Expand Down
4 changes: 2 additions & 2 deletions packages/chili/src/bodys/fuse.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ export class FuseNode extends ParameterShapeNode {
return this.getPrivateValue("bottom");
}
set bottom(value: IShape) {
this.setProperty("bottom", value);
this.setPropertyEmitShapeChanged("bottom", value);
}

@Serializer.serialze()
get top(): IShape {
return this.getPrivateValue("top");
}
set top(value: IShape) {
this.setProperty("top", value);
this.setPropertyEmitShapeChanged("top", value);
}

constructor(document: IDocument, bottom: IShape, top: IShape) {
Expand Down
4 changes: 2 additions & 2 deletions packages/chili/src/bodys/line.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class LineNode extends ParameterShapeNode {
return this.getPrivateValue("start");
}
set start(pnt: XYZ) {
this.setProperty("start", pnt);
this.setPropertyEmitShapeChanged("start", pnt);
}

@Serializer.serialze()
Expand All @@ -32,7 +32,7 @@ export class LineNode extends ParameterShapeNode {
return this.getPrivateValue("end");
}
set end(pnt: XYZ) {
this.setProperty("end", pnt);
this.setPropertyEmitShapeChanged("end", pnt);
}

constructor(document: IDocument, start: XYZ, end: XYZ) {
Expand Down
2 changes: 1 addition & 1 deletion packages/chili/src/bodys/polygon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export class PolygonNode extends FacebaseNode {
return this.getPrivateValue("points");
}
set points(value: XYZ[]) {
this.setProperty("points", value);
this.setPropertyEmitShapeChanged("points", value);
}

constructor(document: IDocument, points: XYZ[]) {
Expand Down
4 changes: 2 additions & 2 deletions packages/chili/src/bodys/prism.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export class PrismNode extends ParameterShapeNode {
return this.getPrivateValue("section");
}
set section(value: IShape) {
this.setProperty("section", value);
this.setPropertyEmitShapeChanged("section", value);
}

@Serializer.serialze()
Expand All @@ -32,7 +32,7 @@ export class PrismNode extends ParameterShapeNode {
return this.getPrivateValue("length");
}
set length(value: number) {
this.setProperty("length", value);
this.setPropertyEmitShapeChanged("length", value);
}

constructor(document: IDocument, face: IShape, length: number) {
Expand Down
4 changes: 2 additions & 2 deletions packages/chili/src/bodys/rect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export class RectNode extends FacebaseNode {
return this.getPrivateValue("dx");
}
set dx(dx: number) {
this.setProperty("dx", dx);
this.setPropertyEmitShapeChanged("dx", dx);
}

@Serializer.serialze()
Expand All @@ -33,7 +33,7 @@ export class RectNode extends FacebaseNode {
return this.getPrivateValue("dy");
}
set dy(dy: number) {
this.setProperty("dy", dy);
this.setPropertyEmitShapeChanged("dy", dy);
}

@Serializer.serialze()
Expand Down
6 changes: 3 additions & 3 deletions packages/chili/src/bodys/revolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,23 +13,23 @@ export class RevolvedNode extends ParameterShapeNode {
return this.getPrivateValue("profile");
}
set profile(value: IShape) {
this.setProperty("profile", value);
this.setPropertyEmitShapeChanged("profile", value);
}

@Serializer.serialze()
get axis() {
return this.getPrivateValue("axis");
}
set axis(value: Ray) {
this.setProperty("axis", value);
this.setPropertyEmitShapeChanged("axis", value);
}

@Serializer.serialze()
get angle() {
return this.getPrivateValue("angle");
}
set angle(value: number) {
this.setProperty("angle", value);
this.setPropertyEmitShapeChanged("angle", value);
}

constructor(document: IDocument, profile: IShape, axis: Ray, angle: number) {
Expand Down
4 changes: 2 additions & 2 deletions packages/chili/src/bodys/sweep.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,15 @@ export class SweepedNode extends ParameterShapeNode {
return this.getPrivateValue("profile");
}
set profile(value: IShape) {
this.setProperty("profile", value);
this.setPropertyEmitShapeChanged("profile", value);
}

@Serializer.serialze()
get path() {
return this.getPrivateValue("path");
}
set path(value: IWire) {
this.setProperty("path", value);
this.setPropertyEmitShapeChanged("path", value);
}

constructor(document: IDocument, profile: IShape, path: IWire | IEdge) {
Expand Down
2 changes: 1 addition & 1 deletion packages/chili/src/bodys/wire.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class WireNode extends ParameterShapeNode {
return this.getPrivateValue("edges");
}
set edges(values: IEdge[]) {
this.setProperty("edges", values);
this.setPropertyEmitShapeChanged("edges", values);
}

constructor(document: IDocument, edges: IEdge[]) {
Expand Down

0 comments on commit 77f9dd7

Please sign in to comment.