fluidcad 0.0.7 → 0.0.8
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/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/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
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { Wire } from "../common/wire.js";
|
|
2
|
+
import { Edge } from "../common/edge.js";
|
|
3
|
+
import { Face } from "../common/face.js";
|
|
4
|
+
import { GeometrySceneObject } from "./2d/geometry.js";
|
|
5
|
+
import { BooleanOps } from "../oc/boolean-ops.js";
|
|
6
|
+
import { ShapeOps } from "../oc/shape-ops.js";
|
|
7
|
+
import { Explorer } from "../oc/explorer.js";
|
|
8
|
+
import { FaceMaker2 } from "../oc/face-maker2.js";
|
|
9
|
+
export class Subtract2D extends GeometrySceneObject {
|
|
10
|
+
target1;
|
|
11
|
+
target2;
|
|
12
|
+
constructor(target1, target2) {
|
|
13
|
+
super();
|
|
14
|
+
this.target1 = target1;
|
|
15
|
+
this.target2 = target2;
|
|
16
|
+
}
|
|
17
|
+
collectEdges(target) {
|
|
18
|
+
const edges = new Map();
|
|
19
|
+
for (const shape of target.getShapes()) {
|
|
20
|
+
if (shape instanceof Edge) {
|
|
21
|
+
edges.set(shape, target);
|
|
22
|
+
}
|
|
23
|
+
else if (shape instanceof Wire) {
|
|
24
|
+
for (const edge of shape.getEdges()) {
|
|
25
|
+
edges.set(edge, target);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return edges;
|
|
30
|
+
}
|
|
31
|
+
build(context) {
|
|
32
|
+
const plane = this.sketch.getPlane();
|
|
33
|
+
const baseEdgeMap = this.collectEdges(this.target1);
|
|
34
|
+
const toolEdgeMap = this.collectEdges(this.target2);
|
|
35
|
+
const baseFaces = FaceMaker2.getRegions(Array.from(baseEdgeMap.keys()), plane);
|
|
36
|
+
const toolFaces = FaceMaker2.getRegions(Array.from(toolEdgeMap.keys()), plane);
|
|
37
|
+
if (baseFaces.length === 0 || toolFaces.length === 0) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const baseCompound = ShapeOps.makeCompoundRaw(baseFaces.map(f => f.getShape()));
|
|
41
|
+
const toolCompound = ShapeOps.makeCompoundRaw(toolFaces.map(f => f.getShape()));
|
|
42
|
+
const result = BooleanOps.cutShapesRaw(baseCompound, toolCompound);
|
|
43
|
+
const resultFaces = Explorer.findShapes(result, Explorer.getOcShapeType("face"))
|
|
44
|
+
.map(f => Face.fromTopoDSFace(Explorer.toFace(f)));
|
|
45
|
+
const newEdges = resultFaces.flatMap(face => face.getEdges());
|
|
46
|
+
for (const [edge, owner] of baseEdgeMap) {
|
|
47
|
+
owner.removeShape(edge, this);
|
|
48
|
+
}
|
|
49
|
+
for (const [edge, owner] of toolEdgeMap) {
|
|
50
|
+
owner.removeShape(edge, this);
|
|
51
|
+
}
|
|
52
|
+
this.addShapes(newEdges);
|
|
53
|
+
}
|
|
54
|
+
getDependencies() {
|
|
55
|
+
return [this.target1, this.target2];
|
|
56
|
+
}
|
|
57
|
+
createCopy(remap) {
|
|
58
|
+
const t1 = remap.get(this.target1) || this.target1;
|
|
59
|
+
const t2 = remap.get(this.target2) || this.target2;
|
|
60
|
+
return new Subtract2D(t1, t2);
|
|
61
|
+
}
|
|
62
|
+
compareTo(other) {
|
|
63
|
+
if (!(other instanceof Subtract2D)) {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
if (!super.compareTo(other)) {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
if (!this.target1.compareTo(other.target1) || !this.target2.compareTo(other.target2)) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
getType() {
|
|
75
|
+
return "subtract2d";
|
|
76
|
+
}
|
|
77
|
+
serialize() {
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
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 BelongsToFaceFilter extends FilterBase<Edge> {
|
|
6
|
+
private faceFilterBuilders;
|
|
7
|
+
private scopeFaces;
|
|
8
|
+
constructor(faceFilterBuilders: FilterBuilderBase<Face>[]);
|
|
9
|
+
setScopeFaces(faces: Face[]): void;
|
|
10
|
+
match(shape: Edge): boolean;
|
|
11
|
+
compareTo(other: BelongsToFaceFilter): boolean;
|
|
12
|
+
transform(matrix: Matrix4): BelongsToFaceFilter;
|
|
13
|
+
}
|
|
14
|
+
export declare class NotBelongsToFaceFilter extends FilterBase<Edge> {
|
|
15
|
+
private faceFilterBuilders;
|
|
16
|
+
private scopeFaces;
|
|
17
|
+
constructor(faceFilterBuilders: FilterBuilderBase<Face>[]);
|
|
18
|
+
setScopeFaces(faces: Face[]): void;
|
|
19
|
+
match(shape: Edge): boolean;
|
|
20
|
+
compareTo(other: NotBelongsToFaceFilter): boolean;
|
|
21
|
+
transform(matrix: Matrix4): NotBelongsToFaceFilter;
|
|
22
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { FilterBase } from "../filter-base.js";
|
|
2
|
+
export class BelongsToFaceFilter extends FilterBase {
|
|
3
|
+
faceFilterBuilders;
|
|
4
|
+
scopeFaces = [];
|
|
5
|
+
constructor(faceFilterBuilders) {
|
|
6
|
+
super();
|
|
7
|
+
this.faceFilterBuilders = faceFilterBuilders;
|
|
8
|
+
}
|
|
9
|
+
setScopeFaces(faces) {
|
|
10
|
+
this.scopeFaces = faces;
|
|
11
|
+
}
|
|
12
|
+
match(shape) {
|
|
13
|
+
const containingFaces = this.scopeFaces.filter(face => face.hasEdge(shape.getShape()) !== null);
|
|
14
|
+
return this.faceFilterBuilders.every(builder => {
|
|
15
|
+
const filters = builder.getFilters();
|
|
16
|
+
return containingFaces.some(face => filters.every(f => f.match(face)));
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
compareTo(other) {
|
|
20
|
+
if (this.faceFilterBuilders.length !== other.faceFilterBuilders.length) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
for (let i = 0; i < this.faceFilterBuilders.length; i++) {
|
|
24
|
+
if (!this.faceFilterBuilders[i].equals(other.faceFilterBuilders[i])) {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return true;
|
|
29
|
+
}
|
|
30
|
+
transform(matrix) {
|
|
31
|
+
const transformed = this.faceFilterBuilders.map(builder => builder.transform(matrix));
|
|
32
|
+
return new BelongsToFaceFilter(transformed);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
export class NotBelongsToFaceFilter extends FilterBase {
|
|
36
|
+
faceFilterBuilders;
|
|
37
|
+
scopeFaces = [];
|
|
38
|
+
constructor(faceFilterBuilders) {
|
|
39
|
+
super();
|
|
40
|
+
this.faceFilterBuilders = faceFilterBuilders;
|
|
41
|
+
}
|
|
42
|
+
setScopeFaces(faces) {
|
|
43
|
+
this.scopeFaces = faces;
|
|
44
|
+
}
|
|
45
|
+
match(shape) {
|
|
46
|
+
const containingFaces = this.scopeFaces.filter(face => face.hasEdge(shape.getShape()) !== null);
|
|
47
|
+
return !this.faceFilterBuilders.every(builder => {
|
|
48
|
+
const filters = builder.getFilters();
|
|
49
|
+
return containingFaces.some(face => filters.every(f => f.match(face)));
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
compareTo(other) {
|
|
53
|
+
if (this.faceFilterBuilders.length !== other.faceFilterBuilders.length) {
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
for (let i = 0; i < this.faceFilterBuilders.length; i++) {
|
|
57
|
+
if (!this.faceFilterBuilders[i].equals(other.faceFilterBuilders[i])) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
transform(matrix) {
|
|
64
|
+
const transformed = this.faceFilterBuilders.map(builder => builder.transform(matrix));
|
|
65
|
+
return new NotBelongsToFaceFilter(transformed);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Matrix4 } from "../../math/matrix4.js";
|
|
2
|
+
import { Edge } from "../../common/shapes.js";
|
|
3
|
+
import { FilterBase } from "../filter-base.js";
|
|
4
|
+
import { SceneObject } from "../../common/scene-object.js";
|
|
5
|
+
export declare class BelongsToFaceFromSceneObjectFilter extends FilterBase<Edge> {
|
|
6
|
+
private sceneObject;
|
|
7
|
+
constructor(sceneObject: SceneObject);
|
|
8
|
+
match(shape: Edge): boolean;
|
|
9
|
+
compareTo(other: BelongsToFaceFromSceneObjectFilter): boolean;
|
|
10
|
+
transform(_matrix: Matrix4): BelongsToFaceFromSceneObjectFilter;
|
|
11
|
+
}
|
|
12
|
+
export declare class NotBelongsToFaceFromSceneObjectFilter extends FilterBase<Edge> {
|
|
13
|
+
private sceneObject;
|
|
14
|
+
constructor(sceneObject: SceneObject);
|
|
15
|
+
match(shape: Edge): boolean;
|
|
16
|
+
compareTo(other: NotBelongsToFaceFromSceneObjectFilter): boolean;
|
|
17
|
+
transform(_matrix: Matrix4): NotBelongsToFaceFromSceneObjectFilter;
|
|
18
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { FilterBase } from "../filter-base.js";
|
|
2
|
+
export class BelongsToFaceFromSceneObjectFilter extends FilterBase {
|
|
3
|
+
sceneObject;
|
|
4
|
+
constructor(sceneObject) {
|
|
5
|
+
super();
|
|
6
|
+
this.sceneObject = sceneObject;
|
|
7
|
+
}
|
|
8
|
+
match(shape) {
|
|
9
|
+
const objectFaces = this.sceneObject.getShapes()
|
|
10
|
+
.flatMap(s => s.getSubShapes("face"));
|
|
11
|
+
return objectFaces.some(face => face.hasEdge(shape.getShape()) !== null);
|
|
12
|
+
}
|
|
13
|
+
compareTo(other) {
|
|
14
|
+
return this.sceneObject.compareTo(other.sceneObject);
|
|
15
|
+
}
|
|
16
|
+
transform(_matrix) {
|
|
17
|
+
return new BelongsToFaceFromSceneObjectFilter(this.sceneObject);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class NotBelongsToFaceFromSceneObjectFilter extends FilterBase {
|
|
21
|
+
sceneObject;
|
|
22
|
+
constructor(sceneObject) {
|
|
23
|
+
super();
|
|
24
|
+
this.sceneObject = sceneObject;
|
|
25
|
+
}
|
|
26
|
+
match(shape) {
|
|
27
|
+
const objectFaces = this.sceneObject.getShapes()
|
|
28
|
+
.flatMap(s => s.getSubShapes("face"));
|
|
29
|
+
return !objectFaces.some(face => face.hasEdge(shape.getShape()) !== null);
|
|
30
|
+
}
|
|
31
|
+
compareTo(other) {
|
|
32
|
+
return this.sceneObject.compareTo(other.sceneObject);
|
|
33
|
+
}
|
|
34
|
+
transform(_matrix) {
|
|
35
|
+
return new NotBelongsToFaceFromSceneObjectFilter(this.sceneObject);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
@@ -1,22 +1,107 @@
|
|
|
1
1
|
import { PlaneLike } from "../../math/plane.js";
|
|
2
|
-
import { Edge } from "../../common/shapes.js";
|
|
2
|
+
import { Edge, 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 { ISceneObject } from "../../core/interfaces.js";
|
|
5
6
|
export declare class EdgeFilterBuilder extends FilterBuilderBase<Edge> {
|
|
6
7
|
constructor();
|
|
8
|
+
/**
|
|
9
|
+
* Selects the edge at the given index.
|
|
10
|
+
* @param index - Zero-based edge index.
|
|
11
|
+
* @param shapes - The edge array to index into.
|
|
12
|
+
* @param originalShapes - Optional original edge array before filtering.
|
|
13
|
+
*/
|
|
7
14
|
atIndex(index: number, shapes: Edge[], originalShapes?: Edge[]): this;
|
|
15
|
+
/**
|
|
16
|
+
* Excludes the edge at the given index.
|
|
17
|
+
* @param index - Zero-based edge index to exclude.
|
|
18
|
+
* @param shapes - The edge array to index into.
|
|
19
|
+
* @param originalShapes - Optional original edge array before filtering.
|
|
20
|
+
*/
|
|
8
21
|
notAtIndex(index: number, shapes: Edge[], originalShapes?: Edge[]): this;
|
|
22
|
+
/**
|
|
23
|
+
* Selects edges that lie on the given plane.
|
|
24
|
+
* @param plane - The reference plane.
|
|
25
|
+
* @param offset - Optional distance to offset the plane before matching.
|
|
26
|
+
* @param bothDirections - When true, also matches the plane offset in the opposite direction.
|
|
27
|
+
*/
|
|
9
28
|
onPlane(plane: PlaneLike | PlaneObjectBase, offset?: number, bothDirections?: boolean): this;
|
|
29
|
+
/**
|
|
30
|
+
* Excludes edges that lie on the given plane.
|
|
31
|
+
* @param plane - The reference plane.
|
|
32
|
+
* @param offset - Optional distance to offset the plane before matching.
|
|
33
|
+
* @param bothDirections - When true, also excludes the plane offset in the opposite direction.
|
|
34
|
+
*/
|
|
10
35
|
notOnPlane(plane: PlaneLike | PlaneObjectBase, offset?: number, bothDirections?: boolean): this;
|
|
36
|
+
/**
|
|
37
|
+
* Selects edges that are parallel to the given plane.
|
|
38
|
+
* @param plane - The reference plane.
|
|
39
|
+
*/
|
|
11
40
|
parallelTo(plane: PlaneLike | PlaneObjectBase): this;
|
|
41
|
+
/**
|
|
42
|
+
* Excludes edges that are parallel to the given plane.
|
|
43
|
+
* @param plane - The reference plane.
|
|
44
|
+
*/
|
|
12
45
|
notParallelTo(plane: PlaneLike | PlaneObjectBase): this;
|
|
46
|
+
/**
|
|
47
|
+
* Selects edges that are perpendicular (vertical) to the given plane.
|
|
48
|
+
* @param plane - The reference plane.
|
|
49
|
+
*/
|
|
13
50
|
verticalTo(plane: PlaneLike | PlaneObjectBase): this;
|
|
51
|
+
/**
|
|
52
|
+
* Excludes edges that are perpendicular (vertical) to the given plane.
|
|
53
|
+
* @param plane - The reference plane.
|
|
54
|
+
*/
|
|
14
55
|
notVerticalTo(plane: PlaneLike | PlaneObjectBase): this;
|
|
56
|
+
/**
|
|
57
|
+
* Selects circular edges, optionally matching a specific diameter.
|
|
58
|
+
* @param diameter - Optional diameter to match.
|
|
59
|
+
*/
|
|
15
60
|
circle(diameter?: number): this;
|
|
61
|
+
/**
|
|
62
|
+
* Excludes circular edges, optionally matching a specific diameter.
|
|
63
|
+
* @param diameter - Optional diameter to exclude.
|
|
64
|
+
*/
|
|
16
65
|
notCircle(diameter?: number): this;
|
|
66
|
+
/**
|
|
67
|
+
* Selects arc edges, optionally matching a specific radius.
|
|
68
|
+
* @param radius - Optional radius to match.
|
|
69
|
+
*/
|
|
17
70
|
arc(radius?: number): this;
|
|
71
|
+
/**
|
|
72
|
+
* Excludes arc edges, optionally matching a specific radius.
|
|
73
|
+
* @param radius - Optional radius to exclude.
|
|
74
|
+
*/
|
|
18
75
|
notArc(radius?: number): this;
|
|
19
|
-
|
|
20
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Selects straight-line edges, optionally matching a specific length.
|
|
78
|
+
* @param length - Optional length to match.
|
|
79
|
+
*/
|
|
80
|
+
line(length?: number): this;
|
|
81
|
+
/**
|
|
82
|
+
* Excludes straight-line edges, optionally matching a specific length.
|
|
83
|
+
* @param length - Optional length to exclude.
|
|
84
|
+
*/
|
|
85
|
+
notLine(length?: number): this;
|
|
86
|
+
/**
|
|
87
|
+
* Selects edges that belong to a face from the given scene object.
|
|
88
|
+
* @param sceneObject - A scene object whose faces are matched against.
|
|
89
|
+
*/
|
|
90
|
+
belongsToFace(sceneObject: ISceneObject): this;
|
|
91
|
+
/**
|
|
92
|
+
* Selects edges that belong to a face matching the given face filters.
|
|
93
|
+
* @param faceFilters - One or more face filter builders to match against.
|
|
94
|
+
*/
|
|
95
|
+
belongsToFace(...faceFilters: FilterBuilderBase<Face>[]): this;
|
|
96
|
+
/**
|
|
97
|
+
* Excludes edges that belong to a face from the given scene object.
|
|
98
|
+
* @param sceneObject - A scene object whose faces are matched against.
|
|
99
|
+
*/
|
|
100
|
+
notBelongsToFace(sceneObject: ISceneObject): this;
|
|
101
|
+
/**
|
|
102
|
+
* Excludes edges that belong to a face matching the given face filters.
|
|
103
|
+
* @param faceFilters - One or more face filter builders to match against.
|
|
104
|
+
*/
|
|
105
|
+
notBelongsToFace(...faceFilters: FilterBuilderBase<Face>[]): this;
|
|
21
106
|
static build(): EdgeFilterBuilder;
|
|
22
107
|
}
|
|
@@ -9,20 +9,41 @@ import { NotVerticalFilter, VerticalFilter } from "./vertical-plane.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 { BelongsToFaceFilter, NotBelongsToFaceFilter } from "./belongs-to-face.js";
|
|
13
|
+
import { BelongsToFaceFromSceneObjectFilter, NotBelongsToFaceFromSceneObjectFilter } from "./belongs-to-object.js";
|
|
14
|
+
import { SceneObject } from "../../common/scene-object.js";
|
|
12
15
|
export class EdgeFilterBuilder extends FilterBuilderBase {
|
|
13
16
|
constructor() {
|
|
14
17
|
super();
|
|
15
18
|
}
|
|
19
|
+
/**
|
|
20
|
+
* Selects the edge at the given index.
|
|
21
|
+
* @param index - Zero-based edge index.
|
|
22
|
+
* @param shapes - The edge array to index into.
|
|
23
|
+
* @param originalShapes - Optional original edge array before filtering.
|
|
24
|
+
*/
|
|
16
25
|
atIndex(index, shapes, originalShapes) {
|
|
17
26
|
const filter = new AtIndexFilter(index, shapes, originalShapes);
|
|
18
27
|
this.filters.push(filter);
|
|
19
28
|
return this;
|
|
20
29
|
}
|
|
30
|
+
/**
|
|
31
|
+
* Excludes the edge at the given index.
|
|
32
|
+
* @param index - Zero-based edge index to exclude.
|
|
33
|
+
* @param shapes - The edge array to index into.
|
|
34
|
+
* @param originalShapes - Optional original edge array before filtering.
|
|
35
|
+
*/
|
|
21
36
|
notAtIndex(index, shapes, originalShapes) {
|
|
22
37
|
const filter = new NotAtIndexFilter(index, shapes, originalShapes);
|
|
23
38
|
this.filters.push(filter);
|
|
24
39
|
return this;
|
|
25
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Selects edges that lie on the given plane.
|
|
43
|
+
* @param plane - The reference plane.
|
|
44
|
+
* @param offset - Optional distance to offset the plane before matching.
|
|
45
|
+
* @param bothDirections - When true, also matches the plane offset in the opposite direction.
|
|
46
|
+
*/
|
|
26
47
|
onPlane(plane, offset = 0, bothDirections = false) {
|
|
27
48
|
if (!plane) {
|
|
28
49
|
throw new Error('Plane is required');
|
|
@@ -48,6 +69,12 @@ export class EdgeFilterBuilder extends FilterBuilderBase {
|
|
|
48
69
|
this.filters.push(filter);
|
|
49
70
|
return this;
|
|
50
71
|
}
|
|
72
|
+
/**
|
|
73
|
+
* Excludes edges that lie on the given plane.
|
|
74
|
+
* @param plane - The reference plane.
|
|
75
|
+
* @param offset - Optional distance to offset the plane before matching.
|
|
76
|
+
* @param bothDirections - When true, also excludes the plane offset in the opposite direction.
|
|
77
|
+
*/
|
|
51
78
|
notOnPlane(plane, offset = 0, bothDirections = false) {
|
|
52
79
|
if (!plane) {
|
|
53
80
|
throw new Error('Plane is required');
|
|
@@ -73,6 +100,10 @@ export class EdgeFilterBuilder extends FilterBuilderBase {
|
|
|
73
100
|
this.filters.push(filter);
|
|
74
101
|
return this;
|
|
75
102
|
}
|
|
103
|
+
/**
|
|
104
|
+
* Selects edges that are parallel to the given plane.
|
|
105
|
+
* @param plane - The reference plane.
|
|
106
|
+
*/
|
|
76
107
|
parallelTo(plane) {
|
|
77
108
|
if (!plane) {
|
|
78
109
|
throw new Error('Plane is required');
|
|
@@ -88,6 +119,10 @@ export class EdgeFilterBuilder extends FilterBuilderBase {
|
|
|
88
119
|
this.filters.push(filter);
|
|
89
120
|
return this;
|
|
90
121
|
}
|
|
122
|
+
/**
|
|
123
|
+
* Excludes edges that are parallel to the given plane.
|
|
124
|
+
* @param plane - The reference plane.
|
|
125
|
+
*/
|
|
91
126
|
notParallelTo(plane) {
|
|
92
127
|
if (!plane) {
|
|
93
128
|
throw new Error('Plane is required');
|
|
@@ -103,6 +138,10 @@ export class EdgeFilterBuilder extends FilterBuilderBase {
|
|
|
103
138
|
this.filters.push(filter);
|
|
104
139
|
return this;
|
|
105
140
|
}
|
|
141
|
+
/**
|
|
142
|
+
* Selects edges that are perpendicular (vertical) to the given plane.
|
|
143
|
+
* @param plane - The reference plane.
|
|
144
|
+
*/
|
|
106
145
|
verticalTo(plane) {
|
|
107
146
|
if (!plane) {
|
|
108
147
|
throw new Error('Plane is required');
|
|
@@ -118,6 +157,10 @@ export class EdgeFilterBuilder extends FilterBuilderBase {
|
|
|
118
157
|
this.filters.push(filter);
|
|
119
158
|
return this;
|
|
120
159
|
}
|
|
160
|
+
/**
|
|
161
|
+
* Excludes edges that are perpendicular (vertical) to the given plane.
|
|
162
|
+
* @param plane - The reference plane.
|
|
163
|
+
*/
|
|
121
164
|
notVerticalTo(plane) {
|
|
122
165
|
if (!plane) {
|
|
123
166
|
throw new Error('Plane is required');
|
|
@@ -133,36 +176,90 @@ export class EdgeFilterBuilder extends FilterBuilderBase {
|
|
|
133
176
|
this.filters.push(filter);
|
|
134
177
|
return this;
|
|
135
178
|
}
|
|
179
|
+
/**
|
|
180
|
+
* Selects circular edges, optionally matching a specific diameter.
|
|
181
|
+
* @param diameter - Optional diameter to match.
|
|
182
|
+
*/
|
|
136
183
|
circle(diameter) {
|
|
137
184
|
const filter = new CircleFilter(diameter);
|
|
138
185
|
this.filters.push(filter);
|
|
139
186
|
return this;
|
|
140
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Excludes circular edges, optionally matching a specific diameter.
|
|
190
|
+
* @param diameter - Optional diameter to exclude.
|
|
191
|
+
*/
|
|
141
192
|
notCircle(diameter) {
|
|
142
193
|
const filter = new NotCircleFilter(diameter);
|
|
143
194
|
this.filters.push(filter);
|
|
144
195
|
return this;
|
|
145
196
|
}
|
|
197
|
+
/**
|
|
198
|
+
* Selects arc edges, optionally matching a specific radius.
|
|
199
|
+
* @param radius - Optional radius to match.
|
|
200
|
+
*/
|
|
146
201
|
arc(radius) {
|
|
147
202
|
const filter = new ArcFilter(radius);
|
|
148
203
|
this.filters.push(filter);
|
|
149
204
|
return this;
|
|
150
205
|
}
|
|
206
|
+
/**
|
|
207
|
+
* Excludes arc edges, optionally matching a specific radius.
|
|
208
|
+
* @param radius - Optional radius to exclude.
|
|
209
|
+
*/
|
|
151
210
|
notArc(radius) {
|
|
152
211
|
const filter = new NotArcFilter(radius);
|
|
153
212
|
this.filters.push(filter);
|
|
154
213
|
return this;
|
|
155
214
|
}
|
|
156
|
-
|
|
157
|
-
|
|
215
|
+
/**
|
|
216
|
+
* Selects straight-line edges, optionally matching a specific length.
|
|
217
|
+
* @param length - Optional length to match.
|
|
218
|
+
*/
|
|
219
|
+
line(length) {
|
|
220
|
+
const filter = new LineFilter(length);
|
|
158
221
|
this.filters.push(filter);
|
|
159
222
|
return this;
|
|
160
223
|
}
|
|
161
|
-
|
|
162
|
-
|
|
224
|
+
/**
|
|
225
|
+
* Excludes straight-line edges, optionally matching a specific length.
|
|
226
|
+
* @param length - Optional length to exclude.
|
|
227
|
+
*/
|
|
228
|
+
notLine(length) {
|
|
229
|
+
const filter = new NotLineFilter(length);
|
|
163
230
|
this.filters.push(filter);
|
|
164
231
|
return this;
|
|
165
232
|
}
|
|
233
|
+
belongsToFace(...args) {
|
|
234
|
+
const filterBuilders = [];
|
|
235
|
+
for (const arg of args) {
|
|
236
|
+
if (arg instanceof SceneObject) {
|
|
237
|
+
this.filters.push(new BelongsToFaceFromSceneObjectFilter(arg));
|
|
238
|
+
}
|
|
239
|
+
else {
|
|
240
|
+
filterBuilders.push(arg);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
if (filterBuilders.length > 0) {
|
|
244
|
+
this.filters.push(new BelongsToFaceFilter(filterBuilders));
|
|
245
|
+
}
|
|
246
|
+
return this;
|
|
247
|
+
}
|
|
248
|
+
notBelongsToFace(...args) {
|
|
249
|
+
const filterBuilders = [];
|
|
250
|
+
for (const arg of args) {
|
|
251
|
+
if (arg instanceof SceneObject) {
|
|
252
|
+
this.filters.push(new NotBelongsToFaceFromSceneObjectFilter(arg));
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
filterBuilders.push(arg);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (filterBuilders.length > 0) {
|
|
259
|
+
this.filters.push(new NotBelongsToFaceFilter(filterBuilders));
|
|
260
|
+
}
|
|
261
|
+
return this;
|
|
262
|
+
}
|
|
166
263
|
static build() {
|
|
167
264
|
return new EdgeFilterBuilder();
|
|
168
265
|
}
|
|
@@ -2,12 +2,15 @@ import { Matrix4 } from "../../math/matrix4.js";
|
|
|
2
2
|
import { Edge } from "../../common/shapes.js";
|
|
3
3
|
import { FilterBase } from "../filter-base.js";
|
|
4
4
|
export declare class LineFilter extends FilterBase<Edge> {
|
|
5
|
-
|
|
5
|
+
private length?;
|
|
6
|
+
constructor(length?: number);
|
|
6
7
|
match(shape: Edge): boolean;
|
|
7
8
|
compareTo(other: LineFilter): boolean;
|
|
8
9
|
transform(matrix: Matrix4): LineFilter;
|
|
9
10
|
}
|
|
10
11
|
export declare class NotLineFilter extends FilterBase<Edge> {
|
|
12
|
+
private length?;
|
|
13
|
+
constructor(length?: number);
|
|
11
14
|
match(shape: Edge): boolean;
|
|
12
15
|
compareTo(other: NotLineFilter): boolean;
|
|
13
16
|
transform(matrix: Matrix4): NotLineFilter;
|
|
@@ -1,27 +1,34 @@
|
|
|
1
1
|
import { FilterBase } from "../filter-base.js";
|
|
2
2
|
import { EdgeQuery } from "../../oc/edge-query.js";
|
|
3
3
|
export class LineFilter extends FilterBase {
|
|
4
|
-
|
|
4
|
+
length;
|
|
5
|
+
constructor(length) {
|
|
5
6
|
super();
|
|
7
|
+
this.length = length;
|
|
6
8
|
}
|
|
7
9
|
match(shape) {
|
|
8
|
-
return EdgeQuery.isLineEdge(shape);
|
|
10
|
+
return EdgeQuery.isLineEdge(shape, this.length);
|
|
9
11
|
}
|
|
10
12
|
compareTo(other) {
|
|
11
|
-
return
|
|
13
|
+
return this.length === other.length;
|
|
12
14
|
}
|
|
13
15
|
transform(matrix) {
|
|
14
|
-
return new LineFilter();
|
|
16
|
+
return new LineFilter(this.length);
|
|
15
17
|
}
|
|
16
18
|
}
|
|
17
19
|
export class NotLineFilter extends FilterBase {
|
|
20
|
+
length;
|
|
21
|
+
constructor(length) {
|
|
22
|
+
super();
|
|
23
|
+
this.length = length;
|
|
24
|
+
}
|
|
18
25
|
match(shape) {
|
|
19
|
-
return !EdgeQuery.isLineEdge(shape);
|
|
26
|
+
return !EdgeQuery.isLineEdge(shape, this.length);
|
|
20
27
|
}
|
|
21
28
|
compareTo(other) {
|
|
22
|
-
return
|
|
29
|
+
return this.length === other.length;
|
|
23
30
|
}
|
|
24
31
|
transform(matrix) {
|
|
25
|
-
return new NotLineFilter();
|
|
32
|
+
return new NotLineFilter(this.length);
|
|
26
33
|
}
|
|
27
34
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Matrix4 } from "../../math/matrix4.js";
|
|
2
|
+
import { Face } from "../../common/shapes.js";
|
|
3
|
+
import { FilterBase } from "../filter-base.js";
|
|
4
|
+
export declare class EdgeCountFilter extends FilterBase<Face> {
|
|
5
|
+
private count;
|
|
6
|
+
constructor(count: number);
|
|
7
|
+
match(shape: Face): boolean;
|
|
8
|
+
compareTo(other: EdgeCountFilter): boolean;
|
|
9
|
+
transform(matrix: Matrix4): EdgeCountFilter;
|
|
10
|
+
}
|
|
11
|
+
export declare class NotEdgeCountFilter extends FilterBase<Face> {
|
|
12
|
+
private count;
|
|
13
|
+
constructor(count: number);
|
|
14
|
+
match(shape: Face): boolean;
|
|
15
|
+
compareTo(other: NotEdgeCountFilter): boolean;
|
|
16
|
+
transform(matrix: Matrix4): NotEdgeCountFilter;
|
|
17
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { FilterBase } from "../filter-base.js";
|
|
2
|
+
export class EdgeCountFilter extends FilterBase {
|
|
3
|
+
count;
|
|
4
|
+
constructor(count) {
|
|
5
|
+
super();
|
|
6
|
+
this.count = count;
|
|
7
|
+
}
|
|
8
|
+
match(shape) {
|
|
9
|
+
return shape.getEdges().length === this.count;
|
|
10
|
+
}
|
|
11
|
+
compareTo(other) {
|
|
12
|
+
return this.count === other.count;
|
|
13
|
+
}
|
|
14
|
+
transform(matrix) {
|
|
15
|
+
return new EdgeCountFilter(this.count);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export class NotEdgeCountFilter extends FilterBase {
|
|
19
|
+
count;
|
|
20
|
+
constructor(count) {
|
|
21
|
+
super();
|
|
22
|
+
this.count = count;
|
|
23
|
+
}
|
|
24
|
+
match(shape) {
|
|
25
|
+
return shape.getEdges().length !== this.count;
|
|
26
|
+
}
|
|
27
|
+
compareTo(other) {
|
|
28
|
+
return this.count === other.count;
|
|
29
|
+
}
|
|
30
|
+
transform(matrix) {
|
|
31
|
+
return new NotEdgeCountFilter(this.count);
|
|
32
|
+
}
|
|
33
|
+
}
|