fluidcad 0.0.7 → 0.0.9
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/bin/fluidcad.js +16 -0
- package/lib/dist/core/2d/arc.d.ts +15 -0
- package/lib/dist/core/2d/arc.js +10 -0
- package/lib/dist/core/2d/index.d.ts +0 -1
- package/lib/dist/core/2d/index.js +0 -1
- package/lib/dist/core/2d/tarc.d.ts +26 -2
- package/lib/dist/core/2d/tcircle.d.ts +26 -2
- package/lib/dist/core/2d/tline.d.ts +26 -6
- package/lib/dist/core/axis.d.ts +11 -4
- package/lib/dist/core/chamfer.d.ts +6 -6
- package/lib/dist/core/chamfer.js +12 -9
- package/lib/dist/core/cut.d.ts +27 -6
- package/lib/dist/core/extrude.d.ts +15 -3
- package/lib/dist/core/plane.d.ts +11 -4
- package/lib/dist/core/repeat.d.ts +16 -1
- package/lib/dist/core/repeat.js +39 -3
- package/lib/dist/core/sketch.d.ts +9 -3
- package/lib/dist/core/subtract.d.ts +5 -4
- package/lib/dist/core/subtract.js +9 -2
- package/lib/dist/features/2d/arc-three-points.d.ts +19 -0
- package/lib/dist/features/2d/arc-three-points.js +75 -0
- package/lib/dist/features/2d/constraints/geometry-qualifier.d.ts +16 -0
- package/lib/dist/features/2d/constraints/geometry-qualifier.js +16 -0
- package/lib/dist/features/2d/offset.js +10 -0
- package/lib/dist/features/2d/projection.js +9 -0
- package/lib/dist/features/2d/rect.js +19 -16
- package/lib/dist/features/chamfer.d.ts +4 -4
- package/lib/dist/features/chamfer.js +33 -15
- package/lib/dist/features/common2d.js +26 -8
- package/lib/dist/features/fuse2d.js +24 -6
- package/lib/dist/features/repeat-matrix.d.ts +14 -0
- package/lib/dist/features/repeat-matrix.js +41 -0
- package/lib/dist/features/select.d.ts +1 -0
- package/lib/dist/features/select.js +19 -0
- package/lib/dist/features/subtract2d.d.ts +14 -0
- package/lib/dist/features/subtract2d.js +80 -0
- package/lib/dist/filters/edge/belongs-to-face.d.ts +22 -0
- package/lib/dist/filters/edge/belongs-to-face.js +67 -0
- package/lib/dist/filters/edge/belongs-to-object.d.ts +18 -0
- package/lib/dist/filters/edge/belongs-to-object.js +37 -0
- package/lib/dist/filters/edge/edge-filter.d.ts +88 -3
- package/lib/dist/filters/edge/edge-filter.js +101 -4
- package/lib/dist/filters/edge/line-filter.d.ts +4 -1
- package/lib/dist/filters/edge/line-filter.js +14 -7
- package/lib/dist/filters/face/edge-count.d.ts +17 -0
- package/lib/dist/filters/face/edge-count.js +33 -0
- package/lib/dist/filters/face/face-filter.d.ts +93 -0
- package/lib/dist/filters/face/face-filter.js +112 -0
- package/lib/dist/filters/face/has-edge.d.ts +18 -0
- package/lib/dist/filters/face/has-edge.js +59 -0
- package/lib/dist/filters/face/has-object.d.ts +18 -0
- package/lib/dist/filters/face/has-object.js +37 -0
- package/lib/dist/filters/index.d.ts +6 -0
- package/lib/dist/filters/index.js +6 -0
- package/lib/dist/index.js +1 -1
- package/lib/dist/oc/edge-query.d.ts +2 -2
- package/lib/dist/oc/edge-query.js +13 -4
- package/lib/dist/tests/features/2d/arc.test.js +15 -1
- package/lib/dist/tests/features/select.test.js +249 -0
- package/lib/dist/tests/features/subtract2d.test.d.ts +1 -0
- package/lib/dist/tests/features/subtract2d.test.js +63 -0
- package/lib/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -2
- package/server/dist/fluidcad-server.js +3 -2
- package/server/dist/index.js +2 -1
- package/server/dist/normalize-path.d.ts +6 -0
- package/server/dist/normalize-path.js +8 -0
- package/server/dist/vite-manager.js +3 -2
- package/lib/dist/core/2d/wire.d.ts +0 -11
- package/lib/dist/core/2d/wire.js +0 -29
- package/lib/dist/features/2d/wire.d.ts +0 -12
- package/lib/dist/features/2d/wire.js +0 -76
|
@@ -2,20 +2,113 @@ import { PlaneLike } from "../../math/plane.js";
|
|
|
2
2
|
import { Face } from "../../common/shapes.js";
|
|
3
3
|
import { FilterBuilderBase } from "../filter-builder-base.js";
|
|
4
4
|
import { PlaneObjectBase } from "../../features/plane-renderable-base.js";
|
|
5
|
+
import { EdgeFilterBuilder } from "../edge/edge-filter.js";
|
|
6
|
+
import { ISceneObject } from "../../core/interfaces.js";
|
|
5
7
|
export declare class FaceFilterBuilder extends FilterBuilderBase<Face> {
|
|
6
8
|
constructor();
|
|
9
|
+
/**
|
|
10
|
+
* Selects the face at the given index.
|
|
11
|
+
* @param index - Zero-based face index.
|
|
12
|
+
* @param shapes - The face array to index into.
|
|
13
|
+
* @param originalShapes - Optional original face array before filtering.
|
|
14
|
+
*/
|
|
7
15
|
atIndex(index: number, shapes: Face[], originalShapes?: Face[]): this;
|
|
16
|
+
/**
|
|
17
|
+
* Excludes the face at the given index.
|
|
18
|
+
* @param index - Zero-based face index to exclude.
|
|
19
|
+
* @param shapes - The face array to index into.
|
|
20
|
+
* @param originalShapes - Optional original face array before filtering.
|
|
21
|
+
*/
|
|
8
22
|
notAtIndex(index: number, shapes: Face[], originalShapes?: Face[]): this;
|
|
23
|
+
/**
|
|
24
|
+
* Selects faces that lie on the given plane.
|
|
25
|
+
* @param plane - The reference plane.
|
|
26
|
+
* @param offset - Optional distance to offset the plane before matching.
|
|
27
|
+
*/
|
|
9
28
|
onPlane(plane: PlaneLike | PlaneObjectBase, offset?: number): this;
|
|
29
|
+
/**
|
|
30
|
+
* Excludes faces that lie on the given plane.
|
|
31
|
+
* @param plane - The reference plane.
|
|
32
|
+
* @param offset - Optional distance to offset the plane before matching.
|
|
33
|
+
*/
|
|
10
34
|
notOnPlane(plane: PlaneLike | PlaneObjectBase, offset?: number): this;
|
|
35
|
+
/**
|
|
36
|
+
* Selects circular (flat, disc-shaped) faces, optionally matching a specific diameter.
|
|
37
|
+
* @param diameter - Optional diameter to match.
|
|
38
|
+
*/
|
|
11
39
|
circle(diameter?: number): this;
|
|
40
|
+
/**
|
|
41
|
+
* Excludes circular (flat, disc-shaped) faces, optionally matching a specific diameter.
|
|
42
|
+
* @param diameter - Optional diameter to exclude.
|
|
43
|
+
*/
|
|
12
44
|
notCircle(diameter?: number): this;
|
|
45
|
+
/**
|
|
46
|
+
* Selects cylindrical faces, optionally matching a specific diameter.
|
|
47
|
+
* @param diameter - Optional diameter to match.
|
|
48
|
+
*/
|
|
13
49
|
cylinder(diameter?: number): this;
|
|
50
|
+
/**
|
|
51
|
+
* Excludes cylindrical faces, optionally matching a specific diameter.
|
|
52
|
+
* @param diameter - Optional diameter to exclude.
|
|
53
|
+
*/
|
|
14
54
|
notCylinder(diameter?: number): this;
|
|
55
|
+
/**
|
|
56
|
+
* Selects faces bounded by cylindrical curves, optionally matching a specific diameter.
|
|
57
|
+
* @param diameter - Optional diameter to match.
|
|
58
|
+
*/
|
|
15
59
|
cylinderCurve(diameter?: number): this;
|
|
60
|
+
/**
|
|
61
|
+
* Excludes faces bounded by cylindrical curves, optionally matching a specific diameter.
|
|
62
|
+
* @param diameter - Optional diameter to exclude.
|
|
63
|
+
*/
|
|
16
64
|
notCylinderCurve(diameter?: number): this;
|
|
65
|
+
/**
|
|
66
|
+
* Selects faces whose normal is parallel to the given plane.
|
|
67
|
+
* @param plane - The reference plane.
|
|
68
|
+
*/
|
|
17
69
|
parallelTo(plane: PlaneLike | PlaneObjectBase): this;
|
|
70
|
+
/**
|
|
71
|
+
* Excludes faces whose normal is parallel to the given plane.
|
|
72
|
+
* @param plane - The reference plane.
|
|
73
|
+
*/
|
|
18
74
|
notParallelTo(plane: PlaneLike | PlaneObjectBase): this;
|
|
75
|
+
/**
|
|
76
|
+
* Selects conical faces.
|
|
77
|
+
*/
|
|
19
78
|
cone(): this;
|
|
79
|
+
/**
|
|
80
|
+
* Excludes conical faces.
|
|
81
|
+
*/
|
|
20
82
|
notCone(): this;
|
|
83
|
+
/**
|
|
84
|
+
* Selects faces that share an edge with the given scene object.
|
|
85
|
+
* @param sceneObject - A scene object whose edges are matched against.
|
|
86
|
+
*/
|
|
87
|
+
hasEdge(sceneObject: ISceneObject): this;
|
|
88
|
+
/**
|
|
89
|
+
* Selects faces that have edges matching all of the given edge filters.
|
|
90
|
+
* Each edge filter builder must match at least one edge of the face.
|
|
91
|
+
* @param edgeFilters - One or more edge filter builders. All must be satisfied.
|
|
92
|
+
*/
|
|
93
|
+
hasEdge(...edgeFilters: EdgeFilterBuilder[]): this;
|
|
94
|
+
/**
|
|
95
|
+
* Excludes faces that share an edge with the given scene object.
|
|
96
|
+
* @param sceneObject - A scene object whose edges are matched against.
|
|
97
|
+
*/
|
|
98
|
+
notHasEdge(sceneObject: ISceneObject): this;
|
|
99
|
+
/**
|
|
100
|
+
* Excludes faces that have edges matching all of the given edge filters.
|
|
101
|
+
* @param edgeFilters - One or more edge filter builders. If all are satisfied, the face is excluded.
|
|
102
|
+
*/
|
|
103
|
+
notHasEdge(...edgeFilters: EdgeFilterBuilder[]): this;
|
|
104
|
+
/**
|
|
105
|
+
* Selects faces with exactly the given number of edges.
|
|
106
|
+
* @param count - The exact number of edges to match.
|
|
107
|
+
*/
|
|
108
|
+
edgeCount(count: number): this;
|
|
109
|
+
/**
|
|
110
|
+
* Excludes faces with the given number of edges.
|
|
111
|
+
* @param count - The number of edges to exclude.
|
|
112
|
+
*/
|
|
113
|
+
notEdgeCount(count: number): this;
|
|
21
114
|
}
|
|
@@ -9,20 +9,41 @@ import { NotParallelFilter, ParallelFilter } from "./parallel.js";
|
|
|
9
9
|
import { PlaneObject } from "../../features/plane.js";
|
|
10
10
|
import { PlaneObjectBase } from "../../features/plane-renderable-base.js";
|
|
11
11
|
import { AtIndexFilter, NotAtIndexFilter } from "./at-index.js";
|
|
12
|
+
import { HasEdgeFilter, NotHasEdgeFilter } from "./has-edge.js";
|
|
13
|
+
import { HasEdgeFromSceneObjectFilter, NotHasEdgeFromSceneObjectFilter } from "./has-object.js";
|
|
14
|
+
import { EdgeCountFilter, NotEdgeCountFilter } from "./edge-count.js";
|
|
15
|
+
import { SceneObject } from "../../common/scene-object.js";
|
|
12
16
|
export class FaceFilterBuilder extends FilterBuilderBase {
|
|
13
17
|
constructor() {
|
|
14
18
|
super();
|
|
15
19
|
}
|
|
20
|
+
/**
|
|
21
|
+
* Selects the face at the given index.
|
|
22
|
+
* @param index - Zero-based face index.
|
|
23
|
+
* @param shapes - The face array to index into.
|
|
24
|
+
* @param originalShapes - Optional original face array before filtering.
|
|
25
|
+
*/
|
|
16
26
|
atIndex(index, shapes, originalShapes) {
|
|
17
27
|
const filter = new AtIndexFilter(index, shapes, originalShapes);
|
|
18
28
|
this.filters.push(filter);
|
|
19
29
|
return this;
|
|
20
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Excludes the face at the given index.
|
|
33
|
+
* @param index - Zero-based face index to exclude.
|
|
34
|
+
* @param shapes - The face array to index into.
|
|
35
|
+
* @param originalShapes - Optional original face array before filtering.
|
|
36
|
+
*/
|
|
21
37
|
notAtIndex(index, shapes, originalShapes) {
|
|
22
38
|
const filter = new NotAtIndexFilter(index, shapes, originalShapes);
|
|
23
39
|
this.filters.push(filter);
|
|
24
40
|
return this;
|
|
25
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Selects faces that lie on the given plane.
|
|
44
|
+
* @param plane - The reference plane.
|
|
45
|
+
* @param offset - Optional distance to offset the plane before matching.
|
|
46
|
+
*/
|
|
26
47
|
onPlane(plane, offset = 0) {
|
|
27
48
|
if (!plane) {
|
|
28
49
|
throw new Error('Plane is required');
|
|
@@ -42,6 +63,11 @@ export class FaceFilterBuilder extends FilterBuilderBase {
|
|
|
42
63
|
this.filters.push(filter);
|
|
43
64
|
return this;
|
|
44
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Excludes faces that lie on the given plane.
|
|
68
|
+
* @param plane - The reference plane.
|
|
69
|
+
* @param offset - Optional distance to offset the plane before matching.
|
|
70
|
+
*/
|
|
45
71
|
notOnPlane(plane, offset = 0) {
|
|
46
72
|
if (!plane) {
|
|
47
73
|
throw new Error('Plane is required');
|
|
@@ -61,36 +87,64 @@ export class FaceFilterBuilder extends FilterBuilderBase {
|
|
|
61
87
|
this.filters.push(filter);
|
|
62
88
|
return this;
|
|
63
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Selects circular (flat, disc-shaped) faces, optionally matching a specific diameter.
|
|
92
|
+
* @param diameter - Optional diameter to match.
|
|
93
|
+
*/
|
|
64
94
|
circle(diameter) {
|
|
65
95
|
const filter = new CircleFilter(diameter);
|
|
66
96
|
this.filters.push(filter);
|
|
67
97
|
return this;
|
|
68
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Excludes circular (flat, disc-shaped) faces, optionally matching a specific diameter.
|
|
101
|
+
* @param diameter - Optional diameter to exclude.
|
|
102
|
+
*/
|
|
69
103
|
notCircle(diameter) {
|
|
70
104
|
const filter = new NotCircleFilter(diameter);
|
|
71
105
|
this.filters.push(filter);
|
|
72
106
|
return this;
|
|
73
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* Selects cylindrical faces, optionally matching a specific diameter.
|
|
110
|
+
* @param diameter - Optional diameter to match.
|
|
111
|
+
*/
|
|
74
112
|
cylinder(diameter) {
|
|
75
113
|
const filter = new CylinderFilter(diameter);
|
|
76
114
|
this.filters.push(filter);
|
|
77
115
|
return this;
|
|
78
116
|
}
|
|
117
|
+
/**
|
|
118
|
+
* Excludes cylindrical faces, optionally matching a specific diameter.
|
|
119
|
+
* @param diameter - Optional diameter to exclude.
|
|
120
|
+
*/
|
|
79
121
|
notCylinder(diameter) {
|
|
80
122
|
const filter = new NotCylinderFilter(diameter);
|
|
81
123
|
this.filters.push(filter);
|
|
82
124
|
return this;
|
|
83
125
|
}
|
|
126
|
+
/**
|
|
127
|
+
* Selects faces bounded by cylindrical curves, optionally matching a specific diameter.
|
|
128
|
+
* @param diameter - Optional diameter to match.
|
|
129
|
+
*/
|
|
84
130
|
cylinderCurve(diameter) {
|
|
85
131
|
const filter = new CylinderCurveFilter(diameter);
|
|
86
132
|
this.filters.push(filter);
|
|
87
133
|
return this;
|
|
88
134
|
}
|
|
135
|
+
/**
|
|
136
|
+
* Excludes faces bounded by cylindrical curves, optionally matching a specific diameter.
|
|
137
|
+
* @param diameter - Optional diameter to exclude.
|
|
138
|
+
*/
|
|
89
139
|
notCylinderCurve(diameter) {
|
|
90
140
|
const filter = new NotCylinderCurveFilter(diameter);
|
|
91
141
|
this.filters.push(filter);
|
|
92
142
|
return this;
|
|
93
143
|
}
|
|
144
|
+
/**
|
|
145
|
+
* Selects faces whose normal is parallel to the given plane.
|
|
146
|
+
* @param plane - The reference plane.
|
|
147
|
+
*/
|
|
94
148
|
parallelTo(plane) {
|
|
95
149
|
if (!plane) {
|
|
96
150
|
throw new Error('Plane is required');
|
|
@@ -106,6 +160,10 @@ export class FaceFilterBuilder extends FilterBuilderBase {
|
|
|
106
160
|
this.filters.push(filter);
|
|
107
161
|
return this;
|
|
108
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Excludes faces whose normal is parallel to the given plane.
|
|
165
|
+
* @param plane - The reference plane.
|
|
166
|
+
*/
|
|
109
167
|
notParallelTo(plane) {
|
|
110
168
|
if (!plane) {
|
|
111
169
|
throw new Error('Plane is required');
|
|
@@ -121,14 +179,68 @@ export class FaceFilterBuilder extends FilterBuilderBase {
|
|
|
121
179
|
this.filters.push(filter);
|
|
122
180
|
return this;
|
|
123
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Selects conical faces.
|
|
184
|
+
*/
|
|
124
185
|
cone() {
|
|
125
186
|
const filter = new ConeFilter();
|
|
126
187
|
this.filters.push(filter);
|
|
127
188
|
return this;
|
|
128
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Excludes conical faces.
|
|
192
|
+
*/
|
|
129
193
|
notCone() {
|
|
130
194
|
const filter = new NotConeFilter();
|
|
131
195
|
this.filters.push(filter);
|
|
132
196
|
return this;
|
|
133
197
|
}
|
|
198
|
+
hasEdge(...args) {
|
|
199
|
+
const filterBuilders = [];
|
|
200
|
+
for (const arg of args) {
|
|
201
|
+
if (arg instanceof SceneObject) {
|
|
202
|
+
this.filters.push(new HasEdgeFromSceneObjectFilter(arg));
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
filterBuilders.push(arg);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
if (filterBuilders.length > 0) {
|
|
209
|
+
this.filters.push(new HasEdgeFilter(filterBuilders));
|
|
210
|
+
}
|
|
211
|
+
return this;
|
|
212
|
+
}
|
|
213
|
+
notHasEdge(...args) {
|
|
214
|
+
const filterBuilders = [];
|
|
215
|
+
for (const arg of args) {
|
|
216
|
+
if (arg instanceof SceneObject) {
|
|
217
|
+
this.filters.push(new NotHasEdgeFromSceneObjectFilter(arg));
|
|
218
|
+
}
|
|
219
|
+
else {
|
|
220
|
+
filterBuilders.push(arg);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
if (filterBuilders.length > 0) {
|
|
224
|
+
this.filters.push(new NotHasEdgeFilter(filterBuilders));
|
|
225
|
+
}
|
|
226
|
+
return this;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Selects faces with exactly the given number of edges.
|
|
230
|
+
* @param count - The exact number of edges to match.
|
|
231
|
+
*/
|
|
232
|
+
edgeCount(count) {
|
|
233
|
+
const filter = new EdgeCountFilter(count);
|
|
234
|
+
this.filters.push(filter);
|
|
235
|
+
return this;
|
|
236
|
+
}
|
|
237
|
+
/**
|
|
238
|
+
* Excludes faces with the given number of edges.
|
|
239
|
+
* @param count - The number of edges to exclude.
|
|
240
|
+
*/
|
|
241
|
+
notEdgeCount(count) {
|
|
242
|
+
const filter = new NotEdgeCountFilter(count);
|
|
243
|
+
this.filters.push(filter);
|
|
244
|
+
return this;
|
|
245
|
+
}
|
|
134
246
|
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Matrix4 } from "../../math/matrix4.js";
|
|
2
|
+
import { Edge, Face } from "../../common/shapes.js";
|
|
3
|
+
import { FilterBase } from "../filter-base.js";
|
|
4
|
+
import { FilterBuilderBase } from "../filter-builder-base.js";
|
|
5
|
+
export declare class HasEdgeFilter extends FilterBase<Face> {
|
|
6
|
+
private edgeFilterBuilders;
|
|
7
|
+
constructor(edgeFilterBuilders: FilterBuilderBase<Edge>[]);
|
|
8
|
+
match(shape: Face): boolean;
|
|
9
|
+
compareTo(other: HasEdgeFilter): boolean;
|
|
10
|
+
transform(matrix: Matrix4): HasEdgeFilter;
|
|
11
|
+
}
|
|
12
|
+
export declare class NotHasEdgeFilter extends FilterBase<Face> {
|
|
13
|
+
private edgeFilterBuilders;
|
|
14
|
+
constructor(edgeFilterBuilders: FilterBuilderBase<Edge>[]);
|
|
15
|
+
match(shape: Face): boolean;
|
|
16
|
+
compareTo(other: NotHasEdgeFilter): boolean;
|
|
17
|
+
transform(matrix: Matrix4): NotHasEdgeFilter;
|
|
18
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { FilterBase } from "../filter-base.js";
|
|
2
|
+
export class HasEdgeFilter extends FilterBase {
|
|
3
|
+
edgeFilterBuilders;
|
|
4
|
+
constructor(edgeFilterBuilders) {
|
|
5
|
+
super();
|
|
6
|
+
this.edgeFilterBuilders = edgeFilterBuilders;
|
|
7
|
+
}
|
|
8
|
+
match(shape) {
|
|
9
|
+
const edges = shape.getEdges();
|
|
10
|
+
return this.edgeFilterBuilders.every(builder => {
|
|
11
|
+
const filters = builder.getFilters();
|
|
12
|
+
return edges.some(edge => filters.every(f => f.match(edge)));
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
compareTo(other) {
|
|
16
|
+
if (this.edgeFilterBuilders.length !== other.edgeFilterBuilders.length) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
for (let i = 0; i < this.edgeFilterBuilders.length; i++) {
|
|
20
|
+
if (!this.edgeFilterBuilders[i].equals(other.edgeFilterBuilders[i])) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
transform(matrix) {
|
|
27
|
+
const transformed = this.edgeFilterBuilders.map(builder => builder.transform(matrix));
|
|
28
|
+
return new HasEdgeFilter(transformed);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export class NotHasEdgeFilter extends FilterBase {
|
|
32
|
+
edgeFilterBuilders;
|
|
33
|
+
constructor(edgeFilterBuilders) {
|
|
34
|
+
super();
|
|
35
|
+
this.edgeFilterBuilders = edgeFilterBuilders;
|
|
36
|
+
}
|
|
37
|
+
match(shape) {
|
|
38
|
+
const edges = shape.getEdges();
|
|
39
|
+
return !this.edgeFilterBuilders.every(builder => {
|
|
40
|
+
const filters = builder.getFilters();
|
|
41
|
+
return edges.some(edge => filters.every(f => f.match(edge)));
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
compareTo(other) {
|
|
45
|
+
if (this.edgeFilterBuilders.length !== other.edgeFilterBuilders.length) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
for (let i = 0; i < this.edgeFilterBuilders.length; i++) {
|
|
49
|
+
if (!this.edgeFilterBuilders[i].equals(other.edgeFilterBuilders[i])) {
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return true;
|
|
54
|
+
}
|
|
55
|
+
transform(matrix) {
|
|
56
|
+
const transformed = this.edgeFilterBuilders.map(builder => builder.transform(matrix));
|
|
57
|
+
return new NotHasEdgeFilter(transformed);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Matrix4 } from "../../math/matrix4.js";
|
|
2
|
+
import { Face } from "../../common/shapes.js";
|
|
3
|
+
import { FilterBase } from "../filter-base.js";
|
|
4
|
+
import { SceneObject } from "../../common/scene-object.js";
|
|
5
|
+
export declare class HasEdgeFromSceneObjectFilter extends FilterBase<Face> {
|
|
6
|
+
private sceneObject;
|
|
7
|
+
constructor(sceneObject: SceneObject);
|
|
8
|
+
match(shape: Face): boolean;
|
|
9
|
+
compareTo(other: HasEdgeFromSceneObjectFilter): boolean;
|
|
10
|
+
transform(_matrix: Matrix4): HasEdgeFromSceneObjectFilter;
|
|
11
|
+
}
|
|
12
|
+
export declare class NotHasEdgeFromSceneObjectFilter extends FilterBase<Face> {
|
|
13
|
+
private sceneObject;
|
|
14
|
+
constructor(sceneObject: SceneObject);
|
|
15
|
+
match(shape: Face): boolean;
|
|
16
|
+
compareTo(other: NotHasEdgeFromSceneObjectFilter): boolean;
|
|
17
|
+
transform(_matrix: Matrix4): NotHasEdgeFromSceneObjectFilter;
|
|
18
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { FilterBase } from "../filter-base.js";
|
|
2
|
+
export class HasEdgeFromSceneObjectFilter extends FilterBase {
|
|
3
|
+
sceneObject;
|
|
4
|
+
constructor(sceneObject) {
|
|
5
|
+
super();
|
|
6
|
+
this.sceneObject = sceneObject;
|
|
7
|
+
}
|
|
8
|
+
match(shape) {
|
|
9
|
+
const objectEdges = this.sceneObject.getShapes()
|
|
10
|
+
.flatMap(s => s.getSubShapes("edge"));
|
|
11
|
+
return objectEdges.some(objEdge => shape.hasEdge(objEdge.getShape()) !== null);
|
|
12
|
+
}
|
|
13
|
+
compareTo(other) {
|
|
14
|
+
return this.sceneObject.compareTo(other.sceneObject);
|
|
15
|
+
}
|
|
16
|
+
transform(_matrix) {
|
|
17
|
+
return new HasEdgeFromSceneObjectFilter(this.sceneObject);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class NotHasEdgeFromSceneObjectFilter extends FilterBase {
|
|
21
|
+
sceneObject;
|
|
22
|
+
constructor(sceneObject) {
|
|
23
|
+
super();
|
|
24
|
+
this.sceneObject = sceneObject;
|
|
25
|
+
}
|
|
26
|
+
match(shape) {
|
|
27
|
+
const objectEdges = this.sceneObject.getShapes()
|
|
28
|
+
.flatMap(s => s.getSubShapes("edge"));
|
|
29
|
+
return !objectEdges.some(objEdge => shape.hasEdge(objEdge.getShape()) !== null);
|
|
30
|
+
}
|
|
31
|
+
compareTo(other) {
|
|
32
|
+
return this.sceneObject.compareTo(other.sceneObject);
|
|
33
|
+
}
|
|
34
|
+
transform(_matrix) {
|
|
35
|
+
return new NotHasEdgeFromSceneObjectFilter(this.sceneObject);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { FaceFilterBuilder } from './face/face-filter.js';
|
|
2
2
|
import { EdgeFilterBuilder } from './edge/edge-filter.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a new face filter builder for selecting faces by geometric properties.
|
|
5
|
+
*/
|
|
3
6
|
export declare function face(): FaceFilterBuilder;
|
|
7
|
+
/**
|
|
8
|
+
* Creates a new edge filter builder for selecting edges by geometric properties.
|
|
9
|
+
*/
|
|
4
10
|
export declare function edge(): EdgeFilterBuilder;
|
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import { FaceFilterBuilder } from './face/face-filter.js';
|
|
2
2
|
import { EdgeFilterBuilder } from './edge/edge-filter.js';
|
|
3
|
+
/**
|
|
4
|
+
* Creates a new face filter builder for selecting faces by geometric properties.
|
|
5
|
+
*/
|
|
3
6
|
export function face() {
|
|
4
7
|
return new FaceFilterBuilder();
|
|
5
8
|
}
|
|
9
|
+
/**
|
|
10
|
+
* Creates a new edge filter builder for selecting edges by geometric properties.
|
|
11
|
+
*/
|
|
6
12
|
export function edge() {
|
|
7
13
|
return new EdgeFilterBuilder();
|
|
8
14
|
}
|
package/lib/dist/index.js
CHANGED
|
@@ -7,7 +7,7 @@ export function captureSourceLocation() {
|
|
|
7
7
|
}
|
|
8
8
|
const lines = stack.split('\n');
|
|
9
9
|
for (const frame of lines) {
|
|
10
|
-
const match = frame.match(/(
|
|
10
|
+
const match = frame.match(/((?:[A-Za-z]:)?\/[^\s]+?\.fluid\.js):(\d+):(\d+)/);
|
|
11
11
|
if (match) {
|
|
12
12
|
return {
|
|
13
13
|
filePath: match[1],
|
|
@@ -7,7 +7,7 @@ import { Edge } from "../common/edge.js";
|
|
|
7
7
|
export declare class EdgeQuery {
|
|
8
8
|
static isCircleEdge(edge: Shape, diameter?: number): boolean;
|
|
9
9
|
static isArcEdge(edge: Shape, radius?: number): boolean;
|
|
10
|
-
static isLineEdge(edge: Shape): boolean;
|
|
10
|
+
static isLineEdge(edge: Shape, length?: number): boolean;
|
|
11
11
|
static isEdgeOnPlane(edge: Shape, plane: Plane): boolean;
|
|
12
12
|
static isEdgeParallelToPlane(edge: Shape, planeNormal: Vector3d): boolean;
|
|
13
13
|
static isEdgeAlignedWithNormal(edge: Shape, planeNormal: Vector3d): boolean;
|
|
@@ -25,7 +25,7 @@ export declare class EdgeQuery {
|
|
|
25
25
|
};
|
|
26
26
|
static isCircleEdgeRaw(edge: TopoDS_Shape, diameter?: number): boolean;
|
|
27
27
|
static isArcEdgeRaw(edge: TopoDS_Shape, radius?: number): boolean;
|
|
28
|
-
static isLineEdgeRaw(edge: TopoDS_Shape): boolean;
|
|
28
|
+
static isLineEdgeRaw(edge: TopoDS_Shape, length?: number): boolean;
|
|
29
29
|
static isEdgeOnPlaneRaw(edge: TopoDS_Shape, plane: gp_Pln): boolean;
|
|
30
30
|
static isEdgeParallelToPlaneRaw(edge: TopoDS_Shape, planeNormal: gp_Vec): boolean;
|
|
31
31
|
static isEdgeAlignedWithNormalRaw(edge: TopoDS_Shape, planeNormal: gp_Vec): boolean;
|
|
@@ -10,8 +10,8 @@ export class EdgeQuery {
|
|
|
10
10
|
static isArcEdge(edge, radius) {
|
|
11
11
|
return EdgeQuery.isArcEdgeRaw(edge.getShape(), radius);
|
|
12
12
|
}
|
|
13
|
-
static isLineEdge(edge) {
|
|
14
|
-
return EdgeQuery.isLineEdgeRaw(edge.getShape());
|
|
13
|
+
static isLineEdge(edge, length) {
|
|
14
|
+
return EdgeQuery.isLineEdgeRaw(edge.getShape(), length);
|
|
15
15
|
}
|
|
16
16
|
static isEdgeOnPlane(edge, plane) {
|
|
17
17
|
const [gpPln, dispose] = Convert.toGpPln(plane);
|
|
@@ -93,13 +93,22 @@ export class EdgeQuery {
|
|
|
93
93
|
curveAdaptor.delete();
|
|
94
94
|
return Math.abs(r - radius) <= oc.Precision.Confusion();
|
|
95
95
|
}
|
|
96
|
-
static isLineEdgeRaw(edge) {
|
|
96
|
+
static isLineEdgeRaw(edge, length) {
|
|
97
97
|
const oc = getOC();
|
|
98
98
|
const ocEdge = oc.TopoDS.Edge(edge);
|
|
99
99
|
const curveAdaptor = new oc.BRepAdaptor_Curve(ocEdge);
|
|
100
100
|
const curveType = curveAdaptor.GetType();
|
|
101
|
+
if (curveType !== oc.GeomAbs_CurveType.GeomAbs_Line) {
|
|
102
|
+
curveAdaptor.delete();
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
if (length === undefined) {
|
|
106
|
+
curveAdaptor.delete();
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
const edgeLength = Math.abs(curveAdaptor.LastParameter() - curveAdaptor.FirstParameter());
|
|
101
110
|
curveAdaptor.delete();
|
|
102
|
-
return
|
|
111
|
+
return Math.abs(edgeLength - length) <= oc.Precision.Confusion();
|
|
103
112
|
}
|
|
104
113
|
static isEdgeOnPlaneRaw(edge, plane) {
|
|
105
114
|
const oc = getOC();
|
|
@@ -2,7 +2,7 @@ import { describe, it, expect } from "vitest";
|
|
|
2
2
|
import { setupOC, render } from "../../setup.js";
|
|
3
3
|
import sketch from "../../../core/sketch.js";
|
|
4
4
|
import extrude from "../../../core/extrude.js";
|
|
5
|
-
import { arc, hLine, vLine } from "../../../core/2d/index.js";
|
|
5
|
+
import { arc, hLine, vLine, line } from "../../../core/2d/index.js";
|
|
6
6
|
import { getEdgesByType } from "../../utils.js";
|
|
7
7
|
describe("arc", () => {
|
|
8
8
|
setupOC();
|
|
@@ -22,6 +22,20 @@ describe("arc", () => {
|
|
|
22
22
|
expect(arcEdges.length).toBeGreaterThan(0);
|
|
23
23
|
});
|
|
24
24
|
});
|
|
25
|
+
describe("from three points (start, end, center)", () => {
|
|
26
|
+
it("should create an arc from start to end around a center point", () => {
|
|
27
|
+
sketch("xy", () => {
|
|
28
|
+
arc([0, 0], [20, 0], [10, 0]);
|
|
29
|
+
line([0, 0]);
|
|
30
|
+
});
|
|
31
|
+
const e = extrude(10);
|
|
32
|
+
render();
|
|
33
|
+
expect(e.getShapes()).toHaveLength(1);
|
|
34
|
+
const solid = e.getShapes()[0];
|
|
35
|
+
const arcEdges = getEdgesByType(solid, "arc");
|
|
36
|
+
expect(arcEdges.length).toBeGreaterThan(0);
|
|
37
|
+
});
|
|
38
|
+
});
|
|
25
39
|
describe("combined with lines", () => {
|
|
26
40
|
it("should create a shape with straight and curved edges", () => {
|
|
27
41
|
sketch("xy", () => {
|