fluidcad 0.0.13 → 0.0.15
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/lib/dist/common/scene-object.d.ts +3 -0
- package/lib/dist/common/scene-object.js +7 -0
- package/lib/dist/core/2d/arc.d.ts +14 -56
- package/lib/dist/core/2d/arc.js +8 -23
- package/lib/dist/core/2d/center.d.ts +9 -0
- package/lib/dist/core/2d/center.js +10 -0
- package/lib/dist/core/2d/index.d.ts +2 -0
- package/lib/dist/core/2d/index.js +2 -0
- package/lib/dist/core/2d/intersect.d.ts +17 -0
- package/lib/dist/core/2d/intersect.js +20 -0
- package/lib/dist/core/interfaces.d.ts +50 -2
- package/lib/dist/core/repeat.js +10 -3
- package/lib/dist/features/2d/arc.d.ts +27 -14
- package/lib/dist/features/2d/arc.js +269 -38
- package/lib/dist/features/2d/intersect.d.ts +15 -0
- package/lib/dist/features/2d/intersect.js +83 -0
- package/lib/dist/features/2d/plane-center.d.ts +13 -0
- package/lib/dist/features/2d/plane-center.js +40 -0
- package/lib/dist/features/2d/projection.js +3 -4
- package/lib/dist/features/2d/rect.d.ts +2 -2
- package/lib/dist/features/2d/rect.js +3 -3
- package/lib/dist/features/2d/sketch.d.ts +2 -2
- package/lib/dist/features/2d/sketch.js +13 -1
- package/lib/dist/features/2d/slot.d.ts +2 -2
- package/lib/dist/features/2d/slot.js +3 -3
- package/lib/dist/features/extrude-base.d.ts +4 -0
- package/lib/dist/features/extrude-base.js +27 -0
- package/lib/dist/features/extrude-to-face.d.ts +1 -0
- package/lib/dist/features/extrude-to-face.js +5 -1
- package/lib/dist/features/extrude-two-distances.d.ts +1 -0
- package/lib/dist/features/extrude-two-distances.js +5 -2
- package/lib/dist/features/extrude.d.ts +1 -0
- package/lib/dist/features/extrude.js +5 -1
- package/lib/dist/features/plane-renderable-base.d.ts +2 -1
- package/lib/dist/features/plane-renderable-base.js +1 -1
- package/lib/dist/features/plane.d.ts +1 -1
- package/lib/dist/filters/face/face-filter.d.ts +10 -0
- package/lib/dist/filters/face/face-filter.js +39 -0
- package/lib/dist/filters/face/intersects-with.d.ts +18 -0
- package/lib/dist/filters/face/intersects-with.js +41 -0
- package/lib/dist/helpers/clone-transform.js +1 -0
- package/lib/dist/oc/boolean-ops.js +0 -2
- package/lib/dist/oc/face-query.d.ts +1 -0
- package/lib/dist/oc/face-query.js +15 -0
- package/lib/dist/oc/index.d.ts +1 -0
- package/lib/dist/oc/index.js +1 -0
- package/lib/dist/oc/section-ops.d.ts +6 -0
- package/lib/dist/oc/section-ops.js +26 -0
- package/lib/dist/oc/thin-face-maker.d.ts +29 -0
- package/lib/dist/oc/thin-face-maker.js +163 -0
- package/lib/dist/rendering/render.js +16 -0
- package/lib/dist/tests/features/2d/arc.test.js +2 -2
- package/lib/dist/tests/features/2d/intersect.test.d.ts +1 -0
- package/lib/dist/tests/features/2d/intersect.test.js +22 -0
- package/lib/dist/tests/features/2d/rect.test.js +1 -1
- package/lib/dist/tests/features/loft.test.js +1 -1
- package/lib/dist/tests/features/select.test.js +49 -1
- package/lib/dist/tests/features/thin-extrude.test.d.ts +1 -0
- package/lib/dist/tests/features/thin-extrude.test.js +137 -0
- package/lib/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/server/dist/index.js +23 -15
- package/ui/dist/assets/{index-mLcpjEcV.js → index-BJG141m7.js} +2 -2
- package/ui/dist/index.html +1 -1
- package/lib/dist/features/2d/arc-three-points.d.ts +0 -19
- package/lib/dist/features/2d/arc-three-points.js +0 -75
- package/lib/dist/features/2d/arc-to-point.d.ts +0 -17
- package/lib/dist/features/2d/arc-to-point.js +0 -95
|
@@ -3,35 +3,233 @@ import { Geometry } from "../../oc/geometry.js";
|
|
|
3
3
|
import { rad } from "../../helpers/math-helpers.js";
|
|
4
4
|
import { Point2D } from "../../math/point.js";
|
|
5
5
|
import { GeometrySceneObject } from "./geometry.js";
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
6
|
+
import { normalizePoint2D } from "../../helpers/normalize.js";
|
|
7
|
+
export class Arc extends GeometrySceneObject {
|
|
8
|
+
// Two-point mode state (set by factory)
|
|
9
|
+
_startPoint = null;
|
|
10
|
+
_endPoint = null;
|
|
11
|
+
// Angle mode state (set by factory)
|
|
12
|
+
_arcRadius = 0;
|
|
13
|
+
_startAngle = 0;
|
|
14
|
+
_endAngle = 180;
|
|
15
|
+
// Chainable state
|
|
16
|
+
_bulgeRadius = 0;
|
|
17
|
+
_centerPoint = null;
|
|
18
|
+
_centered = false;
|
|
19
|
+
_targetPlane;
|
|
20
|
+
constructor(targetPlane = null) {
|
|
13
21
|
super();
|
|
14
|
-
this.
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
22
|
+
this._targetPlane = targetPlane;
|
|
23
|
+
}
|
|
24
|
+
static toPoint(endPoint, targetPlane = null) {
|
|
25
|
+
const arc = new Arc(targetPlane);
|
|
26
|
+
arc._endPoint = endPoint;
|
|
27
|
+
return arc;
|
|
28
|
+
}
|
|
29
|
+
static twoPoints(startPoint, endPoint, targetPlane = null) {
|
|
30
|
+
const arc = new Arc(targetPlane);
|
|
31
|
+
arc._startPoint = startPoint;
|
|
32
|
+
arc._endPoint = endPoint;
|
|
33
|
+
return arc;
|
|
34
|
+
}
|
|
35
|
+
static fromAngles(arcRadius, startAngle, endAngle, targetPlane = null) {
|
|
36
|
+
const arc = new Arc(targetPlane);
|
|
37
|
+
arc._arcRadius = arcRadius;
|
|
38
|
+
arc._startAngle = startAngle;
|
|
39
|
+
arc._endAngle = endAngle;
|
|
40
|
+
return arc;
|
|
41
|
+
}
|
|
42
|
+
// Chainable methods (IArc)
|
|
43
|
+
radius(value) {
|
|
44
|
+
this._bulgeRadius = value;
|
|
45
|
+
return this;
|
|
46
|
+
}
|
|
47
|
+
center(value) {
|
|
48
|
+
this._centerPoint = normalizePoint2D(value);
|
|
49
|
+
return this;
|
|
50
|
+
}
|
|
51
|
+
centered() {
|
|
52
|
+
this._centered = true;
|
|
53
|
+
return this;
|
|
19
54
|
}
|
|
20
55
|
build() {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
56
|
+
if (this._startPoint && this._endPoint) {
|
|
57
|
+
// Two explicit points: default center = current position
|
|
58
|
+
if (this._bulgeRadius !== 0) {
|
|
59
|
+
this.buildTwoPointsBulge();
|
|
60
|
+
}
|
|
61
|
+
else {
|
|
62
|
+
this.buildTwoPointsCenter();
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (this._endPoint) {
|
|
66
|
+
// From current position to endpoint
|
|
67
|
+
if (this._centerPoint) {
|
|
68
|
+
this.buildWithCenter();
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
this.buildToPoint();
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.buildFromAngles();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
buildTwoPointsCenter() {
|
|
79
|
+
const plane = this._targetPlane?.getPlane() || this.sketch.getPlane();
|
|
80
|
+
const startPt = this._startPoint.asPoint2D();
|
|
81
|
+
const endPt = this._endPoint.asPoint2D();
|
|
82
|
+
const centerPt = this._centerPoint
|
|
83
|
+
? this._centerPoint.asPoint2D()
|
|
26
84
|
: this.getCurrentPosition();
|
|
27
|
-
|
|
28
|
-
const
|
|
29
|
-
const
|
|
30
|
-
const
|
|
85
|
+
const dx = startPt.x - centerPt.x;
|
|
86
|
+
const dy = startPt.y - centerPt.y;
|
|
87
|
+
const radius = Math.sqrt(dx * dx + dy * dy);
|
|
88
|
+
const endAngle = Math.atan2(endPt.y - centerPt.y, endPt.x - centerPt.x);
|
|
89
|
+
const center = plane.localToWorld(centerPt);
|
|
90
|
+
const start = plane.localToWorld(startPt);
|
|
91
|
+
const end = plane.localToWorld(endPt);
|
|
92
|
+
const arc = Geometry.makeArc(center, radius, plane.normal, start, end);
|
|
93
|
+
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
94
|
+
const tx = -Math.sin(endAngle);
|
|
95
|
+
const ty = Math.cos(endAngle);
|
|
96
|
+
this.setTangent(new Point2D(tx, ty));
|
|
97
|
+
this.setState('start', Vertex.fromPoint2D(startPt));
|
|
98
|
+
this.setState('end', Vertex.fromPoint2D(endPt));
|
|
99
|
+
this.addShape(edge);
|
|
100
|
+
if (this.sketch) {
|
|
101
|
+
this.setCurrentPosition(endPt);
|
|
102
|
+
}
|
|
103
|
+
if (this._targetPlane) {
|
|
104
|
+
this._targetPlane.removeShapes(this);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
buildTwoPointsBulge() {
|
|
108
|
+
const plane = this._targetPlane?.getPlane() || this.sketch.getPlane();
|
|
109
|
+
const startPoint = this._startPoint.asPoint2D();
|
|
110
|
+
const targetPoint = this._endPoint.asPoint2D();
|
|
111
|
+
const dx = targetPoint.x - startPoint.x;
|
|
112
|
+
const dy = targetPoint.y - startPoint.y;
|
|
113
|
+
const chordLen = Math.sqrt(dx * dx + dy * dy);
|
|
114
|
+
let r = this._bulgeRadius;
|
|
115
|
+
const cw = r < 0;
|
|
116
|
+
r = Math.abs(r);
|
|
117
|
+
if (r < chordLen / 2) {
|
|
118
|
+
r = chordLen / 2;
|
|
119
|
+
}
|
|
120
|
+
const mx = (startPoint.x + targetPoint.x) / 2;
|
|
121
|
+
const my = (startPoint.y + targetPoint.y) / 2;
|
|
122
|
+
const px = -dy / chordLen;
|
|
123
|
+
const py = dx / chordLen;
|
|
124
|
+
const d = Math.sqrt(r * r - (chordLen / 2) * (chordLen / 2));
|
|
125
|
+
const sign = cw ? -1 : 1;
|
|
126
|
+
const centerPoint = new Point2D(mx + sign * d * px, my + sign * d * py);
|
|
127
|
+
const endAngle = Math.atan2(targetPoint.y - centerPoint.y, targetPoint.x - centerPoint.x);
|
|
128
|
+
const normal = cw ? plane.normal.negate() : plane.normal;
|
|
129
|
+
const center = plane.localToWorld(centerPoint);
|
|
130
|
+
const start = plane.localToWorld(startPoint);
|
|
131
|
+
const end = plane.localToWorld(targetPoint);
|
|
132
|
+
const arc = Geometry.makeArc(center, r, normal, start, end);
|
|
133
|
+
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
134
|
+
const signT = cw ? -1 : 1;
|
|
135
|
+
const endTx = signT * (-Math.sin(endAngle));
|
|
136
|
+
const endTy = signT * Math.cos(endAngle);
|
|
137
|
+
this.setTangent(new Point2D(endTx, endTy));
|
|
138
|
+
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
139
|
+
this.setState('end', Vertex.fromPoint2D(targetPoint));
|
|
140
|
+
this.addShape(edge);
|
|
141
|
+
if (this.sketch) {
|
|
142
|
+
this.setCurrentPosition(targetPoint);
|
|
143
|
+
}
|
|
144
|
+
if (this._targetPlane) {
|
|
145
|
+
this._targetPlane.removeShapes(this);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
buildToPoint() {
|
|
149
|
+
const plane = this._targetPlane?.getPlane() || this.sketch.getPlane();
|
|
150
|
+
const targetPoint = this._endPoint.asPoint2D();
|
|
151
|
+
const startPoint = this._targetPlane
|
|
152
|
+
? plane.worldToLocal(this._targetPlane.getPlaneCenter())
|
|
153
|
+
: this.getCurrentPosition();
|
|
154
|
+
const dx = targetPoint.x - startPoint.x;
|
|
155
|
+
const dy = targetPoint.y - startPoint.y;
|
|
156
|
+
const chordLen = Math.sqrt(dx * dx + dy * dy);
|
|
157
|
+
let r = this._bulgeRadius || (chordLen / 2);
|
|
158
|
+
const cw = r < 0;
|
|
159
|
+
r = Math.abs(r);
|
|
160
|
+
if (r < chordLen / 2) {
|
|
161
|
+
r = chordLen / 2;
|
|
162
|
+
}
|
|
163
|
+
const mx = (startPoint.x + targetPoint.x) / 2;
|
|
164
|
+
const my = (startPoint.y + targetPoint.y) / 2;
|
|
165
|
+
const px = -dy / chordLen;
|
|
166
|
+
const py = dx / chordLen;
|
|
167
|
+
const d = Math.sqrt(r * r - (chordLen / 2) * (chordLen / 2));
|
|
168
|
+
const sign = cw ? -1 : 1;
|
|
169
|
+
const centerPoint = new Point2D(mx + sign * d * px, my + sign * d * py);
|
|
170
|
+
const startAngle = Math.atan2(startPoint.y - centerPoint.y, startPoint.x - centerPoint.x);
|
|
171
|
+
const endAngle = Math.atan2(targetPoint.y - centerPoint.y, targetPoint.x - centerPoint.x);
|
|
172
|
+
const normal = cw ? plane.normal.negate() : plane.normal;
|
|
173
|
+
const center = plane.localToWorld(centerPoint);
|
|
174
|
+
const start = plane.localToWorld(startPoint);
|
|
175
|
+
const end = plane.localToWorld(targetPoint);
|
|
176
|
+
const arc = Geometry.makeArc(center, r, normal, start, end);
|
|
177
|
+
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
178
|
+
const signT = cw ? -1 : 1;
|
|
179
|
+
const endTx = signT * (-Math.sin(endAngle));
|
|
180
|
+
const endTy = signT * Math.cos(endAngle);
|
|
181
|
+
this.setTangent(new Point2D(endTx, endTy));
|
|
182
|
+
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
183
|
+
this.setState('end', Vertex.fromPoint2D(targetPoint));
|
|
184
|
+
this.addShape(edge);
|
|
185
|
+
if (this.sketch) {
|
|
186
|
+
this.setCurrentPosition(targetPoint);
|
|
187
|
+
}
|
|
188
|
+
if (this._targetPlane) {
|
|
189
|
+
this._targetPlane.removeShapes(this);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
buildWithCenter() {
|
|
193
|
+
const plane = this._targetPlane?.getPlane() || this.sketch.getPlane();
|
|
194
|
+
const startPt = this._targetPlane
|
|
195
|
+
? plane.worldToLocal(this._targetPlane.getPlaneCenter())
|
|
196
|
+
: this.getCurrentPosition();
|
|
197
|
+
const endPt = this._endPoint.asPoint2D();
|
|
198
|
+
const centerPt = this._centerPoint.asPoint2D();
|
|
199
|
+
const dx = startPt.x - centerPt.x;
|
|
200
|
+
const dy = startPt.y - centerPt.y;
|
|
201
|
+
const radius = Math.sqrt(dx * dx + dy * dy);
|
|
202
|
+
const endAngle = Math.atan2(endPt.y - centerPt.y, endPt.x - centerPt.x);
|
|
203
|
+
const center = plane.localToWorld(centerPt);
|
|
204
|
+
const start = plane.localToWorld(startPt);
|
|
205
|
+
const end = plane.localToWorld(endPt);
|
|
206
|
+
const arc = Geometry.makeArc(center, radius, plane.normal, start, end);
|
|
207
|
+
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
208
|
+
const tx = -Math.sin(endAngle);
|
|
209
|
+
const ty = Math.cos(endAngle);
|
|
210
|
+
this.setTangent(new Point2D(tx, ty));
|
|
211
|
+
this.setState('start', Vertex.fromPoint2D(startPt));
|
|
212
|
+
this.setState('end', Vertex.fromPoint2D(endPt));
|
|
213
|
+
this.addShape(edge);
|
|
214
|
+
if (this.sketch) {
|
|
215
|
+
this.setCurrentPosition(endPt);
|
|
216
|
+
}
|
|
217
|
+
if (this._targetPlane) {
|
|
218
|
+
this._targetPlane.removeShapes(this);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
buildFromAngles() {
|
|
222
|
+
const plane = this._targetPlane?.getPlane() || this.sketch.getPlane();
|
|
223
|
+
const radius = this._arcRadius;
|
|
224
|
+
const centerPoint = this._targetPlane
|
|
225
|
+
? plane.worldToLocal(this._targetPlane.getPlaneCenter())
|
|
226
|
+
: this.getCurrentPosition();
|
|
227
|
+
const cw = this._endAngle < 0;
|
|
228
|
+
const absStartAngle = Math.abs(this._startAngle);
|
|
229
|
+
const absEndAngle = Math.abs(this._endAngle);
|
|
31
230
|
let startAngleRad;
|
|
32
231
|
let endAngleRad;
|
|
33
|
-
if (this.
|
|
34
|
-
// Centered: the sweep is split equally around startAngle
|
|
232
|
+
if (this._centered) {
|
|
35
233
|
const halfSweep = rad(absEndAngle) / 2;
|
|
36
234
|
const midAngle = rad(absStartAngle);
|
|
37
235
|
startAngleRad = midAngle - halfSweep;
|
|
@@ -51,44 +249,77 @@ export class ArcFromTwoAngles extends GeometrySceneObject {
|
|
|
51
249
|
const edge = Geometry.makeEdgeFromCurve(arc);
|
|
52
250
|
this.setState('start', Vertex.fromPoint2D(startPoint));
|
|
53
251
|
this.setState('end', Vertex.fromPoint2D(endPoint));
|
|
54
|
-
// Tangent at end point: CCW: (-sin θ, cos θ), CW: (sin θ, -cos θ)
|
|
55
252
|
const sign = cw ? -1 : 1;
|
|
56
253
|
const tx = sign * (-Math.sin(endAngleRad));
|
|
57
254
|
const ty = sign * Math.cos(endAngleRad);
|
|
58
255
|
this.setTangent(new Point2D(tx, ty));
|
|
59
256
|
this.addShape(edge);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this.targetPlane.removeShapes(this);
|
|
257
|
+
if (this._targetPlane) {
|
|
258
|
+
this._targetPlane.removeShapes(this);
|
|
63
259
|
}
|
|
64
260
|
}
|
|
65
261
|
getType() {
|
|
66
262
|
return 'arc';
|
|
67
263
|
}
|
|
68
264
|
compareTo(other) {
|
|
69
|
-
if (!(other instanceof
|
|
265
|
+
if (!(other instanceof Arc)) {
|
|
70
266
|
return false;
|
|
71
267
|
}
|
|
72
268
|
if (!super.compareTo(other)) {
|
|
73
269
|
return false;
|
|
74
270
|
}
|
|
75
|
-
if (this.
|
|
271
|
+
if (this._targetPlane?.constructor !== other._targetPlane?.constructor) {
|
|
76
272
|
return false;
|
|
77
273
|
}
|
|
78
|
-
if (this.
|
|
274
|
+
if (this._targetPlane && other._targetPlane && !this._targetPlane.compareTo(other._targetPlane)) {
|
|
79
275
|
return false;
|
|
80
276
|
}
|
|
81
|
-
|
|
82
|
-
this.
|
|
83
|
-
|
|
84
|
-
|
|
277
|
+
if (this._endPoint && other._endPoint) {
|
|
278
|
+
if (!this._endPoint.compareTo(other._endPoint)) {
|
|
279
|
+
return false;
|
|
280
|
+
}
|
|
281
|
+
if (this._startPoint && other._startPoint) {
|
|
282
|
+
if (!this._startPoint.compareTo(other._startPoint)) {
|
|
283
|
+
return false;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
else if (this._startPoint !== other._startPoint) {
|
|
287
|
+
return false;
|
|
288
|
+
}
|
|
289
|
+
if (this._centerPoint && other._centerPoint) {
|
|
290
|
+
return this._centerPoint.compareTo(other._centerPoint);
|
|
291
|
+
}
|
|
292
|
+
return this._bulgeRadius === other._bulgeRadius;
|
|
293
|
+
}
|
|
294
|
+
if (!this._endPoint && !other._endPoint) {
|
|
295
|
+
return this._arcRadius === other._arcRadius &&
|
|
296
|
+
this._startAngle === other._startAngle &&
|
|
297
|
+
this._endAngle === other._endAngle &&
|
|
298
|
+
this._centered === other._centered;
|
|
299
|
+
}
|
|
300
|
+
return false;
|
|
85
301
|
}
|
|
86
302
|
serialize() {
|
|
303
|
+
if (this._endPoint) {
|
|
304
|
+
const base = {
|
|
305
|
+
endPoint: this._endPoint.serialize(),
|
|
306
|
+
};
|
|
307
|
+
if (this._startPoint) {
|
|
308
|
+
base.startPoint = this._startPoint.serialize();
|
|
309
|
+
}
|
|
310
|
+
if (this._centerPoint) {
|
|
311
|
+
base.center = this._centerPoint.serialize();
|
|
312
|
+
}
|
|
313
|
+
if (this._bulgeRadius !== 0) {
|
|
314
|
+
base.radius = this._bulgeRadius;
|
|
315
|
+
}
|
|
316
|
+
return base;
|
|
317
|
+
}
|
|
87
318
|
return {
|
|
88
|
-
radius: this.
|
|
89
|
-
startAngle: this.
|
|
90
|
-
endAngle: this.
|
|
91
|
-
centered: this.
|
|
319
|
+
radius: this._arcRadius,
|
|
320
|
+
startAngle: this._startAngle,
|
|
321
|
+
endAngle: this._endAngle,
|
|
322
|
+
centered: this._centered
|
|
92
323
|
};
|
|
93
324
|
}
|
|
94
325
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { BuildSceneObjectContext, SceneObject } from "../../common/scene-object.js";
|
|
2
|
+
import { PlaneObjectBase } from "../plane-renderable-base.js";
|
|
3
|
+
import { ExtrudableGeometryBase } from "./extrudable-base.js";
|
|
4
|
+
export declare class Intersect extends ExtrudableGeometryBase {
|
|
5
|
+
private sourceObjects;
|
|
6
|
+
constructor(sourceObjects: SceneObject[], targetPlane?: PlaneObjectBase);
|
|
7
|
+
build(context?: BuildSceneObjectContext): void;
|
|
8
|
+
getDependencies(): SceneObject[];
|
|
9
|
+
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
10
|
+
compareTo(other: Intersect): boolean;
|
|
11
|
+
getType(): string;
|
|
12
|
+
serialize(): {
|
|
13
|
+
objectIds: string[];
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { Vertex } from "../../common/vertex.js";
|
|
2
|
+
import { SectionOps } from "../../oc/section-ops.js";
|
|
3
|
+
import { ExtrudableGeometryBase } from "./extrudable-base.js";
|
|
4
|
+
export class Intersect extends ExtrudableGeometryBase {
|
|
5
|
+
sourceObjects;
|
|
6
|
+
constructor(sourceObjects, targetPlane = null) {
|
|
7
|
+
super(targetPlane);
|
|
8
|
+
this.sourceObjects = sourceObjects;
|
|
9
|
+
}
|
|
10
|
+
build(context) {
|
|
11
|
+
const plane = this.targetPlane?.getPlane() || this.sketch.getPlane();
|
|
12
|
+
const shapes = this.sourceObjects.flatMap(obj => obj.getShapes());
|
|
13
|
+
const transform = context?.getTransform() ?? null;
|
|
14
|
+
let lastEdge = null;
|
|
15
|
+
for (let shape of shapes) {
|
|
16
|
+
const edges = SectionOps.sectionShapeWithPlane(plane, shape);
|
|
17
|
+
for (const edge of edges) {
|
|
18
|
+
lastEdge = edge;
|
|
19
|
+
}
|
|
20
|
+
this.addShapes(edges);
|
|
21
|
+
}
|
|
22
|
+
if (lastEdge) {
|
|
23
|
+
const localStart = plane.worldToLocal(lastEdge.getFirstVertex().toPoint());
|
|
24
|
+
const localEnd = plane.worldToLocal(lastEdge.getLastVertex().toPoint());
|
|
25
|
+
this.setState('start', Vertex.fromPoint2D(localStart));
|
|
26
|
+
this.setState('end', Vertex.fromPoint2D(localEnd));
|
|
27
|
+
}
|
|
28
|
+
for (const obj of this.sourceObjects) {
|
|
29
|
+
obj.removeShapes(this);
|
|
30
|
+
}
|
|
31
|
+
if (this.targetPlane) {
|
|
32
|
+
this.targetPlane.removeShapes(this);
|
|
33
|
+
}
|
|
34
|
+
if (this.sketch) {
|
|
35
|
+
this.setCurrentPosition(this.getCurrentPosition());
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
getDependencies() {
|
|
39
|
+
const deps = [...this.sourceObjects];
|
|
40
|
+
if (this.targetPlane) {
|
|
41
|
+
deps.push(this.targetPlane);
|
|
42
|
+
}
|
|
43
|
+
return deps;
|
|
44
|
+
}
|
|
45
|
+
createCopy(remap) {
|
|
46
|
+
const objects = this.sourceObjects.map(obj => remap.get(obj) || obj);
|
|
47
|
+
const targetPlane = this.targetPlane ? (remap.get(this.targetPlane) || this.targetPlane) : null;
|
|
48
|
+
return new Intersect(objects, targetPlane);
|
|
49
|
+
}
|
|
50
|
+
compareTo(other) {
|
|
51
|
+
if (!(other instanceof Intersect)) {
|
|
52
|
+
return false;
|
|
53
|
+
}
|
|
54
|
+
if (!super.compareTo(other)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
if (this.targetPlane?.constructor !== other.targetPlane?.constructor) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
if (this.targetPlane && other.targetPlane && !this.targetPlane.compareTo(other.targetPlane)) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
const thisObjects = this.sourceObjects || [];
|
|
64
|
+
const otherObjects = other.sourceObjects || [];
|
|
65
|
+
if (thisObjects.length !== otherObjects.length) {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
for (let i = 0; i < thisObjects.length; i++) {
|
|
69
|
+
if (!thisObjects[i].compareTo(otherObjects[i])) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
getType() {
|
|
76
|
+
return 'intersect';
|
|
77
|
+
}
|
|
78
|
+
serialize() {
|
|
79
|
+
return {
|
|
80
|
+
objectIds: this.sourceObjects.map(o => o.id)
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { SceneObject } from "../../common/scene-object.js";
|
|
2
|
+
import { GeometrySceneObject } from "./geometry.js";
|
|
3
|
+
import { LazyVertex } from "../lazy-vertex.js";
|
|
4
|
+
export declare class PlaneCenter extends GeometrySceneObject {
|
|
5
|
+
constructor();
|
|
6
|
+
getType(): string;
|
|
7
|
+
build(): void;
|
|
8
|
+
center(): LazyVertex;
|
|
9
|
+
getDependencies(): SceneObject[];
|
|
10
|
+
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
11
|
+
compareTo(other: this): boolean;
|
|
12
|
+
serialize(): {};
|
|
13
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { GeometrySceneObject } from "./geometry.js";
|
|
2
|
+
import { LazyVertex } from "../lazy-vertex.js";
|
|
3
|
+
export class PlaneCenter extends GeometrySceneObject {
|
|
4
|
+
constructor() {
|
|
5
|
+
super();
|
|
6
|
+
}
|
|
7
|
+
getType() {
|
|
8
|
+
return 'plane-center';
|
|
9
|
+
}
|
|
10
|
+
build() {
|
|
11
|
+
const plane = this.sketch.getPlane();
|
|
12
|
+
const centerPoint = this.sketch.planeObj.getPlaneCenter();
|
|
13
|
+
const local = plane.worldToLocal(centerPoint);
|
|
14
|
+
this.setCurrentPosition(local);
|
|
15
|
+
}
|
|
16
|
+
center() {
|
|
17
|
+
return new LazyVertex(this.generateUniqueName('center'), () => {
|
|
18
|
+
const vertex = this.getState('center-vertex');
|
|
19
|
+
if (vertex) {
|
|
20
|
+
return [vertex];
|
|
21
|
+
}
|
|
22
|
+
return [];
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
getDependencies() {
|
|
26
|
+
return [];
|
|
27
|
+
}
|
|
28
|
+
createCopy(remap) {
|
|
29
|
+
return new PlaneCenter();
|
|
30
|
+
}
|
|
31
|
+
compareTo(other) {
|
|
32
|
+
if (!(other instanceof PlaneCenter)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
return super.compareTo(other);
|
|
36
|
+
}
|
|
37
|
+
serialize() {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { Face } from "../../common/face.js";
|
|
2
|
-
import { ShapeOps } from "../../oc/shape-ops.js";
|
|
3
2
|
import { Edge } from "../../common/edge.js";
|
|
4
3
|
import { Vertex } from "../../common/vertex.js";
|
|
5
4
|
import { ProjectionOps } from "../../oc/intersection.js";
|
|
@@ -18,9 +17,9 @@ export class Projection extends ExtrudableGeometryBase {
|
|
|
18
17
|
let lastWire = null;
|
|
19
18
|
console.log('Projection: building with shapes:', shapes.length);
|
|
20
19
|
for (let shape of shapes) {
|
|
21
|
-
if (transform) {
|
|
22
|
-
|
|
23
|
-
}
|
|
20
|
+
// if (transform) {
|
|
21
|
+
// shape = ShapeOps.transform(shape, transform);
|
|
22
|
+
// }
|
|
24
23
|
let wires = [];
|
|
25
24
|
if (shape instanceof Face) {
|
|
26
25
|
wires = ProjectionOps.projectFaceOntoPlane(plane, shape);
|
|
@@ -34,12 +34,12 @@ export declare class Rect extends ExtrudableGeometryBase implements IRect {
|
|
|
34
34
|
bottomLeft(): LazyVertex;
|
|
35
35
|
bottomRight(): LazyVertex;
|
|
36
36
|
radius(...r: number[]): this;
|
|
37
|
-
|
|
37
|
+
centered(value?: CenteringOptions): this;
|
|
38
38
|
serialize(): {
|
|
39
39
|
width: number;
|
|
40
40
|
height: number;
|
|
41
41
|
radius: number | number[];
|
|
42
|
-
|
|
42
|
+
centered: CenteringOptions;
|
|
43
43
|
};
|
|
44
44
|
}
|
|
45
45
|
export {};
|
|
@@ -152,7 +152,7 @@ export class Rect extends ExtrudableGeometryBase {
|
|
|
152
152
|
if (this._radius) {
|
|
153
153
|
rect.radius(...(Array.isArray(this._radius) ? this._radius : [this._radius]));
|
|
154
154
|
}
|
|
155
|
-
rect.
|
|
155
|
+
rect.centered(this._center);
|
|
156
156
|
return rect;
|
|
157
157
|
}
|
|
158
158
|
compareTo(other) {
|
|
@@ -250,7 +250,7 @@ export class Rect extends ExtrudableGeometryBase {
|
|
|
250
250
|
}
|
|
251
251
|
return this;
|
|
252
252
|
}
|
|
253
|
-
|
|
253
|
+
centered(value = true) {
|
|
254
254
|
this._center = value;
|
|
255
255
|
return this;
|
|
256
256
|
}
|
|
@@ -259,7 +259,7 @@ export class Rect extends ExtrudableGeometryBase {
|
|
|
259
259
|
width: this.width,
|
|
260
260
|
height: this.height,
|
|
261
261
|
radius: this._radius,
|
|
262
|
-
|
|
262
|
+
centered: this._center
|
|
263
263
|
};
|
|
264
264
|
}
|
|
265
265
|
}
|
|
@@ -2,7 +2,7 @@ import { Plane } from "../../math/plane.js";
|
|
|
2
2
|
import { Point2D } from "../../math/point.js";
|
|
3
3
|
import { GeometrySceneObject } from "./geometry.js";
|
|
4
4
|
import { PlaneObjectBase } from "../plane-renderable-base.js";
|
|
5
|
-
import { SceneObject } from "../../common/scene-object.js";
|
|
5
|
+
import { BuildSceneObjectContext, SceneObject } from "../../common/scene-object.js";
|
|
6
6
|
import { Edge } from "../../common/edge.js";
|
|
7
7
|
import { Extrudable } from "../../helpers/types.js";
|
|
8
8
|
export declare class Sketch extends SceneObject implements Extrudable {
|
|
@@ -15,7 +15,7 @@ export declare class Sketch extends SceneObject implements Extrudable {
|
|
|
15
15
|
getTangentAt(currentObj: GeometrySceneObject): Point2D | null;
|
|
16
16
|
getPositionAt(currentObj: GeometrySceneObject): Point2D;
|
|
17
17
|
getLastPosition(scope?: Set<SceneObject>): Point2D;
|
|
18
|
-
build(): void;
|
|
18
|
+
build(context?: BuildSceneObjectContext): void;
|
|
19
19
|
getEdges(): Edge[];
|
|
20
20
|
getEdgesWithOwner(): Map<Edge, GeometrySceneObject>;
|
|
21
21
|
getGeometriesWithOwner(): Map<Edge, GeometrySceneObject>;
|
|
@@ -3,6 +3,7 @@ import { GeometrySceneObject } from "./geometry.js";
|
|
|
3
3
|
import { SceneObject } from "../../common/scene-object.js";
|
|
4
4
|
import { Edge } from "../../common/edge.js";
|
|
5
5
|
import { Wire } from "../../common/wire.js";
|
|
6
|
+
import { ShapeOps } from "../../oc/shape-ops.js";
|
|
6
7
|
export class Sketch extends SceneObject {
|
|
7
8
|
planeObj;
|
|
8
9
|
constructor(planeObj) {
|
|
@@ -77,10 +78,21 @@ export class Sketch extends SceneObject {
|
|
|
77
78
|
children.pop();
|
|
78
79
|
}
|
|
79
80
|
}
|
|
80
|
-
build() {
|
|
81
|
+
build(context) {
|
|
81
82
|
this.planeObj.removeShapes(this);
|
|
83
|
+
const source = this.getCloneSource();
|
|
84
|
+
const transform = context?.getTransform();
|
|
85
|
+
if (source instanceof Sketch && transform) {
|
|
86
|
+
const originalEdges = source.getEdges();
|
|
87
|
+
const transformedEdges = originalEdges.map(edge => ShapeOps.transform(edge, transform));
|
|
88
|
+
this.setState('cloned-edges', transformedEdges);
|
|
89
|
+
}
|
|
82
90
|
}
|
|
83
91
|
getEdges() {
|
|
92
|
+
const clonedEdges = this.getState('cloned-edges');
|
|
93
|
+
if (clonedEdges) {
|
|
94
|
+
return clonedEdges;
|
|
95
|
+
}
|
|
84
96
|
return [...this.getEdgesWithOwner().keys()];
|
|
85
97
|
}
|
|
86
98
|
getEdgesWithOwner() {
|
|
@@ -8,7 +8,7 @@ export declare class Slot extends ExtrudableGeometryBase implements ISlot {
|
|
|
8
8
|
private _center;
|
|
9
9
|
private _angle;
|
|
10
10
|
constructor(distance: number, radius: number, targetPlane?: PlaneObjectBase);
|
|
11
|
-
|
|
11
|
+
centered(value?: boolean): this;
|
|
12
12
|
rotate(angle: number): this;
|
|
13
13
|
build(): void;
|
|
14
14
|
getType(): string;
|
|
@@ -18,7 +18,7 @@ export declare class Slot extends ExtrudableGeometryBase implements ISlot {
|
|
|
18
18
|
serialize(): {
|
|
19
19
|
distance: number;
|
|
20
20
|
radius: number;
|
|
21
|
-
|
|
21
|
+
centered: boolean;
|
|
22
22
|
angle: number;
|
|
23
23
|
};
|
|
24
24
|
}
|
|
@@ -12,7 +12,7 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
12
12
|
this.distance = distance;
|
|
13
13
|
this.radius = radius;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
centered(value = true) {
|
|
16
16
|
this._center = value;
|
|
17
17
|
return this;
|
|
18
18
|
}
|
|
@@ -86,7 +86,7 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
86
86
|
createCopy(remap) {
|
|
87
87
|
const targetPlane = this.targetPlane ? (remap.get(this.targetPlane) || this.targetPlane) : null;
|
|
88
88
|
const s = new Slot(this.distance, this.radius, targetPlane);
|
|
89
|
-
s.
|
|
89
|
+
s.centered(this._center);
|
|
90
90
|
s.rotate(this._angle);
|
|
91
91
|
return s;
|
|
92
92
|
}
|
|
@@ -112,7 +112,7 @@ export class Slot extends ExtrudableGeometryBase {
|
|
|
112
112
|
return {
|
|
113
113
|
distance: this.distance,
|
|
114
114
|
radius: this.radius,
|
|
115
|
-
|
|
115
|
+
centered: this._center,
|
|
116
116
|
angle: this._angle,
|
|
117
117
|
};
|
|
118
118
|
}
|