hello there
Saw your correspondence and struggles with CGAL. Could you please share your code on how you got to obtain the vertices and faces of the triangulation using Complex_2_in_triangulation_3_file_writer.h as suggested ?
Regards
GT
--- On Tue, 9/2/08, Jernej Barbic <> wrote:
From: Jernej Barbic <> Subject: [cgal-discuss] my experience with CGAL To: Date: Tuesday, September 2, 2008, 11:11 AM
Dear CGAL,
I am posting these two message by invitation of Dr. Pierre Alliez. I attended the CGAL course at SIGGRAPH in LA, and then tried using CGAL to do surface mesh generation. I then had an email discussion
with Pierre, relating my experience with CGAL. Also, please note that (due to other work) it might be difficult for me to keep up with the follow-ups; however, I wanted to share my experience, so I wrote the emails below. Best of luck to CGAL!
Regards, Jernej Barbic Post-doc associate, Computer Science and Artificial Intelligence Lab, Massachusetts Institute of Technology http://people.csail.mit.edu/barbic/
The first email message: ===================
Dear Pierre,
I am a computer graphics post-doc at MIT, and I saw your presentation in this year's SIGGRAPH class on CGAL in Los Angeles.
I was impressed with the presentation and the capabilities of CGAL, so I tried using it as a tool in my project. Specifically, I wanted to use it to generate good quality triangulations of isosurfaces, as in the "skull"
example: http://www.cgal.org/Manual/3.3/doc_html/cgal_manual/Surface_mesher/Chapter_main.html
I managed to compile and run the "skull" example (under Mac OS X). However, I then ran into a problem which will most likely seem quite trivial to you: I was unable to adapt the example so that I could actually capture the output. That is, CGAL will generate an output mesh; I then wanted to convert this mesh to my own in-memory representation. This representation would be very simple: a list of vertices, each given as three double precision values, followed by a list of faces (triangles), each a set of three integer indices into the preceding table of vertices. I was ultimately unable to figure out how to do this.
I listened to your presentation at SIGGRAPH, and then read the CGAL manual several times. I spent two days looking through many CGAL header files (about 8-10 hours of work total), following
seemingly endless templated (and cryptic at times) arguments, in an attempt to find clues as per how to access vertices of triangulations, and how to obtain the integer indices of the vertices of every face. For example, I "chased" the definition of "Vertex", over many header files, following (many) typedefs and templates, and did not succeed in finding a final answer.
I program in C++ all the time, and am quite proficient with templates and STL. I could not find a final answer - and got a bit frustrated given how simple and trivial the task. If I was on the CGAL team, I am pretty sure I could just ask somebody and get the answer very quickly, but with the information available to me, things were difficult.
Here is what I did figure out. One can print out the vertices like this:
for ( C2t3::Vertex_iterator v = c2t3.vertices_begin(); v != c2t3.vertices_end(); ++v) { std::cout << "v
" << v->point() << std::endl; }
(but printing is not what I really wanted; it would be better if I could store v->point() into a C array such as "double [3]")
And one can traverse the faces (but unsure if these are tet mesh cells, or surface mesh triangles, or surface mesh triangles+edges+vertices) like this:
int count = 0; for(C2t3::Facet_iterator f = c2t3.facets_begin(); f != c2t3.facets_end(); f++) { //printf("%d\n", f->second); // this I am guessing is the dimensionality of the facet if (f->second == 3) { std::cout << f->first->vertex(0)->point() << " "; std::cout << f->first->vertex(1)->point() << " "; std::cout << f->first->vertex(2)->point(); std::cout << std::endl; count++; } }
However, here I don't know what to do with
f->first->vertex to pull out the global integer index of that vertex. As you can see, I figured out how to convert the vertex to its 3D location (3 coordinates); but getting the global integer index would be much better. Also, I am not sure if this method will give me the triangle faces of the surface mesh, or will it give me the entire tet mesh. And if I run it on the (unmodified, as shipped with CGAL) skull example, I get many 4-tuples (I assume tets from the output tetrahedralization) that look ok, but at the end there are several that have three zero entries and one entry equalling 1. So if those are tets, unsure what they mean.
I think CGAL is great: it really implements many useful algorithms and the ability to have exact arithmetic is very good. Based on my experience, may I add a suggestion: right now, the manual talks a lot about templates and about computational geometry algorithms, which
is all good. Templates certainly make CGAL more powerful. However, at times the manual reads like the art of templatization was the main point of CGAL; there is a lot of template lingo. This will be good for somebody who is much into templates, but might be difficult to read for other people. I would add even more concrete examples: whenever you present some generic datastructure or algorithm (such as the kernel, for example), consider giving concrete examples of templated arguments that one can pass to those datastructures or algorithms. And as per triangulations, it would be good to have a manual page listing the methods available to vertex iterators, face iterators, cell iterators; the difference between face, facet, cell; and more documentation on input and output.
Thank you for creating CGAL, and for your help, Jernej Barbic
The second email message: ======================
>>dear
Jernej, >> >>thanks for your positive feedback, that's very useful and encouraging. >> >>as I am still on holidays, the short answer can be found in file Complex_2_in_triangulation_3_file_writer.h >> >>I invite you to post your detailed email to the CGAL discuss list, so that all developers see the trend (more and more people start using that surface mesh generator, that's good to know). >> >>thanks again for your time, >> >>Pierre
Hi Pierre,
Thank you very much for the pointer to Complex_2_in_triangulation_3_file_writer.h. I was able to "reverse-engineer" that file and now the mesher works fine for me. I already meshed several isosurfaces. The mesher is very good. I am not aware of any other mesher that can achieve similar results.
One minor issue that I noticed is that there is sometimes a spot on the output mesh
where for some reason the vertex density is unnecessarily high. If there is such a spot, there is always exactly one. It's not a big deal, but it does require either removing it manually, or running several runs, guessing parameters until it disappears. The location of this spot might be related to the location of the center of the bounding sphere (user-supplied parameter), and to how deep that center is inside the volume enclosed by the isosurface. But not 100% sure.
Also, documentation says that the sphere center must be inside the volume enclosed by the isosurface - but I noticed that the mesher produces a plausible result even if it is not. And, I am not completely sure if the bounding sphere has to cover the entire volume where the grayscale image is defined, or only the output isosurface. Also, I don't exactly understand the difference between the "distance bound" and "radius bound" (inputs to the
mesher); I read it several times in the manual and from that text I don't see the difference (and I know they must be different, or else you would not have two separate parameters).
FYI: I am combining your surface mesher with "tetgen" to generate volumetric tet meshes (I do so since I am assuming that your mesher doesn't generate a (quality) tet mesh, only a quality surface mesh). I am getting very good quality meshes using this process.
Again, my suggestion to CGAL would be to boost the documentation. Much of the documentation talks about "concepts" and how these concepts are implemented in "models". This is interesting on its own, however, it might be hard for a CGAL novice to parse this. For example, I'd try to lookup "Vertex", expecting to see a concrete class, and a list of methods that can be used with this class. Instead, there would be lots of typedefs and talk about how this is a model of
some concept and how it has to implement certain things. And then I'd wonder why those typedefs are the way they are, and what alternative choices would be and where I would look up those. And whether the class that I am looking at (Vertex) is an actual class that I can use, or is it just an abstract concept for me to implement (or partially implement), etc. All this is just my 5 cents of course, take my criticism lightly. I realize templatization has big benefits.
As per posting to the CGAL discussion list, please go ahead and post my previous email, in my name (it is easier for me if you post it, than if I post it). You can also post this email if you wish.
Thank you for your help. Jernej Barbic -- You are currently subscribed to cgal-discuss. To unsubscribe or access the archives, go to https://lists-sop.inria.fr/wws/info/cgal-discuss
|