Creating Brick Patterns - How To Cover A Shape In Bricks

How to cover a shape in a collection of bricks using python and cadquery

Make The Initial Shape

import cadquery as cq
height = 50
diameter = 30

base_shape = (
    cq.Workplane("XY")
    .cylinder(height, diameter / 2)
    .translate((0,0, height / 2))
)

show_object(base_shape)
01

Make A Grid

  • Determine how many columns / rows / layers you want.
  • How much space you want between the bricks.
  • Make the brick / tile shape to be replicated.
rows = 5
columns = 4
layers = 9

x_size = diameter / rows
y_size = diameter / columns
z_size = height / layers
space = .5

brick = cq.Workplane("XY").box(
    x_size-space*2, 
    y_size-space*2, 
    z_size-space*2
).translate((0,0,z_size/2))

def add_brick(loc):
    return brick.val().located(loc)

grid = (
    cq.Workplane("XY")
    .rarray(
        xSpacing = x_size, 
        ySpacing = y_size,
        xCount = rows+1, 
        yCount= columns+1, 
        center = True)
    .eachpoint(add_brick)

)

show_object(grid)
02

Layer The Grid

layer_grid = cq.Workplane("XY")

for i in range(layers):
    layer_grid = layer_grid.add(grid.translate((0,0,i*z_size)))

show_object(layer_grid)
03

Intersect Grid With Your Base Shape

brick_shape = base_shape.intersect(layer_grid)

show_object(brick_shape)
04

Add A Smaller Interior Shape And Union

inner_height = 50 - (space * 4)
inner_diameter = 30 - (space * 4)

inner_shape = (
    cq.Workplane("XY")
    .cylinder(inner_height, inner_diameter / 2)
    .translate((0,0, height / 2))
)

combined = brick_shape.union(inner_shape)

show_object(combined)
05

Offset The Even Brick Layers

  • Modify the layer loop to offset the even brick rows.
for i in range(layers):
    x_translate = 0
    y_translate = 0
    
    if i % 2 == 0:
        x_translate = x_size / 2
        y_translate = y_size / 2
    
    layer_grid = (
        layer_grid
        .add(grid.translate((
            x_translate,
            y_translate,
            i*z_size
        )))
    )

show_object(layer_grid)
06

Bringing It All Together

import cadquery as cq
height = 50
diameter = 30

base_shape = (
    cq.Workplane("XY")
    .cylinder(height,diameter/2)
    .translate((0,0,height/2))
)

#show_object(base_shape)

rows = 5
columns = 4
layers = 9

x_size = diameter / rows
y_size = diameter / columns
z_size = height / layers
space = .5

brick = cq.Workplane("XY").box(
    x_size-space*2, 
    y_size-space*2, 
    z_size-space*2
).translate((0,0,(z_size-space*2)/2))

def add_brick(loc):
    return brick.val().located(loc)

grid = (
    cq.Workplane("XY")
    .rarray(
        xSpacing = x_size, 
        ySpacing = y_size,
        xCount = rows+1, 
        yCount= columns+1, 
        center = True)
    .eachpoint(add_brick)
)

#show_object(grid)

layer_grid = cq.Workplane("XY")

for i in range(layers):
    x_translate = 0
    y_translate = 0
    
    if i % 2 == 0:
        x_translate = x_size / 2
        y_translate = y_size / 2
    
    layer_grid = (
        layer_grid
        .add(grid.translate((
            x_translate,
            y_translate,
            i*z_size
        )))
    )

#show_object(layer_grid)

brick_shape = base_shape.intersect(layer_grid)

#show_object(brick_shape)

inner_height = 50 - (space * 4)
inner_diameter = 30 - (space * 4)

inner_shape = (
    cq.Workplane("XY")
    .cylinder(inner_height, inner_diameter / 2)
    .translate((0,0, inner_height / 2))
)

combined = brick_shape.union(inner_shape)

show_object(combined)
07

The overall pattern can reused and modified for all kinds of use cases.

14
view raw brickify.md hosted with ❤ by GitHub