fluidcad 0.0.28 → 0.0.30
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/profiler.d.ts +12 -0
- package/lib/dist/common/profiler.js +35 -0
- package/lib/dist/common/scene-object.d.ts +3 -0
- package/lib/dist/common/scene-object.js +3 -0
- package/lib/dist/common/shape-history-tracker.d.ts +9 -1
- package/lib/dist/common/shape-history-tracker.js +37 -23
- package/lib/dist/core/2d/aline.d.ts +13 -13
- package/lib/dist/core/2d/aline.js +20 -11
- package/lib/dist/core/2d/arc.d.ts +6 -6
- package/lib/dist/core/2d/arc.js +19 -15
- package/lib/dist/core/2d/back.d.ts +12 -0
- package/lib/dist/core/2d/back.js +11 -0
- package/lib/dist/core/2d/circle.d.ts +2 -2
- package/lib/dist/core/2d/circle.js +14 -10
- package/lib/dist/core/2d/ellipse.d.ts +35 -0
- package/lib/dist/core/2d/ellipse.js +65 -0
- package/lib/dist/core/2d/hline.d.ts +20 -13
- package/lib/dist/core/2d/hline.js +33 -15
- package/lib/dist/core/2d/index.d.ts +2 -0
- package/lib/dist/core/2d/index.js +2 -0
- package/lib/dist/core/2d/intersect.d.ts +2 -2
- package/lib/dist/core/2d/intersect.js +7 -3
- package/lib/dist/core/2d/line.d.ts +2 -2
- package/lib/dist/core/2d/line.js +14 -10
- package/lib/dist/core/2d/offset.d.ts +4 -4
- package/lib/dist/core/2d/offset.js +9 -5
- package/lib/dist/core/2d/polygon.d.ts +4 -4
- package/lib/dist/core/2d/polygon.js +24 -20
- package/lib/dist/core/2d/project.d.ts +2 -2
- package/lib/dist/core/2d/project.js +7 -3
- package/lib/dist/core/2d/rect.d.ts +2 -2
- package/lib/dist/core/2d/rect.js +22 -21
- package/lib/dist/core/2d/slot.d.ts +6 -6
- package/lib/dist/core/2d/slot.js +29 -32
- package/lib/dist/core/2d/vline.d.ts +20 -13
- package/lib/dist/core/2d/vline.js +29 -15
- package/lib/dist/core/interfaces.d.ts +62 -0
- package/lib/dist/core/mirror.d.ts +7 -7
- package/lib/dist/core/mirror.js +17 -11
- package/lib/dist/core/part.d.ts +3 -1
- package/lib/dist/core/part.js +1 -1
- package/lib/dist/core/rotate.d.ts +5 -5
- package/lib/dist/core/rotate.js +4 -1
- package/lib/dist/core/sketch.d.ts +3 -1
- package/lib/dist/core/sketch.js +1 -1
- package/lib/dist/core/translate.d.ts +9 -9
- package/lib/dist/features/2d/aline.d.ts +8 -5
- package/lib/dist/features/2d/aline.js +70 -18
- package/lib/dist/features/2d/back.d.ts +14 -0
- package/lib/dist/features/2d/back.js +35 -0
- package/lib/dist/features/2d/ellipse.d.ts +23 -0
- package/lib/dist/features/2d/ellipse.js +75 -0
- package/lib/dist/features/2d/hline.d.ts +9 -4
- package/lib/dist/features/2d/hline.js +65 -14
- package/lib/dist/features/2d/offset.d.ts +3 -0
- package/lib/dist/features/2d/offset.js +27 -3
- package/lib/dist/features/2d/sketch.d.ts +1 -0
- package/lib/dist/features/2d/sketch.js +15 -0
- package/lib/dist/features/2d/vline.d.ts +9 -4
- package/lib/dist/features/2d/vline.js +67 -15
- package/lib/dist/features/common.js +2 -1
- package/lib/dist/features/extrude-base.d.ts +19 -1
- package/lib/dist/features/extrude-base.js +75 -12
- package/lib/dist/features/extrude-two-distances.js +32 -27
- package/lib/dist/features/extrude.d.ts +39 -0
- package/lib/dist/features/extrude.js +196 -156
- package/lib/dist/features/fuse.js +2 -1
- package/lib/dist/features/lazy-scene-object.d.ts +1 -0
- package/lib/dist/features/lazy-scene-object.js +3 -0
- package/lib/dist/features/lazy-vertex.d.ts +1 -0
- package/lib/dist/features/lazy-vertex.js +3 -0
- package/lib/dist/features/loft.js +11 -8
- package/lib/dist/features/mirror-shape.d.ts +2 -0
- package/lib/dist/features/mirror-shape.js +16 -0
- package/lib/dist/features/mirror-shape2d.d.ts +2 -0
- package/lib/dist/features/mirror-shape2d.js +22 -1
- package/lib/dist/features/revolve.d.ts +31 -0
- package/lib/dist/features/revolve.js +178 -95
- package/lib/dist/features/rotate.d.ts +2 -0
- package/lib/dist/features/rotate.js +16 -0
- package/lib/dist/features/rotate2d.d.ts +2 -0
- package/lib/dist/features/rotate2d.js +16 -0
- package/lib/dist/features/select.js +2 -1
- package/lib/dist/features/simple-extruder.d.ts +3 -1
- package/lib/dist/features/simple-extruder.js +13 -9
- package/lib/dist/features/subtract.d.ts +2 -2
- package/lib/dist/features/subtract.js +3 -3
- package/lib/dist/features/sweep.d.ts +14 -0
- package/lib/dist/features/sweep.js +93 -80
- package/lib/dist/features/translate.d.ts +2 -0
- package/lib/dist/features/translate.js +23 -2
- package/lib/dist/filters/edge/edge-filter.d.ts +6 -0
- package/lib/dist/filters/edge/edge-filter.js +11 -0
- package/lib/dist/filters/face/face-filter.d.ts +6 -0
- package/lib/dist/filters/face/face-filter.js +11 -0
- package/lib/dist/filters/filter-base.d.ts +7 -1
- package/lib/dist/filters/filter-base.js +8 -0
- package/lib/dist/filters/filter-builder-base.js +11 -0
- package/lib/dist/filters/from-object.d.ts +14 -0
- package/lib/dist/filters/from-object.js +40 -0
- package/lib/dist/helpers/scene-helpers.d.ts +2 -0
- package/lib/dist/helpers/scene-helpers.js +68 -48
- package/lib/dist/oc/color-transfer.js +6 -0
- package/lib/dist/oc/edge-ops.d.ts +1 -0
- package/lib/dist/oc/edge-ops.js +17 -0
- package/lib/dist/oc/extrude-ops.d.ts +18 -1
- package/lib/dist/oc/extrude-ops.js +34 -1
- package/lib/dist/oc/geometry.d.ts +1 -0
- package/lib/dist/oc/geometry.js +27 -0
- package/lib/dist/oc/mesh.js +11 -9
- package/lib/dist/oc/ray-intersect.d.ts +16 -0
- package/lib/dist/oc/ray-intersect.js +91 -0
- package/lib/dist/oc/thin-face-maker.d.ts +0 -1
- package/lib/dist/oc/thin-face-maker.js +2 -20
- package/lib/dist/rendering/render.d.ts +2 -1
- package/lib/dist/rendering/render.js +72 -33
- package/lib/dist/rendering/scene.d.ts +4 -0
- package/lib/dist/tests/features/2d/back.test.d.ts +1 -0
- package/lib/dist/tests/features/2d/back.test.js +60 -0
- package/lib/dist/tests/features/2d/circle.test.js +1 -1
- package/lib/dist/tests/features/2d/constrained.test.js +4 -4
- package/lib/dist/tests/features/2d/ellipse.test.d.ts +1 -0
- package/lib/dist/tests/features/2d/ellipse.test.js +100 -0
- package/lib/dist/tests/features/2d/line.test.js +89 -3
- package/lib/dist/tests/features/2d/offset.test.js +1 -1
- package/lib/dist/tests/features/2d/polygon.test.js +2 -2
- package/lib/dist/tests/features/2d/rect.test.js +1 -1
- package/lib/dist/tests/features/2d/slot-from-edge.test.js +1 -1
- package/lib/dist/tests/features/2d/slot.test.js +1 -1
- package/lib/dist/tests/features/mirror.test.js +58 -0
- package/lib/dist/tests/features/mirror2d.test.js +63 -0
- package/lib/dist/tests/features/rotate.test.js +62 -0
- package/lib/dist/tests/features/rotate2d.test.js +47 -0
- package/lib/dist/tests/features/thin-revolve.test.js +37 -1
- package/lib/dist/tests/features/translate.test.js +63 -0
- package/lib/dist/tests/perf/record-fusion-history.bench.test.d.ts +1 -0
- package/lib/dist/tests/perf/record-fusion-history.bench.test.js +77 -0
- package/lib/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/server/dist/index.js +77 -45
- package/server/dist/ws-protocol.d.ts +11 -0
- package/ui/dist/assets/{index-BrW_x4uc.js → index-6Ep4GPxf.js} +131 -77
- package/ui/dist/assets/index-DRKfe6N9.css +2 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-gPoNOiIs.css +0 -2
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type ProfileCategory = {
|
|
2
|
+
category: string;
|
|
3
|
+
durationMs: number;
|
|
4
|
+
};
|
|
5
|
+
export declare class Profiler {
|
|
6
|
+
private categories;
|
|
7
|
+
private stack;
|
|
8
|
+
start(category: string): void;
|
|
9
|
+
end(category: string): void;
|
|
10
|
+
record<T>(category: string, fn: () => T): T;
|
|
11
|
+
getCategories(): ProfileCategory[];
|
|
12
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export class Profiler {
|
|
2
|
+
categories = new Map();
|
|
3
|
+
stack = [];
|
|
4
|
+
start(category) {
|
|
5
|
+
this.stack.push({ category, startTime: performance.now() });
|
|
6
|
+
}
|
|
7
|
+
end(category) {
|
|
8
|
+
for (let i = this.stack.length - 1; i >= 0; i--) {
|
|
9
|
+
if (this.stack[i].category === category) {
|
|
10
|
+
const entry = this.stack.splice(i, 1)[0];
|
|
11
|
+
const elapsed = performance.now() - entry.startTime;
|
|
12
|
+
const current = this.categories.get(category) || 0;
|
|
13
|
+
this.categories.set(category, current + elapsed);
|
|
14
|
+
this.stack.length = i;
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
record(category, fn) {
|
|
20
|
+
this.start(category);
|
|
21
|
+
try {
|
|
22
|
+
return fn();
|
|
23
|
+
}
|
|
24
|
+
finally {
|
|
25
|
+
this.end(category);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
getCategories() {
|
|
29
|
+
const result = [];
|
|
30
|
+
for (const [category, durationMs] of this.categories.entries()) {
|
|
31
|
+
result.push({ category, durationMs: Math.round(durationMs * 10) / 10 });
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -5,6 +5,7 @@ import { Matrix4 } from "../math/matrix4.js";
|
|
|
5
5
|
import { ISceneObject } from "../core/interfaces.js";
|
|
6
6
|
import { FusionScope, OperationMode } from "../features/extrude-options.js";
|
|
7
7
|
import { ShapeType } from "./shape-type.js";
|
|
8
|
+
import { Profiler } from "./profiler.js";
|
|
8
9
|
export type SourceLocation = {
|
|
9
10
|
filePath: string;
|
|
10
11
|
line: number;
|
|
@@ -35,6 +36,7 @@ export type BuildSceneObjectContext = {
|
|
|
35
36
|
getSceneObjectsFromTo(obj: SceneObject, to: SceneObject, type?: string): SceneObject[];
|
|
36
37
|
getTransform(): Matrix4 | null;
|
|
37
38
|
getLastObject(): SceneObject | null;
|
|
39
|
+
getProfiler(): Profiler;
|
|
38
40
|
};
|
|
39
41
|
export declare abstract class SceneObject implements Comparable<SceneObject>, Serializable, ISceneObject {
|
|
40
42
|
private state;
|
|
@@ -67,6 +69,7 @@ export declare abstract class SceneObject implements Comparable<SceneObject>, Se
|
|
|
67
69
|
getPreviousSibling(obj: SceneObject): SceneObject | null;
|
|
68
70
|
getPreviousSiblings(obj: SceneObject): SceneObject[];
|
|
69
71
|
isContainer(): boolean;
|
|
72
|
+
isLazy(): boolean;
|
|
70
73
|
saveShapesSnapshot(context: BuildSceneObjectContext): void;
|
|
71
74
|
getSnapshot(): Map<SceneObject, Shape[]>;
|
|
72
75
|
abstract serialize(scope?: Set<SceneObject>): any;
|
|
@@ -30,6 +30,14 @@ export declare class ShapeHistoryTracker {
|
|
|
30
30
|
*/
|
|
31
31
|
static remapFaces(faces: Face[], history: ShapeHistory): Face[];
|
|
32
32
|
static remapEdges(edges: Edge[], history: ShapeHistory): Edge[];
|
|
33
|
-
|
|
33
|
+
/**
|
|
34
|
+
* Collect history for `inputs` against `maker`'s output. When `opts.skipAdded`
|
|
35
|
+
* is set, the added* fields come back empty — callers that compute additions
|
|
36
|
+
* themselves (e.g. `recordFusionHistory` aggregates across all scene shapes)
|
|
37
|
+
* skip the per-call output traversal and per-result claimed-map updates.
|
|
38
|
+
*/
|
|
39
|
+
static collect(maker: BRepBuilderAPI_MakeShape, inputs: Shape[], opts?: {
|
|
40
|
+
skipAdded?: boolean;
|
|
41
|
+
}): ShapeHistory;
|
|
34
42
|
private static collectForType;
|
|
35
43
|
}
|
|
@@ -41,15 +41,22 @@ export class ShapeHistoryTracker {
|
|
|
41
41
|
}
|
|
42
42
|
return result;
|
|
43
43
|
}
|
|
44
|
-
|
|
44
|
+
/**
|
|
45
|
+
* Collect history for `inputs` against `maker`'s output. When `opts.skipAdded`
|
|
46
|
+
* is set, the added* fields come back empty — callers that compute additions
|
|
47
|
+
* themselves (e.g. `recordFusionHistory` aggregates across all scene shapes)
|
|
48
|
+
* skip the per-call output traversal and per-result claimed-map updates.
|
|
49
|
+
*/
|
|
50
|
+
static collect(maker, inputs, opts = {}) {
|
|
45
51
|
const oc = getOC();
|
|
46
52
|
const FACE = oc.TopAbs_ShapeEnum.TopAbs_FACE;
|
|
47
53
|
const EDGE = oc.TopAbs_ShapeEnum.TopAbs_EDGE;
|
|
48
|
-
const
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
const
|
|
52
|
-
const
|
|
54
|
+
const skipAdded = opts.skipAdded === true;
|
|
55
|
+
const output = skipAdded ? null : maker.Shape();
|
|
56
|
+
const outputFaces = output ? Explorer.findShapes(output, FACE) : [];
|
|
57
|
+
const outputEdges = output ? Explorer.findShapes(output, EDGE) : [];
|
|
58
|
+
const faces = ShapeHistoryTracker.collectForType(maker, inputs, FACE, outputFaces, (raw) => Face.fromTopoDSFace(Explorer.toFace(raw)), skipAdded);
|
|
59
|
+
const edges = ShapeHistoryTracker.collectForType(maker, inputs, EDGE, outputEdges, (raw) => Edge.fromTopoDSEdge(Explorer.toEdge(raw)), skipAdded);
|
|
53
60
|
return {
|
|
54
61
|
addedFaces: faces.added,
|
|
55
62
|
modifiedFaces: faces.modified,
|
|
@@ -61,28 +68,30 @@ export class ShapeHistoryTracker {
|
|
|
61
68
|
removedEdges: edges.removed,
|
|
62
69
|
};
|
|
63
70
|
}
|
|
64
|
-
static collectForType(maker, inputs, type, outputRaws, wrap) {
|
|
71
|
+
static collectForType(maker, inputs, type, outputRaws, wrap, skipAdded) {
|
|
65
72
|
const oc = getOC();
|
|
66
73
|
const modified = [];
|
|
67
74
|
const generated = [];
|
|
68
75
|
const removed = [];
|
|
69
|
-
//
|
|
70
|
-
//
|
|
71
|
-
|
|
76
|
+
// Track which output raws are claimed by a Modified/Generated record so the
|
|
77
|
+
// remaining outputs can be reported as pure additions. When `skipAdded`,
|
|
78
|
+
// we don't compute additions, so skip the bookkeeping entirely.
|
|
79
|
+
const claimed = skipAdded ? null : new oc.TopTools_MapOfShape();
|
|
72
80
|
const isOfType = (raw) => raw.ShapeType() === type;
|
|
73
81
|
for (const input of inputs) {
|
|
74
82
|
const inputRaws = Explorer.findShapes(input.getShape(), type);
|
|
75
83
|
for (const inputRaw of inputRaws) {
|
|
76
84
|
const modifiedRaws = ShapeOps.shapeListToArray(maker.Modified(inputRaw)).filter(isOfType);
|
|
77
85
|
const generatedRaws = ShapeOps.shapeListToArray(maker.Generated(inputRaw)).filter(isOfType);
|
|
78
|
-
const isDeleted = maker.IsDeleted(inputRaw);
|
|
79
86
|
if (modifiedRaws.length > 0) {
|
|
80
87
|
modified.push({
|
|
81
88
|
sources: [wrap(inputRaw)],
|
|
82
89
|
results: modifiedRaws.map(wrap),
|
|
83
90
|
});
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
if (claimed) {
|
|
92
|
+
for (const r of modifiedRaws) {
|
|
93
|
+
claimed.Add(r);
|
|
94
|
+
}
|
|
86
95
|
}
|
|
87
96
|
}
|
|
88
97
|
if (generatedRaws.length > 0) {
|
|
@@ -90,25 +99,30 @@ export class ShapeHistoryTracker {
|
|
|
90
99
|
sources: [wrap(inputRaw)],
|
|
91
100
|
results: generatedRaws.map(wrap),
|
|
92
101
|
});
|
|
93
|
-
|
|
94
|
-
|
|
102
|
+
if (claimed) {
|
|
103
|
+
for (const r of generatedRaws) {
|
|
104
|
+
claimed.Add(r);
|
|
105
|
+
}
|
|
95
106
|
}
|
|
96
107
|
}
|
|
97
|
-
//
|
|
98
|
-
// Modified
|
|
99
|
-
// its fate —
|
|
100
|
-
if (
|
|
108
|
+
// IsDeleted is only meaningful when the input has no successor. If
|
|
109
|
+
// Modified or Generated produced anything, that record already
|
|
110
|
+
// captures its fate — skip the (relatively expensive) IsDeleted call.
|
|
111
|
+
if (modifiedRaws.length === 0 && generatedRaws.length === 0
|
|
112
|
+
&& maker.IsDeleted(inputRaw)) {
|
|
101
113
|
removed.push(wrap(inputRaw));
|
|
102
114
|
}
|
|
103
115
|
}
|
|
104
116
|
}
|
|
105
117
|
const added = [];
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
118
|
+
if (claimed) {
|
|
119
|
+
for (const raw of outputRaws) {
|
|
120
|
+
if (!claimed.Contains(raw)) {
|
|
121
|
+
added.push(wrap(raw));
|
|
122
|
+
}
|
|
109
123
|
}
|
|
124
|
+
claimed.delete();
|
|
110
125
|
}
|
|
111
|
-
claimed.delete();
|
|
112
126
|
return { added, modified, generated, removed };
|
|
113
127
|
}
|
|
114
128
|
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
import { PlaneLike } from "../../math/plane.js";
|
|
2
|
-
import {
|
|
2
|
+
import { IALine, ISceneObject } from "../interfaces.js";
|
|
3
3
|
interface ALineFunction {
|
|
4
4
|
/**
|
|
5
5
|
* Draws a line at the given angle with the given length.
|
|
6
|
-
*
|
|
6
|
+
* Chain `.centered()` to center the line on the current position.
|
|
7
7
|
* @param angle - The angle in degrees
|
|
8
|
-
* @param
|
|
8
|
+
* @param length - The line length
|
|
9
9
|
*/
|
|
10
|
-
(
|
|
10
|
+
(angle: number, length: number): IALine;
|
|
11
11
|
/**
|
|
12
|
-
* Draws a line at the given angle
|
|
13
|
-
*
|
|
12
|
+
* Draws a line at the given angle that ends where it intersects the target
|
|
13
|
+
* geometry. The nearest intersection along the line's direction (in either
|
|
14
|
+
* sign) is used.
|
|
14
15
|
* @param angle - The angle in degrees
|
|
15
|
-
* @param
|
|
16
|
+
* @param target - The geometry to intersect with
|
|
16
17
|
*/
|
|
17
|
-
(
|
|
18
|
+
(angle: number, target: ISceneObject): IALine;
|
|
18
19
|
/**
|
|
19
|
-
* Draws a
|
|
20
|
-
* @param length - The line length
|
|
21
|
-
* @param angle - The angle in degrees
|
|
22
|
-
* @param centered - Whether to center the line on the current position
|
|
20
|
+
* Draws a line at the given angle on a specific plane.
|
|
23
21
|
* @param targetPlane - The plane to draw on
|
|
22
|
+
* @param angle - The angle in degrees
|
|
23
|
+
* @param length - The line length
|
|
24
24
|
*/
|
|
25
|
-
(
|
|
25
|
+
(targetPlane: PlaneLike | ISceneObject, angle: number, length: number): IALine;
|
|
26
26
|
}
|
|
27
27
|
declare const _default: ALineFunction;
|
|
28
28
|
export default _default;
|
|
@@ -6,19 +6,28 @@ import { resolvePlane } from "../../helpers/resolve.js";
|
|
|
6
6
|
function build(context) {
|
|
7
7
|
return function line() {
|
|
8
8
|
let planeObj = null;
|
|
9
|
-
let
|
|
10
|
-
|
|
11
|
-
if (
|
|
12
|
-
const
|
|
13
|
-
if (isPlaneLike(
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
let argOffset = 0;
|
|
10
|
+
const inSketch = context.getActiveSketch() !== null;
|
|
11
|
+
if (arguments.length > 0) {
|
|
12
|
+
const firstArg = arguments[0];
|
|
13
|
+
if (isPlaneLike(firstArg)) {
|
|
14
|
+
if (inSketch) {
|
|
15
|
+
throw new Error("aLine(plane, ...) cannot be used inside a sketch. Use aLine(...) instead.");
|
|
16
|
+
}
|
|
17
|
+
planeObj = resolvePlane(firstArg, context);
|
|
18
|
+
argOffset = 1;
|
|
19
|
+
}
|
|
20
|
+
else if (!inSketch && firstArg instanceof SceneObject) {
|
|
21
|
+
planeObj = resolvePlane(firstArg, context);
|
|
22
|
+
argOffset = 1;
|
|
16
23
|
}
|
|
17
24
|
}
|
|
18
|
-
const
|
|
19
|
-
const
|
|
20
|
-
const
|
|
21
|
-
|
|
25
|
+
const angle = arguments[argOffset];
|
|
26
|
+
const second = arguments[argOffset + 1];
|
|
27
|
+
const lengthOrTarget = second instanceof SceneObject
|
|
28
|
+
? second
|
|
29
|
+
: second;
|
|
30
|
+
const aline = new AngledLine(angle, lengthOrTarget, planeObj);
|
|
22
31
|
context.addSceneObject(aline);
|
|
23
32
|
return aline;
|
|
24
33
|
};
|
|
@@ -26,25 +26,25 @@ interface ArcFunction {
|
|
|
26
26
|
(radius: number, startAngle?: number, endAngle?: number): IArcAngles;
|
|
27
27
|
/**
|
|
28
28
|
* Draws an arc to an end point on a specific plane.
|
|
29
|
-
* @param endPoint - The end point of the arc
|
|
30
29
|
* @param targetPlane - The plane to draw on
|
|
30
|
+
* @param endPoint - The end point of the arc
|
|
31
31
|
*/
|
|
32
|
-
(
|
|
32
|
+
(targetPlane: PlaneLike | ISceneObject, endPoint: Point2DLike): IArcPoints;
|
|
33
33
|
/**
|
|
34
34
|
* Draws an arc between two points on a specific plane.
|
|
35
|
+
* @param targetPlane - The plane to draw on
|
|
35
36
|
* @param startPoint - The start point of the arc
|
|
36
37
|
* @param endPoint - The end point of the arc
|
|
37
|
-
* @param targetPlane - The plane to draw on
|
|
38
38
|
*/
|
|
39
|
-
(
|
|
39
|
+
(targetPlane: PlaneLike | ISceneObject, startPoint: Point2DLike, endPoint: Point2DLike): IArcPoints;
|
|
40
40
|
/**
|
|
41
41
|
* Draws an arc by radius and angle range on a specific plane.
|
|
42
|
+
* @param targetPlane - The plane to draw on
|
|
42
43
|
* @param radius - The arc radius
|
|
43
44
|
* @param startAngle - The start angle in degrees
|
|
44
45
|
* @param endAngle - The end angle in degrees
|
|
45
|
-
* @param targetPlane - The plane to draw on
|
|
46
46
|
*/
|
|
47
|
-
(radius: number, startAngle: number, endAngle: number
|
|
47
|
+
(targetPlane: PlaneLike | ISceneObject, radius: number, startAngle: number, endAngle: number): IArcAngles;
|
|
48
48
|
}
|
|
49
49
|
declare const _default: ArcFunction;
|
|
50
50
|
export default _default;
|
package/lib/dist/core/2d/arc.js
CHANGED
|
@@ -8,34 +8,38 @@ import { resolvePlane } from "../../helpers/resolve.js";
|
|
|
8
8
|
function build(context) {
|
|
9
9
|
return function arc() {
|
|
10
10
|
let planeObj = null;
|
|
11
|
-
let
|
|
12
|
-
// Detect plane as
|
|
13
|
-
if (
|
|
14
|
-
const
|
|
15
|
-
if (isPlaneLike(
|
|
16
|
-
|
|
17
|
-
|
|
11
|
+
let argOffset = 0;
|
|
12
|
+
// Detect plane as first argument (only valid outside a sketch)
|
|
13
|
+
if (arguments.length > 0) {
|
|
14
|
+
const firstArg = arguments[0];
|
|
15
|
+
if (isPlaneLike(firstArg) || (firstArg instanceof SceneObject && !isPoint2DLike(firstArg))) {
|
|
16
|
+
if (context.getActiveSketch() !== null) {
|
|
17
|
+
throw new Error("arc(plane, ...) cannot be used inside a sketch. Use arc(...) instead.");
|
|
18
|
+
}
|
|
19
|
+
planeObj = resolvePlane(firstArg, context);
|
|
20
|
+
argOffset = 1;
|
|
18
21
|
}
|
|
19
22
|
}
|
|
23
|
+
const argCount = arguments.length - argOffset;
|
|
20
24
|
// (startPoint, endPoint) — two Point2DLike args, default center = current position
|
|
21
|
-
if (argCount >= 2 && isPoint2DLike(arguments[
|
|
22
|
-
const start = normalizePoint2D(arguments[
|
|
23
|
-
const end = normalizePoint2D(arguments[1]);
|
|
25
|
+
if (argCount >= 2 && isPoint2DLike(arguments[argOffset]) && isPoint2DLike(arguments[argOffset + 1])) {
|
|
26
|
+
const start = normalizePoint2D(arguments[argOffset]);
|
|
27
|
+
const end = normalizePoint2D(arguments[argOffset + 1]);
|
|
24
28
|
const arcObj = Arc.twoPoints(start, end, planeObj);
|
|
25
29
|
context.addSceneObject(arcObj);
|
|
26
30
|
return arcObj;
|
|
27
31
|
}
|
|
28
32
|
// (endPoint) — single Point2DLike arg
|
|
29
|
-
if (isPoint2DLike(arguments[
|
|
30
|
-
const end = normalizePoint2D(arguments[
|
|
33
|
+
if (isPoint2DLike(arguments[argOffset])) {
|
|
34
|
+
const end = normalizePoint2D(arguments[argOffset]);
|
|
31
35
|
const arcObj = Arc.toPoint(end, planeObj);
|
|
32
36
|
context.addSceneObject(arcObj);
|
|
33
37
|
return arcObj;
|
|
34
38
|
}
|
|
35
39
|
// (radius, startAngle?, endAngle?) — all numeric args
|
|
36
|
-
const radius = arguments[
|
|
37
|
-
const startAngle = arguments[1] || 0;
|
|
38
|
-
const endAngle = argCount >= 3 ? arguments[2] : 180;
|
|
40
|
+
const radius = arguments[argOffset] || 100;
|
|
41
|
+
const startAngle = arguments[argOffset + 1] || 0;
|
|
42
|
+
const endAngle = argCount >= 3 ? arguments[argOffset + 2] : 180;
|
|
39
43
|
const arcObj = Arc.fromAngles(radius, startAngle, endAngle, planeObj);
|
|
40
44
|
context.addSceneObject(arcObj);
|
|
41
45
|
return arcObj;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { IGeometry } from "../interfaces.js";
|
|
2
|
+
interface BackFunction {
|
|
3
|
+
/** Reverts the cursor to the previous position. */
|
|
4
|
+
(): IGeometry;
|
|
5
|
+
/**
|
|
6
|
+
* Reverts the cursor `count` position-changes back.
|
|
7
|
+
* @param count - How many prior cursor changes to undo (default 1).
|
|
8
|
+
*/
|
|
9
|
+
(count: number): IGeometry;
|
|
10
|
+
}
|
|
11
|
+
declare const _default: BackFunction;
|
|
12
|
+
export default _default;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Back } from "../../features/2d/back.js";
|
|
2
|
+
import { registerBuilder } from "../../index.js";
|
|
3
|
+
function build(context) {
|
|
4
|
+
return function back() {
|
|
5
|
+
const count = arguments[0] ?? 1;
|
|
6
|
+
const obj = new Back(count);
|
|
7
|
+
context.addSceneObject(obj);
|
|
8
|
+
return obj;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export default registerBuilder(build);
|
|
@@ -15,10 +15,10 @@ interface CircleFunction {
|
|
|
15
15
|
(diameter?: number): IExtrudableGeometry;
|
|
16
16
|
/**
|
|
17
17
|
* Draws a circle with a given diameter on a specific plane.
|
|
18
|
-
* @param diameter - The circle diameter
|
|
19
18
|
* @param targetPlane - The plane to draw on
|
|
19
|
+
* @param diameter - The circle diameter
|
|
20
20
|
*/
|
|
21
|
-
(
|
|
21
|
+
(targetPlane: PlaneLike | ISceneObject, diameter: number): IExtrudableGeometry;
|
|
22
22
|
}
|
|
23
23
|
declare const _default: CircleFunction;
|
|
24
24
|
export default _default;
|
|
@@ -12,28 +12,32 @@ function build(context) {
|
|
|
12
12
|
let center;
|
|
13
13
|
let circle;
|
|
14
14
|
let planeObj = null;
|
|
15
|
-
let
|
|
16
|
-
// Detect plane as
|
|
17
|
-
if (
|
|
18
|
-
const
|
|
19
|
-
if (isPlaneLike(
|
|
20
|
-
|
|
21
|
-
|
|
15
|
+
let argOffset = 0;
|
|
16
|
+
// Detect plane as first argument (only valid outside a sketch)
|
|
17
|
+
if (arguments.length > 0) {
|
|
18
|
+
const firstArg = arguments[0];
|
|
19
|
+
if (isPlaneLike(firstArg) || (firstArg instanceof SceneObject && !isPoint2DLike(firstArg))) {
|
|
20
|
+
if (context.getActiveSketch() !== null) {
|
|
21
|
+
throw new Error("circle(plane, ...) cannot be used inside a sketch. Use circle(...) instead.");
|
|
22
|
+
}
|
|
23
|
+
planeObj = resolvePlane(firstArg, context);
|
|
24
|
+
argOffset = 1;
|
|
22
25
|
}
|
|
23
26
|
}
|
|
27
|
+
const argCount = arguments.length - argOffset;
|
|
24
28
|
if (argCount === 0) {
|
|
25
29
|
diameter = 40;
|
|
26
30
|
circle = new Circle(diameter, null, planeObj);
|
|
27
31
|
context.addSceneObject(circle);
|
|
28
32
|
}
|
|
29
33
|
else if (argCount === 1) {
|
|
30
|
-
diameter = arguments[
|
|
34
|
+
diameter = arguments[argOffset] || 40;
|
|
31
35
|
circle = new Circle(diameter, null, planeObj);
|
|
32
36
|
context.addSceneObject(circle);
|
|
33
37
|
}
|
|
34
38
|
else {
|
|
35
|
-
center = normalizePoint2D(arguments[
|
|
36
|
-
diameter = arguments[1] || 40;
|
|
39
|
+
center = normalizePoint2D(arguments[argOffset]);
|
|
40
|
+
diameter = arguments[argOffset + 1] || 40;
|
|
37
41
|
circle = new Circle(diameter, null, planeObj);
|
|
38
42
|
const move = new Move(center);
|
|
39
43
|
context.addSceneObjects([move, circle]);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Point2DLike } from "../../math/point.js";
|
|
2
|
+
import { PlaneLike } from "../../math/plane.js";
|
|
3
|
+
import { IExtrudableGeometry, ISceneObject } from "../interfaces.js";
|
|
4
|
+
interface EllipseFunction {
|
|
5
|
+
/**
|
|
6
|
+
* Draws an ellipse at the current position.
|
|
7
|
+
* @param rx - Semi-radius along the plane's X axis
|
|
8
|
+
* @param ry - Semi-radius along the plane's Y axis
|
|
9
|
+
*/
|
|
10
|
+
(rx: number, ry: number): IExtrudableGeometry;
|
|
11
|
+
/**
|
|
12
|
+
* Draws an ellipse at a given center.
|
|
13
|
+
* @param center - The center point
|
|
14
|
+
* @param rx - Semi-radius along the plane's X axis
|
|
15
|
+
* @param ry - Semi-radius along the plane's Y axis
|
|
16
|
+
*/
|
|
17
|
+
(center: Point2DLike, rx: number, ry: number): IExtrudableGeometry;
|
|
18
|
+
/**
|
|
19
|
+
* Draws an ellipse on a specific plane.
|
|
20
|
+
* @param targetPlane - The plane to draw on
|
|
21
|
+
* @param rx - Semi-radius along the plane's X axis
|
|
22
|
+
* @param ry - Semi-radius along the plane's Y axis
|
|
23
|
+
*/
|
|
24
|
+
(targetPlane: PlaneLike | ISceneObject, rx: number, ry: number): IExtrudableGeometry;
|
|
25
|
+
/**
|
|
26
|
+
* Draws an ellipse at a given center on a specific plane.
|
|
27
|
+
* @param targetPlane - The plane to draw on
|
|
28
|
+
* @param center - The center point in plane-local coordinates
|
|
29
|
+
* @param rx - Semi-radius along the plane's X axis
|
|
30
|
+
* @param ry - Semi-radius along the plane's Y axis
|
|
31
|
+
*/
|
|
32
|
+
(targetPlane: PlaneLike | ISceneObject, center: Point2DLike, rx: number, ry: number): IExtrudableGeometry;
|
|
33
|
+
}
|
|
34
|
+
declare const _default: EllipseFunction;
|
|
35
|
+
export default _default;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Point2D, isPoint2DLike } from "../../math/point.js";
|
|
2
|
+
import { LazyVertex } from "../../features/lazy-vertex.js";
|
|
3
|
+
import { Ellipse } from "../../features/2d/ellipse.js";
|
|
4
|
+
import { Move } from "../../features/2d/move.js";
|
|
5
|
+
import { normalizePoint2D } from "../../helpers/normalize.js";
|
|
6
|
+
import { registerBuilder } from "../../index.js";
|
|
7
|
+
import { isPlaneLike } from "../../math/plane.js";
|
|
8
|
+
import { SceneObject } from "../../common/scene-object.js";
|
|
9
|
+
import { resolvePlane } from "../../helpers/resolve.js";
|
|
10
|
+
function toPoint2D(p) {
|
|
11
|
+
if (p instanceof Point2D) {
|
|
12
|
+
return p;
|
|
13
|
+
}
|
|
14
|
+
if (p instanceof LazyVertex) {
|
|
15
|
+
return p.asPoint2D();
|
|
16
|
+
}
|
|
17
|
+
if (Array.isArray(p)) {
|
|
18
|
+
return new Point2D(p[0], p[1]);
|
|
19
|
+
}
|
|
20
|
+
return new Point2D(p.x, p.y);
|
|
21
|
+
}
|
|
22
|
+
function build(context) {
|
|
23
|
+
return function ellipse() {
|
|
24
|
+
let planeObj = null;
|
|
25
|
+
let argOffset = 0;
|
|
26
|
+
if (arguments.length > 0) {
|
|
27
|
+
const firstArg = arguments[0];
|
|
28
|
+
if (isPlaneLike(firstArg) || (firstArg instanceof SceneObject && !isPoint2DLike(firstArg))) {
|
|
29
|
+
if (context.getActiveSketch() !== null) {
|
|
30
|
+
throw new Error("ellipse(plane, ...) cannot be used inside a sketch. Use ellipse(...) instead.");
|
|
31
|
+
}
|
|
32
|
+
planeObj = resolvePlane(firstArg, context);
|
|
33
|
+
argOffset = 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
const argCount = arguments.length - argOffset;
|
|
37
|
+
if (argCount === 2) {
|
|
38
|
+
const rx = arguments[argOffset];
|
|
39
|
+
const ry = arguments[argOffset + 1];
|
|
40
|
+
const e = new Ellipse(rx, ry, planeObj);
|
|
41
|
+
context.addSceneObject(e);
|
|
42
|
+
return e;
|
|
43
|
+
}
|
|
44
|
+
if (argCount === 3) {
|
|
45
|
+
const centerArg = arguments[argOffset];
|
|
46
|
+
const rx = arguments[argOffset + 1];
|
|
47
|
+
const ry = arguments[argOffset + 2];
|
|
48
|
+
if (planeObj) {
|
|
49
|
+
// Standalone (plane, center, rx, ry): center is plane-local. Move
|
|
50
|
+
// can't run outside a sketch, so resolve the center eagerly into the
|
|
51
|
+
// Ellipse via centerOverride.
|
|
52
|
+
const center = toPoint2D(centerArg);
|
|
53
|
+
const e = new Ellipse(rx, ry, planeObj, center);
|
|
54
|
+
context.addSceneObject(e);
|
|
55
|
+
return e;
|
|
56
|
+
}
|
|
57
|
+
const center = normalizePoint2D(centerArg);
|
|
58
|
+
const e = new Ellipse(rx, ry, null);
|
|
59
|
+
context.addSceneObjects([new Move(center), e]);
|
|
60
|
+
return e;
|
|
61
|
+
}
|
|
62
|
+
throw new Error("Invalid arguments for ellipse()");
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
export default registerBuilder(build);
|
|
@@ -1,33 +1,40 @@
|
|
|
1
1
|
import { Point2DLike } from "../../math/point.js";
|
|
2
2
|
import { PlaneLike } from "../../math/plane.js";
|
|
3
|
-
import {
|
|
3
|
+
import { IHLine, ISceneObject } from "../interfaces.js";
|
|
4
4
|
interface HLineFunction {
|
|
5
5
|
/**
|
|
6
6
|
* Draws a horizontal line of the given distance.
|
|
7
|
+
* Chain `.centered()` to center the line on the current position.
|
|
7
8
|
* @param distance - The line length
|
|
8
|
-
* @param centered - Whether to center the line on the current position
|
|
9
9
|
*/
|
|
10
|
-
(distance: number
|
|
10
|
+
(distance: number): IHLine;
|
|
11
|
+
/**
|
|
12
|
+
* Draws a horizontal line that ends where it intersects the target geometry.
|
|
13
|
+
* The nearest intersection (in either direction along the X axis) is used.
|
|
14
|
+
* @param target - The geometry to intersect with
|
|
15
|
+
*/
|
|
16
|
+
(target: ISceneObject): IHLine;
|
|
11
17
|
/**
|
|
12
18
|
* Draws a horizontal line from a start point.
|
|
19
|
+
* Chain `.centered()` to center the line on the start point.
|
|
13
20
|
* @param start - The start point
|
|
14
21
|
* @param distance - The line length
|
|
15
|
-
* @param centered - Whether to center the line on the start point
|
|
16
22
|
*/
|
|
17
|
-
(start: Point2DLike, distance: number
|
|
23
|
+
(start: Point2DLike, distance: number): IHLine;
|
|
18
24
|
/**
|
|
19
|
-
* Draws a horizontal line
|
|
20
|
-
*
|
|
21
|
-
*
|
|
25
|
+
* Draws a horizontal line from a start point that ends where it intersects
|
|
26
|
+
* the target geometry. The nearest intersection (in either direction along
|
|
27
|
+
* the X axis) is used.
|
|
28
|
+
* @param start - The start point
|
|
29
|
+
* @param target - The geometry to intersect with
|
|
22
30
|
*/
|
|
23
|
-
(
|
|
31
|
+
(start: Point2DLike, target: ISceneObject): IHLine;
|
|
24
32
|
/**
|
|
25
|
-
* Draws a horizontal line
|
|
26
|
-
* @param distance - The line length
|
|
27
|
-
* @param centered - Whether to center the line on the current position
|
|
33
|
+
* Draws a horizontal line on a specific plane.
|
|
28
34
|
* @param targetPlane - The plane to draw on
|
|
35
|
+
* @param distance - The line length
|
|
29
36
|
*/
|
|
30
|
-
(
|
|
37
|
+
(targetPlane: PlaneLike | ISceneObject, distance: number): IHLine;
|
|
31
38
|
}
|
|
32
39
|
declare const _default: HLineFunction;
|
|
33
40
|
export default _default;
|