fluidcad 0.0.2 → 0.0.4
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/README.md +7 -7
- package/lib/dist/common/shape-factory.d.ts +1 -1
- package/lib/dist/oc/boolean-ops.d.ts +2 -2
- package/lib/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/lib/dist/constraints/constraint.d.ts +0 -11
- package/lib/dist/constraints/constraint.js +0 -51
- package/lib/dist/constraints/outside.d.ts +0 -3
- package/lib/dist/constraints/outside.js +0 -4
- package/lib/dist/core/2d/aslot.d.ts +0 -12
- package/lib/dist/core/2d/aslot.js +0 -40
- package/lib/dist/core/2d/crect.d.ts +0 -12
- package/lib/dist/core/2d/crect.js +0 -74
- package/lib/dist/core/2d/face-maker.d.ts +0 -13
- package/lib/dist/core/2d/face-maker.js +0 -119
- package/lib/dist/core/2d/face-maker2.d.ts +0 -6
- package/lib/dist/core/2d/face-maker2.js +0 -54
- package/lib/dist/core/region.d.ts +0 -13
- package/lib/dist/core/region.js +0 -18
- package/lib/dist/features/2d/amove.d.ts +0 -14
- package/lib/dist/features/2d/amove.js +0 -33
- package/lib/dist/features/2d/constraints/constraint.d.ts +0 -11
- package/lib/dist/features/2d/constraints/constraint.js +0 -49
- package/lib/dist/features/2d/constraints/outside.d.ts +0 -3
- package/lib/dist/features/2d/constraints/outside.js +0 -4
- package/lib/dist/features/2d/tarc-two-circles.d.ts +0 -18
- package/lib/dist/features/2d/tarc-two-circles.js +0 -61
- package/lib/dist/features/2d/tcircle-three-tan.d.ts +0 -13
- package/lib/dist/features/2d/tcircle-three-tan.js +0 -33
- package/lib/dist/features/2d/tcircle-two-tan.d.ts +0 -13
- package/lib/dist/features/2d/tcircle-two-tan.js +0 -33
- package/lib/dist/features/Extrude.d.ts +0 -1
- package/lib/dist/features/Extrude.js +0 -1
- package/lib/dist/features/cut-base.d.ts +0 -49
- package/lib/dist/features/cut-base.js +0 -312
- package/lib/dist/features/cut-symmetric.d.ts +0 -23
- package/lib/dist/features/cut-symmetric.js +0 -119
- package/lib/dist/features/cut-two-distances.d.ts +0 -24
- package/lib/dist/features/cut-two-distances.js +0 -110
- package/lib/dist/features/cut.d.ts +0 -27
- package/lib/dist/features/cut.js +0 -101
- package/lib/dist/features/extrude-symmetric.d.ts +0 -28
- package/lib/dist/features/extrude-symmetric.js +0 -177
- package/lib/dist/features/region2d.d.ts +0 -25
- package/lib/dist/features/region2d.js +0 -185
- package/lib/dist/features/repeat-circular2d.d.ts +0 -17
- package/lib/dist/features/repeat-circular2d.js +0 -90
- package/lib/dist/features/repeat-linear2d.d.ts +0 -17
- package/lib/dist/features/repeat-linear2d.js +0 -114
- package/lib/dist/features/revolve-options.d.ts +0 -6
- package/lib/dist/features/revolve-options.js +0 -1
- package/lib/dist/features/split.d.ts +0 -14
- package/lib/dist/features/split.js +0 -74
- package/lib/dist/features/state-scene-object.d.ts +0 -15
- package/lib/dist/features/state-scene-object.js +0 -44
- package/lib/dist/features/state-select.d.ts +0 -21
- package/lib/dist/features/state-select.js +0 -73
- package/lib/dist/features/translate2d.d.ts +0 -16
- package/lib/dist/features/translate2d.js +0 -61
- package/lib/dist/filters/all-filter.d.ts +0 -8
- package/lib/dist/filters/all-filter.js +0 -12
- package/lib/dist/filters/near-point-filter.d.ts +0 -11
- package/lib/dist/filters/near-point-filter.js +0 -33
- package/lib/dist/helpers/resolve-filters.d.ts +0 -6
- package/lib/dist/helpers/resolve-filters.js +0 -25
- package/lib/dist/math/axis.test.d.ts +0 -1
- package/lib/dist/math/axis.test.js +0 -287
- package/lib/dist/math/coordinate-system.test.d.ts +0 -1
- package/lib/dist/math/coordinate-system.test.js +0 -308
- package/lib/dist/math/matrix4.test.d.ts +0 -1
- package/lib/dist/math/matrix4.test.js +0 -357
- package/lib/dist/math/plane.test.d.ts +0 -1
- package/lib/dist/math/plane.test.js +0 -398
- package/lib/dist/math/point.test.d.ts +0 -1
- package/lib/dist/math/point.test.js +0 -385
- package/lib/dist/math/quaternion.test.d.ts +0 -1
- package/lib/dist/math/quaternion.test.js +0 -278
- package/lib/dist/math/vector3d.test.d.ts +0 -1
- package/lib/dist/math/vector3d.test.js +0 -276
- package/lib/dist/oc/constraint-resolver.d.ts +0 -7
- package/lib/dist/oc/constraint-resolver.js +0 -31
- package/lib/dist/oc/constraints/curve-constraint-solver.d.ts +0 -1
- package/lib/dist/oc/constraints/curve-constraint-solver.js +0 -2
- package/lib/dist/oc/constraints/geometric-constraint-solver.d.ts +0 -1
- package/lib/dist/oc/constraints/geometric-constraint-solver.js +0 -5
- package/lib/dist/oc/face-maker.d.ts +0 -14
- package/lib/dist/oc/face-maker.js +0 -191
- package/lib/dist/oc/measure.d.ts +0 -21
- package/lib/dist/oc/measure.js +0 -256
- package/lib/dist/oc/tangent-circle-solver.d.ts +0 -17
- package/lib/dist/oc/tangent-circle-solver.js +0 -72
- package/lib/dist/oc/tangent-line-solver.d.ts +0 -17
- package/lib/dist/oc/tangent-line-solver.js +0 -83
- package/lib/dist/oc/tangent-solver.d.ts +0 -14
- package/lib/dist/oc/tangent-solver.js +0 -199
- package/lib/dist/rendering/builder-context.d.ts +0 -16
- package/lib/dist/rendering/builder-context.js +0 -63
- package/lib/dist/tests/extrude.test.d.ts +0 -1
- package/lib/dist/tests/extrude.test.js +0 -48
- package/lib/dist/tests/features/copy.test.d.ts +0 -1
- package/lib/dist/tests/features/copy.test.js +0 -158
- package/lib/dist/tests/features/dispose.test.d.ts +0 -1
- package/lib/dist/tests/features/dispose.test.js +0 -189
- package/lib/dist/tests/features/part-pick.test.d.ts +0 -1
- package/lib/dist/tests/features/part-pick.test.js +0 -73
- package/lib/dist/tests/features/part-repeat.test.d.ts +0 -1
- package/lib/dist/tests/features/part-repeat.test.js +0 -109
- package/server/dist/fluidcad-server.d.ts +0 -32
- package/server/dist/fluidcad-server.js +0 -150
- package/server/dist/index.d.ts +0 -1
- package/server/dist/index.js +0 -290
- package/server/dist/routes/actions.d.ts +0 -3
- package/server/dist/routes/actions.js +0 -100
- package/server/dist/routes/export.d.ts +0 -3
- package/server/dist/routes/export.js +0 -55
- package/server/dist/routes/properties.d.ts +0 -3
- package/server/dist/routes/properties.js +0 -46
- package/server/dist/routes/screenshot.d.ts +0 -2
- package/server/dist/routes/screenshot.js +0 -76
- package/server/dist/vite-manager.d.ts +0 -10
- package/server/dist/vite-manager.js +0 -64
- package/server/dist/ws-protocol.d.ts +0 -138
- package/server/dist/ws-protocol.js +0 -4
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import { GeometrySceneObject } from "./geometry.js";
|
|
2
|
-
import { LazyVertex } from "../lazy-vertex.js";
|
|
3
|
-
import { Vertex } from "../../common/vertex.js";
|
|
4
|
-
import { createConstraintSolver } from "../../oc/constraints/create-solver.js";
|
|
5
|
-
export class TangentArcTwoObjects extends GeometrySceneObject {
|
|
6
|
-
c1;
|
|
7
|
-
c2;
|
|
8
|
-
radius;
|
|
9
|
-
constructor(c1, c2, radius) {
|
|
10
|
-
super();
|
|
11
|
-
this.c1 = c1;
|
|
12
|
-
this.c2 = c2;
|
|
13
|
-
this.radius = radius;
|
|
14
|
-
}
|
|
15
|
-
build() {
|
|
16
|
-
const plane = this.sketch.getPlane();
|
|
17
|
-
const solver = createConstraintSolver();
|
|
18
|
-
const results = solver.getTangentArcs(plane, this.c1.toQualifiedShape(), this.c2.toQualifiedShape(), this.radius);
|
|
19
|
-
for (let i = 0; i < results.edges.length; i++) {
|
|
20
|
-
this.setState(`edge-${i}`, results.edges[i]);
|
|
21
|
-
}
|
|
22
|
-
if (results.edges.length > 0) {
|
|
23
|
-
const lastEdge = results.edges[results.edges.length - 1];
|
|
24
|
-
const endTangent = results.endTangent;
|
|
25
|
-
const firstVertex = lastEdge.getFirstVertex();
|
|
26
|
-
const lastVertex = lastEdge.getLastVertex();
|
|
27
|
-
const localStart = plane.worldToLocal(firstVertex.toPoint());
|
|
28
|
-
const localEnd = plane.worldToLocal(lastVertex.toPoint());
|
|
29
|
-
this.setState('start', Vertex.fromPoint2D(localStart));
|
|
30
|
-
this.setState('end', Vertex.fromPoint2D(localEnd));
|
|
31
|
-
this.setTangent(endTangent);
|
|
32
|
-
this.setCurrentPosition(localEnd);
|
|
33
|
-
}
|
|
34
|
-
this.addShapes(results.edges);
|
|
35
|
-
}
|
|
36
|
-
start(index = 0) {
|
|
37
|
-
return new LazyVertex(this.generateUniqueName(`start-vertex-${index}`), () => [this.getState('start')]);
|
|
38
|
-
}
|
|
39
|
-
end(index = 0) {
|
|
40
|
-
return new LazyVertex(this.generateUniqueName(`end-vertex-${index}`), () => [this.getState('end')]);
|
|
41
|
-
}
|
|
42
|
-
compareTo(other) {
|
|
43
|
-
if (!(other instanceof TangentArcTwoObjects)) {
|
|
44
|
-
return false;
|
|
45
|
-
}
|
|
46
|
-
return this.c1.compareTo(other.c1) &&
|
|
47
|
-
this.c2.compareTo(other.c2) &&
|
|
48
|
-
this.radius === other.radius;
|
|
49
|
-
}
|
|
50
|
-
getType() {
|
|
51
|
-
return 'tarc';
|
|
52
|
-
}
|
|
53
|
-
getUniqueType() {
|
|
54
|
-
return 'two-objects-tarc';
|
|
55
|
-
}
|
|
56
|
-
serialize() {
|
|
57
|
-
return {
|
|
58
|
-
radius: this.radius
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { GeometrySceneObject } from "./geometry.js";
|
|
2
|
-
import { QualifiedGeometry } from "./constraints/qualified-geometry.js";
|
|
3
|
-
export declare class TangentCircle3Tan extends GeometrySceneObject {
|
|
4
|
-
c1: QualifiedGeometry;
|
|
5
|
-
c2: QualifiedGeometry;
|
|
6
|
-
c3: QualifiedGeometry;
|
|
7
|
-
constructor(c1: QualifiedGeometry, c2: QualifiedGeometry, c3: QualifiedGeometry);
|
|
8
|
-
build(): void;
|
|
9
|
-
compareTo(other: TangentCircle3Tan): boolean;
|
|
10
|
-
getType(): string;
|
|
11
|
-
getUniqueType(): string;
|
|
12
|
-
serialize(): {};
|
|
13
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { GeometrySceneObject } from "./geometry.js";
|
|
2
|
-
import { TangentSolver } from "../../oc/tangent-solver.js";
|
|
3
|
-
export class TangentCircle3Tan extends GeometrySceneObject {
|
|
4
|
-
c1;
|
|
5
|
-
c2;
|
|
6
|
-
c3;
|
|
7
|
-
constructor(c1, c2, c3) {
|
|
8
|
-
super();
|
|
9
|
-
this.c1 = c1;
|
|
10
|
-
this.c2 = c2;
|
|
11
|
-
this.c3 = c3;
|
|
12
|
-
}
|
|
13
|
-
build() {
|
|
14
|
-
const plane = this.sketch.getPlane();
|
|
15
|
-
const edges = TangentSolver.getTangentCircles3Tan(plane, this.c1, this.c2, this.c3);
|
|
16
|
-
this.addShapes(edges);
|
|
17
|
-
}
|
|
18
|
-
compareTo(other) {
|
|
19
|
-
if (!(other instanceof TangentCircle3Tan)) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
return this.c1.compareTo(other.c1) && this.c2.compareTo(other.c2) && this.c3.compareTo(other.c3);
|
|
23
|
-
}
|
|
24
|
-
getType() {
|
|
25
|
-
return 'circle';
|
|
26
|
-
}
|
|
27
|
-
getUniqueType() {
|
|
28
|
-
return 'tcircle-3tan';
|
|
29
|
-
}
|
|
30
|
-
serialize() {
|
|
31
|
-
return {};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import { GeometrySceneObject } from "./geometry.js";
|
|
2
|
-
import { QualifiedSceneObject } from "./constraints/qualified-geometry.js";
|
|
3
|
-
export declare class TwoObjectsTangentCircle extends GeometrySceneObject {
|
|
4
|
-
c1: QualifiedSceneObject;
|
|
5
|
-
c2: QualifiedSceneObject;
|
|
6
|
-
radius: number;
|
|
7
|
-
constructor(c1: QualifiedSceneObject, c2: QualifiedSceneObject, radius: number);
|
|
8
|
-
build(): void;
|
|
9
|
-
compareTo(other: TwoObjectsTangentCircle): boolean;
|
|
10
|
-
getType(): string;
|
|
11
|
-
getUniqueType(): string;
|
|
12
|
-
serialize(): {};
|
|
13
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { GeometrySceneObject } from "./geometry.js";
|
|
2
|
-
import { TangentSolver } from "../../oc/tangent-solver.js";
|
|
3
|
-
export class TwoObjectsTangentCircle extends GeometrySceneObject {
|
|
4
|
-
c1;
|
|
5
|
-
c2;
|
|
6
|
-
radius;
|
|
7
|
-
constructor(c1, c2, radius) {
|
|
8
|
-
super();
|
|
9
|
-
this.c1 = c1;
|
|
10
|
-
this.c2 = c2;
|
|
11
|
-
this.radius = radius;
|
|
12
|
-
}
|
|
13
|
-
build() {
|
|
14
|
-
const plane = this.sketch.getPlane();
|
|
15
|
-
const edges = TangentSolver.getTangentCircles(plane, this.c1, this.c2, this.radius);
|
|
16
|
-
this.addShapes(edges);
|
|
17
|
-
}
|
|
18
|
-
compareTo(other) {
|
|
19
|
-
if (!(other instanceof TwoObjectsTangentCircle)) {
|
|
20
|
-
return false;
|
|
21
|
-
}
|
|
22
|
-
return super.compareTo(other) && this.c1.compareTo(other.c1) && this.c2.compareTo(other.c2) && this.radius === other.radius;
|
|
23
|
-
}
|
|
24
|
-
getType() {
|
|
25
|
-
return 'circle';
|
|
26
|
-
}
|
|
27
|
-
getUniqueType() {
|
|
28
|
-
return 'two-objects-tcircle';
|
|
29
|
-
}
|
|
30
|
-
serialize() {
|
|
31
|
-
return {};
|
|
32
|
-
}
|
|
33
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { Face } from "../common/face.js";
|
|
2
|
-
import { Shape } from "../common/shape.js";
|
|
3
|
-
import { SceneObject } from "../common/scene-object.js";
|
|
4
|
-
import { ExtrudeOptions } from "./extrude-options.js";
|
|
5
|
-
import { Extrudable } from "../helpers/types.js";
|
|
6
|
-
import { LazyVertex } from "./lazy-vertex.js";
|
|
7
|
-
import { ICut } from "../core/interfaces.js";
|
|
8
|
-
import { Point2DLike } from "../math/point.js";
|
|
9
|
-
import { Plane } from "../math/plane.js";
|
|
10
|
-
import { FaceFilterBuilder } from "../filters/face/face-filter.js";
|
|
11
|
-
import { EdgeFilterBuilder } from "../filters/edge/edge-filter.js";
|
|
12
|
-
export interface CutOptions extends ExtrudeOptions {
|
|
13
|
-
}
|
|
14
|
-
export declare abstract class CutBase extends SceneObject implements ICut {
|
|
15
|
-
protected _extrudable: Extrudable | null;
|
|
16
|
-
protected _draft?: number | [number, number];
|
|
17
|
-
protected _endOffset?: number;
|
|
18
|
-
protected _picking: boolean;
|
|
19
|
-
protected _pickPoints: LazyVertex[];
|
|
20
|
-
constructor(extrudable?: Extrudable);
|
|
21
|
-
get extrudable(): Extrudable;
|
|
22
|
-
draft(value: number | [number, number]): this;
|
|
23
|
-
endOffset(value: number): this;
|
|
24
|
-
getDraft(): [number, number];
|
|
25
|
-
getEndOffset(): number | undefined;
|
|
26
|
-
pick(...points: Point2DLike[]): this;
|
|
27
|
-
isPicking(): boolean;
|
|
28
|
-
getPickPoints(): LazyVertex[];
|
|
29
|
-
protected resolvePickedFaces(plane: Plane): Face[] | null;
|
|
30
|
-
removeMetaShapes(removedBy: SceneObject): void;
|
|
31
|
-
clean(allObjects: SceneObject[]): void;
|
|
32
|
-
/**
|
|
33
|
-
* Classifies edges and faces from cleaned result shapes by comparing with
|
|
34
|
-
* original stock shapes. Edges/faces not present in stock are "section" geometry
|
|
35
|
-
* created by the cut. Section edges are further classified by signed distance
|
|
36
|
-
* from the cut plane into start, end, and internal groups.
|
|
37
|
-
*/
|
|
38
|
-
protected classifyCutResult(stockShapes: Shape[], cleanedShapes: Shape[], plane: Plane, cutDistance: number): void;
|
|
39
|
-
protected syncWith(other: CutBase): this;
|
|
40
|
-
compareTo(other: CutBase): boolean;
|
|
41
|
-
startEdges(...args: (number | EdgeFilterBuilder)[]): SceneObject;
|
|
42
|
-
endEdges(...args: (number | EdgeFilterBuilder)[]): SceneObject;
|
|
43
|
-
internalEdges(...args: (number | EdgeFilterBuilder)[]): SceneObject;
|
|
44
|
-
internalFaces(...args: (number | FaceFilterBuilder)[]): SceneObject;
|
|
45
|
-
private buildSuffix;
|
|
46
|
-
private resolveEdges;
|
|
47
|
-
private resolveFaces;
|
|
48
|
-
getType(): string;
|
|
49
|
-
}
|
|
@@ -1,312 +0,0 @@
|
|
|
1
|
-
import { SceneObject } from "../common/scene-object.js";
|
|
2
|
-
import { LazySelectionSceneObject } from "./lazy-scene-object.js";
|
|
3
|
-
import { normalizePoint2D } from "../helpers/normalize.js";
|
|
4
|
-
import { FaceOps } from "../oc/face-ops.js";
|
|
5
|
-
import { FaceMaker2 } from "../oc/face-maker2.js";
|
|
6
|
-
import { EdgeOps } from "../oc/edge-ops.js";
|
|
7
|
-
import { Explorer } from "../oc/explorer.js";
|
|
8
|
-
import { FaceFilterBuilder } from "../filters/face/face-filter.js";
|
|
9
|
-
import { EdgeFilterBuilder } from "../filters/edge/edge-filter.js";
|
|
10
|
-
import { ShapeFilter } from "../filters/filter.js";
|
|
11
|
-
export class CutBase extends SceneObject {
|
|
12
|
-
_extrudable = null;
|
|
13
|
-
_draft;
|
|
14
|
-
_endOffset;
|
|
15
|
-
_picking = false;
|
|
16
|
-
_pickPoints = [];
|
|
17
|
-
constructor(extrudable) {
|
|
18
|
-
super();
|
|
19
|
-
this._extrudable = extrudable ?? null;
|
|
20
|
-
}
|
|
21
|
-
get extrudable() {
|
|
22
|
-
return this._extrudable;
|
|
23
|
-
}
|
|
24
|
-
draft(value) {
|
|
25
|
-
this._draft = value;
|
|
26
|
-
return this;
|
|
27
|
-
}
|
|
28
|
-
endOffset(value) {
|
|
29
|
-
this._endOffset = value;
|
|
30
|
-
return this;
|
|
31
|
-
}
|
|
32
|
-
getDraft() {
|
|
33
|
-
const draft = this._draft;
|
|
34
|
-
if (!draft) {
|
|
35
|
-
return null;
|
|
36
|
-
}
|
|
37
|
-
return draft instanceof Array ? draft : [draft, draft];
|
|
38
|
-
}
|
|
39
|
-
getEndOffset() {
|
|
40
|
-
return this._endOffset;
|
|
41
|
-
}
|
|
42
|
-
pick(...points) {
|
|
43
|
-
this._picking = true;
|
|
44
|
-
this._pickPoints = points.map(p => normalizePoint2D(p));
|
|
45
|
-
return this;
|
|
46
|
-
}
|
|
47
|
-
isPicking() {
|
|
48
|
-
return this._picking;
|
|
49
|
-
}
|
|
50
|
-
getPickPoints() {
|
|
51
|
-
return this._pickPoints;
|
|
52
|
-
}
|
|
53
|
-
resolvePickedFaces(plane) {
|
|
54
|
-
if (!this.isPicking()) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
const sketchShapes = this.extrudable.getGeometries();
|
|
58
|
-
const cells = FaceMaker2.getRegions(sketchShapes, plane, false);
|
|
59
|
-
if (cells.length === 0) {
|
|
60
|
-
return [];
|
|
61
|
-
}
|
|
62
|
-
const pickPoints = this.getPickPoints();
|
|
63
|
-
const selectedCells = [];
|
|
64
|
-
for (const cell of cells) {
|
|
65
|
-
let isSelected = false;
|
|
66
|
-
let pickPoint = null;
|
|
67
|
-
for (const lazyPt of pickPoints) {
|
|
68
|
-
const pt2d = lazyPt.asPoint2D();
|
|
69
|
-
const pt3d = plane.localToWorld(pt2d);
|
|
70
|
-
if (FaceOps.isPointInsideFace(pt3d, cell)) {
|
|
71
|
-
isSelected = true;
|
|
72
|
-
pickPoint = [pt2d.x, pt2d.y];
|
|
73
|
-
break;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
if (isSelected) {
|
|
77
|
-
cell.markAsMetaShape('pick-region-selected');
|
|
78
|
-
cell.metaData = { pickPoint };
|
|
79
|
-
selectedCells.push(cell);
|
|
80
|
-
}
|
|
81
|
-
else {
|
|
82
|
-
cell.markAsMetaShape('pick-region');
|
|
83
|
-
}
|
|
84
|
-
this.addShape(cell);
|
|
85
|
-
for (const edge of cell.getEdges()) {
|
|
86
|
-
edge.markAsMetaShape('pick-edge');
|
|
87
|
-
this.addShape(edge);
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
return selectedCells;
|
|
91
|
-
}
|
|
92
|
-
removeMetaShapes(removedBy) {
|
|
93
|
-
for (const shape of this.getAddedShapes()) {
|
|
94
|
-
if (shape.isMetaShape()) {
|
|
95
|
-
this.removeShape(shape, removedBy);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
clean(allObjects) {
|
|
100
|
-
if (!this.isPicking()) {
|
|
101
|
-
return;
|
|
102
|
-
}
|
|
103
|
-
const lastObject = allObjects[allObjects.length - 1];
|
|
104
|
-
if (lastObject !== this) {
|
|
105
|
-
this.removeMetaShapes(lastObject);
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Classifies edges and faces from cleaned result shapes by comparing with
|
|
110
|
-
* original stock shapes. Edges/faces not present in stock are "section" geometry
|
|
111
|
-
* created by the cut. Section edges are further classified by signed distance
|
|
112
|
-
* from the cut plane into start, end, and internal groups.
|
|
113
|
-
*/
|
|
114
|
-
classifyCutResult(stockShapes, cleanedShapes, plane, cutDistance) {
|
|
115
|
-
// Collect stock edge midpoints for geometric comparison
|
|
116
|
-
const stockEdgeMidpoints = [];
|
|
117
|
-
for (const stock of stockShapes) {
|
|
118
|
-
const edges = Explorer.findEdgesWrapped(stock);
|
|
119
|
-
for (const edge of edges) {
|
|
120
|
-
stockEdgeMidpoints.push(EdgeOps.getEdgeMidPoint(edge));
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
const tolerance = 1e-6;
|
|
124
|
-
const isStockEdge = (edge) => {
|
|
125
|
-
const mid = EdgeOps.getEdgeMidPoint(edge);
|
|
126
|
-
return stockEdgeMidpoints.some(sm => Math.abs(mid.x - sm.x) < tolerance &&
|
|
127
|
-
Math.abs(mid.y - sm.y) < tolerance &&
|
|
128
|
-
Math.abs(mid.z - sm.z) < tolerance);
|
|
129
|
-
};
|
|
130
|
-
// Find section edges from cleaned result (edges not in stock)
|
|
131
|
-
const sectionEdges = [];
|
|
132
|
-
const sectionEdgeSet = new Set();
|
|
133
|
-
for (const shape of cleanedShapes) {
|
|
134
|
-
const edges = Explorer.findEdgesWrapped(shape);
|
|
135
|
-
for (const edge of edges) {
|
|
136
|
-
if (!isStockEdge(edge)) {
|
|
137
|
-
sectionEdges.push(edge);
|
|
138
|
-
sectionEdgeSet.add(edge);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
// Internal faces: faces where ALL edges are section edges (not from stock).
|
|
143
|
-
// Modified stock faces (e.g., top face with holes) still have stock edges
|
|
144
|
-
// on their outer boundary, so they are correctly excluded.
|
|
145
|
-
const internalFaces = [];
|
|
146
|
-
for (const shape of cleanedShapes) {
|
|
147
|
-
const faces = Explorer.findFacesWrapped(shape);
|
|
148
|
-
for (const f of faces) {
|
|
149
|
-
const faceEdges = f.getEdges();
|
|
150
|
-
if (faceEdges.length > 0 && faceEdges.every(e => !isStockEdge(e))) {
|
|
151
|
-
internalFaces.push(f);
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
// Classify section edges by signed distance from cut plane
|
|
156
|
-
const startEdges = [];
|
|
157
|
-
const endEdges = [];
|
|
158
|
-
const internalEdges = [];
|
|
159
|
-
if (plane && sectionEdges.length > 0) {
|
|
160
|
-
const isThroughAll = cutDistance === 0;
|
|
161
|
-
const dists = sectionEdges.map(edge => ({
|
|
162
|
-
edge,
|
|
163
|
-
d: plane.signedDistanceToPoint(EdgeOps.getEdgeMidPoint(edge))
|
|
164
|
-
}));
|
|
165
|
-
const startDist = isThroughAll ? Math.max(...dists.map(e => e.d)) : 0;
|
|
166
|
-
const endDist = isThroughAll ? Math.min(...dists.map(e => e.d)) : -cutDistance;
|
|
167
|
-
const distTolerance = 1e-4;
|
|
168
|
-
for (const { edge, d } of dists) {
|
|
169
|
-
if (Math.abs(d - startDist) < distTolerance) {
|
|
170
|
-
startEdges.push(edge);
|
|
171
|
-
}
|
|
172
|
-
else if (Math.abs(d - endDist) < distTolerance) {
|
|
173
|
-
endEdges.push(edge);
|
|
174
|
-
}
|
|
175
|
-
else {
|
|
176
|
-
internalEdges.push(edge);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
this.setState('section-edges', sectionEdges);
|
|
181
|
-
this.setState('start-edges', startEdges);
|
|
182
|
-
this.setState('end-edges', endEdges);
|
|
183
|
-
this.setState('internal-edges', internalEdges);
|
|
184
|
-
this.setState('internal-faces', internalFaces);
|
|
185
|
-
}
|
|
186
|
-
syncWith(other) {
|
|
187
|
-
this._draft = other._draft;
|
|
188
|
-
this._endOffset = other._endOffset;
|
|
189
|
-
this._fusionScope = other.getFusionScope();
|
|
190
|
-
this._picking = other._picking;
|
|
191
|
-
this._pickPoints = other._pickPoints;
|
|
192
|
-
return this;
|
|
193
|
-
}
|
|
194
|
-
compareTo(other) {
|
|
195
|
-
if (!super.compareTo(other)) {
|
|
196
|
-
return false;
|
|
197
|
-
}
|
|
198
|
-
if (this._fusionScope !== other._fusionScope
|
|
199
|
-
|| this._endOffset !== other._endOffset) {
|
|
200
|
-
return false;
|
|
201
|
-
}
|
|
202
|
-
if (this._picking !== other._picking) {
|
|
203
|
-
return false;
|
|
204
|
-
}
|
|
205
|
-
if (this._pickPoints.length !== other._pickPoints.length) {
|
|
206
|
-
return false;
|
|
207
|
-
}
|
|
208
|
-
for (let i = 0; i < this._pickPoints.length; i++) {
|
|
209
|
-
if (!this._pickPoints[i].compareTo(other._pickPoints[i])) {
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
let thisDraft = this._draft || [0, 0];
|
|
214
|
-
let otherDraft = other._draft || [0, 0];
|
|
215
|
-
thisDraft = this._draft instanceof Array ? this._draft : [this._draft, this._draft];
|
|
216
|
-
otherDraft = other._draft instanceof Array ? other._draft : [other._draft, other._draft];
|
|
217
|
-
if (thisDraft[0] !== otherDraft[0] || thisDraft[1] !== otherDraft[1]) {
|
|
218
|
-
return false;
|
|
219
|
-
}
|
|
220
|
-
return true;
|
|
221
|
-
}
|
|
222
|
-
startEdges(...args) {
|
|
223
|
-
const suffix = this.buildSuffix('start-edges', args);
|
|
224
|
-
return new LazySelectionSceneObject(`${this.generateUniqueName(suffix)}`, (parent) => {
|
|
225
|
-
const edges = parent.getState('start-edges') || [];
|
|
226
|
-
const transform = parent.getTransform();
|
|
227
|
-
const originalEdges = transform
|
|
228
|
-
? (this.getState('start-edges') || [])
|
|
229
|
-
: null;
|
|
230
|
-
return this.resolveEdges(edges, args, transform, originalEdges);
|
|
231
|
-
}, this);
|
|
232
|
-
}
|
|
233
|
-
endEdges(...args) {
|
|
234
|
-
const suffix = this.buildSuffix('end-edges', args);
|
|
235
|
-
return new LazySelectionSceneObject(`${this.generateUniqueName(suffix)}`, (parent) => {
|
|
236
|
-
const edges = parent.getState('end-edges') || [];
|
|
237
|
-
const transform = parent.getTransform();
|
|
238
|
-
const originalEdges = transform
|
|
239
|
-
? (this.getState('end-edges') || [])
|
|
240
|
-
: null;
|
|
241
|
-
return this.resolveEdges(edges, args, transform, originalEdges);
|
|
242
|
-
}, this);
|
|
243
|
-
}
|
|
244
|
-
internalEdges(...args) {
|
|
245
|
-
const suffix = this.buildSuffix('internal-edges', args);
|
|
246
|
-
return new LazySelectionSceneObject(`${this.generateUniqueName(suffix)}`, (parent) => {
|
|
247
|
-
const edges = parent.getState('internal-edges') || [];
|
|
248
|
-
const transform = parent.getTransform();
|
|
249
|
-
const originalEdges = transform
|
|
250
|
-
? (this.getState('internal-edges') || [])
|
|
251
|
-
: null;
|
|
252
|
-
return this.resolveEdges(edges, args, transform, originalEdges);
|
|
253
|
-
}, this);
|
|
254
|
-
}
|
|
255
|
-
internalFaces(...args) {
|
|
256
|
-
const suffix = this.buildSuffix('internal-faces', args);
|
|
257
|
-
return new LazySelectionSceneObject(`${this.generateUniqueName(suffix)}`, (parent) => {
|
|
258
|
-
const faces = parent.getState('internal-faces') || [];
|
|
259
|
-
const transform = parent.getTransform();
|
|
260
|
-
const originalFaces = transform
|
|
261
|
-
? (this.getState('internal-faces') || [])
|
|
262
|
-
: null;
|
|
263
|
-
return this.resolveFaces(faces, args, transform, originalFaces);
|
|
264
|
-
}, this);
|
|
265
|
-
}
|
|
266
|
-
buildSuffix(prefix, args) {
|
|
267
|
-
if (args.length === 0) {
|
|
268
|
-
return prefix;
|
|
269
|
-
}
|
|
270
|
-
const key = args.map(a => typeof a === 'number' ? a : 'f').join('-');
|
|
271
|
-
return `${prefix}-${key}`;
|
|
272
|
-
}
|
|
273
|
-
resolveEdges(shapes, args, transform = null, originalShapes = null) {
|
|
274
|
-
if (args.length === 0) {
|
|
275
|
-
return shapes;
|
|
276
|
-
}
|
|
277
|
-
if (args.every(a => typeof a === 'number')) {
|
|
278
|
-
const indices = args;
|
|
279
|
-
let filters = indices.map(i => new EdgeFilterBuilder().atIndex(i, shapes, originalShapes));
|
|
280
|
-
if (transform) {
|
|
281
|
-
filters = filters.map(f => f.transform(transform));
|
|
282
|
-
}
|
|
283
|
-
return new ShapeFilter(shapes, ...filters).apply();
|
|
284
|
-
}
|
|
285
|
-
let filters = args.filter(a => a instanceof EdgeFilterBuilder);
|
|
286
|
-
if (transform) {
|
|
287
|
-
filters = filters.map(f => f.transform(transform));
|
|
288
|
-
}
|
|
289
|
-
return new ShapeFilter(shapes, ...filters).apply();
|
|
290
|
-
}
|
|
291
|
-
resolveFaces(shapes, args, transform = null, originalShapes = null) {
|
|
292
|
-
if (args.length === 0) {
|
|
293
|
-
return shapes;
|
|
294
|
-
}
|
|
295
|
-
if (args.every(a => typeof a === 'number')) {
|
|
296
|
-
const indices = args;
|
|
297
|
-
let filters = indices.map(i => new FaceFilterBuilder().atIndex(i, shapes, originalShapes));
|
|
298
|
-
if (transform) {
|
|
299
|
-
filters = filters.map(f => f.transform(transform));
|
|
300
|
-
}
|
|
301
|
-
return new ShapeFilter(shapes, ...filters).apply();
|
|
302
|
-
}
|
|
303
|
-
let filters = args.filter(a => a instanceof FaceFilterBuilder);
|
|
304
|
-
if (transform) {
|
|
305
|
-
filters = filters.map(f => f.transform(transform));
|
|
306
|
-
}
|
|
307
|
-
return new ShapeFilter(shapes, ...filters).apply();
|
|
308
|
-
}
|
|
309
|
-
getType() {
|
|
310
|
-
return "cut";
|
|
311
|
-
}
|
|
312
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { BuildSceneObjectContext, SceneObject } from "../common/scene-object.js";
|
|
2
|
-
import { Extrudable } from "../helpers/types.js";
|
|
3
|
-
import { CutBase } from "./cut-base.js";
|
|
4
|
-
export declare class CutSymmetric extends CutBase {
|
|
5
|
-
distance: number;
|
|
6
|
-
constructor(distance: number, extrudable?: Extrudable);
|
|
7
|
-
build(context: BuildSceneObjectContext): void;
|
|
8
|
-
getDependencies(): SceneObject[];
|
|
9
|
-
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
10
|
-
compareTo(other: CutSymmetric): boolean;
|
|
11
|
-
edges(...indices: number[]): SceneObject;
|
|
12
|
-
getType(): string;
|
|
13
|
-
serialize(): {
|
|
14
|
-
extrudable: any;
|
|
15
|
-
distance: number;
|
|
16
|
-
symmetric: boolean;
|
|
17
|
-
draft: [number, number];
|
|
18
|
-
endOffset: number;
|
|
19
|
-
fusionScope: import("./extrude-options.js").FusionScope;
|
|
20
|
-
picking: true;
|
|
21
|
-
pickPoints: number[][];
|
|
22
|
-
};
|
|
23
|
-
}
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
import { BooleanOps } from "../oc/boolean-ops.js";
|
|
2
|
-
import { ShapeOps } from "../oc/shape-ops.js";
|
|
3
|
-
import { ExtrudeOps } from "../oc/extrude-ops.js";
|
|
4
|
-
import { ExtrudeThroughAll } from "./infinite-extrude.js";
|
|
5
|
-
import { LazySelectionSceneObject } from "./lazy-scene-object.js";
|
|
6
|
-
import { CutBase } from "./cut-base.js";
|
|
7
|
-
import { FaceMaker2 } from "../oc/face-maker2.js";
|
|
8
|
-
export class CutSymmetric extends CutBase {
|
|
9
|
-
distance;
|
|
10
|
-
constructor(distance, extrudable) {
|
|
11
|
-
super(extrudable);
|
|
12
|
-
this.distance = distance;
|
|
13
|
-
}
|
|
14
|
-
build(context) {
|
|
15
|
-
const plane = this.extrudable.getPlane();
|
|
16
|
-
const pickedFaces = this.resolvePickedFaces(plane);
|
|
17
|
-
if (pickedFaces !== null && pickedFaces.length === 0) {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
const scope = this.resolveFusionScope(context.getSceneObjects());
|
|
21
|
-
const sceneObjects = new Map();
|
|
22
|
-
for (const obj of scope) {
|
|
23
|
-
const shapes = obj.getShapes({ excludeMeta: false }, 'solid');
|
|
24
|
-
if (shapes.length === 0) {
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
sceneObjects.set(obj, shapes);
|
|
28
|
-
}
|
|
29
|
-
let toolShapes;
|
|
30
|
-
const isThroughAll = this.distance === 0;
|
|
31
|
-
if (isThroughAll && !pickedFaces) {
|
|
32
|
-
const extrudeThroughAll = new ExtrudeThroughAll(this.extrudable, true, false);
|
|
33
|
-
toolShapes = extrudeThroughAll.build();
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
const faces = pickedFaces ?? FaceMaker2.getRegions(this.extrudable.getGeometries(), plane);
|
|
37
|
-
const effectiveDistance = isThroughAll ? 10000 : this.distance;
|
|
38
|
-
const vec = plane.normal.multiply(effectiveDistance);
|
|
39
|
-
const translateVec = vec.multiply(-0.5);
|
|
40
|
-
toolShapes = [];
|
|
41
|
-
for (const face of faces) {
|
|
42
|
-
const { solid: rawSolid } = ExtrudeOps.makePrismFromVec(face, vec);
|
|
43
|
-
const solid = ShapeOps.translateShape(ShapeOps.cleanShape(rawSolid), translateVec);
|
|
44
|
-
toolShapes.push(solid);
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
this.extrudable.removeShapes(this);
|
|
48
|
-
const shapeObjectMap = new Map();
|
|
49
|
-
for (const [obj, shapes] of sceneObjects) {
|
|
50
|
-
for (const shape of shapes) {
|
|
51
|
-
shapeObjectMap.set(shape, obj);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
const stock = Array.from(shapeObjectMap.keys());
|
|
55
|
-
const cutResult = BooleanOps.cutMultiShape(stock, toolShapes, plane, this.distance);
|
|
56
|
-
const cleanedShapes = [];
|
|
57
|
-
for (const shape of stock) {
|
|
58
|
-
const list = cutResult.modified(shape);
|
|
59
|
-
if (list.length) {
|
|
60
|
-
for (const newShape of list) {
|
|
61
|
-
const s = ShapeOps.cleanShape(newShape);
|
|
62
|
-
this.addShape(s);
|
|
63
|
-
cleanedShapes.push(s);
|
|
64
|
-
}
|
|
65
|
-
const obj = shapeObjectMap.get(shape);
|
|
66
|
-
obj.removeShape(shape, this);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
this.classifyCutResult(stock, cleanedShapes, plane, this.distance);
|
|
70
|
-
}
|
|
71
|
-
getDependencies() {
|
|
72
|
-
return this.extrudable ? [this.extrudable] : [];
|
|
73
|
-
}
|
|
74
|
-
createCopy(remap) {
|
|
75
|
-
const extrudable = this.extrudable
|
|
76
|
-
? (remap.get(this.extrudable) || this.extrudable)
|
|
77
|
-
: undefined;
|
|
78
|
-
return new CutSymmetric(this.distance, extrudable).syncWith(this);
|
|
79
|
-
}
|
|
80
|
-
compareTo(other) {
|
|
81
|
-
if (!(other instanceof CutSymmetric)) {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
if (!super.compareTo(other)) {
|
|
85
|
-
return false;
|
|
86
|
-
}
|
|
87
|
-
if (this.distance !== other.distance) {
|
|
88
|
-
return false;
|
|
89
|
-
}
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
edges(...indices) {
|
|
93
|
-
const suffix = indices.length > 0 ? `section-edges-${indices.join('-')}` : 'section-edges';
|
|
94
|
-
return new LazySelectionSceneObject(`${this.getOrder()}-cut-symmetric-${suffix}`, (parent) => {
|
|
95
|
-
const edges = parent.getState('section-edges') || [];
|
|
96
|
-
if (indices.length === 0) {
|
|
97
|
-
return edges;
|
|
98
|
-
}
|
|
99
|
-
return indices.filter(i => i >= 0 && i < edges.length).map(i => edges[i]);
|
|
100
|
-
}, this);
|
|
101
|
-
}
|
|
102
|
-
getType() {
|
|
103
|
-
return "cut-symmetric";
|
|
104
|
-
}
|
|
105
|
-
serialize() {
|
|
106
|
-
return {
|
|
107
|
-
extrudable: this.extrudable.serialize(),
|
|
108
|
-
distance: this.distance,
|
|
109
|
-
symmetric: true,
|
|
110
|
-
draft: this.getDraft(),
|
|
111
|
-
endOffset: this.getEndOffset(),
|
|
112
|
-
fusionScope: this.getFusionScope(),
|
|
113
|
-
picking: this.isPicking() || undefined,
|
|
114
|
-
pickPoints: this.isPicking()
|
|
115
|
-
? this._pickPoints.map(p => { const pt = p.asPoint2D(); return [pt.x, pt.y]; })
|
|
116
|
-
: undefined,
|
|
117
|
-
};
|
|
118
|
-
}
|
|
119
|
-
}
|