Irregular Grid

03

Drawing inspiration from this blog post An Algorithm for Irregular Grids I added an irregular grid implementation to cadqueryhelper.

Before delving further check out the blog post!
https://www.gorillasun.de/blog/an-algorithm-for-irregular-grids/

Helpful Videos

Code Referenced


The way it works is:

  • You define the overall shape of your grid in, length, width, and height.
  • Define the individual cell size in millimeters.
  • Define the max number of cells in cols, and rows; that an item can take up.

05

That sets up the outline of the grid, then we randomize a bunch of stuff.

  • Set a seed string value for pseudo random number generation.
  • Tell the grid the max height an item can be.
  • Provide a callback method
    • that takes length, width, height as it's parameters.
    • returns a cadquery shape center aligned by all three axis.
  • The code takes your custom defined shape and places it on the grid.
  • A booleon matrix matching the rows and columns of the grid is updated to reflect the space now reserved.

If we have a grid that's ten columns and five rows; and we add an item that's four columns by three rows it will be represented on the boolean matrix as such.

22

The Grid finds the next open position which is the fifth column and first row. or in this example position E, 0

23

Roll the next items dimensions, by random chance it happens to be two columns by four rows. Which gets placed on the grid.

24

So far we have this: 06

Find the next open position and repeat the process until the grid is full.

07

And the code looks like this:

import cadquery as cq
from cadqueryhelper import irregular_grid

ig = irregular_grid(
    length = 100,
    width = 50,
    col_size = 10,
    row_size = 10,
    union_grid=False,
    seed="test3",
    fill_cells = [(0,0,4,3), (4,0,2,4)],
)

show_object(ig)

Heads up; I'm cheating by setting the first two items to match our specific dimensions. The rest of the cells were randomly filled by the seed "test3".

How simple is that!
Here's some other examples


Simple

01

import cadquery as cq
from cadqueryhelper import irregular_grid

i_grid = irregular_grid(
    length = 75,
    width = 50,
    height = 2,
    max_height = 10,
    col_size = 5,
    row_size = 5,
    union_grid=False,
    seed = "test",
)

show_object(i_grid)

Setting Custom Item callback

02

import cadquery as cq
from cadqueryhelper import irregular_grid

def custom_item(length, width, height):
    return (
        cq.Workplane("XY")
        .box(length-1, width-1, height)
        .chamfer(0.5)
    )

i_grid_2 = irregular_grid(
    length = 150,
    width = 50,
    height = 2,
    max_height = 10,
    col_size = 5,
    row_size = 5,
    align_z = True,
    include_outline = True,
    seed = "test",
    make_item = custom_item
)

show_object(i_grid_2)

Skyline

04

import cadquery as cq
from cadqueryhelper import irregular_grid

def custom_item(length, width, height):
    return (
        cq.Workplane("XY")
        .box(length-1, width-1, height)
        .chamfer(0.5)
    )

i_grid_4_sky_scapers = irregular_grid(
    length = 100,
    width = 100,
    height = 2,
    col_size = 10,
    row_size = 5,
    max_columns = 4,
    max_rows = 4,
    max_height=50,
    align_z = True,
    include_outline = True,
    union_grid = True,
    passes_count = 160,
    seed = "purple",
    make_item = custom_item
)

show_object(i_grid_4_sky_scapers)

Applying Irregular Grids to Terrain

18 For me this is the payoff, because I can do complex greebling in a relatively straighforward fashion.

Walkway

21

import random
import cadquery as cq
from cqindustry import Walkway
from cqterrain import tile as terrain_tile

tile_styles = [
    terrain_tile.plain,
    terrain_tile.chamfer_frame,
    terrain_tile.rivet,
    terrain_tile.slot
]
tile_styles_count = len(tile_styles)

def custom_tile(length, width, height):
    tile_style = random.randrange(0,tile_styles_count)
    tile = tile_styles[tile_style](length, width, height)
    return tile

bp = Walkway()
bp.length = 75
bp.width = 50
bp.height = 6
bp.walkway_chamfer = 3

bp.render_slots = 'irregular'
bp.tile_max_height = 4
bp.tile_seed = 'or'
bp.make_tile_method = custom_tile
bp.tile_max_columns = 5
bp.tile_max_rows = 5

bp.render_tabs = True
bp.tab_chamfer = 4.5
bp.tab_height = 2
bp.tab_length = 5

bp.render_rails = True
bp.rail_width = 4
bp.rail_height = 2
bp.rail_chamfer = 1.9

bp.render_rail_slots = False

bp.make()
walkway_small = bp.build()

show_object(walkway_small)

This is a whole other topic of discussion..
Check out:

That's enough of a brain dump!