Skip to content

Instantly share code, notes, and snippets.

@popey456963
Last active July 5, 2021 11:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save popey456963/470d995032d321b6e49100c51d65f249 to your computer and use it in GitHub Desktop.
Save popey456963/470d995032d321b6e49100c51d65f249 to your computer and use it in GitHub Desktop.
Making Cubes
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
# requires the following libraries:
# - numpy-stl
# - numpy
# - matplotlib
# run as:
# python main.py
# matplotlib requires a window system available
from stl import mesh
import stl
import math
import numpy
from make_cube import make_cube, make_cube_2
layout = [
[True, False],
[True, True]
]
# layout = [
# [True, False, False],
# [True, True, False],
# [True, False, False]
# ]
layout = [
[True, True, True, True],
[True, False, False, True],
[True, False, False, True],
[True, True, True, True]
]
def get(l, i):
if i < 0 or i >= len(l):
return None
return l[i]
def get_md(l, j, i):
if j < 0 or j >= len(l):
return None
return get(l[j], i)
orthogonal_adjacents = [(0, -1), (0, 1), (-1, 0), (1, 0)]
intersections = []
for y in range(len(layout)):
for x in range(len(layout[y])):
if layout[y][x]:
for delta in orthogonal_adjacents:
other_cube = (delta[0] + x, delta[1] + y)
if other_cube[1] < 0 or other_cube[1] >= len(layout) or other_cube[0] < 0 or other_cube[0] >= len(layout[y]):
continue
if not layout[other_cube[1]][other_cube[0]]:
continue
direction = 'ROW' if delta[0] == 0 else 'COLUMN'
intersections.append(((x, y), (other_cube[0], other_cube[1]), direction))
def is_equal(a, b):
return (a[0] == b[0] and a[1] == b[1]) or (a[0] == b[1] and b[0] == a[1])
unique_intersections = []
for i, a in enumerate(intersections):
if not any(is_equal(a, b) for b in intersections[:i]):
unique_intersections.append(a)
print(unique_intersections)
count = int(len(intersections) / 2)
cubes = sum(sum(x) for x in layout)
data = make_cube()
data_2 = make_cube()
cube_size = 25.6
connector_width = 0.7
connector_depth = 0.5
data['vectors'] *= cube_size
meshes = [mesh.Mesh(data.copy()) for _ in range(cubes)]
joining_meshes = [mesh.Mesh(data_2.copy()) for _ in range(count)]
for i, _ in enumerate(joining_meshes):
item = unique_intersections[i]
if item[2] == 'ROW':
# these affect the size of the box
joining_meshes[i].y *= cube_size - (connector_depth * 2)
joining_meshes[i].z *= cube_size - (connector_depth * 2)
joining_meshes[i].x *= connector_width
# these affect it's offset from the center point
joining_meshes[i].y += ((cube_size + connector_width) * max(item[0][0], item[1][0])) + connector_depth
joining_meshes[i].x += ((cube_size + connector_width) * max(item[0][1], item[1][1])) - connector_width
if item[2] == 'COLUMN':
# these affect the size of the box
joining_meshes[i].x *= cube_size - (connector_depth * 2)
joining_meshes[i].y *= connector_width
joining_meshes[i].z *= cube_size - (connector_depth * 2)
# these affect it's offset from the center point
joining_meshes[i].y += ((cube_size + connector_width) * max(item[0][0], item[1][0])) - connector_width
joining_meshes[i].x += ((cube_size + connector_width) * max(item[0][1], item[1][1])) + connector_depth
# we want the joining meshes to be half a mm
joining_meshes[i].z += connector_depth
cur_cube = 0
for row_idx, row in enumerate(layout):
for column_idx, item in enumerate(row):
if item:
meshes[cur_cube].x += (cube_size + connector_width) * row_idx
meshes[cur_cube].y += (cube_size + connector_width) * column_idx
cur_cube += 1
# Optionally render the rotated cube faces
from matplotlib import pyplot
from mpl_toolkits import mplot3d
# Create a new plot
figure = pyplot.figure()
axes = mplot3d.Axes3D(figure)
# Render the cube faces
for m in meshes:
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(m.vectors))
for m in joining_meshes:
axes.add_collection3d(mplot3d.art3d.Poly3DCollection(m.vectors))
# Auto scale to the mesh size
scale = numpy.concatenate([m.points for m in meshes]).flatten()
axes.auto_scale_xyz(scale, scale, scale)
combined = mesh.Mesh(numpy.concatenate([copy.data for copy in meshes] + [a.data for a in joining_meshes]))
combined.save('cube.stl', mode=stl.Mode.ASCII)
# mesh.Mesh(scale).save('cube.stl')
# Show the plot to the screen
pyplot.show()
import numpy
from stl import mesh
def make_cube():
# Create 3 faces of a cube
data = numpy.zeros(12, dtype=mesh.Mesh.dtype)
# Top of the cube
data['vectors'][0] = numpy.array([[0, 1, 1],
[1, 0, 1],
[0, 0, 1]])
data['vectors'][1] = numpy.array([[1, 0, 1],
[0, 1, 1],
[1, 1, 1]])
# Front face
data['vectors'][2] = numpy.array([[1, 0, 0],
[1, 0, 1],
[1, 1, 0]])
data['vectors'][3] = numpy.array([[1, 1, 1],
[1, 0, 1],
[1, 1, 0]])
# Left face
data['vectors'][4] = numpy.array([[0, 0, 0],
[1, 0, 0],
[1, 0, 1]])
data['vectors'][5] = numpy.array([[0, 0, 0],
[0, 0, 1],
[1, 0, 1]])
# Top of the cube
data['vectors'][6] = numpy.array([[0, 1, 0],
[1, 0, 0],
[0, 0, 0]])
data['vectors'][7] = numpy.array([[1, 0, 0],
[0, 1, 0],
[1, 1, 0]])
# Front face
data['vectors'][8] = numpy.array([[0, 0, 0],
[0, 0, 1],
[0, 1, 0]])
data['vectors'][9] = numpy.array([[0, 1, 1],
[0, 0, 1],
[0, 1, 0]])
# Left face
data['vectors'][10] = numpy.array([[0, 1, 0],
[1, 1, 0],
[1, 1, 1]])
data['vectors'][11] = numpy.array([[0, 1, 0],
[0, 1, 1],
[1, 1, 1]])
return data
def make_cube_2():
# Create 3 faces of a cube
data2 = numpy.zeros(8, dtype=mesh.Mesh.dtype)
# Top of the cube
data2['vectors'][0] = numpy.array([[0, 1, 1],
[1, 0, 1],
[0, 0, 1]])
data2['vectors'][1] = numpy.array([[1, 0, 1],
[0, 1, 1],
[1, 1, 1]])
# Left face
data2['vectors'][2] = numpy.array([[0, 0, 0],
[1, 0, 0],
[1, 0, 1]])
data2['vectors'][3] = numpy.array([[0, 0, 0],
[0, 0, 1],
[1, 0, 1]])
# Top of the cube
data2['vectors'][4] = numpy.array([[0, 1, 0],
[1, 0, 0],
[0, 0, 0]])
data2['vectors'][5] = numpy.array([[1, 0, 0],
[0, 1, 0],
[1, 1, 0]])
# Left face
data2['vectors'][6] = numpy.array([[0, 1, 0],
[1, 1, 0],
[1, 1, 1]])
data2['vectors'][7] = numpy.array([[0, 1, 0],
[0, 1, 1],
[1, 1, 1]])
return data2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment