* Parse [T] instead of T[] for array types Signed-off-by: Nick Cameron <nrc@ncameron.org> * homogenous arrays, type coercion, remove solid set and sketch set, etc Signed-off-by: Nick Cameron <nrc@ncameron.org> --------- Signed-off-by: Nick Cameron <nrc@ncameron.org>
		
			
				
	
	
	
		
			748 KiB
		
	
	
	
	
	
	
	
			
		
		
	
	title, excerpt, layout
| title | excerpt | layout | 
|---|---|---|
| patternTransform | Repeat a 3-dimensional solid, changing it each time. | manual | 
Repeat a 3-dimensional solid, changing it each time.
Replicates the 3D solid, applying a transformation function to each replica. Transformation function could alter rotation, scale, visibility, position, etc.
The patternTransform call itself takes a number for how many total instances of the shape should be. For example, if you use a circle with patternTransform(instances = 4, transform = f) then there will be 4 circles: the original, and 3 created by replicating the original and calling the transform function on each.
The transform function 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. This simplifies your math: the transform function can rely on id 0 being the original instance passed into the patternTransform. See the examples.
The transform function returns a transform object. All properties of the object are optional, they each default to "no change". So the overall transform object defaults to "no change" too. Its properties are:
- 
translate(3D point)Translates the replica, moving its position in space.
 - 
replicate(bool)If false, this ID will not actually copy the object. It'll be skipped.
 - 
scale(3D point)Stretches the object, multiplying its width in the given dimension by the point's component in that direction.
 - 
rotation(object, with the following properties)- 
rotation.axis(a 3D point, defaults to the Z axis) - 
rotation.angle(number of degrees) - 
rotation.origin(either "local" i.e. rotate around its own center, "global" i.e. rotate around the scene's center, or a 3D point, defaults to "local") 
 - 
 
patternTransform(
  solids: [Solid],
  instances: integer,
  transform: FunctionSource,
  useOriginal?: bool,
): [Solid]
Arguments
| Name | Type | Description | Required | 
|---|---|---|---|
solids | 
[Solid] | 
The solid(s) to duplicate | Yes | 
instances | 
integer | 
The number of total instances. Must be greater than or equal to 1. This includes the original entity. For example, if instances is 2, there will be two copies -- the original, and one new copy. If instances is 1, this has no effect. | Yes | 
transform | 
FunctionSource | 
How each replica should be transformed. The transform function 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. This simplifies your math: the transform function can rely on id 0 being the original instance passed into the patternTransform. See the examples. | 
Yes | 
useOriginal | 
bool | 
If the target was sketched on an extrusion, setting this will use the original sketch as the target, not the entire joined solid. Defaults to false. | No | 
Returns
Examples
// Each instance will be shifted along the X axis.
fn transform(id) {
  return { translate = [4 * id, 0, 0] }
}
// Sketch 4 cylinders.
sketch001 = startSketchOn('XZ')
  |> circle(center = [0, 0], radius = 2)
  |> extrude(length = 5)
  |> patternTransform(instances = 4, transform = transform)
// Each instance will be shifted along the X axis,
// with a gap between the original (at x = 0) and the first replica
// (at x = 8). This is because `id` starts at 1.
fn transform(id) {
  return { translate = [4 * (1 + id), 0, 0] }
}
sketch001 = startSketchOn('XZ')
  |> circle(center = [0, 0], radius = 2)
  |> extrude(length = 5)
  |> patternTransform(instances = 4, transform = transform)
fn cube(length, center) {
  l = length / 2
  x = center[0]
  y = center[1]
  p0 = [-l + x, -l + y]
  p1 = [-l + x, l + y]
  p2 = [l + x, l + y]
  p3 = [l + x, -l + y]
  return startSketchOn('XY')
    |> startProfileAt(p0, %)
    |> line(endAbsolute = p1)
    |> line(endAbsolute = p2)
    |> line(endAbsolute = p3)
    |> line(endAbsolute = p0)
    |> close()
    |> extrude(length = length)
}
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" }
  }
}
myCubes = cube(width, [100, 0])
  |> patternTransform(instances = 25, transform = transform)
fn cube(length, center) {
  l = length / 2
  x = center[0]
  y = center[1]
  p0 = [-l + x, -l + y]
  p1 = [-l + x, l + y]
  p2 = [l + x, l + y]
  p3 = [l + x, -l + y]
  return startSketchOn('XY')
    |> startProfileAt(p0, %)
    |> line(endAbsolute = p1)
    |> line(endAbsolute = p2)
    |> line(endAbsolute = p3)
    |> line(endAbsolute = p0)
    |> close()
    |> extrude(length = length)
}
width = 20
fn transform(i) {
  return {
    translate = [0, 0, -i * width],
    rotation = {
      angle = 90 * i,
      // Rotate around the overall scene's origin.
      origin = "global"
    }
  }
}
myCubes = cube(width, [100, 100])
  |> patternTransform(instances = 4, transform = transform)
// Parameters
r = 50 // base radius
h = 10 // layer height
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) {
  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, tag = $tag1)
    |> extrude(length = h)
}
// The vase is 100 layers tall.
// The 100 layers are replica of each other, with a slight transformation applied to each.
vase = layer()
  |> patternTransform(instances = 100, transform = transform)
fn transform(i) {
  // Transform functions can return multiple transforms. They'll be applied in order.
  return [
    { translate = [30 * i, 0, 0] },
    { rotation = { angle = 45 * i } }
  ]
}
startSketchOn('XY')
  |> startProfileAt([0, 0], %)
  |> polygon({
       radius = 10,
       numSides = 4,
       center = [0, 0],
       inscribed = false
     }, %)
  |> extrude(length = 4)
  |> patternTransform(instances = 3, transform = transform)