fluidcad 0.0.3 → 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 +2 -2
- 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,24 +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 CutTwoDistances extends CutBase {
|
|
5
|
-
distance1: number;
|
|
6
|
-
distance2: number;
|
|
7
|
-
constructor(distance1: number, distance2: number, extrudable?: Extrudable);
|
|
8
|
-
build(context: BuildSceneObjectContext): void;
|
|
9
|
-
getDependencies(): SceneObject[];
|
|
10
|
-
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
11
|
-
compareTo(other: CutTwoDistances): boolean;
|
|
12
|
-
edges(...indices: number[]): SceneObject;
|
|
13
|
-
getUniqueType(): string;
|
|
14
|
-
serialize(): {
|
|
15
|
-
extrudable: any;
|
|
16
|
-
distance1: number;
|
|
17
|
-
distance2: number;
|
|
18
|
-
draft: [number, number];
|
|
19
|
-
endOffset: number;
|
|
20
|
-
fusionScope: import("./extrude-options.js").FusionScope;
|
|
21
|
-
picking: true;
|
|
22
|
-
pickPoints: number[][];
|
|
23
|
-
};
|
|
24
|
-
}
|
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
import { Extruder } from "./simple-extruder.js";
|
|
2
|
-
import { BooleanOps } from "../oc/boolean-ops.js";
|
|
3
|
-
import { ShapeOps } from "../oc/shape-ops.js";
|
|
4
|
-
import { LazySelectionSceneObject } from "./lazy-scene-object.js";
|
|
5
|
-
import { CutBase } from "./cut-base.js";
|
|
6
|
-
import { FaceMaker2 } from "../oc/face-maker2.js";
|
|
7
|
-
export class CutTwoDistances extends CutBase {
|
|
8
|
-
distance1;
|
|
9
|
-
distance2;
|
|
10
|
-
constructor(distance1, distance2, extrudable) {
|
|
11
|
-
super(extrudable);
|
|
12
|
-
this.distance1 = distance1;
|
|
13
|
-
this.distance2 = distance2;
|
|
14
|
-
}
|
|
15
|
-
build(context) {
|
|
16
|
-
const plane = this.extrudable.getPlane();
|
|
17
|
-
const pickedFaces = this.resolvePickedFaces(plane);
|
|
18
|
-
if (pickedFaces !== null && pickedFaces.length === 0) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
const scope = this.resolveFusionScope(context.getSceneObjects());
|
|
22
|
-
const sceneObjects = new Map();
|
|
23
|
-
for (const obj of scope) {
|
|
24
|
-
const shapes = obj.getShapes({}, 'solid');
|
|
25
|
-
if (shapes.length === 0) {
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
sceneObjects.set(obj, shapes);
|
|
29
|
-
}
|
|
30
|
-
const faces = pickedFaces ?? FaceMaker2.getRegions(this.extrudable.getGeometries(), plane);
|
|
31
|
-
// Positive distance = reverse normal direction, negate before passing to Extruder
|
|
32
|
-
const extruder1 = new Extruder(faces, plane, -this.distance1, this.getDraft(), this.getEndOffset());
|
|
33
|
-
const extrusions1 = extruder1.extrude();
|
|
34
|
-
const extruder2 = new Extruder(faces, plane, this.distance2, this.getDraft(), this.getEndOffset());
|
|
35
|
-
const extrusions2 = extruder2.extrude();
|
|
36
|
-
const all = [...extrusions1, ...extrusions2];
|
|
37
|
-
const { result: toolShapes } = BooleanOps.fuse(all);
|
|
38
|
-
this.extrudable.removeShapes(this);
|
|
39
|
-
const shapeObjectMap = new Map();
|
|
40
|
-
for (const [obj, shapes] of sceneObjects) {
|
|
41
|
-
for (const shape of shapes) {
|
|
42
|
-
shapeObjectMap.set(shape, obj);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
const stock = Array.from(shapeObjectMap.keys());
|
|
46
|
-
const cutResult = BooleanOps.cutMultiShape(stock, toolShapes, plane, this.distance1);
|
|
47
|
-
const cleanedShapes = [];
|
|
48
|
-
for (const shape of stock) {
|
|
49
|
-
const list = cutResult.modified(shape);
|
|
50
|
-
if (list.length) {
|
|
51
|
-
for (const newShape of list) {
|
|
52
|
-
const s = ShapeOps.cleanShape(newShape);
|
|
53
|
-
this.addShape(s);
|
|
54
|
-
cleanedShapes.push(s);
|
|
55
|
-
}
|
|
56
|
-
const obj = shapeObjectMap.get(shape);
|
|
57
|
-
obj.removeShape(shape, this);
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
this.classifyCutResult(stock, cleanedShapes, plane, this.distance1);
|
|
61
|
-
}
|
|
62
|
-
getDependencies() {
|
|
63
|
-
return this.extrudable ? [this.extrudable] : [];
|
|
64
|
-
}
|
|
65
|
-
createCopy(remap) {
|
|
66
|
-
const extrudable = this.extrudable
|
|
67
|
-
? (remap.get(this.extrudable) || this.extrudable)
|
|
68
|
-
: undefined;
|
|
69
|
-
return new CutTwoDistances(this.distance1, this.distance2, extrudable).syncWith(this);
|
|
70
|
-
}
|
|
71
|
-
compareTo(other) {
|
|
72
|
-
if (!(other instanceof CutTwoDistances)) {
|
|
73
|
-
return false;
|
|
74
|
-
}
|
|
75
|
-
if (!super.compareTo(other)) {
|
|
76
|
-
return false;
|
|
77
|
-
}
|
|
78
|
-
if (this.distance1 !== other.distance1 || this.distance2 !== other.distance2) {
|
|
79
|
-
return false;
|
|
80
|
-
}
|
|
81
|
-
return true;
|
|
82
|
-
}
|
|
83
|
-
edges(...indices) {
|
|
84
|
-
const suffix = indices.length > 0 ? `section-edges-${indices.join('-')}` : 'section-edges';
|
|
85
|
-
return new LazySelectionSceneObject(`${this.getOrder()}-cut-two-distances-${suffix}`, (parent) => {
|
|
86
|
-
const edges = parent.getState('section-edges') || [];
|
|
87
|
-
if (indices.length === 0) {
|
|
88
|
-
return edges;
|
|
89
|
-
}
|
|
90
|
-
return indices.filter(i => i >= 0 && i < edges.length).map(i => edges[i]);
|
|
91
|
-
}, this);
|
|
92
|
-
}
|
|
93
|
-
getUniqueType() {
|
|
94
|
-
return 'cut-by-two-distances';
|
|
95
|
-
}
|
|
96
|
-
serialize() {
|
|
97
|
-
return {
|
|
98
|
-
extrudable: this.extrudable.serialize(),
|
|
99
|
-
distance1: this.distance1,
|
|
100
|
-
distance2: this.distance2,
|
|
101
|
-
draft: this.getDraft(),
|
|
102
|
-
endOffset: this.getEndOffset(),
|
|
103
|
-
fusionScope: this.getFusionScope(),
|
|
104
|
-
picking: this.isPicking() || undefined,
|
|
105
|
-
pickPoints: this.isPicking()
|
|
106
|
-
? this._pickPoints.map(p => { const pt = p.asPoint2D(); return [pt.x, pt.y]; })
|
|
107
|
-
: undefined,
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { BuildSceneObjectContext, SceneObject } from "../common/scene-object.js";
|
|
2
|
-
import { ExtrudeOptions } from "./extrude-options.js";
|
|
3
|
-
import { Extrudable } from "../helpers/types.js";
|
|
4
|
-
export interface CutOptions extends ExtrudeOptions {
|
|
5
|
-
}
|
|
6
|
-
export type CutDirection = 'normal' | 'reversed' | 'symmetric';
|
|
7
|
-
export type CutRotation = {
|
|
8
|
-
x?: number;
|
|
9
|
-
y?: number;
|
|
10
|
-
};
|
|
11
|
-
export declare class Cut extends SceneObject {
|
|
12
|
-
private extrudable;
|
|
13
|
-
distance: number;
|
|
14
|
-
options: CutOptions;
|
|
15
|
-
isThroughAll: boolean;
|
|
16
|
-
constructor(extrudable: Extrudable, distance: number, options?: CutOptions);
|
|
17
|
-
build(context: BuildSceneObjectContext): void;
|
|
18
|
-
clone(): SceneObject[];
|
|
19
|
-
compareTo(other: Cut): boolean;
|
|
20
|
-
getType(): string;
|
|
21
|
-
serialize(): {
|
|
22
|
-
extrudable: any;
|
|
23
|
-
distance: number;
|
|
24
|
-
isThroughAll: boolean;
|
|
25
|
-
options: CutOptions;
|
|
26
|
-
};
|
|
27
|
-
}
|
package/lib/dist/features/cut.js
DELETED
|
@@ -1,101 +0,0 @@
|
|
|
1
|
-
import { SceneObject } from "../common/scene-object.js";
|
|
2
|
-
import { ExtrudeThroughAll } from "./infinite-extrude.js";
|
|
3
|
-
import { Sketch } from "./2d/sketch.js";
|
|
4
|
-
import { FaceMaker } from "../core/2d/face-maker.js";
|
|
5
|
-
import { Extruder } from "./simple-extruder.js";
|
|
6
|
-
import { BooleanOps } from "../oc/boolean-ops.js";
|
|
7
|
-
import { ShapeOps } from "../oc/shape-ops.js";
|
|
8
|
-
export class Cut extends SceneObject {
|
|
9
|
-
extrudable;
|
|
10
|
-
distance;
|
|
11
|
-
options;
|
|
12
|
-
isThroughAll = false;
|
|
13
|
-
constructor(extrudable, distance, options = {}) {
|
|
14
|
-
super();
|
|
15
|
-
this.extrudable = extrudable;
|
|
16
|
-
this.distance = distance;
|
|
17
|
-
this.options = options;
|
|
18
|
-
this.isThroughAll = this.distance === 0;
|
|
19
|
-
}
|
|
20
|
-
build(context) {
|
|
21
|
-
let sceneObjects;
|
|
22
|
-
sceneObjects = new Map();
|
|
23
|
-
for (const obj of context.getSceneObjects()) {
|
|
24
|
-
const shapes = obj.getShapes(false, 'solid');
|
|
25
|
-
if (shapes.length === 0) {
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
sceneObjects.set(obj, shapes);
|
|
29
|
-
}
|
|
30
|
-
console.log('Cut: Scene objects for cut:', Array.from(sceneObjects.keys()).map(o => o.getType()));
|
|
31
|
-
let distance = this.distance === 0 ? 0 : -this.distance;
|
|
32
|
-
let extrusionShapes = [];
|
|
33
|
-
if (this.isThroughAll) {
|
|
34
|
-
const extrudeThroughAll = new ExtrudeThroughAll(this.extrudable, false, true);
|
|
35
|
-
extrusionShapes = extrudeThroughAll.build();
|
|
36
|
-
}
|
|
37
|
-
else {
|
|
38
|
-
const wires = this.extrudable.getGeometries();
|
|
39
|
-
const faces = FaceMaker.getFaces(wires, this.extrudable.getPlane());
|
|
40
|
-
const plane = this.extrudable.getPlane();
|
|
41
|
-
const extruder = new Extruder(faces, plane, distance, this.options);
|
|
42
|
-
extrusionShapes = extruder.extrude();
|
|
43
|
-
}
|
|
44
|
-
this.extrudable.removeShapes(this);
|
|
45
|
-
const shapeObjectMap = new Map();
|
|
46
|
-
for (const [obj, shapes] of sceneObjects) {
|
|
47
|
-
for (const shape of shapes) {
|
|
48
|
-
shapeObjectMap.set(shape, obj);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
const stock = Array.from(shapeObjectMap.keys());
|
|
52
|
-
console.log('Cut: Stock shapes count:', stock.length);
|
|
53
|
-
const toBeRemoved = extrusionShapes;
|
|
54
|
-
console.log('Cut: Stock shapes count:', stock.length);
|
|
55
|
-
console.log('Cut: To be removed shapes count:', toBeRemoved.length);
|
|
56
|
-
const cutResult = BooleanOps.cutMultiShape(stock, toBeRemoved);
|
|
57
|
-
for (const shape of stock) {
|
|
58
|
-
const list = cutResult.modified(shape);
|
|
59
|
-
console.log('Cut: Modified shapes for shape:', list.length);
|
|
60
|
-
if (list.length) {
|
|
61
|
-
for (const newShape of list) {
|
|
62
|
-
const s = ShapeOps.cleanShape(newShape);
|
|
63
|
-
console.log('Cut: Adding modified shape:', s);
|
|
64
|
-
this.addShape(s);
|
|
65
|
-
}
|
|
66
|
-
const obj = shapeObjectMap.get(shape);
|
|
67
|
-
obj.removeShape(shape, this);
|
|
68
|
-
}
|
|
69
|
-
console.log('Cut: Shape modified count:', list.length);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
clone() {
|
|
73
|
-
const extrudableClone = this.extrudable.clone();
|
|
74
|
-
const extrudable = extrudableClone.find(c => c instanceof Sketch);
|
|
75
|
-
const cutClone = new Cut(extrudable, this.distance, this.options);
|
|
76
|
-
return [...extrudableClone, cutClone];
|
|
77
|
-
}
|
|
78
|
-
compareTo(other) {
|
|
79
|
-
if (!(other instanceof Cut)) {
|
|
80
|
-
return false;
|
|
81
|
-
}
|
|
82
|
-
if (this.distance !== other.distance) {
|
|
83
|
-
return false;
|
|
84
|
-
}
|
|
85
|
-
if (JSON.stringify(this.options || {}) !== JSON.stringify(other.options || {})) {
|
|
86
|
-
return false;
|
|
87
|
-
}
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
getType() {
|
|
91
|
-
return "cut";
|
|
92
|
-
}
|
|
93
|
-
serialize() {
|
|
94
|
-
return {
|
|
95
|
-
extrudable: this.extrudable.serialize(),
|
|
96
|
-
distance: this.distance,
|
|
97
|
-
isThroughAll: this.isThroughAll,
|
|
98
|
-
options: this.options
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { BuildSceneObjectContext } from "../common/scene-object.js";
|
|
2
|
-
import { ExtrudeOptions } from "./extrude-options.js";
|
|
3
|
-
import { ExtrudeBase } from "./extrude-base.js";
|
|
4
|
-
import { SceneObject } from "../common/scene-object.js";
|
|
5
|
-
import { Extrudable } from "../helpers/types.js";
|
|
6
|
-
export declare class ExtrudeSymmetric extends ExtrudeBase {
|
|
7
|
-
extrudable: Extrudable;
|
|
8
|
-
distance?: number;
|
|
9
|
-
options: ExtrudeOptions;
|
|
10
|
-
constructor(extrudable: Extrudable, distance?: number, options?: ExtrudeOptions);
|
|
11
|
-
build(context: BuildSceneObjectContext): void;
|
|
12
|
-
private applyDraft;
|
|
13
|
-
private doExtrude;
|
|
14
|
-
private getUniqueName;
|
|
15
|
-
startFace(...indices: number[]): SceneObject;
|
|
16
|
-
endFace(...indices: number[]): SceneObject;
|
|
17
|
-
startEdge(...indices: number[]): SceneObject;
|
|
18
|
-
endEdge(...indices: number[]): SceneObject;
|
|
19
|
-
sideFace(...indices: number[]): SceneObject;
|
|
20
|
-
compareTo(other: ExtrudeSymmetric): boolean;
|
|
21
|
-
getUniqueType(): string;
|
|
22
|
-
serialize(): {
|
|
23
|
-
extrudables: any;
|
|
24
|
-
distance: number;
|
|
25
|
-
symmetric: boolean;
|
|
26
|
-
options: ExtrudeOptions;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
import { rad } from "../helpers/math-helpers.js";
|
|
2
|
-
import { ExtrudeBase } from "./extrude-base.js";
|
|
3
|
-
import { fuseWithSceneObjects } from "../helpers/scene-helpers.js";
|
|
4
|
-
import { FaceMaker } from "../core/2d/face-maker.js";
|
|
5
|
-
import { ExtrudeOps } from "../oc/extrude-ops.js";
|
|
6
|
-
import { ShapeOps } from "../oc/shape-ops.js";
|
|
7
|
-
import { BooleanOps } from "../oc/boolean-ops.js";
|
|
8
|
-
import { Explorer } from "../oc/explorer.js";
|
|
9
|
-
import { LazySceneObject } from "./lazy-scene-object.js";
|
|
10
|
-
export class ExtrudeSymmetric extends ExtrudeBase {
|
|
11
|
-
extrudable;
|
|
12
|
-
distance;
|
|
13
|
-
options;
|
|
14
|
-
constructor(extrudable, distance, options = {}) {
|
|
15
|
-
super(options);
|
|
16
|
-
this.extrudable = extrudable;
|
|
17
|
-
this.distance = distance;
|
|
18
|
-
this.options = options;
|
|
19
|
-
}
|
|
20
|
-
build(context) {
|
|
21
|
-
let solids = [];
|
|
22
|
-
const sceneObjects = context.getSceneObjects();
|
|
23
|
-
const wires = this.extrudable.getGeometries();
|
|
24
|
-
const faces = FaceMaker.getFaces(wires, this.extrudable.getPlane());
|
|
25
|
-
console.log("Extruding faces:", faces);
|
|
26
|
-
const plane = this.extrudable.getPlane();
|
|
27
|
-
const hasDraft = !!this.options?.draft;
|
|
28
|
-
let startFaces = [];
|
|
29
|
-
let endFaces = [];
|
|
30
|
-
let sideFaces = [];
|
|
31
|
-
if (hasDraft) {
|
|
32
|
-
let vec = plane.normal.multiply(this.distance / 2);
|
|
33
|
-
for (const face of faces) {
|
|
34
|
-
let { solid, firstFace, lastFace } = this.doExtrude(face, vec);
|
|
35
|
-
solid = this.applyDraft(solid, firstFace, lastFace, plane);
|
|
36
|
-
const center = face.center();
|
|
37
|
-
const mirrored = ShapeOps.mirrorShape(solid, center);
|
|
38
|
-
const fused = BooleanOps.fuseShapes(solid, mirrored);
|
|
39
|
-
const solidFaces = Explorer.findFacesWrapped(fused);
|
|
40
|
-
for (const f of solidFaces) {
|
|
41
|
-
if (f.getShape().IsSame(firstFace.getShape())) {
|
|
42
|
-
startFaces.push(f);
|
|
43
|
-
}
|
|
44
|
-
else if (f.getShape().IsSame(lastFace.getShape())) {
|
|
45
|
-
endFaces.push(f);
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
sideFaces.push(f);
|
|
49
|
-
}
|
|
50
|
-
}
|
|
51
|
-
solids.push(fused);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
else {
|
|
55
|
-
let vec = plane.normal.multiply(this.distance);
|
|
56
|
-
const translateVec = vec.multiply(-0.5);
|
|
57
|
-
for (const face of faces) {
|
|
58
|
-
let { solid, firstFace, lastFace } = this.doExtrude(face, vec);
|
|
59
|
-
solid = ShapeOps.translateShape(solid, translateVec);
|
|
60
|
-
const solidFaces = Explorer.findFacesWrapped(solid);
|
|
61
|
-
for (const f of solidFaces) {
|
|
62
|
-
// here we use IsPartner instead of IsSame because the place location has changed after translation
|
|
63
|
-
if (f.getShape().IsPartner(firstFace.getShape())) {
|
|
64
|
-
startFaces.push(f);
|
|
65
|
-
}
|
|
66
|
-
else if (f.getShape().IsPartner(lastFace.getShape())) {
|
|
67
|
-
endFaces.push(f);
|
|
68
|
-
}
|
|
69
|
-
else {
|
|
70
|
-
sideFaces.push(f);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
solids.push(solid);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
this.setState('start-faces', startFaces);
|
|
77
|
-
this.setState('end-faces', endFaces);
|
|
78
|
-
this.setState('side-faces', sideFaces);
|
|
79
|
-
this.extrudable.removeShapes(this);
|
|
80
|
-
if (this.options?.mergeScope === 'none' || solids.length === 0 || sceneObjects?.length === 0) {
|
|
81
|
-
const fusionResult = fuseWithSceneObjects(sceneObjects, solids);
|
|
82
|
-
solids = fusionResult.extrusions;
|
|
83
|
-
for (const modifiedShape of fusionResult.modifiedShapes) {
|
|
84
|
-
modifiedShape.object.removeShape(modifiedShape.shape, this);
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
this.addShapes(solids);
|
|
88
|
-
}
|
|
89
|
-
applyDraft(solid, firstFace, lastFace, plane) {
|
|
90
|
-
if (this.options.draft instanceof Array) {
|
|
91
|
-
throw new Error("Draft with two angles for start and end faces is supported only for extrusions with two distances");
|
|
92
|
-
}
|
|
93
|
-
const angle = this.options.draft;
|
|
94
|
-
return ExtrudeOps.applyDraftOnSideFaces(solid, firstFace, lastFace, plane, rad(angle));
|
|
95
|
-
}
|
|
96
|
-
doExtrude(shape, vector) {
|
|
97
|
-
const { solid: rawSolid, firstFace, lastFace } = ExtrudeOps.makePrismFromVec(shape, vector);
|
|
98
|
-
const solid = ShapeOps.cleanShape(rawSolid);
|
|
99
|
-
return { solid, firstFace, lastFace };
|
|
100
|
-
}
|
|
101
|
-
getUniqueName(suffix) {
|
|
102
|
-
return `${this.getOrder()}-${this.getUniqueType()}-${suffix}`;
|
|
103
|
-
}
|
|
104
|
-
startFace(...indices) {
|
|
105
|
-
const suffix = indices.length > 0 ? `start-faces-${indices.join('-')}` : 'start-faces';
|
|
106
|
-
return new LazySceneObject(`${this.getUniqueName(suffix)}`, () => {
|
|
107
|
-
const faces = this.getState('start-faces') || [];
|
|
108
|
-
if (indices.length === 0)
|
|
109
|
-
return faces.length > 0 ? [faces[0]] : [];
|
|
110
|
-
return indices.filter(i => i >= 0 && i < faces.length).map(i => faces[i]);
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
endFace(...indices) {
|
|
114
|
-
const suffix = indices.length > 0 ? `end-faces-${indices.join('-')}` : 'end-faces';
|
|
115
|
-
return new LazySceneObject(`${this.getUniqueName(suffix)}`, () => {
|
|
116
|
-
const faces = this.getState('end-faces') || [];
|
|
117
|
-
if (indices.length === 0)
|
|
118
|
-
return faces.length > 0 ? [faces[0]] : [];
|
|
119
|
-
return indices.filter(i => i >= 0 && i < faces.length).map(i => faces[i]);
|
|
120
|
-
});
|
|
121
|
-
}
|
|
122
|
-
startEdge(...indices) {
|
|
123
|
-
const suffix = indices.length > 0 ? `start-edges-${indices.join('-')}` : 'start-edges';
|
|
124
|
-
return new LazySceneObject(`${this.getUniqueName(suffix)}`, () => {
|
|
125
|
-
const faces = this.getState('start-faces') || [];
|
|
126
|
-
const edges = faces.flatMap(f => f.getEdges());
|
|
127
|
-
if (indices.length === 0)
|
|
128
|
-
return edges.length > 0 ? [edges[0]] : [];
|
|
129
|
-
return indices.filter(i => i >= 0 && i < edges.length).map(i => edges[i]);
|
|
130
|
-
});
|
|
131
|
-
}
|
|
132
|
-
endEdge(...indices) {
|
|
133
|
-
const suffix = indices.length > 0 ? `end-edges-${indices.join('-')}` : 'end-edges';
|
|
134
|
-
return new LazySceneObject(`${this.getUniqueName(suffix)}`, () => {
|
|
135
|
-
const faces = this.getState('end-faces') || [];
|
|
136
|
-
const edges = faces.flatMap(f => f.getEdges());
|
|
137
|
-
if (indices.length === 0)
|
|
138
|
-
return edges.length > 0 ? [edges[0]] : [];
|
|
139
|
-
return indices.filter(i => i >= 0 && i < edges.length).map(i => edges[i]);
|
|
140
|
-
});
|
|
141
|
-
}
|
|
142
|
-
sideFace(...indices) {
|
|
143
|
-
const suffix = indices.length > 0 ? `side-faces-${indices.join('-')}` : 'side-faces';
|
|
144
|
-
return new LazySceneObject(`${this.getUniqueName(suffix)}`, () => {
|
|
145
|
-
const faces = this.getState('side-faces') || [];
|
|
146
|
-
if (indices.length === 0)
|
|
147
|
-
return faces.length > 0 ? [faces[0]] : [];
|
|
148
|
-
return indices.filter(i => i >= 0 && i < faces.length).map(i => faces[i]);
|
|
149
|
-
});
|
|
150
|
-
}
|
|
151
|
-
compareTo(other) {
|
|
152
|
-
if (!(other instanceof ExtrudeSymmetric)) {
|
|
153
|
-
return false;
|
|
154
|
-
}
|
|
155
|
-
if (this.distance !== other.distance) {
|
|
156
|
-
return false;
|
|
157
|
-
}
|
|
158
|
-
if (JSON.stringify(this.options || {}) !== JSON.stringify(other.options || {})) {
|
|
159
|
-
return false;
|
|
160
|
-
}
|
|
161
|
-
if (!this.extrudable.compareTo(other.extrudable)) {
|
|
162
|
-
return false;
|
|
163
|
-
}
|
|
164
|
-
return true;
|
|
165
|
-
}
|
|
166
|
-
getUniqueType() {
|
|
167
|
-
return 'extrude-symmetric';
|
|
168
|
-
}
|
|
169
|
-
serialize() {
|
|
170
|
-
return {
|
|
171
|
-
extrudables: this.extrudable.serialize(),
|
|
172
|
-
distance: this.distance,
|
|
173
|
-
symmetric: true,
|
|
174
|
-
options: this.options
|
|
175
|
-
};
|
|
176
|
-
}
|
|
177
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { SceneObject } from "../common/scene-object.js";
|
|
2
|
-
import { Edge } from "../common/edge.js";
|
|
3
|
-
import { Wire } from "../common/wire.js";
|
|
4
|
-
import { Extrudable } from "../helpers/types.js";
|
|
5
|
-
import { LazyVertex } from "./lazy-vertex.js";
|
|
6
|
-
import { GeometrySceneObject } from "./2d/geometry.js";
|
|
7
|
-
export declare class Region2D extends SceneObject implements Extrudable {
|
|
8
|
-
private _points;
|
|
9
|
-
private _extrudable;
|
|
10
|
-
constructor(extrudable: Extrudable);
|
|
11
|
-
points(...ps: LazyVertex[]): this;
|
|
12
|
-
isExtrudable(): boolean;
|
|
13
|
-
build(): void;
|
|
14
|
-
getGeometries(): (Wire | Edge)[];
|
|
15
|
-
getGeometriesWithOwner(): Map<Wire | Edge, GeometrySceneObject>;
|
|
16
|
-
getPlane(): import("../math/plane.js").Plane;
|
|
17
|
-
getDependencies(): SceneObject[];
|
|
18
|
-
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
19
|
-
compareTo(other: Region2D): boolean;
|
|
20
|
-
getType(): string;
|
|
21
|
-
serialize(): {
|
|
22
|
-
plane: any;
|
|
23
|
-
selections: any;
|
|
24
|
-
};
|
|
25
|
-
}
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import { SceneObject } from "../common/scene-object.js";
|
|
2
|
-
import { FaceOps } from "../oc/face-ops.js";
|
|
3
|
-
import { Explorer } from "../oc/explorer.js";
|
|
4
|
-
import { ShapeOps } from "../oc/shape-ops.js";
|
|
5
|
-
export class Region2D extends SceneObject {
|
|
6
|
-
_points = [];
|
|
7
|
-
_extrudable;
|
|
8
|
-
constructor(extrudable) {
|
|
9
|
-
super();
|
|
10
|
-
this._extrudable = extrudable;
|
|
11
|
-
}
|
|
12
|
-
points(...ps) {
|
|
13
|
-
this._points = ps;
|
|
14
|
-
return this;
|
|
15
|
-
}
|
|
16
|
-
isExtrudable() {
|
|
17
|
-
return true;
|
|
18
|
-
}
|
|
19
|
-
build() {
|
|
20
|
-
const plane = this._extrudable.getPlane();
|
|
21
|
-
const shapes = this._extrudable.getGeometries();
|
|
22
|
-
const allFaces = FaceOps.buildPlanarFaces(shapes, plane);
|
|
23
|
-
if (allFaces.length === 0) {
|
|
24
|
-
return;
|
|
25
|
-
}
|
|
26
|
-
// Compute bounding box diagonals for disambiguation (smallest face wins)
|
|
27
|
-
const faceDiagonals = allFaces.map(face => {
|
|
28
|
-
const bbox = ShapeOps.getBoundingBox(face);
|
|
29
|
-
return Math.sqrt((bbox.maxX - bbox.minX) ** 2 +
|
|
30
|
-
(bbox.maxY - bbox.minY) ** 2);
|
|
31
|
-
});
|
|
32
|
-
// Match each user point to the smallest face containing it
|
|
33
|
-
const selectedIndices = new Set();
|
|
34
|
-
const pointForFace = new Map();
|
|
35
|
-
for (const lazyPoint of this._points) {
|
|
36
|
-
const point2d = lazyPoint.asPoint2D();
|
|
37
|
-
const point3d = plane.localToWorld(point2d);
|
|
38
|
-
let bestIdx = -1;
|
|
39
|
-
let bestDiag = Infinity;
|
|
40
|
-
for (let i = 0; i < allFaces.length; i++) {
|
|
41
|
-
if (FaceOps.isPointInsideFace(point3d, allFaces[i])) {
|
|
42
|
-
if (faceDiagonals[i] < bestDiag) {
|
|
43
|
-
bestDiag = faceDiagonals[i];
|
|
44
|
-
bestIdx = i;
|
|
45
|
-
}
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
if (bestIdx >= 0) {
|
|
49
|
-
selectedIndices.add(bestIdx);
|
|
50
|
-
// Store rounded values to match what handleInsertPoint writes to source code
|
|
51
|
-
pointForFace.set(bestIdx, [
|
|
52
|
-
Math.round(point2d.x * 100) / 100,
|
|
53
|
-
Math.round(point2d.y * 100) / 100,
|
|
54
|
-
]);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
// Determine nesting: find holes for each selected face
|
|
58
|
-
const holesFor = new Map();
|
|
59
|
-
for (const selIdx of selectedIndices) {
|
|
60
|
-
const holes = [];
|
|
61
|
-
for (let i = 0; i < allFaces.length; i++) {
|
|
62
|
-
if (i === selIdx || selectedIndices.has(i)) {
|
|
63
|
-
continue;
|
|
64
|
-
}
|
|
65
|
-
const innerWires = Explorer.findWiresWrapped(allFaces[i]);
|
|
66
|
-
if (innerWires.length > 0) {
|
|
67
|
-
const firstVertex = innerWires[0].getFirstVertex();
|
|
68
|
-
if (firstVertex && FaceOps.isPointInsideFace(firstVertex.toPoint(), allFaces[selIdx])) {
|
|
69
|
-
holes.push(i);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (holes.length > 0) {
|
|
74
|
-
holesFor.set(selIdx, holes);
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
// Extract wires for getGeometries() BEFORE drilling (which mutates wires in-place)
|
|
78
|
-
const resultWires = [];
|
|
79
|
-
for (const selIdx of selectedIndices) {
|
|
80
|
-
const wires = Explorer.findWiresWrapped(allFaces[selIdx]);
|
|
81
|
-
if (wires.length > 0) {
|
|
82
|
-
resultWires.push(wires[0]);
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
for (const [, holeIndices] of holesFor) {
|
|
86
|
-
for (const hi of holeIndices) {
|
|
87
|
-
const wires = Explorer.findWiresWrapped(allFaces[hi]);
|
|
88
|
-
if (wires.length > 0) {
|
|
89
|
-
resultWires.push(wires[0]);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
this.setState('result-wires', resultWires);
|
|
94
|
-
// Build drilled faces for selected regions with holes
|
|
95
|
-
const drilledFaces = new Map();
|
|
96
|
-
for (const [selIdx, holeIndices] of holesFor) {
|
|
97
|
-
const outerWires = Explorer.findWiresWrapped(allFaces[selIdx]);
|
|
98
|
-
if (outerWires.length === 0) {
|
|
99
|
-
continue;
|
|
100
|
-
}
|
|
101
|
-
const outerWire = outerWires[0];
|
|
102
|
-
const holeWires = [];
|
|
103
|
-
for (const hi of holeIndices) {
|
|
104
|
-
const wires = Explorer.findWiresWrapped(allFaces[hi]);
|
|
105
|
-
if (wires.length > 0) {
|
|
106
|
-
wires[0].getShape().Reverse();
|
|
107
|
-
holeWires.push(wires[0]);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (holeWires.length > 0) {
|
|
111
|
-
drilledFaces.set(selIdx, FaceOps.makeFaceWithHoles(outerWire, holeWires));
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
// Add ALL faces as shapes (for rendering/raycasting)
|
|
115
|
-
// Selected faces that have holes are replaced with drilled versions
|
|
116
|
-
for (let i = 0; i < allFaces.length; i++) {
|
|
117
|
-
const face = drilledFaces.has(i) ? drilledFaces.get(i) : allFaces[i];
|
|
118
|
-
this.addShape(face);
|
|
119
|
-
}
|
|
120
|
-
// Build selection mapping: map shape indices to their selection state
|
|
121
|
-
const addedShapes = this.getOwnShapes({ excludeMeta: false, excludeGuide: false });
|
|
122
|
-
const selections = [];
|
|
123
|
-
for (let i = 0; i < addedShapes.length; i++) {
|
|
124
|
-
if (selectedIndices.has(i) && pointForFace.has(i)) {
|
|
125
|
-
selections.push({
|
|
126
|
-
shapeId: addedShapes[i].id,
|
|
127
|
-
point: pointForFace.get(i),
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
this.setState('selections', selections);
|
|
132
|
-
this.setState('all-face-count', allFaces.length);
|
|
133
|
-
this.setState('selected-indices', [...selectedIndices]);
|
|
134
|
-
}
|
|
135
|
-
getGeometries() {
|
|
136
|
-
return this.getState('result-wires') || [];
|
|
137
|
-
}
|
|
138
|
-
getGeometriesWithOwner() {
|
|
139
|
-
const result = new Map();
|
|
140
|
-
for (const wire of this.getGeometries()) {
|
|
141
|
-
result.set(wire, this);
|
|
142
|
-
}
|
|
143
|
-
return result;
|
|
144
|
-
}
|
|
145
|
-
getPlane() {
|
|
146
|
-
return this._extrudable.getPlane();
|
|
147
|
-
}
|
|
148
|
-
getDependencies() {
|
|
149
|
-
return [this._extrudable];
|
|
150
|
-
}
|
|
151
|
-
createCopy(remap) {
|
|
152
|
-
const extrudable = (remap.get(this._extrudable) || this._extrudable);
|
|
153
|
-
const copy = new Region2D(extrudable);
|
|
154
|
-
if (this._points.length > 0) {
|
|
155
|
-
copy.points(...this._points);
|
|
156
|
-
}
|
|
157
|
-
return copy;
|
|
158
|
-
}
|
|
159
|
-
compareTo(other) {
|
|
160
|
-
if (!(other instanceof Region2D)) {
|
|
161
|
-
return false;
|
|
162
|
-
}
|
|
163
|
-
if (!super.compareTo(other)) {
|
|
164
|
-
return false;
|
|
165
|
-
}
|
|
166
|
-
if (this._points.length !== other._points.length) {
|
|
167
|
-
return false;
|
|
168
|
-
}
|
|
169
|
-
for (let i = 0; i < this._points.length; i++) {
|
|
170
|
-
if (!this._points[i].compareTo(other._points[i])) {
|
|
171
|
-
return false;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
return true;
|
|
175
|
-
}
|
|
176
|
-
getType() {
|
|
177
|
-
return "region";
|
|
178
|
-
}
|
|
179
|
-
serialize() {
|
|
180
|
-
return {
|
|
181
|
-
plane: this._extrudable.serialize?.()?.plane || null,
|
|
182
|
-
selections: this.getState('selections') || [],
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
}
|