Pattern transforms now have a new `rotation` parameter, letting you rotate each instance of the shape. Currently only rotation around the local origin (i.e. rotating the object around the center of its own bounding box) works correctly. Rotating around a global origin (i.e. center of the scene) will be fixed on the server side soon.
511 lines
428 KiB
Markdown
511 lines
428 KiB
Markdown
---
|
||
title: "patternTransform"
|
||
excerpt: "Repeat a 3-dimensional solid by successively applying a transformation (such"
|
||
layout: manual
|
||
---
|
||
|
||
Repeat a 3-dimensional solid by successively applying a transformation (such
|
||
|
||
as rotation, scale, translation, visibility) on each repetition.
|
||
The transformation takes a single parameter: an integer representing which number replication the transform is for. E.g. the first replica to be transformed will be passed the argument `1`.
|
||
|
||
```js
|
||
patternTransform(num_repetitions: u32, transform_function: FunctionParam, extrude_group_set: ExtrudeGroupSet) -> [ExtrudeGroup]
|
||
```
|
||
|
||
### Examples
|
||
|
||
```js
|
||
fn cube = (length, center) => {
|
||
let l = length / 2
|
||
let x = center[0]
|
||
let y = center[1]
|
||
let p0 = [-l + x, -l + y]
|
||
let p1 = [-l + x, l + y]
|
||
let p2 = [l + x, l + y]
|
||
let p3 = [l + x, -l + y]
|
||
|
||
return startSketchAt(p0)
|
||
|> lineTo(p1, %)
|
||
|> lineTo(p2, %)
|
||
|> lineTo(p3, %)
|
||
|> lineTo(p0, %)
|
||
|> close(%)
|
||
|> extrude(length, %)
|
||
}
|
||
|
||
let width = 20
|
||
fn transform = (i) => {
|
||
return {
|
||
// Move down each time.
|
||
translate: [0, 0, -i * width],
|
||
// Make the cube longer, wider and flatter each time.
|
||
scale: [pow(1.1, i), pow(1.1, i), pow(0.9, i)],
|
||
// Turn by 15 degrees each time.
|
||
rotation: { angle: 15 * i, origin: "local" }
|
||
}
|
||
}
|
||
|
||
let myCubes = cube(width, [100, 0])
|
||
|> patternTransform(25, transform, %)
|
||
```
|
||
|
||

|
||
|
||
```js
|
||
// Parameters
|
||
const r = 50 // base radius
|
||
const h = 10 // layer height
|
||
const t = 0.005 // taper factor [0-1)
|
||
// Defines how to modify each layer of the vase.
|
||
// Each replica is shifted up the Z axis, and has a smoothly-varying radius
|
||
fn transform = (replicaId) => {
|
||
let scale = r * abs(1 - (t * replicaId)) * (5 + cos(replicaId / 8))
|
||
return {
|
||
translate: [0, 0, replicaId * 10],
|
||
scale: [scale, scale, 0]
|
||
}
|
||
}
|
||
// Each layer is just a pretty thin cylinder.
|
||
fn layer = () => {
|
||
return startSketchOn("XY")
|
||
// or some other plane idk
|
||
|> circle({ center: [0, 0], radius: 1 }, %, $tag1)
|
||
|> extrude(h, %)
|
||
}
|
||
// The vase is 100 layers tall.
|
||
// The 100 layers are replica of each other, with a slight transformation applied to each.
|
||
let vase = layer()
|
||
|> patternTransform(100, transform, %)
|
||
```
|
||
|
||

|
||
|
||
### Arguments
|
||
|
||
* `num_repetitions`: `u32` (REQUIRED)
|
||
* `transform_function`: `FunctionParam` (REQUIRED)
|
||
* `extrude_group_set`: `ExtrudeGroupSet` - A extrude group or a group of extrude groups. (REQUIRED)
|
||
```js
|
||
{
|
||
// Chamfers or fillets on this extrude group.
|
||
edgeCuts: [{
|
||
// The engine id of the edge to fillet.
|
||
edgeId: uuid,
|
||
// The id of the engine command that called this fillet.
|
||
id: uuid,
|
||
radius: number,
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "fillet",
|
||
} |
|
||
{
|
||
// The engine id of the edge to chamfer.
|
||
edgeId: uuid,
|
||
// The id of the engine command that called this chamfer.
|
||
id: uuid,
|
||
length: number,
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "chamfer",
|
||
}],
|
||
// The id of the extrusion end cap
|
||
endCapId: uuid,
|
||
// The height of the extrude group.
|
||
height: number,
|
||
// The id of the extrude group.
|
||
id: uuid,
|
||
// The sketch group.
|
||
sketchGroup: {
|
||
// The id of the sketch group (this will change when the engine's reference to it changes.
|
||
id: uuid,
|
||
// What the sketch is on (can be a plane or a face).
|
||
on: {
|
||
// The id of the plane.
|
||
id: uuid,
|
||
// Origin of the plane.
|
||
origin: {
|
||
x: number,
|
||
y: number,
|
||
z: number,
|
||
},
|
||
type: "plane",
|
||
// Type for a plane.
|
||
value: "XY" | "XZ" | "YZ" | "Custom",
|
||
// What should the plane’s X axis be?
|
||
xAxis: {
|
||
x: number,
|
||
y: number,
|
||
z: number,
|
||
},
|
||
// What should the plane’s Y axis be?
|
||
yAxis: {
|
||
x: number,
|
||
y: number,
|
||
z: number,
|
||
},
|
||
// The z-axis (normal).
|
||
zAxis: {
|
||
x: number,
|
||
y: number,
|
||
z: number,
|
||
},
|
||
} |
|
||
{
|
||
// The extrude group the face is on.
|
||
extrudeGroup: {
|
||
// Chamfers or fillets on this extrude group.
|
||
edgeCuts: [{
|
||
// The engine id of the edge to fillet.
|
||
edgeId: uuid,
|
||
// The id of the engine command that called this fillet.
|
||
id: uuid,
|
||
radius: number,
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "fillet",
|
||
} |
|
||
{
|
||
// The engine id of the edge to chamfer.
|
||
edgeId: uuid,
|
||
// The id of the engine command that called this chamfer.
|
||
id: uuid,
|
||
length: number,
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "chamfer",
|
||
}],
|
||
// The id of the extrusion end cap
|
||
endCapId: uuid,
|
||
// The height of the extrude group.
|
||
height: number,
|
||
// The id of the extrude group.
|
||
id: uuid,
|
||
// The sketch group.
|
||
sketchGroup: SketchGroup,
|
||
// The id of the extrusion start cap
|
||
startCapId: uuid,
|
||
// The extrude surfaces.
|
||
value: [{
|
||
// The face id for the extrude plane.
|
||
faceId: uuid,
|
||
// The id of the geometry.
|
||
id: uuid,
|
||
// The source range.
|
||
sourceRange: [number, number],
|
||
// The tag.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "extrudePlane",
|
||
} |
|
||
{
|
||
// The face id for the extrude plane.
|
||
faceId: uuid,
|
||
// The id of the geometry.
|
||
id: uuid,
|
||
// The source range.
|
||
sourceRange: [number, number],
|
||
// The tag.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "extrudeArc",
|
||
} |
|
||
{
|
||
// The id for the chamfer surface.
|
||
faceId: uuid,
|
||
// The id of the geometry.
|
||
id: uuid,
|
||
// The source range.
|
||
sourceRange: [number, number],
|
||
// The tag.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "chamfer",
|
||
} |
|
||
{
|
||
// The id for the fillet surface.
|
||
faceId: uuid,
|
||
// The id of the geometry.
|
||
id: uuid,
|
||
// The source range.
|
||
sourceRange: [number, number],
|
||
// The tag.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "fillet",
|
||
}],
|
||
},
|
||
// The id of the face.
|
||
id: uuid,
|
||
type: "face",
|
||
// The tag of the face.
|
||
value: string,
|
||
// What should the face’s X axis be?
|
||
xAxis: {
|
||
x: number,
|
||
y: number,
|
||
z: number,
|
||
},
|
||
// What should the face’s Y axis be?
|
||
yAxis: {
|
||
x: number,
|
||
y: number,
|
||
z: number,
|
||
},
|
||
// The z-axis (normal).
|
||
zAxis: {
|
||
x: number,
|
||
y: number,
|
||
z: number,
|
||
},
|
||
},
|
||
// The starting path.
|
||
start: {
|
||
// The from point.
|
||
from: [number, number],
|
||
// The tag of the path.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
// The to point.
|
||
to: [number, number],
|
||
},
|
||
// Tag identifiers that have been declared in this sketch group.
|
||
tags: {
|
||
},
|
||
// The paths in the sketch group.
|
||
value: [{
|
||
// The from point.
|
||
from: [number, number],
|
||
// The tag of the path.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
// The to point.
|
||
to: [number, number],
|
||
type: "ToPoint",
|
||
} |
|
||
{
|
||
// arc's direction
|
||
ccw: bool,
|
||
// the arc's center
|
||
center: [number, number],
|
||
// The from point.
|
||
from: [number, number],
|
||
// The tag of the path.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
// The to point.
|
||
to: [number, number],
|
||
type: "TangentialArcTo",
|
||
} |
|
||
{
|
||
// arc's direction
|
||
ccw: bool,
|
||
// the arc's center
|
||
center: [number, number],
|
||
// The from point.
|
||
from: [number, number],
|
||
// The tag of the path.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
// The to point.
|
||
to: [number, number],
|
||
type: "TangentialArc",
|
||
} |
|
||
{
|
||
// arc's direction
|
||
ccw: bool,
|
||
// the arc's center
|
||
center: [number, number],
|
||
// The from point.
|
||
from: [number, number],
|
||
// the arc's radius
|
||
radius: number,
|
||
// The tag of the path.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
// The to point.
|
||
to: [number, number],
|
||
type: "Circle",
|
||
} |
|
||
{
|
||
// The from point.
|
||
from: [number, number],
|
||
// The tag of the path.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
// The to point.
|
||
to: [number, number],
|
||
type: "Horizontal",
|
||
// The x coordinate.
|
||
x: number,
|
||
} |
|
||
{
|
||
// The from point.
|
||
from: [number, number],
|
||
// The tag of the path.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
// The to point.
|
||
to: [number, number],
|
||
type: "AngledLineTo",
|
||
// The x coordinate.
|
||
x: number,
|
||
// The y coordinate.
|
||
y: number,
|
||
} |
|
||
{
|
||
// The from point.
|
||
from: [number, number],
|
||
// The tag of the path.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
// The to point.
|
||
to: [number, number],
|
||
type: "Base",
|
||
}],
|
||
},
|
||
// The id of the extrusion start cap
|
||
startCapId: uuid,
|
||
type: "extrudeGroup",
|
||
// The extrude surfaces.
|
||
value: [{
|
||
// The face id for the extrude plane.
|
||
faceId: uuid,
|
||
// The id of the geometry.
|
||
id: uuid,
|
||
// The source range.
|
||
sourceRange: [number, number],
|
||
// The tag.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "extrudePlane",
|
||
} |
|
||
{
|
||
// The face id for the extrude plane.
|
||
faceId: uuid,
|
||
// The id of the geometry.
|
||
id: uuid,
|
||
// The source range.
|
||
sourceRange: [number, number],
|
||
// The tag.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "extrudeArc",
|
||
} |
|
||
{
|
||
// The id for the chamfer surface.
|
||
faceId: uuid,
|
||
// The id of the geometry.
|
||
id: uuid,
|
||
// The source range.
|
||
sourceRange: [number, number],
|
||
// The tag.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "chamfer",
|
||
} |
|
||
{
|
||
// The id for the fillet surface.
|
||
faceId: uuid,
|
||
// The id of the geometry.
|
||
id: uuid,
|
||
// The source range.
|
||
sourceRange: [number, number],
|
||
// The tag.
|
||
tag: {
|
||
digest: [number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number, number],
|
||
end: number,
|
||
start: number,
|
||
value: string,
|
||
},
|
||
type: "fillet",
|
||
}],
|
||
} |
|
||
{
|
||
type: "extrudeGroups",
|
||
}
|
||
```
|
||
|
||
### Returns
|
||
|
||
`[ExtrudeGroup]`
|
||
|
||
|
||
|