Cinder
Cinder copied to clipboard
Allow 3d triangulation
I needed to do some basic 3d triangulation and noticed that libtess2 supports it but the Triangulator wrapper did not. It wasn't too hard to hook it up but the mesh output is wonky. I've added some really basic unit tests to demonstrate what it's doing.
Will this PR allow people to add both 2D and 3D vertices to the same Triangulate
instance? Because I think that would be problematic, conceptually.
In that case it would be better to have a Triangulate2d
and Triangulate3d
, similar to other Cinder classes.
It seems like libtess2 uses 3 dimensions internally and leaves the z at 0 if you don't provide a value but I think it could be clearer to have specialized classes for each. I'll take a swing at that interface and see how it looks.
I took a swing at putting the 3d version in it's own class. I'm not sure if there's a good way to share code between the two classes. Since this is really just a proof of concept I set it up as a Triangulator3d
class that used Triangulator::Winding
and Exception
. Ended up having to duplicate a fair bit of code but open to see what people think.
How about converting into a templated class?
template<typename T>
class Triangulator {
};
typedef Triangulator<vec2> Triangulator2;
typedef Triangulator<vec3> Triangulator3;
@vinjn yeah that was what i'd looked at initially but i wasn't clear how you'd get a scalar 2
or 3
to pass as a parameter out of the template type.
int getVecDim(vec3) { return 3;}
int getVecDim(vec2) { return 2;}
or using type traits like ChanTraits.h
@drewish
I'm thinking this might be hard to generalize for random 3d input. I've been getting really strange behavior with multiple contours. Adding a second contour causes it to return no output. I think this is due to the way libtess builds the arrangement by projecting everything onto a single sweep plane. Duplicated points on the plan seem to clear the output. It looks like you can influence the choice of plane by passing in a normal. So I think the only way it would reliably work in 3d would be to either require a normal be provided when calculating the mesh or just limit it to a single input contour.
I went ahead and folded this back into one class. The only difference is flow is really in the mesh outputting so I just added a parallel set of calc/createMesh3d functions. The 3d version takes a normal and I think in the docs we just need to make it clear that you only want to tesselate things on the same plane unless you know what you're doing.
I was wrong btw.: The cast from int*
to uin32_t*
seems to be legal (at least on systems, where uint32_t
is the same as unsigned int
Since over on #1698 it sounded like PolyLine3 might not be around long I switched this interface to just use std::vector<vec3>
instead.
Any reason this didn't get merged?
Not that I'm aware of. Happy to rebase it or make any changes that are necessary.
Sorry for the unreasonable delay on this. Two quick questions as my head is no longer in this code unfortunately. First, should we consider moving to the latest here? https://github.com/memononen/libtess2 And second, does the tesselator do the right thing if I supply a mixture of 2D and 3D contours as input?