-
Notifications
You must be signed in to change notification settings - Fork 1
Description
This is awesome. I've been able to use it successfully to convert a picture of the 2024 eclipse into an stl I can import to Fusion360. Hoping to machine it out, ebonize the wood, pour in translucent epoxy, then machine flat and obtain a cool gradient look.
Anyway, had some thoughts as I wrapped my head around the code.
-
what about adjusting parameters to be more objective vs. relative?
reduction_factor
andscale
work, but I wasn't able to figure out what values to use except by trial and error. I could envision providing a scaled image dimensions instead, or having scale be the output object dimensions in mm. -
super minor, but I think you can get away with this instead of the use of
baselayer_height
and subtracting 1 fromnum_layers
. Also,right=True
fordigitize
seemed to work better thanright=False
(default) and subtracting 1 from the height map result.
# Discretize the height map
discrete_heights = np.linspace(layer_height, layer_height * num_levels, num_levels)
height_map = np.digitize(img, bins=np.linspace(0, 1, num_levels), right=True)
height_map = discrete_heights[height_map]
- I also used this, and didn't get any errors or issues... is there a reason to do
range(0, height-1, 1)
instead?
# Create the faces array
faces = []
for y in range(height):
for x in range(width):
- I noticed for every bottom face, you were connecting to a vertex at the lowest height. As this is primarily for 3d printing, maybe that's correct? For me, it seemed unintuitive why to do this. I changed it to this, which gives us a flat back at
z=0
vs. atz=layer_height
# Bottom face (base of the lithophane)
v0_b = [v0[0], v0[1], 0]
v1_b = [v1[0], v1[1], 0]
v2_b = [v2[0], v2[1], 0]
v3_b = [v3[0], v3[1], 0]
- lastly, I wanted my stl high res for a nice smooth gradient, so I'm currently using 100 levels. This slows things down quite a bit. If I'm not mistaken, I believe you are adding sides to every single set of vertices internally? I'm not sure how things would behave with 3d printing, but I had success commenting that bit out, and then adding 8 faces just to the perimeter (2 triangles per side). I also added an argument so one could specify to "fill" (internal sides, use your existing code) or not (just add exterior sides to complete the shell)
# Add side faces around perimeter if internal faces not created
if not filled:
tl = vertices[0, 0]
tr = vertices[0, width - 1]
bl = vertices[height-1, 0]
br = vertices[height-1, width - 1]
faces.append([tl, bl, [bl[0], bl[1], 0]])
faces.append([tl, [tl[0], tl[1], 0], [bl[0], bl[1], 0]])
faces.append([tl, tr, [tr[0], tr[1], 0]])
faces.append([tl, [tr[0], tr[1], 0], [tl[0], tl[1], 0]])
faces.append([tr, br, [br[0], br[1], 0]])
faces.append([tr, [br[0], br[1], 0], [tr[0], tr[1], 0]])
faces.append([br, bl, [bl[0], bl[1], 0]])
faces.append([br, [bl[0], bl[1], 0], [br[0], br[1], 0]])
If any of this is useful, I can do a PR. Happy to putz on some other ideas above, like how to scale to a set size. This would be awesome for my purposes. My image is 900px, so I get a 900mm image (I'm using reduction_factor=scale=1
) and then scale to my target of 6x6in.