fluidcad 0.0.7 → 0.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/bin/fluidcad.js +16 -0
  2. package/lib/dist/core/2d/arc.d.ts +15 -0
  3. package/lib/dist/core/2d/arc.js +10 -0
  4. package/lib/dist/core/2d/index.d.ts +0 -1
  5. package/lib/dist/core/2d/index.js +0 -1
  6. package/lib/dist/core/2d/tarc.d.ts +26 -2
  7. package/lib/dist/core/2d/tcircle.d.ts +26 -2
  8. package/lib/dist/core/2d/tline.d.ts +26 -6
  9. package/lib/dist/core/axis.d.ts +11 -4
  10. package/lib/dist/core/chamfer.d.ts +6 -6
  11. package/lib/dist/core/chamfer.js +12 -9
  12. package/lib/dist/core/cut.d.ts +27 -6
  13. package/lib/dist/core/extrude.d.ts +15 -3
  14. package/lib/dist/core/plane.d.ts +11 -4
  15. package/lib/dist/core/repeat.d.ts +16 -1
  16. package/lib/dist/core/repeat.js +39 -3
  17. package/lib/dist/core/sketch.d.ts +9 -3
  18. package/lib/dist/core/subtract.d.ts +5 -4
  19. package/lib/dist/core/subtract.js +9 -2
  20. package/lib/dist/features/2d/arc-three-points.d.ts +19 -0
  21. package/lib/dist/features/2d/arc-three-points.js +75 -0
  22. package/lib/dist/features/2d/constraints/geometry-qualifier.d.ts +16 -0
  23. package/lib/dist/features/2d/constraints/geometry-qualifier.js +16 -0
  24. package/lib/dist/features/2d/offset.js +10 -0
  25. package/lib/dist/features/2d/projection.js +9 -0
  26. package/lib/dist/features/2d/rect.js +19 -16
  27. package/lib/dist/features/chamfer.d.ts +4 -4
  28. package/lib/dist/features/chamfer.js +33 -15
  29. package/lib/dist/features/common2d.js +26 -8
  30. package/lib/dist/features/fuse2d.js +24 -6
  31. package/lib/dist/features/repeat-matrix.d.ts +14 -0
  32. package/lib/dist/features/repeat-matrix.js +41 -0
  33. package/lib/dist/features/select.d.ts +1 -0
  34. package/lib/dist/features/select.js +19 -0
  35. package/lib/dist/features/subtract2d.d.ts +14 -0
  36. package/lib/dist/features/subtract2d.js +80 -0
  37. package/lib/dist/filters/edge/belongs-to-face.d.ts +22 -0
  38. package/lib/dist/filters/edge/belongs-to-face.js +67 -0
  39. package/lib/dist/filters/edge/belongs-to-object.d.ts +18 -0
  40. package/lib/dist/filters/edge/belongs-to-object.js +37 -0
  41. package/lib/dist/filters/edge/edge-filter.d.ts +88 -3
  42. package/lib/dist/filters/edge/edge-filter.js +101 -4
  43. package/lib/dist/filters/edge/line-filter.d.ts +4 -1
  44. package/lib/dist/filters/edge/line-filter.js +14 -7
  45. package/lib/dist/filters/face/edge-count.d.ts +17 -0
  46. package/lib/dist/filters/face/edge-count.js +33 -0
  47. package/lib/dist/filters/face/face-filter.d.ts +93 -0
  48. package/lib/dist/filters/face/face-filter.js +112 -0
  49. package/lib/dist/filters/face/has-edge.d.ts +18 -0
  50. package/lib/dist/filters/face/has-edge.js +59 -0
  51. package/lib/dist/filters/face/has-object.d.ts +18 -0
  52. package/lib/dist/filters/face/has-object.js +37 -0
  53. package/lib/dist/filters/index.d.ts +6 -0
  54. package/lib/dist/filters/index.js +6 -0
  55. package/lib/dist/oc/edge-query.d.ts +2 -2
  56. package/lib/dist/oc/edge-query.js +13 -4
  57. package/lib/dist/tests/features/2d/arc.test.js +15 -1
  58. package/lib/dist/tests/features/select.test.js +249 -0
  59. package/lib/dist/tests/features/subtract2d.test.d.ts +1 -0
  60. package/lib/dist/tests/features/subtract2d.test.js +63 -0
  61. package/lib/dist/tsconfig.tsbuildinfo +1 -1
  62. package/package.json +3 -2
  63. package/lib/dist/core/2d/wire.d.ts +0 -11
  64. package/lib/dist/core/2d/wire.js +0 -29
  65. package/lib/dist/features/2d/wire.d.ts +0 -12
  66. package/lib/dist/features/2d/wire.js +0 -76
