Skip to content

Instantly share code, notes, and snippets.

@medicationforall
Last active December 17, 2025 06:28
Show Gist options
  • Select an option

  • Save medicationforall/a9f69e8f389d60a53e73327a3d77283e to your computer and use it in GitHub Desktop.

Select an option

Save medicationforall/a9f69e8f389d60a53e73327a3d77283e to your computer and use it in GitHub Desktop.

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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment