Last active
July 2, 2023 18:34
-
-
Save bramp/ad9e0cf6781bf9e20454dd2e07be82bd to your computer and use it in GitHub Desktop.
Creates a model of a 3D Hilbert curve, suitable for 3D printing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python3 | |
# Creates a model of a 3D Hilbert curve, suitable for 3D printing. | |
# by Andrew Brampton (bramp.net) 2023 | |
# See https://www.printables.com/model/518431 | |
# | |
# Usage: | |
# python3 make.py 4 4 4 --voxelizer voxelmap --spacing 3 | |
# python3 make.py 4 4 4 --voxelizer trimesh --spacing 2 | |
# | |
from gilbert import gilbert3d | |
import numpy as np | |
import argparse | |
def vxmVoxel(array): | |
"""Uses MarchingMesh and tends to create diamond shaped tunneled.""" | |
import voxelmap as vxm | |
model = vxm.Model() | |
model.array = array | |
print('Display as a voxel') | |
#model.draw(wireframe=True, background_color='#3e404e',window_size=[1024,1024]) | |
print('Convert to mesh') | |
model.MarchingMesh(method="lewiner") | |
model.MeshView(wireframe=True,alpha=1,background_color='#b064fd',viewport=[1024,1024]) | |
def trimeshVoxel(array): | |
"""Uses as_boxes and creates square shaped tunneled.""" | |
from trimesh import voxel as v | |
voxels = v.VoxelGrid(array) | |
print('Convert to mesh (saved as trimesh.obj)') | |
boxes = voxels.as_boxes() | |
boxes.export("trimesh.obj") | |
boxes.show() | |
#voxels.marching_cubes.show() | |
def cmp(a, b): | |
return (a > b) - (a < b) | |
def line(a, start, end, value): | |
"""Very quick and dirty 3D line drawing in steps of 1""" | |
while start != end: | |
a[start] = value | |
start = ( | |
start[0] - cmp(start[0], end[0]), | |
start[1] - cmp(start[1], end[1]), | |
start[2] - cmp(start[2], end[2]) | |
) | |
a[start] = value | |
if __name__ == "__main__": | |
parser = argparse.ArgumentParser() | |
parser.add_argument('width', type=int) | |
parser.add_argument('height', type=int) | |
parser.add_argument('depth', type=int) | |
parser.add_argument('--margin', default=1, type=int) | |
parser.add_argument('--spacing', default=3, type=int) | |
parser.add_argument('--voxelizer', choices=["voxelmap", "trimesh"], default="voxelmap") | |
args = parser.parse_args() | |
array = np.zeros(( | |
args.width * args.spacing + 2*args.margin, | |
args.height * args.spacing + 2*args.margin, | |
args.depth * args.spacing + 2*args.margin, | |
)) | |
last = None | |
for x, y, z in gilbert3d.gilbert3d(args.width, args.height, args.depth): | |
cur = ( | |
x * args.spacing + args.margin, | |
y * args.spacing + args.margin, | |
z * args.spacing + args.margin, | |
) | |
if last != None: | |
# Draw line from las to cur | |
line(array, last, cur, 1) | |
last = cur | |
if args.voxelizer == "voxelmap": | |
vxmVoxel(array) | |
elif args.voxelizer == "trimesh": | |
trimeshVoxel(array) | |
else: | |
print("unknown voxel engine") | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment