trimesh
trimesh copied to clipboard
sweep_polygon with cyclic path
Hello there. First let me thank you for such great library!
I'm looking for making a path extrude like sweep_polygon where path is actually a closed shape (the beginning of the path is the same as the end). I've tried using the function and it works fine, but not for cyclic path, it stays open at the end. By looking at the code I see the "cap" at beginning and and are created and I see no option to remove them and close the shape. Would that be an interesting feature to develop add a flag for that use case (I could contribute)? Or maybe I missed a function doing this already.
funny example: from svg (red one is the profile=polygon and blue one is the cyclic path) into a mesh
Thank you.
Glad it's useful! Yeah I think that case probably isn't handled in sweep (PR's welcome!). You could also try trimesh.creation.revolve and then apply a skew if the path is just an elipse. Revolve definitely handles the closed case as it's used for generating all the revolved solids (capsule/cone/cylinder/etc) in trimesh.creation.
https://github.com/mikedh/trimesh/blob/c880b028243fdcb128368d9dcd73fdb343fa15ac/trimesh/creation.py#L41-L76
Greetings @mikedh! During the time since posting, I've wrote my own implementation, the reason is I wanted something general that can handle pretty much anything simply. One of my concrete example was making a screw thread. I tried in trimesh and here is what happened (the shape starts at the bottom and goes upwards, we can see the original polygon at beginning, it started so well):
Basically I specify a path that's a XY circle up to 2*pi*height/pitch and Z is np.linspace going up (one pitch for each revolution of XY). We can see the sweeped polygon is rotated more and more with every turn (some kind of roll), that's really weird! My implementation doesn't have path pitch yet but has proper orientation, this is what I expected:
Any idea why trimesh does that roll? It seems it wasn't made for rotations >2pi I'm not sure. I tried reading the code but didn't had much time. Maybe you can shed some light on that aspect?
Here is another example I wanted to be able to do: rails along arbitrary path with an arbitrary profile:
Depending if the incremental roll exhibited above by trimesh is part of its feature (for some reason it escapes me right now), if not I may be able to adapt it to make a PR in trimesh then we can assess if it's useful to contribute. Also I'm sorry I don't have the trimesh code at hand but I can provide it or try rewriting it quickly if necessary (let me know). Thoughts?
PS: I was curious so I've given a shot with revolve but it's closing the top surface (which doesn't make sense to me because the profile shape isn't wide enough to close it). Left is revolve and right is mine I remade:
Actually I was able to isolate my code into something standalone:
#!/usr/bin/python
import numpy as np
from numpy import array as V
import math
from trimesh.exchange.export import export_mesh
from trimesh.creation import sweep_polygon
from shapely.geometry import Polygon
def arc_2d(final_angle, d=1, start_angle=0, splits=20):
xs = np.linspace(start_angle, final_angle, splits)
return np.stack((d/2 * np.cos(xs), d/2 * np.sin(xs)), axis=1)
h=200
d=8
h1=1
w = 2
d = d - w
h2 = h1
lead = 2
splits_per_turn = 4*20
polygon = V([(-0.01, -h1/2),
(w, -h2/2),
(w, +h2/2),
(-0.01, +h1/2)])
h_ = h + h1
n = math.ceil(splits_per_turn * h_ / lead)
turns = n / splits_per_turn
xys = arc_2d(2*np.pi * turns, d, splits=n)
zs = np.linspace(0, h_, n)[:,None]
spin_path = np.concatenate((xys, zs), axis=1)
x = sweep_polygon(Polygon(polygon), spin_path)
export_mesh(x, 'screw_test_trimesh.stl')
Although it's not exactly the same screw as in the screenshot above, it exhibits the same "roll" behavior. Hope this helps.