fluidcad 0.0.27 → 0.0.29
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 +47 -0
- package/lib/dist/common/scene-object.js +121 -0
- package/lib/dist/common/shape-factory.d.ts +1 -1
- package/lib/dist/common/shape-history-tracker.d.ts +43 -0
- package/lib/dist/common/shape-history-tracker.js +128 -0
- package/lib/dist/common/shape.js +7 -1
- package/lib/dist/common/solid.js +5 -1
- package/lib/dist/core/2d/aline.d.ts +4 -4
- package/lib/dist/core/2d/aline.js +14 -10
- package/lib/dist/core/2d/arc.d.ts +6 -6
- package/lib/dist/core/2d/arc.js +19 -15
- 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 +4 -4
- package/lib/dist/core/2d/hline.js +14 -10
- package/lib/dist/core/2d/index.d.ts +1 -0
- package/lib/dist/core/2d/index.js +1 -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 +4 -4
- package/lib/dist/core/2d/vline.js +14 -10
- package/lib/dist/core/interfaces.d.ts +8 -0
- 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.js +4 -1
- package/lib/dist/core/sketch.d.ts +3 -1
- package/lib/dist/core/sketch.js +1 -1
- package/lib/dist/features/2d/ellipse.d.ts +23 -0
- package/lib/dist/features/2d/ellipse.js +75 -0
- package/lib/dist/features/2d/offset.d.ts +3 -0
- package/lib/dist/features/2d/offset.js +27 -3
- package/lib/dist/features/chamfer.js +12 -6
- package/lib/dist/features/common.js +2 -1
- package/lib/dist/features/extrude-base.d.ts +55 -1
- package/lib/dist/features/extrude-base.js +168 -33
- package/lib/dist/features/extrude-to-face.js +13 -2
- package/lib/dist/features/extrude-two-distances.js +45 -25
- package/lib/dist/features/extrude.d.ts +39 -0
- package/lib/dist/features/extrude.js +207 -144
- package/lib/dist/features/fillet.js +3 -4
- package/lib/dist/features/fuse.js +16 -1
- package/lib/dist/features/infinite-extrude.d.ts +1 -0
- package/lib/dist/features/infinite-extrude.js +33 -4
- package/lib/dist/features/loft.js +26 -10
- package/lib/dist/features/revolve.d.ts +31 -0
- package/lib/dist/features/revolve.js +179 -85
- 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 -69
- 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 +9 -1
- package/lib/dist/helpers/scene-helpers.js +298 -13
- package/lib/dist/oc/boolean-ops.d.ts +29 -3
- package/lib/dist/oc/boolean-ops.js +107 -9
- package/lib/dist/oc/color-transfer.d.ts +37 -0
- package/lib/dist/oc/color-transfer.js +141 -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 +59 -4
- package/lib/dist/oc/fillet-ops.d.ts +5 -3
- package/lib/dist/oc/fillet-ops.js +23 -4
- package/lib/dist/oc/geometry.d.ts +1 -0
- package/lib/dist/oc/geometry.js +27 -0
- package/lib/dist/oc/intersection.js +6 -3
- package/lib/dist/oc/mesh.js +12 -10
- package/lib/dist/oc/shape-ops.d.ts +25 -0
- package/lib/dist/oc/shape-ops.js +131 -12
- 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 +68 -32
- package/lib/dist/rendering/scene.d.ts +4 -0
- package/lib/dist/tests/common/scene-object-history.test.d.ts +1 -0
- package/lib/dist/tests/common/scene-object-history.test.js +274 -0
- package/lib/dist/tests/common/shape-history-tracker.test.d.ts +1 -0
- package/lib/dist/tests/common/shape-history-tracker.test.js +110 -0
- package/lib/dist/tests/features/2d/circle.test.js +1 -1
- 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 +1 -1
- 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/project-regression.test.d.ts +1 -0
- package/lib/dist/tests/features/2d/project-regression.test.js +69 -0
- package/lib/dist/tests/features/2d/project-user-regression.test.d.ts +1 -0
- package/lib/dist/tests/features/2d/project-user-regression.test.js +37 -0
- package/lib/dist/tests/features/2d/rect.test.js +1 -1
- package/lib/dist/tests/features/2d/slot.test.js +1 -1
- package/lib/dist/tests/features/color-lineage.test.d.ts +1 -0
- package/lib/dist/tests/features/color-lineage.test.js +213 -0
- package/lib/dist/tests/features/cut-symmetric-through-all.test.d.ts +1 -0
- package/lib/dist/tests/features/cut-symmetric-through-all.test.js +32 -0
- package/lib/dist/tests/features/extrude-history.test.d.ts +1 -0
- package/lib/dist/tests/features/extrude-history.test.js +248 -0
- package/lib/dist/tests/features/peer-ops-history.test.d.ts +1 -0
- package/lib/dist/tests/features/peer-ops-history.test.js +119 -0
- package/lib/dist/tests/features/subtract.test.js +21 -1
- package/lib/dist/tests/features/thin-revolve.test.js +37 -1
- 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 +3 -3
- package/ui/dist/assets/{index-gPoNOiIs.css → index-VKkXzLfR.css} +1 -1
- package/ui/dist/assets/{index-55iqIwnj.js → index-VY48_dgc.js} +64 -47
- package/ui/dist/index.html +2 -2
|
@@ -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);
|
|
@@ -17,17 +17,17 @@ interface HLineFunction {
|
|
|
17
17
|
(start: Point2DLike, distance: number, centered?: boolean): IGeometry;
|
|
18
18
|
/**
|
|
19
19
|
* Draws a horizontal line on a specific plane.
|
|
20
|
-
* @param distance - The line length
|
|
21
20
|
* @param targetPlane - The plane to draw on
|
|
21
|
+
* @param distance - The line length
|
|
22
22
|
*/
|
|
23
|
-
(
|
|
23
|
+
(targetPlane: PlaneLike | ISceneObject, distance: number): IGeometry;
|
|
24
24
|
/**
|
|
25
25
|
* Draws a horizontal line with centering on a specific plane.
|
|
26
|
+
* @param targetPlane - The plane to draw on
|
|
26
27
|
* @param distance - The line length
|
|
27
28
|
* @param centered - Whether to center the line on the current position
|
|
28
|
-
* @param targetPlane - The plane to draw on
|
|
29
29
|
*/
|
|
30
|
-
(distance: number, centered: boolean
|
|
30
|
+
(targetPlane: PlaneLike | ISceneObject, distance: number, centered: boolean): IGeometry;
|
|
31
31
|
}
|
|
32
32
|
declare const _default: HLineFunction;
|
|
33
33
|
export default _default;
|
|
@@ -9,16 +9,20 @@ import { resolvePlane } from "../../helpers/resolve.js";
|
|
|
9
9
|
function build(context) {
|
|
10
10
|
return function line() {
|
|
11
11
|
let planeObj = null;
|
|
12
|
-
let
|
|
13
|
-
// Detect plane as
|
|
14
|
-
if (
|
|
15
|
-
const
|
|
16
|
-
if (isPlaneLike(
|
|
17
|
-
|
|
18
|
-
|
|
12
|
+
let argOffset = 0;
|
|
13
|
+
// Detect plane as first argument (only valid outside a sketch)
|
|
14
|
+
if (arguments.length > 0) {
|
|
15
|
+
const firstArg = arguments[0];
|
|
16
|
+
if (isPlaneLike(firstArg) || (firstArg instanceof SceneObject && !isPoint2DLike(firstArg))) {
|
|
17
|
+
if (context.getActiveSketch() !== null) {
|
|
18
|
+
throw new Error("hLine(plane, ...) cannot be used inside a sketch. Use hLine(...) instead.");
|
|
19
|
+
}
|
|
20
|
+
planeObj = resolvePlane(firstArg, context);
|
|
21
|
+
argOffset = 1;
|
|
19
22
|
}
|
|
20
23
|
}
|
|
21
|
-
|
|
24
|
+
const argCount = arguments.length - argOffset;
|
|
25
|
+
if (argOffset === 0 && typeof arguments[0] !== 'number') {
|
|
22
26
|
// hline(start, distance) or hline(start, distance, centered)
|
|
23
27
|
const start = normalizePoint2D(arguments[0]);
|
|
24
28
|
const distance = arguments[1];
|
|
@@ -27,8 +31,8 @@ function build(context) {
|
|
|
27
31
|
context.addSceneObjects([new Move(start), hline]);
|
|
28
32
|
return hline;
|
|
29
33
|
}
|
|
30
|
-
const distance = arguments[
|
|
31
|
-
const centered = argCount >= 2 ? arguments[1] : false;
|
|
34
|
+
const distance = arguments[argOffset];
|
|
35
|
+
const centered = argCount >= 2 ? arguments[argOffset + 1] : false;
|
|
32
36
|
const hline = new HorizontalLine(distance, centered, planeObj);
|
|
33
37
|
context.addSceneObject(hline);
|
|
34
38
|
return hline;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as line } from './line.js';
|
|
2
2
|
export { default as circle } from './circle.js';
|
|
3
|
+
export { default as ellipse } from './ellipse.js';
|
|
3
4
|
export { default as rect } from './rect.js';
|
|
4
5
|
export { default as hMove } from './hmove.js';
|
|
5
6
|
export { default as vMove } from './vmove.js';
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { default as line } from './line.js';
|
|
2
2
|
export { default as circle } from './circle.js';
|
|
3
|
+
export { default as ellipse } from './ellipse.js';
|
|
3
4
|
export { default as rect } from './rect.js';
|
|
4
5
|
export { default as hMove } from './hmove.js';
|
|
5
6
|
export { default as vMove } from './vmove.js';
|
|
@@ -8,10 +8,10 @@ interface IntersectFunction {
|
|
|
8
8
|
(...sourceObjects: ISceneObject[]): IExtrudableGeometry;
|
|
9
9
|
/**
|
|
10
10
|
* Intersects 3D objects with a target plane, producing cross-section edges.
|
|
11
|
-
* @param sourceObjects - The 3D objects to intersect
|
|
12
11
|
* @param targetPlane - The plane to intersect with
|
|
12
|
+
* @param sourceObjects - The 3D objects to intersect
|
|
13
13
|
*/
|
|
14
|
-
(
|
|
14
|
+
(targetPlane: PlaneLike | ISceneObject, sourceObjects: ISceneObject[]): IExtrudableGeometry;
|
|
15
15
|
}
|
|
16
16
|
declare const _default: IntersectFunction;
|
|
17
17
|
export default _default;
|
|
@@ -3,10 +3,14 @@ import { resolvePlane } from "../../helpers/resolve.js";
|
|
|
3
3
|
import { registerBuilder } from "../../index.js";
|
|
4
4
|
function build(context) {
|
|
5
5
|
return function intersect(...args) {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
// Plane-first mode: intersect(plane, sources[])
|
|
7
|
+
if (args.length === 2 && Array.isArray(args[1])) {
|
|
8
|
+
if (context.getActiveSketch() !== null) {
|
|
9
|
+
throw new Error("intersect(plane, sources[]) cannot be used inside a sketch. Use intersect(...sources) instead.");
|
|
10
|
+
}
|
|
11
|
+
const planeObj = resolvePlane(args[0], context);
|
|
12
|
+
const sourceObjects = args[1];
|
|
8
13
|
context.addSceneObjects(sourceObjects);
|
|
9
|
-
const planeObj = resolvePlane(args[1], context);
|
|
10
14
|
const result = new Intersect(sourceObjects, planeObj);
|
|
11
15
|
context.addSceneObject(result);
|
|
12
16
|
return result;
|
|
@@ -15,10 +15,10 @@ interface LineFunction {
|
|
|
15
15
|
(start: Point2DLike, end: Point2DLike): IGeometry;
|
|
16
16
|
/**
|
|
17
17
|
* Draws a line to the given point on a specific plane.
|
|
18
|
-
* @param end - The end point
|
|
19
18
|
* @param targetPlane - The plane to draw on
|
|
19
|
+
* @param end - The end point
|
|
20
20
|
*/
|
|
21
|
-
(
|
|
21
|
+
(targetPlane: PlaneLike | ISceneObject, end: Point2DLike): IGeometry;
|
|
22
22
|
}
|
|
23
23
|
declare const _default: LineFunction;
|
|
24
24
|
export default _default;
|
package/lib/dist/core/2d/line.js
CHANGED
|
@@ -10,24 +10,28 @@ function build(context) {
|
|
|
10
10
|
return function line() {
|
|
11
11
|
let line;
|
|
12
12
|
let planeObj = null;
|
|
13
|
-
let
|
|
14
|
-
// Detect plane as
|
|
13
|
+
let argOffset = 0;
|
|
14
|
+
// Detect plane as first argument (only valid outside a sketch)
|
|
15
15
|
// Point2DLike is not plane-like so no conflict
|
|
16
|
-
if (
|
|
17
|
-
const
|
|
18
|
-
if (isPlaneLike(
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
if (arguments.length > 0) {
|
|
17
|
+
const firstArg = arguments[0];
|
|
18
|
+
if (isPlaneLike(firstArg) || (firstArg instanceof SceneObject && !isPoint2DLike(firstArg))) {
|
|
19
|
+
if (context.getActiveSketch() !== null) {
|
|
20
|
+
throw new Error("line(plane, ...) cannot be used inside a sketch. Use line(...) instead.");
|
|
21
|
+
}
|
|
22
|
+
planeObj = resolvePlane(firstArg, context);
|
|
23
|
+
argOffset = 1;
|
|
21
24
|
}
|
|
22
25
|
}
|
|
26
|
+
const argCount = arguments.length - argOffset;
|
|
23
27
|
if (argCount === 1) {
|
|
24
|
-
const vertex = normalizePoint2D(arguments[
|
|
28
|
+
const vertex = normalizePoint2D(arguments[argOffset]);
|
|
25
29
|
line = new LineTo(vertex, planeObj);
|
|
26
30
|
context.addSceneObject(line);
|
|
27
31
|
}
|
|
28
32
|
else if (argCount === 2) {
|
|
29
|
-
const start = normalizePoint2D(arguments[
|
|
30
|
-
const end = normalizePoint2D(arguments[1]);
|
|
33
|
+
const start = normalizePoint2D(arguments[argOffset]);
|
|
34
|
+
const end = normalizePoint2D(arguments[argOffset + 1]);
|
|
31
35
|
line = new LineTo(end, planeObj);
|
|
32
36
|
context.addSceneObjects([new Move(start), line]);
|
|
33
37
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { PlaneLike } from "../../math/plane.js";
|
|
2
|
-
import {
|
|
2
|
+
import { IOffset, ISceneObject } from "../interfaces.js";
|
|
3
3
|
import { Extrudable } from "../../helpers/types.js";
|
|
4
4
|
interface OffsetFunction {
|
|
5
5
|
/**
|
|
@@ -7,15 +7,15 @@ interface OffsetFunction {
|
|
|
7
7
|
* @param distance - The offset distance (defaults to 1)
|
|
8
8
|
* @param removeOriginal - Whether to remove the original geometry
|
|
9
9
|
*/
|
|
10
|
-
(distance?: number, removeOriginal?: boolean):
|
|
10
|
+
(distance?: number, removeOriginal?: boolean): IOffset;
|
|
11
11
|
/**
|
|
12
12
|
* Offsets source geometries onto a target plane.
|
|
13
|
+
* @param targetPlane - The plane to offset onto
|
|
13
14
|
* @param distance - The offset distance
|
|
14
15
|
* @param removeOriginal - Whether to remove the original geometry
|
|
15
|
-
* @param targetPlane - The plane to offset onto
|
|
16
16
|
* @param sourceGeometries - The geometries to offset
|
|
17
17
|
*/
|
|
18
|
-
(distance: number, removeOriginal: boolean,
|
|
18
|
+
(targetPlane: PlaneLike | ISceneObject, distance: number, removeOriginal: boolean, ...sourceGeometries: Extrudable[]): IOffset;
|
|
19
19
|
}
|
|
20
20
|
declare const _default: OffsetFunction;
|
|
21
21
|
export default _default;
|
|
@@ -3,11 +3,15 @@ import { registerBuilder } from "../../index.js";
|
|
|
3
3
|
import { resolvePlane } from "../../helpers/resolve.js";
|
|
4
4
|
function build(context) {
|
|
5
5
|
return function offset(...args) {
|
|
6
|
-
//
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
// Plane-first mode: offset(plane, distance, removeOriginal, ...sourceGeometries)
|
|
7
|
+
// Detected when first arg is not a number/undefined.
|
|
8
|
+
if (args.length > 0 && args[0] !== undefined && typeof args[0] !== 'number' && typeof args[0] !== 'boolean') {
|
|
9
|
+
if (context.getActiveSketch() !== null) {
|
|
10
|
+
throw new Error("offset(plane, ...) cannot be used inside a sketch. Use offset(...) instead.");
|
|
11
|
+
}
|
|
12
|
+
const planeObj = resolvePlane(args[0], context);
|
|
13
|
+
const distance = args[1] ?? 1;
|
|
14
|
+
const removeOriginal = args[2] ?? false;
|
|
11
15
|
const sourceObjects = args.slice(3);
|
|
12
16
|
const off = new Offset(distance, removeOriginal, sourceObjects, planeObj);
|
|
13
17
|
context.addSceneObject(off);
|
|
@@ -20,19 +20,19 @@ interface PolygonFunction {
|
|
|
20
20
|
(center: Point2DLike, numberOfSides: number, diameter: number, mode?: PolygonMode): IPolygon;
|
|
21
21
|
/**
|
|
22
22
|
* Draws a regular polygon on a specific plane.
|
|
23
|
+
* @param targetPlane - The plane to draw on
|
|
23
24
|
* @param numberOfSides - The number of sides
|
|
24
25
|
* @param diameter - The circumscribed or inscribed diameter
|
|
25
|
-
* @param targetPlane - The plane to draw on
|
|
26
26
|
*/
|
|
27
|
-
(
|
|
27
|
+
(targetPlane: PlaneLike | ISceneObject, numberOfSides: number, diameter: number): IPolygon;
|
|
28
28
|
/**
|
|
29
29
|
* Draws a regular polygon with a given mode on a specific plane.
|
|
30
|
+
* @param targetPlane - The plane to draw on
|
|
30
31
|
* @param numberOfSides - The number of sides
|
|
31
32
|
* @param diameter - The circumscribed or inscribed diameter
|
|
32
33
|
* @param mode - `'inscribed'` or `'circumscribed'`
|
|
33
|
-
* @param targetPlane - The plane to draw on
|
|
34
34
|
*/
|
|
35
|
-
(numberOfSides: number, diameter: number, mode: PolygonMode
|
|
35
|
+
(targetPlane: PlaneLike | ISceneObject, numberOfSides: number, diameter: number, mode: PolygonMode): IPolygon;
|
|
36
36
|
}
|
|
37
37
|
declare const _default: PolygonFunction;
|
|
38
38
|
export default _default;
|
|
@@ -14,46 +14,50 @@ function build(context) {
|
|
|
14
14
|
let center;
|
|
15
15
|
let poly;
|
|
16
16
|
let planeObj = null;
|
|
17
|
-
let
|
|
18
|
-
// Detect plane as
|
|
17
|
+
let argOffset = 0;
|
|
18
|
+
// Detect plane as first argument (only valid outside a sketch)
|
|
19
19
|
// PolygonMode strings ('inscribed'/'circumscribed') don't overlap with StandardPlane strings
|
|
20
|
-
if (
|
|
21
|
-
const
|
|
22
|
-
if (isPlaneLike(
|
|
23
|
-
|
|
20
|
+
if (arguments.length > 0) {
|
|
21
|
+
const firstArg = arguments[0];
|
|
22
|
+
if (isPlaneLike(firstArg) || (firstArg instanceof SceneObject && !isPoint2DLike(firstArg))) {
|
|
23
|
+
if (context.getActiveSketch() !== null) {
|
|
24
|
+
throw new Error("polygon(plane, ...) cannot be used inside a sketch. Use polygon(...) instead.");
|
|
25
|
+
}
|
|
26
|
+
planeObj = resolvePlane(firstArg, context);
|
|
24
27
|
context.addSceneObject(planeObj);
|
|
25
|
-
|
|
28
|
+
argOffset = 1;
|
|
26
29
|
}
|
|
27
30
|
}
|
|
31
|
+
const argCount = arguments.length - argOffset;
|
|
28
32
|
if (argCount === 2) {
|
|
29
|
-
numberOfSides = arguments[
|
|
30
|
-
diameter = arguments[1];
|
|
33
|
+
numberOfSides = arguments[argOffset];
|
|
34
|
+
diameter = arguments[argOffset + 1];
|
|
31
35
|
mode = 'inscribed';
|
|
32
36
|
poly = new Polygon(numberOfSides, diameter, mode, planeObj);
|
|
33
37
|
context.addSceneObject(poly);
|
|
34
38
|
}
|
|
35
39
|
else if (argCount === 3) {
|
|
36
|
-
if (typeof arguments[
|
|
37
|
-
numberOfSides = arguments[
|
|
38
|
-
diameter = arguments[1];
|
|
39
|
-
mode = arguments[2];
|
|
40
|
+
if (typeof arguments[argOffset] === 'number') {
|
|
41
|
+
numberOfSides = arguments[argOffset];
|
|
42
|
+
diameter = arguments[argOffset + 1];
|
|
43
|
+
mode = arguments[argOffset + 2];
|
|
40
44
|
poly = new Polygon(numberOfSides, diameter, mode, planeObj);
|
|
41
45
|
context.addSceneObject(poly);
|
|
42
46
|
}
|
|
43
47
|
else {
|
|
44
|
-
center = normalizePoint2D(arguments[
|
|
45
|
-
numberOfSides = arguments[1];
|
|
46
|
-
diameter = arguments[2];
|
|
48
|
+
center = normalizePoint2D(arguments[argOffset]);
|
|
49
|
+
numberOfSides = arguments[argOffset + 1];
|
|
50
|
+
diameter = arguments[argOffset + 2];
|
|
47
51
|
mode = 'inscribed';
|
|
48
52
|
poly = new Polygon(numberOfSides, diameter, mode, planeObj);
|
|
49
53
|
context.addSceneObjects([new Move(center), poly]);
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
else if (argCount === 4) {
|
|
53
|
-
center = normalizePoint2D(arguments[
|
|
54
|
-
numberOfSides = arguments[1];
|
|
55
|
-
diameter = arguments[2];
|
|
56
|
-
mode = arguments[3];
|
|
57
|
+
center = normalizePoint2D(arguments[argOffset]);
|
|
58
|
+
numberOfSides = arguments[argOffset + 1];
|
|
59
|
+
diameter = arguments[argOffset + 2];
|
|
60
|
+
mode = arguments[argOffset + 3];
|
|
57
61
|
poly = new Polygon(numberOfSides, diameter, mode, planeObj);
|
|
58
62
|
context.addSceneObjects([new Move(center), poly]);
|
|
59
63
|
}
|
|
@@ -8,10 +8,10 @@ interface ProjectFunction {
|
|
|
8
8
|
(...sourceObjects: ISceneObject[]): IExtrudableGeometry;
|
|
9
9
|
/**
|
|
10
10
|
* Projects 3D objects onto a target plane.
|
|
11
|
-
* @param sourceObjects - The 3D objects to project
|
|
12
11
|
* @param targetPlane - The plane to project onto
|
|
12
|
+
* @param sourceObjects - The 3D objects to project
|
|
13
13
|
*/
|
|
14
|
-
(
|
|
14
|
+
(targetPlane: PlaneLike | ISceneObject, sourceObjects: ISceneObject[]): IExtrudableGeometry;
|
|
15
15
|
}
|
|
16
16
|
declare const _default: ProjectFunction;
|
|
17
17
|
export default _default;
|
|
@@ -3,10 +3,14 @@ import { resolvePlane } from "../../helpers/resolve.js";
|
|
|
3
3
|
import { registerBuilder } from "../../index.js";
|
|
4
4
|
function build(context) {
|
|
5
5
|
return function project(...args) {
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
// Plane-first mode: project(plane, sources[])
|
|
7
|
+
if (args.length === 2 && Array.isArray(args[1])) {
|
|
8
|
+
if (context.getActiveSketch() !== null) {
|
|
9
|
+
throw new Error("project(plane, sources[]) cannot be used inside a sketch. Use project(...sources) instead.");
|
|
10
|
+
}
|
|
11
|
+
const planeObj = resolvePlane(args[0], context);
|
|
12
|
+
const sourceObjects = args[1];
|
|
8
13
|
context.addSceneObjects(sourceObjects);
|
|
9
|
-
const planeObj = resolvePlane(args[1], context);
|
|
10
14
|
const projection = new Projection(sourceObjects, planeObj);
|
|
11
15
|
context.addSceneObject(projection);
|
|
12
16
|
return projection;
|
|
@@ -17,11 +17,11 @@ interface RectFunction {
|
|
|
17
17
|
(start: Point2DLike, width: number, height?: number): IRect;
|
|
18
18
|
/**
|
|
19
19
|
* Draws a rectangle with given dimensions on a specific plane.
|
|
20
|
+
* @param targetPlane - The plane to draw on
|
|
20
21
|
* @param width - The rectangle width
|
|
21
22
|
* @param height - The rectangle height
|
|
22
|
-
* @param targetPlane - The plane to draw on
|
|
23
23
|
*/
|
|
24
|
-
(
|
|
24
|
+
(targetPlane: PlaneLike | ISceneObject, width: number, height: number): IRect;
|
|
25
25
|
}
|
|
26
26
|
declare const _default: RectFunction;
|
|
27
27
|
export default _default;
|
package/lib/dist/core/2d/rect.js
CHANGED
|
@@ -8,7 +8,22 @@ import { SceneObject } from "../../common/scene-object.js";
|
|
|
8
8
|
import { resolvePlane } from "../../helpers/resolve.js";
|
|
9
9
|
function build(context) {
|
|
10
10
|
return function cRect() {
|
|
11
|
-
|
|
11
|
+
// Detect plane as first argument (only valid outside a sketch)
|
|
12
|
+
if (arguments.length > 0) {
|
|
13
|
+
const firstArg = arguments[0];
|
|
14
|
+
if (isPlaneLike(firstArg) || (firstArg instanceof SceneObject && !isPoint2DLike(firstArg))) {
|
|
15
|
+
if (context.getActiveSketch() !== null) {
|
|
16
|
+
throw new Error("rect(plane, ...) cannot be used inside a sketch. Use rect(...) instead.");
|
|
17
|
+
}
|
|
18
|
+
const planeObj = resolvePlane(firstArg, context);
|
|
19
|
+
const width = arguments[1];
|
|
20
|
+
const height = arguments[2];
|
|
21
|
+
const rect = new Rect(width, height, planeObj);
|
|
22
|
+
context.addSceneObject(rect);
|
|
23
|
+
return rect;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
const argCount = arguments.length;
|
|
12
27
|
if (argCount === 1) {
|
|
13
28
|
const width = arguments[0];
|
|
14
29
|
const rect = new Rect(width, width);
|
|
@@ -32,26 +47,12 @@ function build(context) {
|
|
|
32
47
|
}
|
|
33
48
|
}
|
|
34
49
|
else if (argCount === 3) {
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
planeObj = resolvePlane(lastArg, context);
|
|
42
|
-
}
|
|
43
|
-
const rect = new Rect(width, height, planeObj);
|
|
44
|
-
context.addSceneObject(rect);
|
|
45
|
-
return rect;
|
|
46
|
-
}
|
|
47
|
-
else {
|
|
48
|
-
const start = normalizePoint2D(arguments[0]);
|
|
49
|
-
const width = arguments[1];
|
|
50
|
-
const height = arguments[2];
|
|
51
|
-
const rect = new Rect(width, height);
|
|
52
|
-
context.addSceneObjects([new Move(start), rect]);
|
|
53
|
-
return rect;
|
|
54
|
-
}
|
|
50
|
+
const start = normalizePoint2D(arguments[0]);
|
|
51
|
+
const width = arguments[1];
|
|
52
|
+
const height = arguments[2];
|
|
53
|
+
const rect = new Rect(width, height);
|
|
54
|
+
context.addSceneObjects([new Move(start), rect]);
|
|
55
|
+
return rect;
|
|
55
56
|
}
|
|
56
57
|
};
|
|
57
58
|
}
|
|
@@ -10,11 +10,11 @@ interface SlotFunction {
|
|
|
10
10
|
(distance: number, radius: number): ISlot;
|
|
11
11
|
/**
|
|
12
12
|
* Draws a slot on a specific plane.
|
|
13
|
+
* @param targetPlane - The plane to draw on
|
|
13
14
|
* @param distance - The slot length
|
|
14
15
|
* @param radius - The end cap radius
|
|
15
|
-
* @param targetPlane - The plane to draw on
|
|
16
16
|
*/
|
|
17
|
-
(
|
|
17
|
+
(targetPlane: PlaneLike | ISceneObject, distance: number, radius: number): ISlot;
|
|
18
18
|
/**
|
|
19
19
|
* Draws a slot from a start point with the given length and end radius.
|
|
20
20
|
* @param start - The start point
|
|
@@ -31,19 +31,19 @@ interface SlotFunction {
|
|
|
31
31
|
(geometry: ISceneObject, radius: number, deleteSource?: boolean): ISlot;
|
|
32
32
|
/**
|
|
33
33
|
* Creates a slot from a geometry edge on a specific plane.
|
|
34
|
+
* @param targetPlane - The plane to draw on
|
|
34
35
|
* @param geometry - The source geometry edge
|
|
35
36
|
* @param radius - The end cap radius
|
|
36
|
-
* @param targetPlane - The plane to draw on
|
|
37
37
|
*/
|
|
38
|
-
(
|
|
38
|
+
(targetPlane: PlaneLike | ISceneObject, geometry: ISceneObject, radius: number): ISlot;
|
|
39
39
|
/**
|
|
40
40
|
* Creates a slot from a geometry edge, optionally keeping the source, on a specific plane.
|
|
41
|
+
* @param targetPlane - The plane to draw on
|
|
41
42
|
* @param geometry - The source geometry edge
|
|
42
43
|
* @param radius - The end cap radius
|
|
43
44
|
* @param deleteSource - Whether to delete the source geometry
|
|
44
|
-
* @param targetPlane - The plane to draw on
|
|
45
45
|
*/
|
|
46
|
-
(geometry: ISceneObject, radius: number, deleteSource: boolean
|
|
46
|
+
(targetPlane: PlaneLike | ISceneObject, geometry: ISceneObject, radius: number, deleteSource: boolean): ISlot;
|
|
47
47
|
}
|
|
48
48
|
declare const _default: SlotFunction;
|
|
49
49
|
export default _default;
|