fluidcad 0.0.31 → 0.0.33
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 +2 -0
- package/lib/dist/common/scene-object.js +6 -0
- package/lib/dist/common/solid.d.ts +4 -1
- package/lib/dist/common/solid.js +13 -0
- package/lib/dist/core/extrude.d.ts +17 -4
- package/lib/dist/core/extrude.js +8 -6
- package/lib/dist/core/index.d.ts +2 -1
- package/lib/dist/core/index.js +1 -0
- package/lib/dist/core/interfaces.d.ts +91 -5
- package/lib/dist/core/load.d.ts +2 -2
- package/lib/dist/core/mirror.d.ts +5 -5
- package/lib/dist/core/rib.d.ts +18 -0
- package/lib/dist/core/rib.js +37 -0
- package/lib/dist/features/2d/line.d.ts +2 -0
- package/lib/dist/features/2d/line.js +4 -0
- package/lib/dist/features/extrude-to-face.d.ts +5 -1
- package/lib/dist/features/extrude-to-face.js +50 -8
- package/lib/dist/features/extrude.js +19 -28
- package/lib/dist/features/load.d.ts +6 -0
- package/lib/dist/features/load.js +53 -1
- package/lib/dist/features/rib.d.ts +31 -0
- package/lib/dist/features/rib.js +321 -0
- package/lib/dist/features/rotate.js +2 -2
- package/lib/dist/features/select.d.ts +2 -0
- package/lib/dist/features/select.js +120 -21
- package/lib/dist/features/simple-extruder.js +6 -3
- package/lib/dist/filters/edge/belongs-to-face.d.ts +12 -9
- package/lib/dist/filters/edge/belongs-to-face.js +64 -15
- package/lib/dist/filters/face/above-below.d.ts +20 -0
- package/lib/dist/filters/face/above-below.js +57 -0
- package/lib/dist/filters/face/face-filter.d.ts +26 -0
- package/lib/dist/filters/face/face-filter.js +64 -0
- package/lib/dist/filters/face/planar-filter.d.ts +15 -0
- package/lib/dist/filters/face/planar-filter.js +30 -0
- package/lib/dist/filters/filter-builder-base.d.ts +25 -0
- package/lib/dist/filters/filter-builder-base.js +47 -0
- package/lib/dist/filters/filter.js +39 -14
- package/lib/dist/filters/from-object.d.ts +5 -0
- package/lib/dist/filters/from-object.js +13 -0
- package/lib/dist/helpers/scene-helpers.d.ts +1 -1
- package/lib/dist/helpers/scene-helpers.js +146 -12
- package/lib/dist/io/file-import.d.ts +5 -1
- package/lib/dist/io/file-import.js +29 -18
- package/lib/dist/oc/boolean-ops.js +8 -3
- package/lib/dist/oc/color-transfer.d.ts +19 -8
- package/lib/dist/oc/color-transfer.js +70 -12
- package/lib/dist/oc/extrude-ops.d.ts +2 -1
- package/lib/dist/oc/extrude-ops.js +51 -2
- package/lib/dist/oc/face-maker2.d.ts +8 -0
- package/lib/dist/oc/face-maker2.js +42 -1
- package/lib/dist/oc/face-ops.d.ts +6 -1
- package/lib/dist/oc/face-ops.js +3 -2
- package/lib/dist/oc/face-query.js +2 -2
- package/lib/dist/oc/rib-ops.d.ts +35 -0
- package/lib/dist/oc/rib-ops.js +619 -0
- package/lib/dist/oc/topology-index.d.ts +6 -0
- package/lib/dist/oc/topology-index.js +36 -0
- package/lib/dist/rendering/render-solid.js +1 -3
- package/lib/dist/rendering/render.d.ts +1 -0
- package/lib/dist/rendering/render.js +44 -1
- package/lib/dist/rendering/scene-compare.js +3 -0
- package/lib/dist/rendering/scene.d.ts +1 -0
- package/lib/dist/rendering/scene.js +4 -0
- package/lib/dist/tests/features/color-lineage.test.js +18 -0
- package/lib/dist/tests/features/cut.test.js +40 -0
- package/lib/dist/tests/features/extrude-to-face.test.js +52 -0
- package/lib/dist/tests/features/extrude.test.js +46 -8
- package/lib/dist/tests/features/filter-positional.test.d.ts +1 -0
- package/lib/dist/tests/features/filter-positional.test.js +129 -0
- package/lib/dist/tests/features/rib.test.d.ts +1 -0
- package/lib/dist/tests/features/rib.test.js +598 -0
- package/lib/dist/tests/features/select.test.js +141 -0
- package/lib/dist/tests/scene-compare.test.d.ts +1 -0
- package/lib/dist/tests/scene-compare.test.js +77 -0
- package/lib/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/ui/dist/assets/{index-B15vMQZ2.js → index-CFi9p7wR.js} +104 -104
- package/ui/dist/index.html +1 -1
- package/lib/dist/features/infinite-extrude.d.ts +0 -13
- package/lib/dist/features/infinite-extrude.js +0 -79
|
@@ -59,6 +59,7 @@ export declare abstract class SceneObject implements Comparable<SceneObject>, Se
|
|
|
59
59
|
constructor();
|
|
60
60
|
get id(): string;
|
|
61
61
|
get parentId(): string | null;
|
|
62
|
+
inheritIdentityFrom(other: SceneObject): void;
|
|
62
63
|
private setParent;
|
|
63
64
|
protected setAlwaysVisible(): void;
|
|
64
65
|
isAlwaysVisible(): boolean;
|
|
@@ -150,6 +151,7 @@ export declare abstract class SceneObject implements Comparable<SceneObject>, Se
|
|
|
150
151
|
setOrder(order: number): void;
|
|
151
152
|
getOrder(): number;
|
|
152
153
|
getName(): string;
|
|
154
|
+
hasCustomName(): boolean;
|
|
153
155
|
name(value: string): this;
|
|
154
156
|
guide(): this;
|
|
155
157
|
reusable(): this;
|
|
@@ -36,6 +36,9 @@ export class SceneObject {
|
|
|
36
36
|
get parentId() {
|
|
37
37
|
return this._parent?.id || null;
|
|
38
38
|
}
|
|
39
|
+
inheritIdentityFrom(other) {
|
|
40
|
+
this._id = other._id;
|
|
41
|
+
}
|
|
39
42
|
setParent(parent) {
|
|
40
43
|
this._parent = parent;
|
|
41
44
|
}
|
|
@@ -452,6 +455,9 @@ export class SceneObject {
|
|
|
452
455
|
getName() {
|
|
453
456
|
return this._name ?? this.getType();
|
|
454
457
|
}
|
|
458
|
+
hasCustomName() {
|
|
459
|
+
return this._name !== null;
|
|
460
|
+
}
|
|
455
461
|
name(value) {
|
|
456
462
|
this._name = value;
|
|
457
463
|
return this;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TopoDS_Edge, TopoDS_Face, TopoDS_Solid } from "occjs-wrapper";
|
|
1
|
+
import type { TopoDS_Edge, TopoDS_Face, TopoDS_Solid, TopTools_IndexedDataMapOfShapeListOfShape } from "occjs-wrapper";
|
|
2
2
|
import { ShapeType } from "./shape-type.js";
|
|
3
3
|
import { Shape } from "./shape.js";
|
|
4
4
|
import { Face } from "./face.js";
|
|
@@ -6,6 +6,7 @@ import { Edge } from "./edge.js";
|
|
|
6
6
|
export declare class Solid extends Shape<TopoDS_Solid> {
|
|
7
7
|
private faces;
|
|
8
8
|
private edges;
|
|
9
|
+
private edgeToFacesIndex;
|
|
9
10
|
constructor(solid: TopoDS_Solid);
|
|
10
11
|
getType(): ShapeType;
|
|
11
12
|
isSolid(): boolean;
|
|
@@ -15,6 +16,8 @@ export declare class Solid extends Shape<TopoDS_Solid> {
|
|
|
15
16
|
getFace(face: TopoDS_Face): Face | null;
|
|
16
17
|
hasFace(face: TopoDS_Face): boolean;
|
|
17
18
|
hasEdge(edge: TopoDS_Edge): TopoDS_Edge;
|
|
19
|
+
getEdgeToFacesIndex(): TopTools_IndexedDataMapOfShapeListOfShape;
|
|
20
|
+
dispose(): void;
|
|
18
21
|
copy(): Shape;
|
|
19
22
|
static fromTopoDSSolid(solid: TopoDS_Solid): Solid;
|
|
20
23
|
}
|
package/lib/dist/common/solid.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Explorer } from "../oc/explorer.js";
|
|
2
|
+
import { TopologyIndex } from "../oc/topology-index.js";
|
|
2
3
|
import { Shape } from "./shape.js";
|
|
3
4
|
export class Solid extends Shape {
|
|
4
5
|
faces = null;
|
|
5
6
|
edges = null;
|
|
7
|
+
edgeToFacesIndex = null;
|
|
6
8
|
constructor(solid) {
|
|
7
9
|
super(solid);
|
|
8
10
|
}
|
|
@@ -59,6 +61,17 @@ export class Solid extends Shape {
|
|
|
59
61
|
}
|
|
60
62
|
return null;
|
|
61
63
|
}
|
|
64
|
+
getEdgeToFacesIndex() {
|
|
65
|
+
if (!this.edgeToFacesIndex) {
|
|
66
|
+
this.edgeToFacesIndex = TopologyIndex.buildEdgeToFaces(this.getShape());
|
|
67
|
+
}
|
|
68
|
+
return this.edgeToFacesIndex;
|
|
69
|
+
}
|
|
70
|
+
dispose() {
|
|
71
|
+
this.edgeToFacesIndex?.delete();
|
|
72
|
+
this.edgeToFacesIndex = null;
|
|
73
|
+
super.dispose();
|
|
74
|
+
}
|
|
62
75
|
copy() {
|
|
63
76
|
const copied = new Solid(this.getShape());
|
|
64
77
|
for (const entry of this.colorMap) {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { IExtrude, ISceneObject } from "./interfaces.js";
|
|
2
|
+
import { FaceFilterBuilder } from "../filters/face/face-filter.js";
|
|
2
3
|
interface ExtrudeFunction {
|
|
3
4
|
/**
|
|
4
5
|
* Extrudes the last sketch with a default distance.
|
|
@@ -33,15 +34,27 @@ interface ExtrudeFunction {
|
|
|
33
34
|
/**
|
|
34
35
|
* Extrudes up to the first intersecting face.
|
|
35
36
|
* @param face - The literal `'first-face'`
|
|
36
|
-
* @param
|
|
37
|
+
* @param filters - Optional face filters to narrow the candidate set
|
|
38
|
+
*/
|
|
39
|
+
(face: 'first-face', ...filters: FaceFilterBuilder[]): IExtrude;
|
|
40
|
+
/**
|
|
41
|
+
* Extrudes up to the first intersecting face.
|
|
42
|
+
* @param face - The literal `'first-face'`
|
|
43
|
+
* @param filtersAndTarget - Optional face filters followed by the target to extrude
|
|
37
44
|
*/
|
|
38
|
-
(face: 'first-face',
|
|
45
|
+
(face: 'first-face', ...filtersAndTarget: [...FaceFilterBuilder[], ISceneObject]): IExtrude;
|
|
39
46
|
/**
|
|
40
47
|
* Extrudes up to the last intersecting face.
|
|
41
48
|
* @param face - The literal `'last-face'`
|
|
42
|
-
* @param
|
|
49
|
+
* @param filters - Optional face filters to narrow the candidate set
|
|
50
|
+
*/
|
|
51
|
+
(face: 'last-face', ...filters: FaceFilterBuilder[]): IExtrude;
|
|
52
|
+
/**
|
|
53
|
+
* Extrudes up to the last intersecting face.
|
|
54
|
+
* @param face - The literal `'last-face'`
|
|
55
|
+
* @param filtersAndTarget - Optional face filters followed by the target to extrude
|
|
43
56
|
*/
|
|
44
|
-
(face: 'last-face',
|
|
57
|
+
(face: 'last-face', ...filtersAndTarget: [...FaceFilterBuilder[], ISceneObject]): IExtrude;
|
|
45
58
|
}
|
|
46
59
|
declare const _default: ExtrudeFunction;
|
|
47
60
|
export default _default;
|
package/lib/dist/core/extrude.js
CHANGED
|
@@ -4,6 +4,7 @@ import { Extrude } from "../features/extrude.js";
|
|
|
4
4
|
import { ExtrudeTwoDistances } from "../features/extrude-two-distances.js";
|
|
5
5
|
import { ExtrudeToFace } from "../features/extrude-to-face.js";
|
|
6
6
|
import { SelectSceneObject } from "../features/select.js";
|
|
7
|
+
import { FaceFilterBuilder } from "../filters/face/face-filter.js";
|
|
7
8
|
function isExtrudable(obj) {
|
|
8
9
|
return obj instanceof SceneObject && obj.isExtrudable();
|
|
9
10
|
}
|
|
@@ -25,16 +26,17 @@ function build(context) {
|
|
|
25
26
|
if (params.length === 0) {
|
|
26
27
|
return new Extrude(defaultDistance, extrudable);
|
|
27
28
|
}
|
|
29
|
+
if (params[0] === 'first-face' || params[0] === 'last-face') {
|
|
30
|
+
const rest = params.slice(1);
|
|
31
|
+
if (!rest.every(a => a instanceof FaceFilterBuilder)) {
|
|
32
|
+
throw new Error("Invalid parameter for extrude function.");
|
|
33
|
+
}
|
|
34
|
+
return new ExtrudeToFace(params[0], extrudable, rest);
|
|
35
|
+
}
|
|
28
36
|
if (params.length === 1) {
|
|
29
37
|
if (typeof params[0] === 'number') {
|
|
30
38
|
return new Extrude(params[0], extrudable);
|
|
31
39
|
}
|
|
32
|
-
else if (params[0] === 'first-face') {
|
|
33
|
-
return new ExtrudeToFace('first-face', extrudable);
|
|
34
|
-
}
|
|
35
|
-
else if (params[0] === 'last-face') {
|
|
36
|
-
return new ExtrudeToFace('last-face', extrudable);
|
|
37
|
-
}
|
|
38
40
|
else if (params[0] instanceof SceneObject) {
|
|
39
41
|
context.addSceneObject(params[0]);
|
|
40
42
|
return new ExtrudeToFace(params[0], extrudable);
|
package/lib/dist/core/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type { ISceneObject, ITransformable, IBooleanOperation, IPlane, IAxis, ISelect, IGeometry, IExtrudableGeometry, IRect, ISlot, IPolygon, ITwoObjectsTangentLine, ITangentArcTwoObjects, IExtrude, ICut, ICommon, ISweep, ILoft, IRevolve, IDraft } from "./interfaces.js";
|
|
1
|
+
export type { ISceneObject, ITransformable, IBooleanOperation, IPlane, IAxis, ISelect, IGeometry, IExtrudableGeometry, IRect, ISlot, IPolygon, ITwoObjectsTangentLine, ITangentArcTwoObjects, IExtrude, ICut, ICommon, ISweep, ILoft, IRevolve, IDraft, IRib } from "./interfaces.js";
|
|
2
2
|
export { default as axis } from "./axis.js";
|
|
3
3
|
export { default as local } from "./local.js";
|
|
4
4
|
export { default as plane } from "./plane.js";
|
|
@@ -23,6 +23,7 @@ export { default as repeat } from "./repeat.js";
|
|
|
23
23
|
export { default as load } from "./load.js";
|
|
24
24
|
export { default as loft } from "./loft.js";
|
|
25
25
|
export { default as sweep } from "./sweep.js";
|
|
26
|
+
export { default as rib } from "./rib.js";
|
|
26
27
|
export { default as color } from "./color.js";
|
|
27
28
|
export { default as draft } from "./draft.js";
|
|
28
29
|
export { default as remove } from "./remove.js";
|
package/lib/dist/core/index.js
CHANGED
|
@@ -22,6 +22,7 @@ export { default as repeat } from "./repeat.js";
|
|
|
22
22
|
export { default as load } from "./load.js";
|
|
23
23
|
export { default as loft } from "./loft.js";
|
|
24
24
|
export { default as sweep } from "./sweep.js";
|
|
25
|
+
export { default as rib } from "./rib.js";
|
|
25
26
|
export { default as color } from "./color.js";
|
|
26
27
|
export { default as draft } from "./draft.js";
|
|
27
28
|
export { default as remove } from "./remove.js";
|
|
@@ -11,11 +11,6 @@ export interface ISceneObject {
|
|
|
11
11
|
* @param value - The display name to assign.
|
|
12
12
|
*/
|
|
13
13
|
name(value: string): this;
|
|
14
|
-
/**
|
|
15
|
-
* Marks this object as construction geometry. Guide objects are excluded from
|
|
16
|
-
* final geometry output unless explicitly included.
|
|
17
|
-
*/
|
|
18
|
-
guide(): this;
|
|
19
14
|
/**
|
|
20
15
|
* Marks this object as reusable. Reusable objects retain their shapes when
|
|
21
16
|
* consumed by features (e.g., extrude, revolve), allowing multiple features
|
|
@@ -24,6 +19,25 @@ export interface ISceneObject {
|
|
|
24
19
|
*/
|
|
25
20
|
reusable(): this;
|
|
26
21
|
}
|
|
22
|
+
export interface ILoadFile extends ISceneObject {
|
|
23
|
+
/**
|
|
24
|
+
* Skip applying colors from the imported file's color metadata sidecar.
|
|
25
|
+
*/
|
|
26
|
+
noColors(): this;
|
|
27
|
+
/**
|
|
28
|
+
* Keep only the solids at the given 0-based indices (in load order).
|
|
29
|
+
* Combined with {@link exclude} by applying include first, then exclude.
|
|
30
|
+
* Repeated calls accumulate.
|
|
31
|
+
* @param indices - The 0-based solid indices to keep.
|
|
32
|
+
*/
|
|
33
|
+
include(...indices: number[]): this;
|
|
34
|
+
/**
|
|
35
|
+
* Drop the solids at the given 0-based indices. Applied after {@link include}.
|
|
36
|
+
* Repeated calls accumulate.
|
|
37
|
+
* @param indices - The 0-based solid indices to drop.
|
|
38
|
+
*/
|
|
39
|
+
exclude(...indices: number[]): this;
|
|
40
|
+
}
|
|
27
41
|
export interface IBooleanOperation extends ISceneObject {
|
|
28
42
|
/**
|
|
29
43
|
* Additive boolean operation — fuses the result with all intersecting scene objects.
|
|
@@ -107,6 +121,12 @@ export interface IAxis extends ISceneObject {
|
|
|
107
121
|
export interface ISelect extends ISceneObject {
|
|
108
122
|
}
|
|
109
123
|
export interface IGeometry extends ISceneObject {
|
|
124
|
+
/**
|
|
125
|
+
* Marks this sketch geometry as construction geometry. Guide geometries are
|
|
126
|
+
* excluded from the final sketch output (e.g., extrude, revolve) unless
|
|
127
|
+
* explicitly included.
|
|
128
|
+
*/
|
|
129
|
+
guide(): this;
|
|
110
130
|
/**
|
|
111
131
|
* Returns a lazy-evaluated vertex at the start point of this geometry element.
|
|
112
132
|
*/
|
|
@@ -665,6 +685,15 @@ export interface IMirror extends IBooleanOperation {
|
|
|
665
685
|
*/
|
|
666
686
|
exclude(...objects: ISceneObject[]): this;
|
|
667
687
|
}
|
|
688
|
+
export interface IMirror2D extends IGeometry {
|
|
689
|
+
/**
|
|
690
|
+
* Excludes the given sketch geometries from the mirror operation. Useful
|
|
691
|
+
* when mirroring "everything" but a few specific geometries should be
|
|
692
|
+
* skipped, or when narrowing an explicit target list.
|
|
693
|
+
* @param objects - The sketch geometries to exclude from mirroring.
|
|
694
|
+
*/
|
|
695
|
+
exclude(...objects: ISceneObject[]): this;
|
|
696
|
+
}
|
|
668
697
|
export interface ITranslate extends ISceneObject {
|
|
669
698
|
/**
|
|
670
699
|
* Excludes the given objects from the translate operation. Useful when
|
|
@@ -685,6 +714,63 @@ export interface IRotate extends ISceneObject {
|
|
|
685
714
|
}
|
|
686
715
|
export interface IDraft extends ISceneObject {
|
|
687
716
|
}
|
|
717
|
+
export interface IRib extends IBooleanOperation {
|
|
718
|
+
/**
|
|
719
|
+
* Selects faces at the start (base) of the rib — the profile face at the sketch plane.
|
|
720
|
+
* @param args - Numeric indices or {@link FaceFilterBuilder} instances to filter the selection.
|
|
721
|
+
*/
|
|
722
|
+
startFaces(...args: (number | FaceFilterBuilder)[]): ISceneObject;
|
|
723
|
+
/**
|
|
724
|
+
* Selects faces at the end (top) of the rib — where the rib meets the boundary.
|
|
725
|
+
* @param args - Numeric indices or {@link FaceFilterBuilder} instances to filter the selection.
|
|
726
|
+
*/
|
|
727
|
+
endFaces(...args: (number | FaceFilterBuilder)[]): ISceneObject;
|
|
728
|
+
/**
|
|
729
|
+
* Selects the lateral wall faces of the rib.
|
|
730
|
+
* @param args - Numeric indices or {@link FaceFilterBuilder} instances to filter the selection.
|
|
731
|
+
*/
|
|
732
|
+
sideFaces(...args: (number | FaceFilterBuilder)[]): ISceneObject;
|
|
733
|
+
/**
|
|
734
|
+
* Selects the small cap faces at the spine endpoints.
|
|
735
|
+
* @param args - Numeric indices or {@link FaceFilterBuilder} instances to filter the selection.
|
|
736
|
+
*/
|
|
737
|
+
capFaces(...args: (number | FaceFilterBuilder)[]): ISceneObject;
|
|
738
|
+
/**
|
|
739
|
+
* Selects edges on the start faces.
|
|
740
|
+
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
741
|
+
*/
|
|
742
|
+
startEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
743
|
+
/**
|
|
744
|
+
* Selects edges on the end faces.
|
|
745
|
+
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
746
|
+
*/
|
|
747
|
+
endEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
748
|
+
/**
|
|
749
|
+
* Selects edges on the side faces, excluding edges shared with start/end faces.
|
|
750
|
+
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
751
|
+
*/
|
|
752
|
+
sideEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
753
|
+
/**
|
|
754
|
+
* Selects edges on the cap faces.
|
|
755
|
+
* @param args - Numeric indices or {@link EdgeFilterBuilder} instances to filter the selection.
|
|
756
|
+
*/
|
|
757
|
+
capEdges(...args: (number | EdgeFilterBuilder)[]): ISceneObject;
|
|
758
|
+
/**
|
|
759
|
+
* Applies a draft (taper) angle to the rib walls.
|
|
760
|
+
* @param value - A single angle for uniform draft, or a `[start, end]` tuple for asymmetric draft.
|
|
761
|
+
*/
|
|
762
|
+
draft(value: number | [number, number]): this;
|
|
763
|
+
/**
|
|
764
|
+
* Switches the extrusion direction to parallel to the sketch plane
|
|
765
|
+
* (perpendicular to the spine within the plane) instead of normal to it.
|
|
766
|
+
*/
|
|
767
|
+
parallel(): this;
|
|
768
|
+
/**
|
|
769
|
+
* Extends the rib's side faces at the spine endpoints outward to blend
|
|
770
|
+
* with the target solids' walls.
|
|
771
|
+
*/
|
|
772
|
+
extend(): this;
|
|
773
|
+
}
|
|
688
774
|
export interface IShell extends ISceneObject {
|
|
689
775
|
/**
|
|
690
776
|
* Selects the inner wall faces created by the shell operation (from thickness removal).
|
package/lib/dist/core/load.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ILoadFile } from "./interfaces.js";
|
|
2
2
|
interface LoadFunction {
|
|
3
3
|
/**
|
|
4
4
|
* Loads a 3D model file (STEP, STL, etc.) by filename.
|
|
5
5
|
* @param fileName - The path to the model file
|
|
6
6
|
*/
|
|
7
|
-
(fileName: string):
|
|
7
|
+
(fileName: string): ILoadFile;
|
|
8
8
|
}
|
|
9
9
|
declare const _default: LoadFunction;
|
|
10
10
|
export default _default;
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { PlaneLike } from "../math/plane.js";
|
|
2
2
|
import { AxisLike } from "../math/axis.js";
|
|
3
|
-
import { IMirror, ISceneObject } from "./interfaces.js";
|
|
3
|
+
import { IMirror, IMirror2D, ISceneObject } from "./interfaces.js";
|
|
4
4
|
interface MirrorFunction {
|
|
5
5
|
/**
|
|
6
6
|
* [2D] Mirror all sketch geometries across a given line.
|
|
7
7
|
* @param line The line to mirror across
|
|
8
8
|
*/
|
|
9
|
-
(line: ISceneObject):
|
|
9
|
+
(line: ISceneObject): IMirror2D;
|
|
10
10
|
/**
|
|
11
11
|
* [2D] Mirror all sketch geometries across a given axis.
|
|
12
12
|
* @param axis The local axis to mirror across
|
|
13
13
|
*/
|
|
14
|
-
(axis: AxisLike):
|
|
14
|
+
(axis: AxisLike): IMirror2D;
|
|
15
15
|
/**
|
|
16
16
|
* [2D] Mirror given sketch geometries across a given line.
|
|
17
17
|
* @param line The line to mirror across
|
|
18
18
|
* @param geometries The geometries to mirror
|
|
19
19
|
*/
|
|
20
|
-
(line: ISceneObject, ...geometries: ISceneObject[]):
|
|
20
|
+
(line: ISceneObject, ...geometries: ISceneObject[]): IMirror2D;
|
|
21
21
|
/**
|
|
22
22
|
* [2D] Mirror given sketch geometries across a given axis.
|
|
23
23
|
* @param axis The local axis to mirror across
|
|
24
24
|
* @param geometries The geometries to mirror
|
|
25
25
|
*/
|
|
26
|
-
(axis: AxisLike, ...geometries: ISceneObject[]):
|
|
26
|
+
(axis: AxisLike, ...geometries: ISceneObject[]): IMirror2D;
|
|
27
27
|
/**
|
|
28
28
|
* [3D] Mirror all scene shapes across a given plane.
|
|
29
29
|
* @param plane The plane to mirror across
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { IRib, ISceneObject } from "./interfaces.js";
|
|
2
|
+
interface RibFunction {
|
|
3
|
+
/**
|
|
4
|
+
* Creates a rib from the last sketch with the given thickness.
|
|
5
|
+
* The rib extends in the sketch normal direction until it reaches
|
|
6
|
+
* surrounding solids. Positive thickness = forward, negative = reverse.
|
|
7
|
+
* @param thickness - Wall thickness (sign controls direction)
|
|
8
|
+
*/
|
|
9
|
+
(thickness: number): IRib;
|
|
10
|
+
/**
|
|
11
|
+
* Creates a rib from an explicit sketch spine with the given thickness.
|
|
12
|
+
* @param thickness - Wall thickness (sign controls direction)
|
|
13
|
+
* @param spine - The sketch providing the rib spine wire and plane
|
|
14
|
+
*/
|
|
15
|
+
(thickness: number, spine: ISceneObject): IRib;
|
|
16
|
+
}
|
|
17
|
+
declare const _default: RibFunction;
|
|
18
|
+
export default _default;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { SceneObject } from "../common/scene-object.js";
|
|
2
|
+
import { registerBuilder } from "../index.js";
|
|
3
|
+
import { Rib } from "../features/rib.js";
|
|
4
|
+
function isExtrudable(obj) {
|
|
5
|
+
return obj instanceof SceneObject && obj.isExtrudable();
|
|
6
|
+
}
|
|
7
|
+
function build(context) {
|
|
8
|
+
//@ts-ignore
|
|
9
|
+
return function rib() {
|
|
10
|
+
const args = [...arguments];
|
|
11
|
+
if (args.length === 0) {
|
|
12
|
+
throw new Error("rib() requires at least a thickness argument.");
|
|
13
|
+
}
|
|
14
|
+
const thickness = args[0];
|
|
15
|
+
if (typeof thickness !== 'number' || thickness === 0) {
|
|
16
|
+
throw new Error("rib() thickness must be a non-zero number.");
|
|
17
|
+
}
|
|
18
|
+
let spine;
|
|
19
|
+
let extrudable;
|
|
20
|
+
if (args.length > 1 && isExtrudable(args[1])) {
|
|
21
|
+
spine = args[1];
|
|
22
|
+
extrudable = args[1];
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
const lastExtrudable = context.getLastExtrudable();
|
|
26
|
+
if (!lastExtrudable) {
|
|
27
|
+
throw new Error("rib() requires a sketch. No sketch found in the scene.");
|
|
28
|
+
}
|
|
29
|
+
spine = lastExtrudable;
|
|
30
|
+
extrudable = lastExtrudable;
|
|
31
|
+
}
|
|
32
|
+
const result = new Rib(thickness, spine, extrudable);
|
|
33
|
+
context.addSceneObject(result);
|
|
34
|
+
return result;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export default registerBuilder(build);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { SceneObject } from "../../common/scene-object.js";
|
|
1
2
|
import { LazyVertex } from "../lazy-vertex.js";
|
|
2
3
|
import { PlaneObjectBase } from "../plane-renderable-base.js";
|
|
3
4
|
import { GeometrySceneObject } from "./geometry.js";
|
|
@@ -6,6 +7,7 @@ export declare class LineTo extends GeometrySceneObject {
|
|
|
6
7
|
private targetPlane;
|
|
7
8
|
constructor(endPoint: LazyVertex, targetPlane?: PlaneObjectBase);
|
|
8
9
|
build(): void;
|
|
10
|
+
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
9
11
|
compareTo(other: LineTo): boolean;
|
|
10
12
|
getType(): string;
|
|
11
13
|
getUniqueType(): string;
|
|
@@ -30,6 +30,10 @@ export class LineTo extends GeometrySceneObject {
|
|
|
30
30
|
this.targetPlane.removeShapes(this);
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
+
createCopy(remap) {
|
|
34
|
+
const targetPlane = this.targetPlane ? (remap.get(this.targetPlane) || this.targetPlane) : null;
|
|
35
|
+
return new LineTo(this.endPoint, targetPlane);
|
|
36
|
+
}
|
|
33
37
|
compareTo(other) {
|
|
34
38
|
if (!(other instanceof LineTo)) {
|
|
35
39
|
return false;
|
|
@@ -2,9 +2,11 @@ import { BuildSceneObjectContext, SceneObject } from "../common/scene-object.js"
|
|
|
2
2
|
import { ExtrudeBase } from "./extrude-base.js";
|
|
3
3
|
import { Extrudable } from "../helpers/types.js";
|
|
4
4
|
import { Point } from "../math/point.js";
|
|
5
|
+
import { FaceFilterBuilder } from "../filters/face/face-filter.js";
|
|
5
6
|
export declare class ExtrudeToFace extends ExtrudeBase {
|
|
6
7
|
face: SceneObject | 'first-face' | 'last-face';
|
|
7
|
-
|
|
8
|
+
private faceFilters;
|
|
9
|
+
constructor(face: SceneObject | 'first-face' | 'last-face', source?: Extrudable | SceneObject, faceFilters?: FaceFilterBuilder[]);
|
|
8
10
|
build(context: BuildSceneObjectContext): void;
|
|
9
11
|
private createAdvancedExtrude;
|
|
10
12
|
private resizePlanarFace;
|
|
@@ -20,6 +22,7 @@ export declare class ExtrudeToFace extends ExtrudeBase {
|
|
|
20
22
|
private createSimpleExtrude;
|
|
21
23
|
private getFace;
|
|
22
24
|
private getFirstOrLastFace;
|
|
25
|
+
private collectFromSceneObjects;
|
|
23
26
|
getDependencies(): SceneObject[];
|
|
24
27
|
createCopy(remap: Map<SceneObject, SceneObject>): SceneObject;
|
|
25
28
|
compareTo(other: ExtrudeToFace): boolean;
|
|
@@ -39,6 +42,7 @@ export declare class ExtrudeToFace extends ExtrudeBase {
|
|
|
39
42
|
draft: [number, number];
|
|
40
43
|
endOffset: number;
|
|
41
44
|
face: string;
|
|
45
|
+
faceFilterCount: number;
|
|
42
46
|
thin: [number, number] | [number];
|
|
43
47
|
};
|
|
44
48
|
}
|
|
@@ -11,11 +11,15 @@ import { Explorer } from "../oc/explorer.js";
|
|
|
11
11
|
import { FaceMaker2 } from "../oc/face-maker2.js";
|
|
12
12
|
import { ThinFaceMaker } from "../oc/thin-face-maker.js";
|
|
13
13
|
import { Point } from "../math/point.js";
|
|
14
|
+
import { ShapeFilter } from "../filters/filter.js";
|
|
15
|
+
import { FromSceneObjectFilter } from "../filters/from-object.js";
|
|
14
16
|
export class ExtrudeToFace extends ExtrudeBase {
|
|
15
17
|
face;
|
|
16
|
-
|
|
18
|
+
faceFilters;
|
|
19
|
+
constructor(face, source, faceFilters = []) {
|
|
17
20
|
super(source);
|
|
18
21
|
this.face = face;
|
|
22
|
+
this.faceFilters = faceFilters;
|
|
19
23
|
}
|
|
20
24
|
build(context) {
|
|
21
25
|
const allSceneObjects = context.getSceneObjects();
|
|
@@ -252,12 +256,31 @@ export class ExtrudeToFace extends ExtrudeBase {
|
|
|
252
256
|
}
|
|
253
257
|
}
|
|
254
258
|
}
|
|
255
|
-
|
|
259
|
+
let candidates = allFaces;
|
|
260
|
+
if (this.faceFilters.length > 0) {
|
|
261
|
+
candidates = new ShapeFilter(allFaces, ...this.faceFilters).apply();
|
|
262
|
+
}
|
|
263
|
+
const result = FaceQuery.findFaceByDistance(candidates, plane, mode);
|
|
256
264
|
if (!result) {
|
|
257
265
|
throw new Error(`No face found for '${mode}-face' extrusion`);
|
|
258
266
|
}
|
|
259
267
|
return result;
|
|
260
268
|
}
|
|
269
|
+
collectFromSceneObjects() {
|
|
270
|
+
const objects = [];
|
|
271
|
+
for (const builder of this.faceFilters) {
|
|
272
|
+
for (const filter of builder.getFilters()) {
|
|
273
|
+
if (filter instanceof FromSceneObjectFilter) {
|
|
274
|
+
for (const obj of filter.getSceneObjects()) {
|
|
275
|
+
if (!objects.includes(obj)) {
|
|
276
|
+
objects.push(obj);
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
return objects;
|
|
283
|
+
}
|
|
261
284
|
getDependencies() {
|
|
262
285
|
const deps = [];
|
|
263
286
|
const source = this.getSource();
|
|
@@ -267,6 +290,11 @@ export class ExtrudeToFace extends ExtrudeBase {
|
|
|
267
290
|
if (this.face instanceof SceneObject) {
|
|
268
291
|
deps.push(this.face);
|
|
269
292
|
}
|
|
293
|
+
for (const obj of this.collectFromSceneObjects()) {
|
|
294
|
+
if (!deps.includes(obj)) {
|
|
295
|
+
deps.push(obj);
|
|
296
|
+
}
|
|
297
|
+
}
|
|
270
298
|
return deps;
|
|
271
299
|
}
|
|
272
300
|
createCopy(remap) {
|
|
@@ -275,7 +303,8 @@ export class ExtrudeToFace extends ExtrudeBase {
|
|
|
275
303
|
: this.face;
|
|
276
304
|
const source = this.getSource();
|
|
277
305
|
const remapped = source ? (remap.get(source) || source) : undefined;
|
|
278
|
-
|
|
306
|
+
const remappedFilters = this.faceFilters.map(f => f.remap(remap));
|
|
307
|
+
return new ExtrudeToFace(newFace, remapped, remappedFilters).syncWith(this);
|
|
279
308
|
}
|
|
280
309
|
compareTo(other) {
|
|
281
310
|
if (!(other instanceof ExtrudeToFace)) {
|
|
@@ -292,15 +321,27 @@ export class ExtrudeToFace extends ExtrudeBase {
|
|
|
292
321
|
if (thisSource && otherSource && !thisSource.compareTo(otherSource)) {
|
|
293
322
|
return false;
|
|
294
323
|
}
|
|
295
|
-
if (
|
|
296
|
-
|
|
324
|
+
if (this.face instanceof SceneObject) {
|
|
325
|
+
if (!(other.face instanceof SceneObject)) {
|
|
326
|
+
return false;
|
|
327
|
+
}
|
|
328
|
+
if (!this.face.compareTo(other.face)) {
|
|
329
|
+
return false;
|
|
330
|
+
}
|
|
297
331
|
}
|
|
298
|
-
|
|
299
|
-
|
|
332
|
+
else {
|
|
333
|
+
if (this.face !== other.face) {
|
|
334
|
+
return false;
|
|
335
|
+
}
|
|
300
336
|
}
|
|
301
|
-
if (this.
|
|
337
|
+
if (this.faceFilters.length !== other.faceFilters.length) {
|
|
302
338
|
return false;
|
|
303
339
|
}
|
|
340
|
+
for (let i = 0; i < this.faceFilters.length; i++) {
|
|
341
|
+
if (!this.faceFilters[i].equals(other.faceFilters[i])) {
|
|
342
|
+
return false;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
304
345
|
return true;
|
|
305
346
|
}
|
|
306
347
|
getUniqueType() {
|
|
@@ -316,6 +357,7 @@ export class ExtrudeToFace extends ExtrudeBase {
|
|
|
316
357
|
draft: this.getDraft(),
|
|
317
358
|
endOffset: this.getEndOffset(),
|
|
318
359
|
face: typeof (this.face) === 'string' ? this.face : 'selection',
|
|
360
|
+
faceFilterCount: this.faceFilters.length,
|
|
319
361
|
thin: this._thin,
|
|
320
362
|
...this.serializePickFields(),
|
|
321
363
|
};
|
|
@@ -5,8 +5,11 @@ import { FaceMaker2 } from "../oc/face-maker2.js";
|
|
|
5
5
|
import { BooleanOps } from "../oc/boolean-ops.js";
|
|
6
6
|
import { EdgeOps } from "../oc/edge-ops.js";
|
|
7
7
|
import { Explorer } from "../oc/explorer.js";
|
|
8
|
-
import { ExtrudeThroughAll } from "./infinite-extrude.js";
|
|
9
8
|
import { ThinFaceMaker } from "../oc/thin-face-maker.js";
|
|
9
|
+
/** Finite stand-in for "infinity" in through-all cuts. Truly infinite prisms
|
|
10
|
+
* (via OC's `Inf=true` flag) silently fail inside `BRepAlgoAPI_Cut` — verified
|
|
11
|
+
* experimentally — so use a large finite extrusion instead. */
|
|
12
|
+
const THROUGH_ALL_LENGTH = 100000;
|
|
10
13
|
export class Extrude extends ExtrudeBase {
|
|
11
14
|
distance;
|
|
12
15
|
constructor(distance, source) {
|
|
@@ -257,36 +260,24 @@ export class Extrude extends ExtrudeBase {
|
|
|
257
260
|
const scope = this.resolveFusionScope(context.getSceneObjects());
|
|
258
261
|
let toolShapes;
|
|
259
262
|
const isThroughAll = this.distance === 0;
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
if (this.isFaceSourced()) {
|
|
264
|
-
throw new Error("through-all is not supported with a face-sourced extrude");
|
|
265
|
-
}
|
|
266
|
-
const extrudeThroughAll = new ExtrudeThroughAll(this.extrudable, true, true, faces);
|
|
267
|
-
toolShapes = extrudeThroughAll.build();
|
|
268
|
-
}
|
|
269
|
-
else {
|
|
270
|
-
const extruder1 = new Extruder(faces, plane, -this.distance / 2, this.getDraft(), this.getEndOffset());
|
|
271
|
-
const extrusions1 = extruder1.extrude();
|
|
272
|
-
const extruder2 = new Extruder(faces, plane, this.distance / 2, this.getDraft(), this.getEndOffset());
|
|
273
|
-
const extrusions2 = extruder2.extrude();
|
|
274
|
-
const all = [...extrusions1, ...extrusions2];
|
|
275
|
-
const halvesFuse = BooleanOps.fuse(all);
|
|
276
|
-
toolShapes = halvesFuse.result;
|
|
277
|
-
halvesFuse.dispose();
|
|
278
|
-
}
|
|
263
|
+
const draft = this.getDraft();
|
|
264
|
+
if (isThroughAll && this.isFaceSourced()) {
|
|
265
|
+
throw new Error("through-all is not supported with a face-sourced extrude");
|
|
279
266
|
}
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const
|
|
285
|
-
|
|
267
|
+
if (this._symmetric) {
|
|
268
|
+
// Symmetric cut: create tool centered on sketch plane, fusing two halves
|
|
269
|
+
// (one on each side). For through-all, each half uses THROUGH_ALL_LENGTH.
|
|
270
|
+
const halfDistance = isThroughAll ? THROUGH_ALL_LENGTH : this.distance / 2;
|
|
271
|
+
const extruder1 = new Extruder(faces, plane, -halfDistance, draft, this.getEndOffset());
|
|
272
|
+
const extruder2 = new Extruder(faces, plane, halfDistance, draft, this.getEndOffset());
|
|
273
|
+
const all = [...extruder1.extrude(), ...extruder2.extrude()];
|
|
274
|
+
const halvesFuse = BooleanOps.fuse(all);
|
|
275
|
+
toolShapes = halvesFuse.result;
|
|
276
|
+
halvesFuse.dispose();
|
|
286
277
|
}
|
|
287
278
|
else {
|
|
288
|
-
const distance = -this.distance;
|
|
289
|
-
const extruder = new Extruder(faces, plane, distance,
|
|
279
|
+
const distance = isThroughAll ? -THROUGH_ALL_LENGTH : -this.distance;
|
|
280
|
+
const extruder = new Extruder(faces, plane, distance, draft, this.getEndOffset());
|
|
290
281
|
toolShapes = extruder.extrude();
|
|
291
282
|
}
|
|
292
283
|
this.getSource()?.removeShapes(this);
|