package/bin/fluidcad.js CHANGED
@@ -28,6 +28,22 @@ if (positionals[0] === 'init') {
28
28
 
29
29
  writeFileSync(initPath, `import { init } from 'fluidcad'\n\nexport default init()\n`);
30
30
 
31
+ const testPath = resolve(cwd, 'test.fluid.js');
32
+ if (!existsSync(testPath)) {
33
+ writeFileSync(testPath, `import { extrude, fillet, rect, shell, sketch } from "fluidcad/core";
34
+
35
+ sketch("xy", () => {
36
+ rect(100, 50).radius(10).center();
37
+ });
38
+
39
+ const e = extrude(30);
40
+
41
+ fillet(4, e.startEdges());
42
+
43
+ shell(-2, e.endFaces());
44
+ `);
45
+ }
46
+
31
47
  const jsconfigPath = resolve(cwd, 'jsconfig.json');
32
48
  if (!existsSync(jsconfigPath)) {
33
49
  writeFileSync(jsconfigPath, JSON.stringify({
@@ -23,6 +23,13 @@ interface ArcFunction {
23
23
  * @param centered - Whether to center the arc on the current position
24
24
  */
25
25
  (radius: number, startAngle?: number, endAngle?: number, centered?: boolean): IGeometry;
26
+ /**
27
+ * Draws an arc from a start point to an end point around a center point.
28
+ * @param startPoint - The start point of the arc
29
+ * @param endPoint - The end point of the arc
30
+ * @param center - The center point of the arc
31
+ */
32
+ (startPoint: Point2DLike, endPoint: Point2DLike, center: Point2DLike): IGeometry;
26
33
  /**
27
34
  * Draws an arc to an end point on a specific plane.
28
35
  * @param endPoint - The end point of the arc
@@ -51,6 +58,14 @@ interface ArcFunction {
51
58
  * @param targetPlane - The plane to draw on
52
59
  */
53
60
  (startPoint: Point2DLike, endPoint: Point2DLike, radius: number, targetPlane: PlaneLike | ISceneObject): IGeometry;
61
+ /**
62
+ * Draws an arc from a start point to an end point around a center point on a specific plane.
63
+ * @param startPoint - The start point of the arc
64
+ * @param endPoint - The end point of the arc
65
+ * @param center - The center point of the arc
66
+ * @param targetPlane - The plane to draw on
67
+ */
68
+ (startPoint: Point2DLike, endPoint: Point2DLike, center: Point2DLike, targetPlane: PlaneLike | ISceneObject): IGeometry;
54
69
  /**
55
70
  * Draws an arc by radius on a specific plane.
56
71
  * @param radius - The arc radius
@@ -1,6 +1,7 @@
1
1
  import { isPoint2DLike } from "../../math/point.js";
2
2
  import { ArcFromTwoAngles } from "../../features/2d/arc.js";
3
3
  import { ArcToPoint } from "../../features/2d/arc-to-point.js";
4
+ import { ArcThreePoints } from "../../features/2d/arc-three-points.js";
4
5
  import { Move } from "../../features/2d/move.js";
5
6
  import { normalizePoint2D } from "../../helpers/normalize.js";
6
7
  import { registerBuilder } from "../../index.js";
@@ -19,6 +20,15 @@ function build(context) {
19
20
  argCount--;
20
21
  }
21
22
  }
23
+ // (startPoint, endPoint, center) — three Point2DLike args
24
+ if (argCount >= 3 && isPoint2DLike(arguments[0]) && isPoint2DLike(arguments[1]) && isPoint2DLike(arguments[2])) {
25
+ const start = normalizePoint2D(arguments[0]);
26
+ const end = normalizePoint2D(arguments[1]);
27
+ const center = normalizePoint2D(arguments[2]);
28
+ const arcObj = new ArcThreePoints(start, end, center, planeObj);
29
+ context.addSceneObjects([new Move(start), arcObj]);
30
+ return arcObj;
31
+ }
22
32
  // (startPoint, endPoint, radius?) — two Point2DLike args
23
33
  if (argCount >= 2 && isPoint2DLike(arguments[0]) && isPoint2DLike(arguments[1])) {
24
34
  const start = normalizePoint2D(arguments[0]);
@@ -13,7 +13,6 @@ export { default as arc } from './arc.js';
13
13
  export { default as move } from './move.js';
14
14
  export { default as pMove } from './pmove.js';
15
15
  export { default as aLine } from './aline.js';
16
- export { default as wire } from './wire.js';
17
16
  export { default as slot } from './slot.js';
18
17
  export { default as connect } from './connect.js';
19
18
  export { default as polygon } from './polygon.js';
@@ -13,7 +13,6 @@ export { default as arc } from './arc.js';
13
13
  export { default as move } from './move.js';
14
14
  export { default as pMove } from './pmove.js';
15
15
  export { default as aLine } from './aline.js';
16
- export { default as wire } from './wire.js';
17
16
  export { default as slot } from './slot.js';
18
17
  export { default as connect } from './connect.js';
19
18
  export { default as polygon } from './polygon.js';
@@ -34,11 +34,35 @@ interface TArcFunction {
34
34
  */
35
35
  (startPoint: Point2DLike, endPoint: Point2DLike, tangent: Point2DLike): IGeometry;
36
36
  /**
37
- * Draws a tangent arc between two objects with a given radius.
37
+ * Draws a tangent arc between two geometry objects.
38
+ * @param c1 - The first geometry object
39
+ * @param c2 - The second geometry object
40
+ * @param radius - The arc radius
41
+ * @param mustTouch - Whether the arc must touch both objects
42
+ */
43
+ (c1: ISceneObject, c2: ISceneObject, radius: number, mustTouch?: boolean): ITangentArcTwoObjects;
44
+ /**
45
+ * Draws a tangent arc between two qualified geometry objects.
46
+ * @param c1 - The first qualified geometry object (e.g., `outside(circle1)`)
47
+ * @param c2 - The second qualified geometry object
48
+ * @param radius - The arc radius
49
+ * @param mustTouch - Whether the arc must touch both objects
50
+ */
51
+ (c1: QualifiedSceneObject, c2: QualifiedSceneObject, radius: number, mustTouch?: boolean): ITangentArcTwoObjects;
52
+ /**
53
+ * Draws a tangent arc between two points.
54
+ * @param c1 - The first point
55
+ * @param c2 - The second point
56
+ * @param radius - The arc radius
57
+ * @param mustTouch - Whether the arc must touch both points
58
+ */
59
+ (c1: Point2DLike, c2: Point2DLike, radius: number, mustTouch?: boolean): ITangentArcTwoObjects;
60
+ /**
61
+ * Draws a tangent arc using a mix of geometry objects, qualified objects, or points as constraints.
38
62
  * @param c1 - The first constraint object or point
39
63
  * @param c2 - The second constraint object or point
40
64
  * @param radius - The arc radius
41
- * @param mustTouch - Whether the arc must touch both objects
65
+ * @param mustTouch - Whether the arc must touch both constraints
42
66
  */
43
67
  (c1: ISceneObject | QualifiedSceneObject | Point2DLike, c2: ISceneObject | QualifiedSceneObject | Point2DLike, radius: number, mustTouch?: boolean): ITangentArcTwoObjects;
44
68
  }
@@ -3,11 +3,35 @@ import { Point2DLike } from "../../math/point.js";
3
3
  import { IGeometry, ISceneObject } from "../interfaces.js";
4
4
  interface TCircleFunction {
5
5
  /**
6
- * Draws a circle tangent to two objects with the given diameter.
6
+ * Draws a circle tangent to two geometry objects.
7
+ * @param c1 - The first geometry object
8
+ * @param c2 - The second geometry object
9
+ * @param diameter - The circle diameter
10
+ * @param mustTouch - Whether the circle must touch both objects
11
+ */
12
+ (c1: ISceneObject, c2: ISceneObject, diameter: number, mustTouch?: boolean): IGeometry;
13
+ /**
14
+ * Draws a circle tangent to two qualified geometry objects.
15
+ * @param c1 - The first qualified geometry object (e.g., `outside(circle1)`)
16
+ * @param c2 - The second qualified geometry object
17
+ * @param diameter - The circle diameter
18
+ * @param mustTouch - Whether the circle must touch both objects
19
+ */
20
+ (c1: QualifiedSceneObject, c2: QualifiedSceneObject, diameter: number, mustTouch?: boolean): IGeometry;
21
+ /**
22
+ * Draws a circle passing through two points.
23
+ * @param c1 - The first point
24
+ * @param c2 - The second point
25
+ * @param diameter - The circle diameter
26
+ * @param mustTouch - Whether the circle must touch both points
27
+ */
28
+ (c1: Point2DLike, c2: Point2DLike, diameter: number, mustTouch?: boolean): IGeometry;
29
+ /**
30
+ * Draws a tangent circle using a mix of geometry objects, qualified objects, or points as constraints.
7
31
  * @param c1 - The first constraint object or point
8
32
  * @param c2 - The second constraint object or point
9
33
  * @param diameter - The circle diameter
10
- * @param mustTouch - Whether the circle must touch both objects
34
+ * @param mustTouch - Whether the circle must touch both constraints
11
35
  */
12
36
  (c1: ISceneObject | QualifiedSceneObject | Point2DLike, c2: ISceneObject | QualifiedSceneObject | Point2DLike, diameter: number, mustTouch?: boolean): IGeometry;
13
37
  }
@@ -7,18 +7,38 @@ interface TLineFunction {
7
7
  */
8
8
  (distance: number): IGeometry;
9
9
  /**
10
- * Draws a line tangent to two objects.
11
- * @param c1 - The first constraint object
12
- * @param c2 - The second constraint object
10
+ * Draws a line tangent to two geometry objects.
11
+ * @param c1 - The first geometry object
12
+ * @param c2 - The second geometry object
13
+ * @param mustTouch - Whether the line must touch both objects
14
+ */
15
+ (c1: ISceneObject, c2: ISceneObject, mustTouch?: boolean): ITwoObjectsTangentLine;
16
+ /**
17
+ * Draws a line tangent to two qualified geometry objects.
18
+ * @param c1 - The first qualified geometry object (e.g., `outside(circle1)`)
19
+ * @param c2 - The second qualified geometry object
20
+ * @param mustTouch - Whether the line must touch both objects
21
+ */
22
+ (c1: QualifiedSceneObject, c2: QualifiedSceneObject, mustTouch?: boolean): ITwoObjectsTangentLine;
23
+ /**
24
+ * Draws a line tangent to a combination of geometry and qualified geometry objects.
25
+ * @param c1 - The first constraint (geometry or qualified geometry)
26
+ * @param c2 - The second constraint (geometry or qualified geometry)
13
27
  * @param mustTouch - Whether the line must touch both objects
14
28
  */
15
29
  (c1: ISceneObject | QualifiedSceneObject, c2: ISceneObject | QualifiedSceneObject, mustTouch?: boolean): ITwoObjectsTangentLine;
16
30
  /**
17
- * Draws a line tangent to one object.
18
- * @param c1 - The constraint object
31
+ * Draws a line tangent to one geometry object.
32
+ * @param c1 - The geometry object to be tangent to
33
+ * @param mustTouch - Whether the line must touch the object
34
+ */
35
+ (c1: ISceneObject, mustTouch?: boolean): IGeometry;
36
+ /**
37
+ * Draws a line tangent to a qualified geometry object.
38
+ * @param c1 - The qualified geometry object (e.g., `outside(circle1)`)
19
39
  * @param mustTouch - Whether the line must touch the object
20
40
  */
21
- (c1: ISceneObject | QualifiedSceneObject, mustTouch?: boolean): IGeometry;
41
+ (c1: QualifiedSceneObject, mustTouch?: boolean): IGeometry;
22
42
  }
23
43
  declare const _default: TLineFunction;
24
44
  export default _default;
@@ -30,12 +30,19 @@ interface AxisFunction {
30
30
  */
31
31
  (axis: IAxis, options: AxisTransformOptions): IAxis;
32
32
  /**
33
- * Creates an axis midway between two axes.
34
- * @param a1 - The first axis
35
- * @param a2 - The second axis
33
+ * Creates an axis midway between two direction vectors.
34
+ * @param a1 - The first direction vector or standard axis
35
+ * @param a2 - The second direction vector or standard axis
36
36
  * @param options - Transform options (offset, flip, etc.)
37
37
  */
38
- (a1: AxisLike | IAxis, a2: AxisLike | IAxis, options?: AxisTransformOptions): IAxis;
38
+ (a1: AxisLike, a2: AxisLike, options?: AxisTransformOptions): IAxis;
39
+ /**
40
+ * Creates an axis midway between two existing Axis objects.
41
+ * @param a1 - The first Axis object
42
+ * @param a2 - The second Axis object
43
+ * @param options - Transform options (offset, flip, etc.)
44
+ */
45
+ (a1: IAxis, a2: IAxis, options?: AxisTransformOptions): IAxis;
39
46
  }
40
47
  declare const _default: AxisFunction;
41
48
  export default _default;
@@ -6,11 +6,11 @@ interface ChamferFunction {
6
6
  */
7
7
  (distance?: number): ISceneObject;
8
8
  /**
9
- * Chamfers the given edge selection with the given distance.
9
+ * Chamfers the given edge selections with the given distance.
10
10
  * @param distance - The chamfer distance
11
- * @param selection - The edge selection to chamfer
11
+ * @param sceneObjects - The edge selections to chamfer
12
12
  */
13
- (distance: number, selection: ISceneObject): ISceneObject;
13
+ (distance: number, ...sceneObjects: ISceneObject[]): ISceneObject;
14
14
  /**
15
15
  * Chamfers selected edges with two distances or a distance and angle.
16
16
  * @param distance - The first chamfer distance
@@ -19,13 +19,13 @@ interface ChamferFunction {
19
19
  */
20
20
  (distance: number, distance2: number, isAngle?: boolean): ISceneObject;
21
21
  /**
22
- * Chamfers the given edge selection with two distances or a distance and angle.
22
+ * Chamfers the given edge selections with two distances or a distance and angle.
23
23
  * @param distance - The first chamfer distance
24
24
  * @param distance2 - The second distance, or angle if `isAngle` is true
25
25
  * @param isAngle - Whether `distance2` is an angle
26
- * @param selection - The edge selection to chamfer
26
+ * @param sceneObjects - The edge selections to chamfer
27
27
  */
28
- (distance: number, distance2: number, isAngle: boolean, selection: ISceneObject): ISceneObject;
28
+ (distance: number, distance2: number, isAngle: boolean, ...sceneObjects: ISceneObject[]): ISceneObject;
29
29
  }
30
30
  declare const _default: ChamferFunction;
31
31
  export default _default;
@@ -4,14 +4,6 @@ import { registerBuilder } from "../index.js";
4
4
  function build(context) {
5
5
  return function chamfer() {
6
6
  const args = Array.from(arguments);
7
- let selection;
8
- if (args.length > 0 && args[args.length - 1] instanceof SceneObject) {
9
- selection = args.pop();
10
- }
11
- else {
12
- selection = context.getLastSelection() || undefined;
13
- }
14
- context.addSceneObject(selection); // Ensure lazy selections are added to the scene
15
7
  let distance = 1;
16
8
  let distance2 = undefined;
17
9
  let isAngle = false;
@@ -24,7 +16,18 @@ function build(context) {
24
16
  if (args.length >= 3 && typeof args[2] === 'boolean') {
25
17
  isAngle = args[2];
26
18
  }
27
- const chamfer = new Chamfer(distance, distance2, isAngle, selection);
19
+ const selections = args
20
+ .filter(a => a instanceof SceneObject);
21
+ if (selections.length === 0) {
22
+ const lastSelection = context.getLastSelection() || undefined;
23
+ if (lastSelection) {
24
+ selections.push(lastSelection);
25
+ }
26
+ }
27
+ for (const selection of selections) {
28
+ context.addSceneObject(selection);
29
+ }
30
+ const chamfer = new Chamfer(distance, distance2, isAngle, ...selections);
28
31
  context.addSceneObject(chamfer);
29
32
  return chamfer;
30
33
  };
@@ -30,17 +30,38 @@ interface CutFunction {
30
30
  */
31
31
  (distance1: number, distance2: number, target: ISceneObject): ICut;
32
32
  /**
33
- * Cuts up to face using the last sketch.
34
- * @param face - The face to cut up to, or `'first-face'`/`'last-face'`
33
+ * Cuts up to a specific face using the last sketch.
34
+ * @param face - A face selection to cut up to
35
+ */
36
+ (face: ISceneObject): ICut;
37
+ /**
38
+ * Cuts up to the first intersecting face using the last sketch.
39
+ * @param face - The literal `'first-face'`
40
+ */
41
+ (face: 'first-face'): ICut;
42
+ /**
43
+ * Cuts up to the last intersecting face using the last sketch.
44
+ * @param face - The literal `'last-face'`
45
+ */
46
+ (face: 'last-face'): ICut;
47
+ /**
48
+ * Cuts up to a specific face using the given sketch.
49
+ * @param face - A face selection to cut up to
50
+ * @param target - The sketch to cut with
51
+ */
52
+ (face: ISceneObject, target: ISceneObject): ICut;
53
+ /**
54
+ * Cuts up to the first intersecting face using the given sketch.
55
+ * @param face - The literal `'first-face'`
35
56
  * @param target - The sketch to cut with
36
57
  */
37
- (face: ISceneObject | 'first-face' | 'last-face'): ICut;
58
+ (face: 'first-face', target: ISceneObject): ICut;
38
59
  /**
39
- * Cuts up to face using the given sketch.
40
- * @param face - The face to cut up to, or `'first-face'`/`'last-face'`
60
+ * Cuts up to the last intersecting face using the given sketch.
61
+ * @param face - The literal `'last-face'`
41
62
  * @param target - The sketch to cut with
42
63
  */
43
- (face: ISceneObject | 'first-face' | 'last-face', target: ISceneObject): ICut;
64
+ (face: 'last-face', target: ISceneObject): ICut;
44
65
  }
45
66
  declare const _default: CutFunction;
46
67
  export default _default;
@@ -26,11 +26,23 @@ interface ExtrudeFunction {
26
26
  */
27
27
  (distance1: number, distance2: number, target: ISceneObject): IExtrude;
28
28
  /**
29
- * Extrudes the last sketch up to a face.
30
- * @param face - The face to extrude up to, or `'first-face'`/`'last-face'`
29
+ * Extrudes the last sketch up to a specific face.
30
+ * @param face - A face selection to extrude up to
31
31
  * @param target - The sketch to extrude
32
32
  */
33
- (face: ISceneObject | 'first-face' | 'last-face', target?: ISceneObject): IExtrude;
33
+ (face: ISceneObject, target?: ISceneObject): IExtrude;
34
+ /**
35
+ * Extrudes the last sketch up to the first intersecting face.
36
+ * @param face - The literal `'first-face'`
37
+ * @param target - The sketch to extrude
38
+ */
39
+ (face: 'first-face', target?: ISceneObject): IExtrude;
40
+ /**
41
+ * Extrudes the last sketch up to the last intersecting face.
42
+ * @param face - The literal `'last-face'`
43
+ * @param target - The sketch to extrude
44
+ */
45
+ (face: 'last-face', target?: ISceneObject): IExtrude;
34
46
  }
35
47
  declare const _default: ExtrudeFunction;
36
48
  export default _default;
@@ -45,12 +45,19 @@ interface PlaneFunction {
45
45
  */
46
46
  (plane: IPlane, options: PlaneRenderableOptions): IPlane;
47
47
  /**
48
- * Creates a plane midway between two planes.
49
- * @param p1 - The first plane
50
- * @param p2 - The second plane
48
+ * Creates a plane midway between two standard planes or normal vectors.
49
+ * @param p1 - The first standard plane or normal vector
50
+ * @param p2 - The second standard plane or normal vector
51
51
  * @param options - Transform options (offset, flip, sticky, etc.)
52
52
  */
53
- (p1: PlaneLike | IPlane, p2: PlaneLike | IPlane, options?: PlaneRenderableOptions): IPlane;
53
+ (p1: PlaneLike, p2: PlaneLike, options?: PlaneRenderableOptions): IPlane;
54
+ /**
55
+ * Creates a plane midway between two existing Plane objects.
56
+ * @param p1 - The first Plane object
57
+ * @param p2 - The second Plane object
58
+ * @param options - Transform options (offset, flip, sticky, etc.)
59
+ */
60
+ (p1: IPlane, p2: IPlane, options?: PlaneRenderableOptions): IPlane;
54
61
  }
55
62
  declare const _default: PlaneFunction;
56
63
  export default _default;
@@ -1,9 +1,10 @@
1
1
  import { AxisLike } from "../math/axis.js";
2
+ import { Matrix4 } from "../math/matrix4.js";
2
3
  import { LinearRepeatOptions } from "../features/repeat-linear.js";
3
4
  import { CircularRepeatOptions } from "../features/repeat-circular.js";
4
5
  import { ISceneObject } from "./interfaces.js";
5
6
  import { PlaneLike } from "../math/plane.js";
6
- export type RepeatType = 'linear' | 'circular' | 'mirror';
7
+ export type RepeatType = 'linear' | 'circular' | 'mirror' | 'rotate';
7
8
  interface RepeatFunction {
8
9
  /**
9
10
  * Creates linear repeated instances along an axis.
@@ -36,6 +37,20 @@ interface RepeatFunction {
36
37
  * @param objects - The objects to mirror (defaults to last object)
37
38
  */
38
39
  (type: 'mirror', plane: PlaneLike, ...objects: ISceneObject[]): ISceneObject;
40
+ /**
41
+ * Creates a rotated clone of objects around an axis.
42
+ * @param type - Must be `'rotate'`
43
+ * @param axis - The axis to rotate around
44
+ * @param angle - The rotation angle in degrees (defaults to 90)
45
+ * @param objects - The objects to rotate (defaults to last object)
46
+ */
47
+ (type: 'rotate', axis: AxisLike, angle?: number, ...objects: ISceneObject[]): ISceneObject;
48
+ /**
49
+ * Creates a transformed clone of objects using an arbitrary matrix.
50
+ * @param matrix - The transformation matrix to apply
51
+ * @param objects - The objects to transform (defaults to last object)
52
+ */
53
+ (matrix: Matrix4, ...objects: ISceneObject[]): ISceneObject;
39
54
  }
40
55
  declare const _default: RepeatFunction;
41
56
  export default _default;
@@ -8,16 +8,30 @@ import { cloneWithTransform } from "../helpers/clone-transform.js";
8
8
  import { PlaneObjectBase } from "../features/plane-renderable-base.js";
9
9
  import { PlaneObject } from "../features/plane.js";
10
10
  import { MirrorFeature } from "../features/mirror-feature.js";
11
+ import { RepeatMatrix } from "../features/repeat-matrix.js";
12
+ import { AxisObjectBase } from "../features/axis-renderable-base.js";
11
13
  function build(context) {
12
14
  return (function repeat() {
13
15
  const args = Array.from(arguments);
14
- if (args.length < 2) {
15
- throw new Error("Invalid arguments for repeat function: expected at least (type, ...)");
16
- }
17
16
  const sketch = context.getActiveSketch();
18
17
  if (sketch) {
19
18
  throw new Error("Cannot call repeat() inside a sketch. Use copy() instead.");
20
19
  }
20
+ if (args[0] instanceof Matrix4) {
21
+ const matrix = args[0];
22
+ const restObjects = args.slice(1);
23
+ const objects = restObjects.length > 0
24
+ ? restObjects
25
+ : [context.getSceneObjects().at(-1)];
26
+ const feature = new RepeatMatrix(matrix, objects);
27
+ const cloned = cloneWithTransform(objects, matrix, feature);
28
+ context.addSceneObject(feature);
29
+ context.addSceneObjects(cloned);
30
+ return feature;
31
+ }
32
+ if (args.length < 2) {
33
+ throw new Error("Invalid arguments for repeat function: expected at least (type, ...)");
34
+ }
21
35
  const type = args[0];
22
36
  if (type === 'linear' || type === 'circular') {
23
37
  const axisArg = args[1];
@@ -140,6 +154,28 @@ function build(context) {
140
154
  context.addSceneObjects(mirrorTree);
141
155
  return mirrorFeature;
142
156
  }
157
+ if (type === 'rotate') {
158
+ const axisArg = args[1];
159
+ const axis = axisArg instanceof AxisObjectBase
160
+ ? axisArg.getAxis()
161
+ : normalizeAxis(axisArg);
162
+ let angle = 90;
163
+ let restStart = 2;
164
+ if (typeof args[2] === 'number') {
165
+ angle = args[2];
166
+ restStart = 3;
167
+ }
168
+ const restObjects = args.slice(restStart);
169
+ const objects = restObjects.length > 0
170
+ ? restObjects
171
+ : [context.getSceneObjects().at(-1)];
172
+ const matrix = Matrix4.fromRotationAroundAxis(axis.origin, axis.direction, rad(angle));
173
+ const feature = new RepeatMatrix(matrix, objects);
174
+ const cloned = cloneWithTransform(objects, matrix, feature);
175
+ context.addSceneObject(feature);
176
+ context.addSceneObjects(cloned);
177
+ return feature;
178
+ }
143
179
  throw new Error(`Invalid repeat type: ${type}`);
144
180
  });
145
181
  }
@@ -8,11 +8,17 @@ interface SketchFunction {
8
8
  */
9
9
  (plane: PlaneLike, sketcher: () => void): ISceneObject;
10
10
  /**
11
- * Draws 2D geometry on a face or plane object.
12
- * @param face - The face or plane object to sketch on
11
+ * Draws 2D geometry on a face selection.
12
+ * @param face - The face to sketch on
13
13
  * @param sketcher - Callback containing sketch operations
14
14
  */
15
- (face: ISceneObject | IPlane, sketcher: () => void): ISceneObject;
15
+ (face: ISceneObject, sketcher: () => void): ISceneObject;
16
+ /**
17
+ * Draws 2D geometry on an existing Plane object.
18
+ * @param plane - The Plane object to sketch on
19
+ * @param sketcher - Callback containing sketch operations
20
+ */
21
+ (plane: IPlane, sketcher: () => void): ISceneObject;
16
22
  }
17
23
  declare const _default: SketchFunction;
18
24
  export default _default;
@@ -1,11 +1,12 @@
1
1
  import { ISceneObject } from "./interfaces.js";
2
2
  interface SubtractFunction {
3
3
  /**
4
- * Subtracts the second solid from the first (boolean difference).
5
- * @param solid1 - The base solid
6
- * @param solid2 - The solid to subtract
4
+ * Subtracts the second shape from the first (boolean difference).
5
+ * Works with both 3D solids and 2D sketch geometries.
6
+ * @param object1 - The base shape
7
+ * @param object2 - The shape to subtract
7
8
  */
8
- (solid1: ISceneObject, solid2: ISceneObject): ISceneObject;
9
+ (object1: ISceneObject, object2: ISceneObject): ISceneObject;
9
10
  }
10
11
  declare const _default: SubtractFunction;
11
12
  export default _default;
@@ -1,8 +1,15 @@
1
1
  import { registerBuilder } from "../index.js";
2
2
  import { Subtract } from "../features/subtract.js";
3
+ import { Subtract2D } from "../features/subtract2d.js";
3
4
  function build(context) {
4
- return function subtract(solid1, solid2) {
5
- const subtract = new Subtract(solid1, solid2);
5
+ return function subtract(object1, object2) {
6
+ const activeSketch = context.getActiveSketch();
7
+ if (activeSketch) {
8
+ const subtract2d = new Subtract2D(object1, object2);
9
+ context.addSceneObject(subtract2d);
10
+ return subtract2d;
11
+ }
12
+ const subtract = new Subtract(object1, object2);
6
13
  context.addSceneObject(subtract);
7
14
  return subtract;
8
15
  };
@@ -0,0 +1,19 @@
1
+ import { GeometrySceneObject } from "./geometry.js";
2
+ import { LazyVertex } from "../lazy-vertex.js";
3
+ import { PlaneObjectBase } from "../plane-renderable-base.js";
4
+ export declare class ArcThreePoints extends GeometrySceneObject {
5
+ startPoint: LazyVertex;
6
+ endPoint: LazyVertex;
7
+ center: LazyVertex;
8
+ private targetPlane;
9
+ constructor(startPoint: LazyVertex, endPoint: LazyVertex, center: LazyVertex, targetPlane?: PlaneObjectBase);
10
+ build(): void;
11
+ compareTo(other: ArcThreePoints): boolean;
12
+ getType(): string;
13
+ getUniqueType(): string;
14
+ serialize(): {
15
+ startPoint: {};
16
+ endPoint: {};
17
+ center: {};
18
+ };
19
+ }