@code3d/core 0.0.1-alpha.0 → 0.0.1-alpha.11
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/README.md +43 -807
- package/THIRD_PARTY.md +40 -0
- package/bld/THIRD_PARTY_NOTICES.txt +182 -0
- package/bld/chunks/chunk-7FIFPADJ.js +1 -0
- package/bld/chunks/chunk-7FIFPADJ.js.map +7 -0
- package/bld/chunks/chunk-CL3E2DE4.js +19 -0
- package/bld/chunks/chunk-CL3E2DE4.js.map +7 -0
- package/bld/chunks/chunk-HZRQUHM2.js +30 -0
- package/bld/chunks/chunk-HZRQUHM2.js.map +7 -0
- package/bld/chunks/chunk-JBVIAMJ6.js +26474 -0
- package/bld/chunks/chunk-JBVIAMJ6.js.map +7 -0
- package/bld/chunks/chunk-QK6ZET47.js +31 -0
- package/bld/chunks/chunk-QK6ZET47.js.map +7 -0
- package/bld/library/bound-solver.d.ts +29 -5
- package/bld/library/bound-solver.d.ts.map +1 -1
- package/bld/library/cached.d.ts +35 -0
- package/bld/library/cached.d.ts.map +1 -0
- package/bld/library/font.d.ts +39 -0
- package/bld/library/font.d.ts.map +1 -0
- package/bld/library/google-font.d.ts +14 -0
- package/bld/library/google-font.d.ts.map +1 -0
- package/bld/library/index.d.ts +10 -2
- package/bld/library/index.d.ts.map +1 -1
- package/bld/library/index.js +94 -3
- package/bld/library/index.js.map +7 -1
- package/bld/library/inspect.d.ts +100 -0
- package/bld/library/inspect.d.ts.map +1 -0
- package/bld/library/kernel-artifact-codec.d.ts.map +1 -1
- package/bld/library/kernel-cache.d.ts +28 -7
- package/bld/library/kernel-cache.d.ts.map +1 -1
- package/bld/library/loft.d.ts.map +1 -1
- package/bld/library/material.d.ts +1 -1
- package/bld/library/material.d.ts.map +1 -1
- package/bld/library/open-cascade.d.ts +4 -0
- package/bld/library/open-cascade.d.ts.map +1 -0
- package/bld/library/relation-solver.d.ts +19 -8
- package/bld/library/relation-solver.d.ts.map +1 -1
- package/bld/library/replicad.d.ts +3 -2
- package/bld/library/replicad.d.ts.map +1 -1
- package/bld/library/replicad.js +10 -24
- package/bld/library/replicad.js.map +7 -1
- package/bld/library/retained-memory.d.ts.map +1 -1
- package/bld/library/runtime.d.ts +518 -155
- package/bld/library/runtime.d.ts.map +1 -1
- package/bld/library/sketch-solver.d.ts +1 -1
- package/bld/library/sketch-solver.d.ts.map +1 -1
- package/bld/library/sketch.d.ts +21 -1
- package/bld/library/sketch.d.ts.map +1 -1
- package/bld/library/text.d.ts +53 -0
- package/bld/library/text.d.ts.map +1 -0
- package/bld/library/three.js +3 -3
- package/bld/library/three.js.map +7 -1
- package/bld/library/topology.d.ts +6 -2
- package/bld/library/topology.d.ts.map +1 -1
- package/bld/node/index.d.ts.map +1 -1
- package/bld/node/index.js +96 -14
- package/bld/node/index.js.map +7 -1
- package/bld/node/replicad.js +13 -3
- package/bld/node/replicad.js.map +7 -1
- package/bld/tooling/index.d.ts +18 -15
- package/bld/tooling/index.d.ts.map +1 -1
- package/bld/tooling/index.js +165 -19
- package/bld/tooling/index.js.map +7 -1
- package/docs/api.md +764 -0
- package/docs/custom-primitives.mdx +58 -0
- package/docs/local-coordinates.md +187 -0
- package/docs/origins-and-rotation.mdx +105 -0
- package/docs/relations.mdx +450 -0
- package/docs/runtime.md +297 -0
- package/docs/shells.mdx +70 -0
- package/docs/sketches.md +83 -0
- package/docs/text.md +23 -0
- package/docs/topology.md +152 -0
- package/docs/values.md +119 -0
- package/package.json +20 -7
- package/src/library/bound-solver.ts +103 -73
- package/src/library/cached.ts +153 -0
- package/src/library/font.ts +186 -0
- package/src/library/google-font.ts +97 -0
- package/src/library/index.ts +53 -5
- package/src/library/inspect.ts +178 -0
- package/src/library/kernel-artifact-codec.ts +129 -20
- package/src/library/kernel-cache.ts +175 -39
- package/src/library/loft.ts +9 -1
- package/src/library/material.ts +3 -4
- package/src/library/open-cascade.ts +13 -0
- package/src/library/relation-solver.ts +230 -113
- package/src/library/replicad.ts +5 -5
- package/src/library/retained-memory.ts +6 -1
- package/src/library/runtime.ts +3769 -1178
- package/src/library/shell.ts +3 -3
- package/src/library/sketch-solver.ts +3 -1
- package/src/library/sketch.ts +112 -13
- package/src/library/text.ts +477 -0
- package/src/library/topology.ts +61 -17
- package/src/library/tsconfig.json +2 -1
- package/src/node/index.ts +14 -3
- package/src/node/tsconfig.json +2 -1
- package/src/tooling/index.ts +64 -51
- package/src/tooling/tsconfig.json +2 -1
- package/bld/library/alignment-geometry.js +0 -322
- package/bld/library/alignment-geometry.js.map +0 -1
- package/bld/library/bound-solver.js +0 -252
- package/bld/library/bound-solver.js.map +0 -1
- package/bld/library/extrude.js +0 -28
- package/bld/library/extrude.js.map +0 -1
- package/bld/library/kernel-artifact-codec.js +0 -148
- package/bld/library/kernel-artifact-codec.js.map +0 -1
- package/bld/library/kernel-cache.js +0 -245
- package/bld/library/kernel-cache.js.map +0 -1
- package/bld/library/kernel-shapes.js +0 -108
- package/bld/library/kernel-shapes.js.map +0 -1
- package/bld/library/loft.js +0 -161
- package/bld/library/loft.js.map +0 -1
- package/bld/library/material.js +0 -176
- package/bld/library/material.js.map +0 -1
- package/bld/library/model-color.js +0 -36
- package/bld/library/model-color.js.map +0 -1
- package/bld/library/open-cascade-error.js +0 -22
- package/bld/library/open-cascade-error.js.map +0 -1
- package/bld/library/relation-solver.js +0 -258
- package/bld/library/relation-solver.js.map +0 -1
- package/bld/library/retained-memory.js +0 -27
- package/bld/library/retained-memory.js.map +0 -1
- package/bld/library/runtime.js +0 -2954
- package/bld/library/runtime.js.map +0 -1
- package/bld/library/shell.js +0 -221
- package/bld/library/shell.js.map +0 -1
- package/bld/library/sketch-curve-intersections.js +0 -117
- package/bld/library/sketch-curve-intersections.js.map +0 -1
- package/bld/library/sketch-curves.js +0 -89
- package/bld/library/sketch-curves.js.map +0 -1
- package/bld/library/sketch-drag-rules.js +0 -522
- package/bld/library/sketch-drag-rules.js.map +0 -1
- package/bld/library/sketch-face.js +0 -72
- package/bld/library/sketch-face.js.map +0 -1
- package/bld/library/sketch-incidence.js +0 -114
- package/bld/library/sketch-incidence.js.map +0 -1
- package/bld/library/sketch-precision.js +0 -55
- package/bld/library/sketch-precision.js.map +0 -1
- package/bld/library/sketch-regions.js +0 -193
- package/bld/library/sketch-regions.js.map +0 -1
- package/bld/library/sketch-solver.js +0 -578
- package/bld/library/sketch-solver.js.map +0 -1
- package/bld/library/sketch.js +0 -650
- package/bld/library/sketch.js.map +0 -1
- package/bld/library/spatial.js +0 -195
- package/bld/library/spatial.js.map +0 -1
- package/bld/library/topology-id.js +0 -67
- package/bld/library/topology-id.js.map +0 -1
- package/bld/library/topology-inspection.js +0 -267
- package/bld/library/topology-inspection.js.map +0 -1
- package/bld/library/topology.js +0 -455
- package/bld/library/topology.js.map +0 -1
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Building custom primitives
|
|
3
|
+
description: Bring a Replicad solid into Code3D with normal model capabilities and parameter tools.
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 10
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import ModelExample from '../../web/src/components/ModelExample.astro';
|
|
9
|
+
|
|
10
|
+
Start with the built-in [modeling operations](api.md) when they
|
|
11
|
+
fit the part. For other solid geometry, `definePrimitive` wraps a synchronous
|
|
12
|
+
Replicad builder as a normal Code3D model.
|
|
13
|
+
|
|
14
|
+
Import both `definePrimitive` and `replicad` from `@code3d/core/replicad`.
|
|
15
|
+
The builder returns one solid; the result supports the usual `material`,
|
|
16
|
+
`relate`, `expose`, fillet, and chamfer operations.
|
|
17
|
+
|
|
18
|
+
## A twisted knob with a shaft bore
|
|
19
|
+
|
|
20
|
+
This example extrudes a hexagonal profile with a twist, cuts a D-shaped bore,
|
|
21
|
+
and places two instances on a base. Its `@code3d.param` annotations make the
|
|
22
|
+
dimensions and twist angle available in call-site panels.
|
|
23
|
+
|
|
24
|
+
<ModelExample id="custom-primitives" />
|
|
25
|
+
|
|
26
|
+
Open the example and place the cursor in either `twistKnob(...)` call to
|
|
27
|
+
adjust its inputs. The short knob supplies a twist of 30°; the tall one uses
|
|
28
|
+
the builder's default of 60°. The twist annotation also declares `default: 60`,
|
|
29
|
+
so the tall knob's panel shows that value as a placeholder. Typing a number
|
|
30
|
+
adds an explicit twist argument; simply opening the panel leaves it omitted.
|
|
31
|
+
|
|
32
|
+
## Return a model, own the intermediate geometry
|
|
33
|
+
|
|
34
|
+
Returning the solid transfers it to Code3D. Do not delete, mutate, or return
|
|
35
|
+
that same shape again. Intermediate Replicad resources remain the builder's
|
|
36
|
+
responsibility; the example uses `localGC()` and `finally` to release them.
|
|
37
|
+
Some Replicad operations consume their inputs, so resource handling follows
|
|
38
|
+
the operations used.
|
|
39
|
+
|
|
40
|
+
Validate dimensions inside the builder. A single-solid aggregate from a
|
|
41
|
+
Replicad boolean can be normalized, but multiple solids, shells, or aggregates
|
|
42
|
+
with stray lower-dimensional geometry are rejected.
|
|
43
|
+
|
|
44
|
+
`definePrimitive()` caches deterministic construction by definition and arguments,
|
|
45
|
+
including validation, normalization, topology and bounds. A hit skips the builder
|
|
46
|
+
and creates a fresh model with its own shape handles and source tracing. Pass all
|
|
47
|
+
changing captured state as explicit arguments. The App fingerprints static
|
|
48
|
+
builders and their dependencies for persistent reuse; dynamic closures and
|
|
49
|
+
ordinary Node calls use function object identity for memory reuse.
|
|
50
|
+
|
|
51
|
+
Primitives share the same memory and disk budgets as Core computations and
|
|
52
|
+
Screws. Use [`cache()`](api.md#cached-computations) for ordinary
|
|
53
|
+
data computations; geometry needs `definePrimitive()` so Core manages its native
|
|
54
|
+
resources.
|
|
55
|
+
|
|
56
|
+
Your function stays ordinary TypeScript and can be exported for other modules.
|
|
57
|
+
See [adding tools to model functions](../../web/src/content/docs/docs/guides/model-tools.mdx) for annotation rules and
|
|
58
|
+
[reusable models](../../web/src/content/docs/docs/guides/reusable-models.mdx) for naming attachment points.
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Local coordinates and placement
|
|
3
|
+
description: Understand positions, origin offsets, model axes, and where a part sits in a composition.
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 3
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
Every model has its own local coordinates. Its origin is `[0, 0, 0]`.
|
|
9
|
+
The geometry can be away from that origin: a point at `[10, 0, 0]` still
|
|
10
|
+
belongs to a model whose origin is zero.
|
|
11
|
+
|
|
12
|
+
## Positions, dimensions, and displacements
|
|
13
|
+
|
|
14
|
+
Use coordinate arrays for positions and separate numbers for dimensions,
|
|
15
|
+
displacements, and angles:
|
|
16
|
+
|
|
17
|
+
| Expression | Meaning |
|
|
18
|
+
| ------------------------------ | ---------------------------------------------------- |
|
|
19
|
+
| `box(10, 20, 30)` | Dimensions along local X, Y, and Z; centered at zero |
|
|
20
|
+
| `point()` | A point at local zero |
|
|
21
|
+
| `point([10, 2, -3])` | A point at the supplied local coordinates |
|
|
22
|
+
| `line([10, 0, 0])` | A line from zero to the supplied endpoint |
|
|
23
|
+
| `line([10, 0, 0], [20, 0, 0])` | A line between two local positions |
|
|
24
|
+
| `originOffset(10, 0, 0)` | Move the origin by a local displacement |
|
|
25
|
+
| `pivot([10, 0, 0])` | Choose a rotation center in self's local coordinates |
|
|
26
|
+
| `offset(10, 0, 0)` | Move a relate result along fixed composition axes |
|
|
27
|
+
| `rotate(0, 90, 0)` | Rotate geometry by 90° around local Y |
|
|
28
|
+
|
|
29
|
+
Curve control points use the returned model's local coordinates too. A common
|
|
30
|
+
offset in their coordinates is retained; the curve does not automatically move
|
|
31
|
+
its start or center to zero.
|
|
32
|
+
|
|
33
|
+
## Default origin rules
|
|
34
|
+
|
|
35
|
+
Constructors define a local coordinate frame. Derived operations inherit their
|
|
36
|
+
main input's frame; they do not automatically recenter the resulting geometry.
|
|
37
|
+
Only an explicit origin operation chooses a different local zero.
|
|
38
|
+
|
|
39
|
+
| Constructor or operation | Origin and coordinate frame |
|
|
40
|
+
| ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
41
|
+
| `box`, `sphere`, `circle`, `ellipse`, `rectangle` | Geometry is constructed around local zero. |
|
|
42
|
+
| `cylinder`, `tube`, `frustum`, `regularPrism` | The central axis passes through zero; height is centered on Y. This is not a center-of-mass rule. |
|
|
43
|
+
| `regularPolygon` | The polygon's construction-circle center, which need not equal its bounding-box center. |
|
|
44
|
+
| `coil` | The helix axis passes through zero; the centerline's axial span is centered on Y. |
|
|
45
|
+
| `point`, `line`, `arc`, `bezier`, `spline` | Retain the supplied coordinates relative to zero; neither endpoints nor curve centers are automatically moved to zero. |
|
|
46
|
+
| Faces made from a sketch | Retain the sketch's local frame. |
|
|
47
|
+
| `text` | All returned faces share the text layout's baseline origin, including its glyph advances and offsets. Individual letters are not centered. |
|
|
48
|
+
| `definePrimitive` | Retain the frame used by the returned geometry; no automatic recentering. |
|
|
49
|
+
| `extrude` | Inherit the input face's frame, without centering the extrusion. |
|
|
50
|
+
| `union`, `intersect` | Inherit the first operand's frame. |
|
|
51
|
+
| `cut` | Inherit the stock's frame. |
|
|
52
|
+
| `loft` | Inherit the first section's frame. |
|
|
53
|
+
| `group` | Inherit the first member's frame after solving placement; an empty group uses the default frame. |
|
|
54
|
+
| `rotate`, `scaled`, `fillet`, `chamfer`, `shell` | Retain the input model's frame, even when its geometric bounds change. |
|
|
55
|
+
| `relate`, `material`, `expose` | Retain the model's local frame; relations describe its placement within a composition. |
|
|
56
|
+
|
|
57
|
+
For example, `point([10, 0, 0])` has geometry at X = 10 and an origin at zero.
|
|
58
|
+
Similarly, `rectangle(10, 10).extrude(20)` keeps its origin on the starting
|
|
59
|
+
plane, while `box(10, 20, 10)` is centered on its origin.
|
|
60
|
+
|
|
61
|
+
Explicit choices are `originOffset(dx, dy, dz)` for a displacement,
|
|
62
|
+
`originPoint(pointRef)` for a referenced point, `originVertex(id)` for an own
|
|
63
|
+
topology vertex, and `originCenter()` for the existing center anchor. The last
|
|
64
|
+
two require geometry and are not available on groups. A carried center anchor
|
|
65
|
+
is not necessarily the center of the current axis-aligned bounding box.
|
|
66
|
+
|
|
67
|
+
## Coordinate references
|
|
68
|
+
|
|
69
|
+
Every model, including a group, provides `model.frame`, a reference to its local
|
|
70
|
+
coordinate system. `model.frame.origin` references that frame's zero point;
|
|
71
|
+
`model.origin` is the same reference. Neither is a geometric model.
|
|
72
|
+
For `point([10, 0, 0])`, the geometry is at X = 10 while its frame origin is zero.
|
|
73
|
+
Changing local geometry with `rotate()` does not rotate the model's coordinate
|
|
74
|
+
axes. Placement through `relate()` determines the frame's pose in a composition.
|
|
75
|
+
|
|
76
|
+
Use `self.origin.align(other.origin)` to coincide just the origins, or
|
|
77
|
+
`self.frame.align(other.frame)` to coincide both origins and all three axes.
|
|
78
|
+
Coordinate references can be named with `expose`; an exposed frame and its
|
|
79
|
+
`.origin` follow the selected occurrence through nested groups and transforms.
|
|
80
|
+
A newly read `model.origin` always references the current local zero. Previously
|
|
81
|
+
selected references retain their meaning through subsequent origin edits.
|
|
82
|
+
|
|
83
|
+
## Changing the origin changes point coordinates
|
|
84
|
+
|
|
85
|
+
`originOffset(dx, dy, dz)` chooses a new origin at that displacement in the
|
|
86
|
+
input model. In the result, that origin is zero and each point has coordinates:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
p_new = p_old - [dx, dy, dz]
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
For example, the point in `point([10, 2, -3]).originOffset(4, 0, 0)` is at
|
|
93
|
+
`[6, 2, -3]`. Conversely, `point().originOffset(-10, -2, 3)` creates the same
|
|
94
|
+
local geometry as `point([10, 2, -3])`.
|
|
95
|
+
|
|
96
|
+
The shape and distances between points stay the same. Geometry, `center`,
|
|
97
|
+
named anchors, and topology positions use the new coordinates together.
|
|
98
|
+
Directions and normals keep their direction. The operation returns a new
|
|
99
|
+
model value and preserves topology IDs; earlier values and references retain
|
|
100
|
+
their meaning. Successive origin offsets add and opposite offsets cancel.
|
|
101
|
+
|
|
102
|
+
Use `originPoint(pointRef)` on any model to make a referenced point zero.
|
|
103
|
+
For geometric models, `originVertex(id)` selects an own topology vertex and
|
|
104
|
+
`originCenter()` selects the carried center anchor. The [origin and rotation guide](origins-and-rotation.mdx)
|
|
105
|
+
shows how to select and drag these in the viewport.
|
|
106
|
+
|
|
107
|
+
## The origin, center, and axes have different roles
|
|
108
|
+
|
|
109
|
+
`line([10, 0, 0])` has its origin at zero and its midpoint at `[5, 0, 0]`.
|
|
110
|
+
Rotating it with `.rotate(0, 90, 0)` gives a line from zero to `[0, 0, -10]`.
|
|
111
|
+
Calling `.originCenter()` first puts the endpoints at `[-5, 0, 0]` and
|
|
112
|
+
`[5, 0, 0]`, so the same rotation now turns the line around its midpoint.
|
|
113
|
+
|
|
114
|
+
Geometric `rotate()` and `scaled()` act around the current local zero.
|
|
115
|
+
The `center` anchor follows these transformations; rotation does not replace
|
|
116
|
+
it with the center of the new axis-aligned bounding box.
|
|
117
|
+
|
|
118
|
+
The model's XYZ axes remain its local coordinate axes. `up` means local +Y
|
|
119
|
+
even after the geometry rotates. A line's tangent or a face's normal belongs
|
|
120
|
+
to that geometric reference and can point in a different direction. Relation
|
|
121
|
+
offsets use the target reference's axes; an explicit `pivot([x, y, z])` uses
|
|
122
|
+
self's model coordinates. See [relations](relations.mdx) for those
|
|
123
|
+
placement rules.
|
|
124
|
+
|
|
125
|
+
## Placing a part in a composition
|
|
126
|
+
|
|
127
|
+
`relate()` describes placement relative to other parts. Inspect a related
|
|
128
|
+
part by itself to see its local geometry; inspect the relation or a consuming
|
|
129
|
+
composition to see the solved placement. An `originOffset()` changes the
|
|
130
|
+
part's local geometry coordinates, while a relation's `offset()` participates
|
|
131
|
+
in its placement conditions.
|
|
132
|
+
|
|
133
|
+
Several relations on one model are solved together. Their offsets belong to
|
|
134
|
+
those conditions, and any remaining freedom uses the solver's default result.
|
|
135
|
+
See [combining conditions](relations.mdx#combine-conditions) before
|
|
136
|
+
using an offset in a system with multiple relations.
|
|
137
|
+
|
|
138
|
+
New model values also have a coordinate frame:
|
|
139
|
+
|
|
140
|
+
- A boolean result uses the main operand's local coordinates.
|
|
141
|
+
- A loft uses its first section's local coordinates.
|
|
142
|
+
- A group uses its first member's local coordinates, retaining relative placement.
|
|
143
|
+
- `expose()` brings a reference into the outer model's local space. For a
|
|
144
|
+
repeated part, use the reference from its specific instance.
|
|
145
|
+
|
|
146
|
+
Export uses these same coordinates: a standalone part has local geometry,
|
|
147
|
+
and a composition includes its parts' resolved placement. The chosen output
|
|
148
|
+
scale and up axis are applied afterward. See [exporting models](../../web/src/content/docs/docs/guides/exporting.md).
|
|
149
|
+
|
|
150
|
+
## Group origins
|
|
151
|
+
|
|
152
|
+
A group first solves the placement of its direct members, then expresses all
|
|
153
|
+
members in the **first member's local coordinate frame**, including its origin
|
|
154
|
+
and axes. This is the same reference rule used by `union`, `intersect`, and
|
|
155
|
+
`loft`; `cut` uses the stock's frame. Reordering members can change the group's
|
|
156
|
+
frame, while preserving their relative placement. A nested group is one member,
|
|
157
|
+
with its own existing frame. An empty group uses the default origin and axes.
|
|
158
|
+
A relation's rotation affects that solved member frame; rotating the member's
|
|
159
|
+
geometry directly with `.rotate()` does not redefine its local axes.
|
|
160
|
+
|
|
161
|
+
```ts
|
|
162
|
+
import {box, group} from '@code3d/core';
|
|
163
|
+
|
|
164
|
+
const base = box(20, 4, 10).originOffset(0, 2, 0);
|
|
165
|
+
const lid = box(20, 2, 10).originOffset(0, -1, 0);
|
|
166
|
+
const assembly = group([base, lid]);
|
|
167
|
+
const mounted = assembly.originPoint(lid.center);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
Here the unrestrained member origins coincide at the contact plane. That point
|
|
171
|
+
becomes the group origin. `originPoint(lid.center)` chooses the lid's center in
|
|
172
|
+
the assembled coordinates; `originOffset()` can then shift it further. Both
|
|
173
|
+
operations re-express the whole group, preserving member spacing and internal
|
|
174
|
+
relations. The default is chosen once and does not overwrite explicit edits.
|
|
175
|
+
|
|
176
|
+
Changing the first member's origin before constructing a new group changes the
|
|
177
|
+
reference frame, even if constraints keep its physical geometry in place.
|
|
178
|
+
Changing a later member's origin does not select a different reference member;
|
|
179
|
+
its placement still follows the assembly constraints.
|
|
180
|
+
Within an existing model, origin edits also update its own stored relation
|
|
181
|
+
references, so a constraint on a selected geometric point still follows that
|
|
182
|
+
same point.
|
|
183
|
+
|
|
184
|
+
For repeated geometry, select an instance's named reference, such as
|
|
185
|
+
`assembly.originPoint(rightPart.body.center)`. A reference to the shared source
|
|
186
|
+
alone is ambiguous and is rejected. The same instance resolution applies to
|
|
187
|
+
`expose()`.
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Choosing an origin and rotating a part
|
|
3
|
+
description: Set a pivot, rotate geometry, and adjust both directly in the viewport.
|
|
4
|
+
sidebar:
|
|
5
|
+
order: 5
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
import ModelExample from '../../web/src/components/ModelExample.astro';
|
|
9
|
+
|
|
10
|
+
The origin defines local coordinates and is always zero in the resulting model.
|
|
11
|
+
An origin offset `d` changes every point coordinate from `p` to `p - d`, preserving
|
|
12
|
+
the shape. `rotate` turns the geometry around that local zero; a
|
|
13
|
+
[relation](relations.mdx) places the resulting part in a composition. For
|
|
14
|
+
positions, dimensions, and reference axes, start with
|
|
15
|
+
[local coordinates and placement](local-coordinates.md).
|
|
16
|
+
|
|
17
|
+
<ModelExample id="rotate" />
|
|
18
|
+
|
|
19
|
+
The [rotation example](/examples/rotate/) focuses on `rotate` alone.
|
|
20
|
+
The companion [origin source](https://github.com/vilicvane/code3d/blob/main/packages/app/examples/operations/origin.ts)
|
|
21
|
+
lets you inspect the origin operations below independently.
|
|
22
|
+
|
|
23
|
+
## Choose a pivot
|
|
24
|
+
|
|
25
|
+
Place the cursor in `blank.originVertex(3)`. Pick a vertex in the viewport to
|
|
26
|
+
use it as the origin. The ID belongs to the operation's input model, just like
|
|
27
|
+
other [topology selections](topology.md).
|
|
28
|
+
|
|
29
|
+
Use `.originPoint(pointRef)` to select a center, named point, or topology vertex
|
|
30
|
+
on any model, including a group member. Use `.originOffset(dx, dy, dz)` to move the origin by a displacement or `.originCenter()` to make
|
|
31
|
+
the body's center local zero. `originVertex()` similarly makes the chosen
|
|
32
|
+
vertex zero. These operations return new model values; `blank` is unchanged.
|
|
33
|
+
|
|
34
|
+
## Fine-tune the origin
|
|
35
|
+
|
|
36
|
+
Move to `pivoted.originOffset(0, 2, 0)` and drag an axis arrow. The origin
|
|
37
|
+
marker moves against the snapshot captured at drag start. On release, the
|
|
38
|
+
geometry switches to the resulting coordinates and the marker returns to local
|
|
39
|
+
zero. Offsets accumulate across calls.
|
|
40
|
+
|
|
41
|
+
You can also drag the origin marker's arrows while inspecting `originPoint`, `originVertex`
|
|
42
|
+
or `originCenter`. The App adds or updates an `originOffset(...)` call so the
|
|
43
|
+
chosen vertex or center remains the starting point.
|
|
44
|
+
|
|
45
|
+
## Rotate the part
|
|
46
|
+
|
|
47
|
+
In the rotation example, move to `blank.rotate(15, 35, 0)` and drag a rotation ring, or enter an angle
|
|
48
|
+
in the panel. Angles are in degrees, applied around fixed local X, then Y,
|
|
49
|
+
then Z axes. Each ring follows the effective axis of its angle parameter;
|
|
50
|
+
the rings need not line up with the world axes when other angles are nonzero.
|
|
51
|
+
|
|
52
|
+
Repeated `rotate` calls compose in source order. Named references
|
|
53
|
+
rotate with the shape, and topology IDs are preserved. Changing the origin
|
|
54
|
+
afterward does not undo an earlier rotation.
|
|
55
|
+
|
|
56
|
+
## Recenter without undoing the rotation
|
|
57
|
+
|
|
58
|
+
After a rotation, `.originCenter()` recenters the result. The `center` anchor follows the body's
|
|
59
|
+
transforms; it is not recalculated from the rotated shape's axis-aligned
|
|
60
|
+
bounding box. A subsequent `originOffset(0, 2, 0)` moves the pivot beyond that center.
|
|
61
|
+
|
|
62
|
+
Applying `originOffset(0, -2, 0)` cancels that last offset. The center is again
|
|
63
|
+
local zero, and the shape retains its rotation.
|
|
64
|
+
|
|
65
|
+
## Compose with other parts
|
|
66
|
+
|
|
67
|
+
Origin operations, `rotate()` and `scaled()` preview their own returned value.
|
|
68
|
+
Their ordinary preview does not add downstream consumers. Select the inputs of
|
|
69
|
+
`group`, `union`, `cut`, `intersect` or `loft` to inspect the context declared by
|
|
70
|
+
that operation's public inspector. A standalone model uses its local frame;
|
|
71
|
+
an ordinary collection retains its members' shared composition positions.
|
|
72
|
+
|
|
73
|
+
Inspectors can retain the pose at the selected operation, so later transformations
|
|
74
|
+
do not replace its geometry or stage. See [source inspection](runtime.md#source-inspection)
|
|
75
|
+
for the common rules and custom JSDoc callbacks.
|
|
76
|
+
|
|
77
|
+
A relation such as `companion.relate(part => part.on(rotated.up))` can place
|
|
78
|
+
a companion against a rotated part before grouping them. Inspecting the companion by itself uses its local
|
|
79
|
+
frame, without its assembly placement.
|
|
80
|
+
|
|
81
|
+
Origin edits update the local coordinates of geometry, bounds and named
|
|
82
|
+
references together. The model's `up` direction remains local +Y even after
|
|
83
|
+
geometry rotates. For a rotation that only affects composition, use a
|
|
84
|
+
[constraint pivot or axis](relations.mdx#choose-a-rotation-pivot-or-axis), with
|
|
85
|
+
coordinates written as `pivot([x, y, z])`.
|
|
86
|
+
|
|
87
|
+
## Finish or cancel a drag
|
|
88
|
+
|
|
89
|
+
Dragging previews the change. Release to write it to source, or press `Esc`
|
|
90
|
+
before releasing to cancel. Cancellation keeps the panel and editor position;
|
|
91
|
+
move the cursor out of the call to leave its tool. Use Undo for an edit already
|
|
92
|
+
written to source.
|
|
93
|
+
|
|
94
|
+
When possible, a drag changes a unique safe upstream parameter. Otherwise it
|
|
95
|
+
adjusts the current expression by a numeric increment. Entering a number in a
|
|
96
|
+
panel can instead replace that expression: see
|
|
97
|
+
[what a panel can edit](../../web/src/content/docs/docs/guides/model-tools.mdx#what-a-panel-can-edit).
|
|
98
|
+
|
|
99
|
+
Solids, faces, curves, and points provide all these operations. Groups provide
|
|
100
|
+
`originPoint()`, `originOffset()` and `rotate()`; their default origin comes from the first member's local coordinate frame. See [group origins](local-coordinates.md#group-origins)
|
|
101
|
+
for direct assembly and instance selection. To rotate the whole assembly about
|
|
102
|
+
a member point, use `assembly.originPoint(part.center).rotate(0, 0, 30)`. Its
|
|
103
|
+
internal placements remain intact, including nested groups; angle inputs and
|
|
104
|
+
rotation rings work the same way as on a single part. See the [API reference](api.md#origins-and-rotation)
|
|
105
|
+
for the complete method list.
|