Skip to content

Instantly share code, notes, and snippets.

@ril3y
Created January 8, 2024 01:56
Show Gist options
  • Save ril3y/0a37ba1f5197dcda3739260fc1379572 to your computer and use it in GitHub Desktop.
Save ril3y/0a37ba1f5197dcda3739260fc1379572 to your computer and use it in GitHub Desktop.
gridfinity drawer generator
import svgwrite
import argparse
# Constants
top_unit_size_mm = 42 # The top size of the grid unit in mm (for spacing)
base_unit_size_mm = 37.1 # The base size of the grid unit in mm (for drawing)
corner_radius_mm = 1.6 # Radius of the rounded corners in mm
mm_per_inch = 25.4 # Millimeters per inch
dpi = 96 # DPI (standard for many systems)
hairline_stroke_mm = .01 # Hairline stroke width in mm for laser cutting
def mm_to_px(mm):
"""Convert millimeters to pixels using the specified DPI."""
return mm * (dpi / mm_per_inch)
def create_gridfinity_baseplate_svg(filename, top_unit_size_px, base_unit_size_px, corner_radius_px, border_width_px,
drawer_size_inch=None, grid_size=None):
if drawer_size_inch:
# Drawer mode: Calculate the number of columns and rows based on drawer dimensions in inches
drawer_width_px = mm_to_px(drawer_size_inch[0] * mm_per_inch)
drawer_height_px = mm_to_px(drawer_size_inch[1] * mm_per_inch)
cols = int(drawer_width_px // top_unit_size_px)
rows = int(drawer_height_px // top_unit_size_px)
# Calculate the starting position to center the grid
start_x_px = (drawer_width_px - (cols * top_unit_size_px)) / 2
start_y_px = (drawer_height_px - (rows * top_unit_size_px)) / 2
print(
f"Drawer mode: Adding {cols} columns and {rows} rows within a {drawer_size_inch[0]} inch x {drawer_size_inch[1]} inch drawer.")
width_px = drawer_width_px
height_px = drawer_height_px
else:
# Custom grid mode
cols, rows = grid_size
width_px = cols * top_unit_size_px + 2 * border_width_px
height_px = rows * top_unit_size_px + 2 * border_width_px
start_x_px = start_y_px = border_width_px # Add border width for offset in custom grid mode
print(
f"Custom grid mode: Creating a grid of {cols} columns and {rows} rows with a border width of {border_width_px / mm_per_inch:.2f} inches.")
# Create SVG drawing with explicit size in pixels
dwg = svgwrite.Drawing(filename, size=(f"{width_px}px", f"{height_px}px"), profile='tiny')
# Draw the enclosing border
if border_width_px > 0 or drawer_size_inch:
dwg.add(dwg.rect(insert=(0, 0), size=(f"{width_px}px", f"{height_px}px"), rx=f"{corner_radius_px}px",
ry=f"{corner_radius_px}px", stroke="black", fill="none",
stroke_width=f"{mm_to_px(hairline_stroke_mm)}px"))
# Draw the grid with rounded corners inside the border
for x in range(cols):
for y in range(rows):
x_pos_px = start_x_px + x * top_unit_size_px + (top_unit_size_px - base_unit_size_px) / 2
y_pos_px = start_y_px + y * top_unit_size_px + (top_unit_size_px - base_unit_size_px) / 2
dwg.add(dwg.rect(insert=(f"{x_pos_px}px", f"{y_pos_px}px"),
size=(f"{base_unit_size_px}px", f"{base_unit_size_px}px"), rx=f"{corner_radius_px}px",
ry=f"{corner_radius_px}px", stroke="black", fill="none",
stroke_width=f"{mm_to_px(hairline_stroke_mm)}px"))
dwg.save()
def main():
parser = argparse.ArgumentParser(description="Create a SVG for a Gridfinity baseplate.")
parser.add_argument("--drawer_width", type=float, help="Width of the drawer in inches.")
parser.add_argument("--drawer_height", type=float, help="Height of the drawer in inches.")
parser.add_argument("--columns", type=int, help="Number of columns in the grid.")
parser.add_argument("--rows", type=int, help="Number of rows in the grid.")
parser.add_argument("--border_width", type=float, default=0, help="Width of the border in mm (optional).")
args = parser.parse_args()
border_width_px = mm_to_px(args.border_width)
if args.drawer_width and args.drawer_height:
# Drawer mode
create_gridfinity_baseplate_svg("gridfinity_baseplate.svg", mm_to_px(top_unit_size_mm),
mm_to_px(base_unit_size_mm), mm_to_px(corner_radius_mm), border_width_px,
drawer_size_inch=(args.drawer_width, args.drawer_height))
elif args.columns and args.rows:
# Custom grid mode
create_gridfinity_baseplate_svg("gridfinity_baseplate.svg", mm_to_px(top_unit_size_mm),
mm_to_px(base_unit_size_mm), mm_to_px(corner_radius_mm), border_width_px,
grid_size=(args.columns, args.rows))
else:
print("Please provide either drawer dimensions or grid size.")
exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment