forgecad 0.1.1 → 0.1.3
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/dist/assets/{evalWorker-DuS4V-H5.js → evalWorker-1m873KWd.js} +107 -107
- package/dist/assets/{index-d60dJDhX.js → index-Dvz3nSDc.js} +342 -326
- package/dist/assets/{manifold-DEOPQqeC.js → manifold-C38sUiKu.js} +1 -1
- package/dist/assets/{manifold-cL7A7HeM.js → manifold-Dk2u-lhj.js} +1 -1
- package/dist/assets/{manifold-DbvY5u9x.js → manifold-rOWQW9fU.js} +1 -1
- package/dist/assets/{reportWorker-GZVKtf9S.js → reportWorker-Cj587shw.js} +129 -129
- package/dist/index.html +1 -1
- package/dist-cli/forgecad.js +204 -19
- package/dist-skill/SKILL.md +31 -4561
- package/dist-skill/docs/API/README.md +24 -0
- package/dist-skill/docs/API/guides/modeling-recipes.md +246 -0
- package/dist-skill/docs/API/internals/compiler.md +300 -0
- package/dist-skill/docs/API/internals/manifold.md +7 -0
- package/dist-skill/docs/API/model-building/README.md +31 -0
- package/dist-skill/docs/API/model-building/assembly.md +205 -0
- package/dist-skill/docs/API/model-building/coordinate-system.md +43 -0
- package/dist-skill/docs/API/model-building/entities.md +282 -0
- package/dist-skill/docs/API/model-building/geometry-conventions.md +104 -0
- package/dist-skill/docs/API/model-building/positioning.md +170 -0
- package/dist-skill/docs/API/model-building/reference.md +1936 -0
- package/dist-skill/docs/API/model-building/sheet-metal.md +180 -0
- package/dist-skill/docs/API/model-building/sketch-anchor.md +32 -0
- package/dist-skill/docs/API/model-building/sketch-booleans.md +101 -0
- package/dist-skill/docs/API/model-building/sketch-core.md +68 -0
- package/dist-skill/docs/API/model-building/sketch-extrude.md +57 -0
- package/dist-skill/docs/API/model-building/sketch-on-face.md +98 -0
- package/dist-skill/docs/API/model-building/sketch-operations.md +92 -0
- package/dist-skill/docs/API/model-building/sketch-path.md +70 -0
- package/dist-skill/docs/API/model-building/sketch-primitives.md +104 -0
- package/dist-skill/docs/API/model-building/sketch-transforms.md +60 -0
- package/dist-skill/docs/API/output/bom.md +53 -0
- package/dist-skill/docs/API/output/brep-export.md +82 -0
- package/dist-skill/docs/API/output/dimensions.md +62 -0
- package/dist-skill/docs/API/runtime/viewport.md +229 -0
- package/dist-skill/docs/CLI.md +672 -0
- package/dist-skill/docs/CODING.md +345 -0
- package/dist-skill/docs/PROGRAM-LEAD.md +180 -0
- package/dist-skill/docs/VISION.md +77 -0
- package/examples/api/import-group-assembly.forge.js +34 -0
- package/examples/api/import-group-source.forge.js +35 -0
- package/package.json +1 -1
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
# Positioning Strategy
|
|
2
|
+
|
|
3
|
+
**This is the most important page for building multi-part assemblies.** Most positioning bugs come from manual coordinate arithmetic. Use the methods below in priority order.
|
|
4
|
+
|
|
5
|
+
## Priority Order
|
|
6
|
+
|
|
7
|
+
### 1. `attachTo()` — Default choice for child-on-parent positioning
|
|
8
|
+
|
|
9
|
+
When placing a part relative to another part, use `attachTo()`. It reads as English: "put my bottom on your top."
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
const base = box(100, 100, 10);
|
|
13
|
+
|
|
14
|
+
// Column stands on top of base, centered
|
|
15
|
+
const column = cylinder(50, 8).attachTo(base, 'top', 'bottom');
|
|
16
|
+
|
|
17
|
+
// Button sticks out from front face, near top-right corner
|
|
18
|
+
const button = box(10, 4, 6, true)
|
|
19
|
+
.attachTo(panel, 'top-front-right', 'top-back-right', [5, -2, -10]);
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**How to read it:** `child.attachTo(parent, parentAnchor, selfAnchor, offset)`
|
|
23
|
+
- `parentAnchor` = "where on the parent do I want to attach?"
|
|
24
|
+
- `selfAnchor` = "which part of myself aligns to that point?"
|
|
25
|
+
- `offset` = "then shift by this much" (optional)
|
|
26
|
+
|
|
27
|
+
**Common patterns:**
|
|
28
|
+
| Intent | parentAnchor | selfAnchor | Why |
|
|
29
|
+
|--------|-------------|------------|-----|
|
|
30
|
+
| Stack on top | `'top'` | `'bottom'` | Bottom of child meets top of parent |
|
|
31
|
+
| Hang below | `'bottom'` | `'top'` | Top of child meets bottom of parent |
|
|
32
|
+
| Stick out from front | `'front'` | `'back'` | Back of child flush with front of parent |
|
|
33
|
+
| Protrude from side | `'left'` | `'right'` | Right face of child meets left face of parent |
|
|
34
|
+
|
|
35
|
+
### 2. `pointAlong()` — Orient cylinders/extrusions before positioning
|
|
36
|
+
|
|
37
|
+
Cylinders default to Z-up. Instead of `rotate(90, 0, 0)` (which is confusing), use `pointAlong()`:
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
// Pipe running along Y axis
|
|
41
|
+
const pipe = cylinder(100, 5).pointAlong([0, 1, 0]);
|
|
42
|
+
|
|
43
|
+
// Axle along X
|
|
44
|
+
const axle = cylinder(80, 3).pointAlong([1, 0, 0]);
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Always call `pointAlong()` BEFORE `attachTo()` or `translate()`** — it reorients around the origin.
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
// Correct: orient first, then position
|
|
51
|
+
const grille = cylinder(4, 30)
|
|
52
|
+
.pointAlong([0, 1, 0])
|
|
53
|
+
.attachTo(outdoorUnit, 'back', 'front', [0, 2, 0]);
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### 3. `rotateAroundTo()` — Aim a point around a hinge/axis
|
|
57
|
+
|
|
58
|
+
Use this when a part already has the correct pivot/axis, and you want to solve the angle from geometry instead of doing trig by hand.
|
|
59
|
+
|
|
60
|
+
```javascript
|
|
61
|
+
const arm = box(80, 8, 8, true)
|
|
62
|
+
.translate(40, 0, 0)
|
|
63
|
+
.withReferences({ points: { tip: [80, 0, 0] } });
|
|
64
|
+
|
|
65
|
+
// Rotate around Z until the tip lies in the plane formed by the Z axis and the target point
|
|
66
|
+
const aimed = arm.rotateAroundTo(
|
|
67
|
+
[0, 0, 1],
|
|
68
|
+
[0, 0, 0],
|
|
69
|
+
"tip",
|
|
70
|
+
[30, 30, 20],
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
// Exact line solve: throws if the target line is unreachable while preserving radius about the axis
|
|
74
|
+
const lineHit = arm.rotateAroundTo(
|
|
75
|
+
[0, 0, 1],
|
|
76
|
+
[0, 0, 0],
|
|
77
|
+
"tip",
|
|
78
|
+
[30, 30, 0],
|
|
79
|
+
{ mode: 'line' },
|
|
80
|
+
);
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### 4. `moveToLocal()` — Position relative to another shape's corner
|
|
84
|
+
|
|
85
|
+
When you need to place something at a specific offset from another shape's bounding box origin (min corner):
|
|
86
|
+
|
|
87
|
+
```javascript
|
|
88
|
+
const base = box(100, 100, 10);
|
|
89
|
+
const part = box(20, 20, 30).moveToLocal(base, 10, 10, 10);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 5. `translate()` — Only for simple offsets or connecting independently-positioned parts
|
|
93
|
+
|
|
94
|
+
Use `translate()` when:
|
|
95
|
+
- Moving a shape by a known fixed amount
|
|
96
|
+
- Positioning between two shapes whose locations you've already computed via `boundingBox()`
|
|
97
|
+
|
|
98
|
+
```javascript
|
|
99
|
+
// Pipe spanning between two independently-positioned units
|
|
100
|
+
const bb1 = indoor.boundingBox();
|
|
101
|
+
const bb2 = outdoor.boundingBox();
|
|
102
|
+
const pipeLen = bb2.min[1] - bb1.max[1];
|
|
103
|
+
const pipe = cylinder(pipeLen, 5)
|
|
104
|
+
.pointAlong([0, 1, 0])
|
|
105
|
+
.translate(40, (bb1.max[1] + bb2.min[1]) / 2, bb1.min[2] + 15);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### 6. `placeReference()` / named import references — For reusable multi-file parts
|
|
109
|
+
|
|
110
|
+
When a part will be imported elsewhere, define semantic placement references once in the source file:
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
// widget.forge.js
|
|
114
|
+
return union(base, post).withReferences({
|
|
115
|
+
points: {
|
|
116
|
+
mount: [0, -16, -4],
|
|
117
|
+
},
|
|
118
|
+
objects: {
|
|
119
|
+
post,
|
|
120
|
+
},
|
|
121
|
+
});
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Then consume them in the importing file:
|
|
125
|
+
|
|
126
|
+
```javascript
|
|
127
|
+
const widget = importPart("widget.forge.js")
|
|
128
|
+
.placeReference("mount", [120, 40, 0]);
|
|
129
|
+
|
|
130
|
+
const cap = box(18, 18, 8, true)
|
|
131
|
+
.attachTo(widget, "objects.post.top", "bottom");
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Use this when manual coordinate math starts to feel like assembly bookkeeping.
|
|
135
|
+
|
|
136
|
+
## Common Mistakes
|
|
137
|
+
|
|
138
|
+
### ❌ Manual center-offset math
|
|
139
|
+
```javascript
|
|
140
|
+
// BAD: easy to get wrong, hard to read
|
|
141
|
+
const child = box(w, d, h, true)
|
|
142
|
+
.translate(0, -parentThickness/2 - d/2 - 5, parentHeight/2 - h/2 - 20);
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### ✅ Anchor-based positioning
|
|
146
|
+
```javascript
|
|
147
|
+
// GOOD: intent is clear, no arithmetic
|
|
148
|
+
const child = box(w, d, h, true)
|
|
149
|
+
.attachTo(parent, 'top-front', 'top-back', [0, -5, -20]);
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### ❌ rotate() for cylinder orientation
|
|
153
|
+
```javascript
|
|
154
|
+
// BAD: which axis? what happens to center?
|
|
155
|
+
const pipe = cylinder(100, 5).rotate(90, 0, 0).translate(x, y, z);
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
### ✅ pointAlong() for cylinder orientation
|
|
159
|
+
```javascript
|
|
160
|
+
// GOOD: reads as "pipe pointing along Y"
|
|
161
|
+
const pipe = cylinder(100, 5).pointAlong([0, 1, 0]).translate(x, y, z);
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Anchor Reference
|
|
165
|
+
|
|
166
|
+
See the [main API doc](API.md#3d-anchor-positioning) for the full list of 26 anchor names. Quick mental model:
|
|
167
|
+
|
|
168
|
+
- **1 word** = face center: `'top'`, `'front'`, `'left'`...
|
|
169
|
+
- **2 words** = edge midpoint: `'top-front'`, `'back-left'`...
|
|
170
|
+
- **3 words** = corner: `'top-front-left'`, `'bottom-back-right'`...
|