diff --git a/.gitattributes b/.gitattributes index d00198eafc6..f693f12f245 100644 --- a/.gitattributes +++ b/.gitattributes @@ -4063,6 +4063,136 @@ Triangulation_3/include/CGAL/internal/Static_filters/Regular_triangulation_stati Triangulation_3/include/CGAL/internal/spatial_sorting_traits_with_indices.h -text Triangulation_3/test/Triangulation_3/include/CGAL/_test_remove_cluster.h -text Triangulation_3/test/Triangulation_3/test_static_filters.cpp -text +Triangulation_3_copy_tds/demo/Triangulation_3/CMakeLists.txt -text +Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.cpp -text +Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.h -text +Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.ui -text +Triangulation_3_copy_tds/demo/Triangulation_3/PreferenceDlg.cpp -text +Triangulation_3_copy_tds/demo/Triangulation_3/PreferenceDlg.h -text +Triangulation_3_copy_tds/demo/Triangulation_3/Scene.cpp -text +Triangulation_3_copy_tds/demo/Triangulation_3/Scene.h -text +Triangulation_3_copy_tds/demo/Triangulation_3/T3_demo.cpp -text +Triangulation_3_copy_tds/demo/Triangulation_3/T3_demo.qrc -text +Triangulation_3_copy_tds/demo/Triangulation_3/Viewer.cpp -text +Triangulation_3_copy_tds/demo/Triangulation_3/Viewer.h -text +Triangulation_3_copy_tds/demo/Triangulation_3/documentation/about.html -text +Triangulation_3_copy_tds/demo/Triangulation_3/documentation/about_CGAL.html -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/about_CGAL.html -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/cgal_logo.xpm -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/clear.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/coordinates.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/empty_sphere.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/fileOpen.png -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/fileSave.png -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/flat.png -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/grid.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/insert.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/insert_point.jpg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/move_1.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/nearest_nb.png -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/normal_view.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/pause.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/play.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/pointRandom.png -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/preferences.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/quit.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/select_hand.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_delaunay.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_facet.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_point.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_voronoi.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/stereo.png -text +Triangulation_3_copy_tds/demo/Triangulation_3/icons/stop.jpeg -text +Triangulation_3_copy_tds/demo/Triangulation_3/typedefs.h -text +Triangulation_3_copy_tds/demo/Triangulation_3/ui_MainWindow.h -text +Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/CMakeLists.txt -text +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.fig -text svneol=unset#application/octet-stream +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/tds3_small.pdf -text +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/tds3_small.png -text +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/flips.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/flips.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.eps -text +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.gif -text +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.pdf -text +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.png -text +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/topo-insert_outside_affine_hull.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/topo-insert_outside_affine_hull.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.fig -text svneol=unset#application/octet-stream +Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.fig -text svneol=unset#application/octet-stream +Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.fig -text svneol=unset#application/octet-stream +Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/Delaunay_3.jpg -text +Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/HD.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/HD.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/api1_01.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/api1_01.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/b35-1.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/b35-1.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/twotets.png -text +Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.xml svneol=native#text/xml +Triangulation_3_copy_tds/doc_tex/Triangulation_3/triangulation3.png -text svneol=unset#image/png +Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/flips.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/flips.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_affine_hull.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_affine_hull.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_convex_hull.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_convex_hull.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/sidedim2.gif -text svneol=unset#image/gif +Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/sidedim2.pdf -text svneol=unset#application/pdf +Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Compare_weighted_squared_radius_3.h -text +Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Power_test_3.h -text +Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Regular_triangulation_static_filters_traits_3.h -text +Triangulation_3_copy_tds/include/CGAL/internal/spatial_sorting_traits_with_indices.h -text +Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_remove_cluster.h -text +Triangulation_3_copy_tds/test/Triangulation_3/test_static_filters.cpp -text Voronoi_diagram_2/doc_tex/Voronoi_diagram_2/voronoi.png -text iostream/doc_tex/IOstream/io.png -text iostream/test/iostream/data/io.cin -text diff --git a/.gitignore b/.gitignore index de42b519866..80e78b7e756 100644 --- a/.gitignore +++ b/.gitignore @@ -1212,3 +1212,46 @@ Triangulation_3/test/Triangulation_3/test_simplex_3 Triangulation_3/test/Triangulation_3/test_static_filters Triangulation_3/test/Triangulation_3/test_triangulation_3 Triangulation_3/test/Triangulation_3/test_triangulation_tds +Triangulation_3_copy_tds/examples/Triangulation_3/*.exe +Triangulation_3_copy_tds/examples/Triangulation_3/CMakeLists.txt +Triangulation_3_copy_tds/examples/Triangulation_3/adding_handles_3 +Triangulation_3_copy_tds/examples/Triangulation_3/cgal_test_with_cmake +Triangulation_3_copy_tds/examples/Triangulation_3/color +Triangulation_3_copy_tds/examples/Triangulation_3/fast_location_3 +Triangulation_3_copy_tds/examples/Triangulation_3/find_conflicts_3 +Triangulation_3_copy_tds/examples/Triangulation_3/hierarchy +Triangulation_3_copy_tds/examples/Triangulation_3/linking_2d_and_3d +Triangulation_3_copy_tds/examples/Triangulation_3/makefile +Triangulation_3_copy_tds/examples/Triangulation_3/output +Triangulation_3_copy_tds/examples/Triangulation_3/output_tds +Triangulation_3_copy_tds/examples/Triangulation_3/regular +Triangulation_3_copy_tds/examples/Triangulation_3/regular_3 +Triangulation_3_copy_tds/examples/Triangulation_3/simple_triangulation_3 +Triangulation_3_copy_tds/examples/Triangulation_3/simplex +Triangulation_3_copy_tds/examples/Triangulation_3/tds +Triangulation_3_copy_tds/test/Triangulation_3/CMakeLists.txt +Triangulation_3_copy_tds/test/Triangulation_3/Makefile +Triangulation_3_copy_tds/test/Triangulation_3/Test1_triangulation_IO_3_binary +Triangulation_3_copy_tds/test/Triangulation_3/Test2_triangulation_IO_3_binary +Triangulation_3_copy_tds/test/Triangulation_3/Test3_triangulation_IO_3_binary +Triangulation_3_copy_tds/test/Triangulation_3/Test4_triangulation_IO_3_binary +Triangulation_3_copy_tds/test/Triangulation_3/Test5_triangulation_IO_3_binary +Triangulation_3_copy_tds/test/Triangulation_3/Test6_triangulation_IO_3_binary +Triangulation_3_copy_tds/test/Triangulation_3/Test7_triangulation_IO_3_binary +Triangulation_3_copy_tds/test/Triangulation_3/Test8_triangulation_IO_3_binary +Triangulation_3_copy_tds/test/Triangulation_3/Test??_triangulation_IO_3 +Triangulation_3_copy_tds/test/Triangulation_3/Test?_triangulation_IO_3 +Triangulation_3_copy_tds/test/Triangulation_3/Test_tds_IO_3 +Triangulation_3_copy_tds/test/Triangulation_3/cgal_test_with_cmake +Triangulation_3_copy_tds/test/Triangulation_3/makefile +Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_3 +Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_hierarchy_3 +Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_hierarchy_3_old +Triangulation_3_copy_tds/test/Triangulation_3/test_regular_3 +Triangulation_3_copy_tds/test/Triangulation_3/test_regular_as_delaunay_3 +Triangulation_3_copy_tds/test/Triangulation_3/test_regular_remove_3 +Triangulation_3_copy_tds/test/Triangulation_3/test_regular_traits_3 +Triangulation_3_copy_tds/test/Triangulation_3/test_simplex_3 +Triangulation_3_copy_tds/test/Triangulation_3/test_static_filters +Triangulation_3_copy_tds/test/Triangulation_3/test_triangulation_3 +Triangulation_3_copy_tds/test/Triangulation_3/test_triangulation_tds diff --git a/Triangulation_3_copy_tds/TODO b/Triangulation_3_copy_tds/TODO new file mode 100644 index 00000000000..302b6fba736 --- /dev/null +++ b/Triangulation_3_copy_tds/TODO @@ -0,0 +1,105 @@ +TDS +- operator->() dans it/circ de facettes/edges (idem T2, a coordonner) +- reflechir a un support de facettes explicites (cf papier de Giesen) +- nettoyer les trucs 2d only (face_circulator etc) +- Bistellar flips ? (cf shewchuck's SoCG'03 paper). + (it's when you have 4 coplanar points, you break 4 cells, + and it gives 4 cells back). +- More compact representation [inspired by a CUJ article for lists] : + instead of having a cell which stores 4 vertex pointers, it only stores the + XOR of them. And a Cell_handle now additionaly stores the 4 vertex pointers + of the cell, the "context". + One problem is the Cell_iterator : it looses the context, so I think that + one way to work around this is to write the Cell_iterator as based on the + Vertex_iterator (a bit like the reverse used to be made) : we iterate over + the vertices, and for each vertex, we compute the incident cells, but we + pick only those whose smallest vertex (adress-wise) is the one in question. + +T3 +- documenter le 2eme tableau de Triangulation_utils +- degree() devrait-il, au niveau geometrique, ne pas compter le sommet infini ? +- is_valid devrait verifier l'enveloppe convexe +- prevoir differentes sorties : geomview (ameliorer le rendu pour + donner un effet de perspective), vrml... + cf Polyhedron_3, file I/O. + +Delaunay +- Put side_of_bounded_sphere_3 into the DelaunayTriangulationTraits_3 as + it is used in the is_Gabriel tests +- dual(vertex) -> Polyhedron_3 +- faire en sorte que les types line, ray, etc Voronoi ne soient plus + qu'optionnels dans la traits, et requis seulement si les fonctions + dual sont effectivement utilisees +- remplacer les create_face du remove2D par des create_cell et virer + les create_face de la tds +- optimiser remove : + - algo d'Olivier si constructions filtrees disponibles (cf Olivier + rappel de la reunion a ce sujet) + - pour la creation de la TDS_2, on devrait pouvoir faire plus simple, + sachant que le trou n'est pas quelconque, mais etoile, et donc on peut + profiter de ca pour avoir les adjacences directement (peut-etre en + squattant le flag des cellules pour y mettre un pointeur vers la facette + 2d correspondante). +- natural neighbors de Raphaelle a integrer +- Pb du type de points pour les fonctions "dual" (robustesse dans le cas +des tetraedres presque plats) rounding ? + +Regular : +- acces aux hidden points et remove sur hidden points, etc +- Regular_triangulation_euclidean_traits_3.h + add a functor Construct_smallest_orthogonal_weighted_point_3 + to build at the same time both the center and the square radius + of the smallest orthogonal sphere +- la cell_base speciale qui stocke une liste de points caches ou pas (et un + tag qui dit si oui ou non elle stocke les points caches ou pas), et un + iterator pour y acceder. A DOCUMENTER. +- remove - les dimensions 1 et 2 ne sont pas gerees. +- faire marcher la hierarchie avec. Le probleme est qu'on delete des + vertex, et donc la hierarchie est perdue avec ses pointeurs up/down qui + pointent dans l'espace, du coup... + La solution qu'on a discutee est : + - la hierarchy devrait avoir tous les etages superieurs simplement Delaunay, + et pas autre chose. + - le insert() (ou find_conflict) de Regular devrait fournir un iterator sur + les Vertex_handle correspondant aux points qui seront caches, et en + fonction de ca, une hierarchy speciale Regular fera ce qu'il faut. +- programmer centre ortho-sphere de 4 points. Aussi centre de l'ortho-cercle + de 3 points... (requete Tamal Dey) +- .dual() + +Hierarchie +- nettoyer hierarchie + cf mail Mariette + la hierarchie surcharge correctement certaines + versions du insert() et locate() + et fait n'importe quoi pour les autres.... + (c'est tout ce qui se trouve apres + // added to make the test program of usual triangulations work + // undocumented + public: + ..... + ) + +-------------------------------------------------------------------- + +General +- mettre des locate_2D, locate_3D, insert idem, pour eviter les tests + redondants sur la dimension a chaque insertion. +- trouver une interface avec T_2 qui permette d'eviter de reprogrammer + tout le 2d dans le 3d +- valgrind +- gcov +- const handle, const it, const circ ... +- utiliser le cell_container_iterator partout ou c'est possible + (unifier le code pour differentes dimensions) + +TEST-SUITE +- si un jour elle est revue, voici quelques idees pour l'organiser : + - prendre un noyau exact pour tout, et supposer qu'on l'a dans les tests. + - avoir des fonctions qui generent differentes distributions + (cas degeneres, grands nombre de points...) + - pour nearest_vertex() : comparer le resultat avec Spatial_searching ? + (c'est impossible dans le cas ou il y a plusieurs points equidistants, + puisqu'il y a un choix arbitraire, il n'y a aucune raison que ca soit + le meme dans un autre package) +- Test-suite Delaunay : .dual() n'est pas vraiment teste... diff --git a/Triangulation_3_copy_tds/benchmark/Triangulation_3/Triangulation_benchmark_3.cpp b/Triangulation_3_copy_tds/benchmark/Triangulation_3/Triangulation_benchmark_3.cpp new file mode 100644 index 00000000000..e8af03ff494 --- /dev/null +++ b/Triangulation_3_copy_tds/benchmark/Triangulation_3/Triangulation_benchmark_3.cpp @@ -0,0 +1,246 @@ +// Benchmark program for the Triangulation_3 package. +// +// Sylvain Pion, 2009. +// +// The data produced by this program is meant to be used +// in the Benchmarks section of the User Manual. +// +// We measure : +// - construction time +// - point location time function of triangulation size +// - vertex removal time +// - memory usage +// +// And this, for the following 4 configurations : +// - Delaunay +// - Delaunay +// - Regular +// - Regular +// +// Notes : +// - points are randomly generated using drand48() +// - weights are zero for regular +// +// TODO (?) : +// - impact of the choice of various kernels +// - impact of the kind of data set ? More or less degenerate... +// - replace drand48() by CGAL Generators +// - move/document Time_accumulator to CGAL/Profiling_tools (?) + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include // for drand48 + +#ifdef SHOW_ITERATIONS +# undef SHOW_ITERATIONS +# define SHOW_ITERATIONS "\t( " << iterations << " iterations used)" << endl +#else +# define SHOW_ITERATIONS endl +#endif + +#ifndef BENCH_MIN_TIME +# define BENCH_MIN_TIME 1 // minimum time for a bench +#endif + +using namespace std; +using namespace CGAL; + +// Choose the kernel type by defining one of those macros: +// - SC_DOUBLE, +// - EPEC, +// - or EPIC (the default) +#ifdef SC_DOUBLE +typedef Simple_cartesian K; +#elif defined(EPEC) +# ifdef CGAL_DONT_USE_LAZY_KERNEL +typedef Epeck K; +# else +typedef Simple_cartesian SK; +typedef Lazy_kernel K; +# endif +#else // EPIC +typedef Exact_predicates_inexact_constructions_kernel K; +#endif +typedef Regular_triangulation_euclidean_traits_3 WK; +typedef K::Point_3 Point; + +vector pts, pts2; +size_t min_pts = 100; +size_t max_pts = 100000; + +bool input_file_selected = false; +std::ifstream input_file; + + +class Time_accumulator +{ + double &accumulator; + Timer timer; +public: + Time_accumulator(double &acc) : accumulator(acc) { timer.reset(); timer.start(); } + ~Time_accumulator() { timer.stop(); accumulator += timer.time(); } +}; + +Point rnd_point() +{ + return Point(drand48(), drand48(), drand48()); +} + +void generate_points() +{ + if (input_file_selected) { + Point p; + while (input_file >> p) + pts.push_back(p); + cout << " [ Read " << pts.size() << " points from file ] " << endl; + min_pts = max_pts = pts.size(); + } + else { + pts.reserve(max_pts); + pts2.reserve(max_pts); + for(size_t i = 0; i < std::max(std::size_t(100000), max_pts); ++i) { + pts.push_back(rnd_point()); + pts2.push_back(rnd_point()); + } + } +} + + +// Triangulation construction +template < typename Tr > +void benchmark_construction() +{ + cout << "\nTriangulation construction : " << endl; + cout << "#pts\tTime" << endl; + size_t mem_size_init = Memory_sizer().virtual_size(); + size_t mem_size = 0; + + for (size_t nb_pts = min_pts; nb_pts <= max_pts; nb_pts *= 10) + { + double time = 0; + size_t iterations = 0; + do { + ++iterations; + Time_accumulator tt(time); + Tr tr(pts.begin(), pts.begin() + nb_pts); + mem_size = Memory_sizer().virtual_size(); + // cout << "#vertices = " << tr.number_of_vertices() << endl; + // cout << "#cells = " << tr.number_of_cells() << endl; + } while (time < BENCH_MIN_TIME); + cout << nb_pts << "\t" << time/iterations << SHOW_ITERATIONS; + } + cout << "\nMemory usage : " << (mem_size - mem_size_init)*1./max_pts << " Bytes/Point" + << " (observed for the largest data set, and may be unreliable)" << endl; +} + + +// Point location +template < typename Tr > +void benchmark_location() +{ + cout << "\nPoint location : " << endl; + cout << "#pts\tTime" << endl; + for (size_t nb_pts = min_pts; nb_pts <= max_pts; nb_pts *= 10) + { + Tr tr(pts.begin(), pts.begin() + nb_pts); + double time = 0; + size_t iterations = 0; + do { + ++iterations; + Time_accumulator tt(time); + // We do chunks of 100000 point locations at once. + for(size_t i = 0; i < 100000; ++i) + tr.locate(pts2[i]); + } while (time < BENCH_MIN_TIME); + cout << nb_pts << "\t" << (time/iterations)/100000 << SHOW_ITERATIONS; + } +} + + +// Vertex removal +template < typename Tr > +void benchmark_remove() +{ + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Vertex_iterator Vertex_iterator; + + cout << "\nVertex removal : " << endl; + cout << "#pts\tTime" << endl; + size_t nb_pts = 100000; // only one size of triangulation hard-coded. + { + Tr tr(pts.begin(), pts.begin() + nb_pts); + vector vhs; + for (Vertex_iterator vit = tr.finite_vertices_begin(), end = tr.finite_vertices_end(); + vit != end; ++vit) + vhs.push_back(vit); + double time = 0; + size_t iterations = 0; + size_t j = 0; + do { + ++iterations; + Time_accumulator tt(time); + // We do chunks of 1024 vertex removal at once. + for(size_t i = 0; i < 1024; ++i, ++j) + tr.remove(vhs[j]); + } while (time < BENCH_MIN_TIME); + cout << nb_pts << "\t" << (time/iterations)/1024 << SHOW_ITERATIONS; + } +} + + +template < typename Tr > +void do_benchmarks(string name) +{ + cout << "\n\nBenchmarking configuration : " << name << endl; + benchmark_construction(); + if (input_file_selected) + return; + benchmark_location(); + benchmark_remove(); +} + +int main(int argc, char **argv) +{ + if (argc >= 2) { + input_file.open(argv[1], std::ios::in); + if (input_file.is_open()) + input_file_selected = true; + else { + input_file_selected = false; + max_pts = atoi(argv[1]); + } + } + + cout << "Usage : " << argv[0] << " [filename]" + << " [max_points = " << max_pts << ", and please use a power of 10]" << endl; + cout << "Benchmarking the Triangulation_3 package for "; + if (input_file_selected) + cout << "data file : " << argv[1] << endl; + else + cout << "up to " << max_pts << " random points." << endl; + + cout.precision(3); + + generate_points(); + + cout << "\nProcessor : " + << ((sizeof(void*)==4) ? 32 : (sizeof(void*)==8) ? 64 : -1) << " bits\n"; + // cout << "Kernel : EPICK\n"; + + do_benchmarks >("Delaunay [Compact_location]"); + if (input_file_selected) + return 0; + do_benchmarks >("Delaunay with Fast_location"); + do_benchmarks >("Regular [with hidden points kept, except there's none in the data sets]"); + do_benchmarks, Triangulation_cell_base_3 > > >("Regular with hidden points discarded"); +} diff --git a/Triangulation_3_copy_tds/benchmark/Triangulation_3/benchs_results_tigre_10_7.txt b/Triangulation_3_copy_tds/benchmark/Triangulation_3/benchs_results_tigre_10_7.txt new file mode 100644 index 00000000000..6624b46e356 --- /dev/null +++ b/Triangulation_3_copy_tds/benchmark/Triangulation_3/benchs_results_tigre_10_7.txt @@ -0,0 +1,116 @@ +spion@tigre:~/CGAL/Triangulation_3_Location_policy/benchmark/Triangulation_3> time ./Triangulation_benchmark_3 10000000 +Benchmarking the Triangulation_3 package for up to 10000000 random points. +Usage : ./Triangulation_benchmark_3 [max_points = 100000, and please use a power of 10] + +Processor : 64 bits +Kernel : EPICK + + +Benchmarking configuration : Delaunay [Compact_location] + +Triangulation construction : +#pts Time +100 0.000541 +1000 0.00724 +10000 0.0785 +100000 0.827 +1000000 8.5 +10000000 87.4 + +Memory usage : 519 Bytes/Point (observed for the largest data set) + +Point location : +#pts Time +100 9.93e-07 +1000 2.25e-06 +10000 4.79e-06 +100000 2.98e-05 +1000000 0.0001 +10000000 0.000259 + +Vertex removal : +#pts Time +100000 0.0001 + + +Benchmarking configuration : Delaunay with Fast_location + +Triangulation construction : +#pts Time +100 0.000576 +1000 0.00748 +10000 0.0838 +100000 0.878 +1000000 9.07 +10000000 92.5 + +Memory usage : 553 Bytes/Point (observed for the largest data set) + +Point location : +#pts Time +100 1.06e-06 +1000 1.93e-06 +10000 3.09e-06 +100000 6.12e-06 +1000000 9.65e-06 +10000000 1.33e-05 + +Vertex removal : +#pts Time +100000 0.000103 + + +Benchmarking configuration : Regular with hidden points discarded + +Triangulation construction : +#pts Time +100 0.000955 +1000 0.0111 +10000 0.117 +100000 1.19 +1000000 12.2 +10000000 125 + +Memory usage : 527 Bytes/Point (observed for the largest data set) + +Point location : +#pts Time +100 6.99e-06 +1000 1.76e-05 +10000 3.87e-05 +100000 0.000106 +1000000 0.000267 +10000000 0.000625 + +Vertex removal : +#pts Time +100000 0.000138 + + +Benchmarking configuration : Regular [with hidden points kept, except there's none in the data sets] + +Triangulation construction : +#pts Time +100 0.000948 +1000 0.0114 +10000 0.122 +100000 1.25 +1000000 12.6 +10000000 129 + +Memory usage : 630 Bytes/Point (observed for the largest data set) + +Point location : +#pts Time +100 7.19e-06 +1000 1.73e-05 +10000 3.96e-05 +100000 0.000106 +1000000 0.00027 +10000000 0.000625 + +Vertex removal : +#pts Time +100000 0.000142 +./Triangulation_benchmark_3 10000000 1247.23s user 29.78s system 99% cpu 21:18.95 total + diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/CMakeLists.txt b/Triangulation_3_copy_tds/demo/Triangulation_3/CMakeLists.txt new file mode 100644 index 00000000000..c4d9fadfda5 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/CMakeLists.txt @@ -0,0 +1,82 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + +project (Triangulation_demo_3) + +cmake_minimum_required(VERSION 2.4.5) + +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +if ( COMMAND cmake_policy ) + cmake_policy( SET CMP0003 NEW ) +endif() + +find_package(CGAL COMPONENTS Qt4) +include(${CGAL_USE_FILE}) + +set( QT_USE_QTXML TRUE ) +set( QT_USE_QTMAIN TRUE ) +set( QT_USE_QTSCRIPT TRUE ) +set( QT_USE_QTOPENGL TRUE ) +set( QT_USE_QTASSISTANT TRUE ) +find_package(Qt4) + +find_package(OpenGL) + +if(QT4_FOUND) + include( ${QT_USE_FILE} ) + find_package(QGLViewer) +endif(QT4_FOUND) + +if ( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND ) + + include(${QT_USE_FILE}) + + include_directories (${QGLVIEWER_INCLUDE_DIR}) + include_directories (BEFORE ../../include ./ ) + + # ui files, created with Qt Designer + qt4_wrap_ui( uis MainWindow.ui ) + + # qrc files (resources files, that contain icons, at least) + qt4_add_resources ( RESOURCE_FILES ./T3_demo.qrc ) + + # moc files (meta object compiler files, run moc preprocessor on the files with Widget defs) + qt4_automoc( MainWindow.cpp Viewer.cpp PreferenceDlg.cpp ) + + # cpp files + add_executable ( T3_demo T3_demo.cpp + MainWindow.cpp Viewer.cpp + PreferenceDlg.cpp + Scene.cpp ${uis} ${RESOURCE_FILES} ) + + add_to_cached_list( CGAL_EXECUTABLE_TARGETS T3_demo ) + + target_link_libraries( T3_demo ${CGAL_LIBRARIES} ${CGAL_3RD_PARTY_LIBRARIES}) + target_link_libraries( T3_demo ${QT_LIBRARIES} ${QGLVIEWER_LIBRARIES} ) + target_link_libraries( T3_demo ${OPENGL_gl_LIBRARY} ${OPENGL_glu_LIBRARY} ) + +else( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND ) + + set(TRIANGULATION_3_MISSING_DEPS "") + + if(NOT CGAL_FOUND) + set(TRIANGULATION_3_MISSING_DEPS "the CGAL Qt4 library, ${TRIANGULATION_3_MISSING_DEPS}") + endif() + + if(NOT QT4_FOUND) + set(TRIANGULATION_3_MISSING_DEPS "Qt4, ${TRIANGULATION_3_MISSING_DEPS}") + endif() + + if(NOT OPENGL_FOUND) + set(TRIANGULATION_3_MISSING_DEPS "OpenGL, ${TRIANGULATION_3_MISSING_DEPS}") + endif() + + if(NOT QGLVIEWER_FOUND) + set(TRIANGULATION_3_MISSING_DEPS "QGLViewer, ${TRIANGULATION_3_MISSING_DEPS}") + endif() + + + message(STATUS "NOTICE: This demo requires ${TRIANGULATION_3_MISSING_DEPS}and will not be compiled.") + +endif( CGAL_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND ) diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.cpp new file mode 100644 index 00000000000..1f1c271168e --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.cpp @@ -0,0 +1,243 @@ +#include "MainWindow.h" +#include + +#include "MainWindow.moc" // .moc will be the output from moc preprocessor + +MainWindow::MainWindow(QWidget* parent) + : CGAL::Qt::DemosMainWindow(parent) +{ + // Qt Automatic Connections + // http://doc.trolltech.com/4.4/designer-using-a-component.html#automatic-connections + // setupUi(this) automatically generates connections to the slots named + // "on__" + setupUi(this); + + this->viewer->setScene(&m_scene); + m_scene.setViewer(this->viewer); + + // setup Mode menu group actions + QActionGroup *modeGroup = new QActionGroup(this); + modeGroup->addAction(this->actionNormal_View); + modeGroup->addAction(this->actionInsert_Vertex); + modeGroup->addAction(this->actionInsert_Point); + modeGroup->addAction(this->actionSelect_Vertex); + modeGroup->addAction(this->actionMove_Vertex); + modeGroup->addAction(this->actionFind_NearestNb); + modeGroup->addAction(this->actionEmpty_Sphere); + QObject::connect(modeGroup, SIGNAL(triggered(QAction *)), this, SLOT(setMode(QAction *))); + + // connect menu actions to viewer slots + connectActions(); + + // About menu + // addAboutCGAL() is a function in DemoMainWindow + // it will add a menu action "About CGAL..." to Help menu and connect to popupAboutCGAL + // default popupAboutCGAL points to a fixed file directory ":/cgal/help/about_CGAL.html" + // here we override it with our directory + this->addAboutCGAL(); + // addAboutDemo(QString htmlResourceName) is also a function in DemoMainWindow + // it will add a menu action "About Demo..." to Help menu + // when the action is invoked, it will popup a messageBox showing the given html + this->addAboutDemo( "documentation/about.html" ); + + // read last setting from .ini file + viewer->readSettings(); +} + +void MainWindow::connectActions() +{ + // Edit menu actions + QObject::connect(this->actionIncremental_Construct, SIGNAL(toggled(bool)), + this->viewer, SLOT(toggleIncremental(bool))); + QObject::connect(this->actionStop_Animation, SIGNAL(triggered()), + this->viewer, SLOT(stopIncremental())); + QObject::connect(this->viewer, SIGNAL(stopIncAnimation()), + this, SLOT(stopAnimation())); + + // Show menu actions + QObject::connect(this->actionShow_Axis, SIGNAL(toggled(bool)), + this->viewer, SLOT(toggleShowAxis(bool))); + QObject::connect(this->actionShow_Vertex, SIGNAL(toggled(bool)), + this->viewer, SLOT(toggleShowVertex(bool))); + QObject::connect(this->actionShow_DEdge, SIGNAL(toggled(bool)), + this->viewer, SLOT(toggleShowDEdge(bool))); + QObject::connect(this->actionShow_VEdge, SIGNAL(toggled(bool)), + this->viewer, SLOT(toggleShowVEdge(bool))); + QObject::connect(this->actionShow_Facet, SIGNAL(toggled(bool)), + this->viewer, SLOT(toggleShowFacet(bool))); + QObject::connect(this->actionFlat, SIGNAL(toggled(bool)), + this->viewer, SLOT(toggleFlat(bool))); + + // Preferences + QObject::connect(this->actionPreferences, SIGNAL(triggered()), + this->viewer, SLOT(setPreferences())); + + // Help menu actions + QObject::connect(this->actionDemo_Help, SIGNAL(triggered()), + this->viewer, SLOT(help())); + QObject::connect(this->actionAbout_T3_demo, SIGNAL(triggered()), + this, SLOT(popupAboutDemo())); + + // Quit + QObject::connect(this->actionQuit, SIGNAL(triggered()), + qApp, SLOT(closeAllWindows())); + + // Viewer signals + QObject::connect(this, SIGNAL(sceneChanged()), + this->viewer, SLOT(updateGL())); +} + +void MainWindow::closeEvent(QCloseEvent *event) +{ + viewer->writeSettings(); +} + +/*************************************************************/ +/* Action functions */ + +void MainWindow::setMode(QAction *action) +{ + if( action == this->actionNormal_View ) + this->viewer->setMode( viewer->NONE ); + else if( action == this->actionInsert_Vertex ) + this->viewer->setMode( viewer->INSERT_V ); + else if( action == this->actionInsert_Point ) + this->viewer->setMode( viewer->INSERT_PT ); + else if( action == this->actionSelect_Vertex ) + this->viewer->setMode( viewer->SELECT ); + else if( action == this->actionMove_Vertex ) + this->viewer->setMode( viewer->MOVE ); + else if( action == this->actionFind_NearestNb ) + this->viewer->setMode( viewer->FINDNB ); + else if( action == this->actionEmpty_Sphere ) + this->viewer->setMode( viewer->EMPTYSPH ); +} + +void MainWindow::on_actionLoad_Points_triggered() +{ + QString fileName = QFileDialog::getOpenFileName(this, + tr("Open an file"), // dialog caption + ".", // initial directory + tr("OFF files (*.off);;XYZ files (*.xyz);;All files (*.*)")); // selection filter + if( fileName.isEmpty() ) return; + + // erase old data + viewer->clear(); + + // parse fileName to get the file type + std::string fname = fileName.toAscii().data(); + std::string ftype = fname.substr( fname.find_last_of('.')+1 ); + + if ( ftype.compare("off")==0 || ftype.compare("OFF")==0 ) { // read from OFF file + m_scene.loadPointsOFF( fname.data() ); + // set selectBuffer size (if necessary) + viewer->setSelBuffSize(); + } else if ( ftype.compare("xyz")==0 || ftype.compare("XYZ")==0 ) { // read from XYZ file + m_scene.loadPointsXYZ( fname.data() ); + // set selectBuffer size (if necessary) + viewer->setSelBuffSize(); + } else { + viewer->displayMessage( tr("Please select an OFF or XYZ file to open!") ); + } + + // update viewer + emit( sceneChanged() ); +} + +void MainWindow::on_actionSave_Points_triggered() +{ + if( m_scene.isDTEmpty() ) { + viewer->displayMessage( tr("Error: no existing triangulation to be saved.") ); + return; + } + + QString fileName = QFileDialog::getSaveFileName(this, + tr("Save an file"), // dialog caption + ".", // initial directory + tr("OFF files (*.off);;XYZ files (*.xyz);;All files (*.*)")); // selection filter + if( fileName.isEmpty() ) return; + + // parse fileName to get the file type + std::string fname = fileName.toAscii().data(); + std::string ftype = fname.substr( fname.find_last_of('.')+1 ); + + if ( ftype.compare("off")==0 || ftype.compare("OFF")==0 ) { // save to OFF file + m_scene.savePointsOFF( fname.data() ); + } else if ( ftype.compare("xyz")==0 || ftype.compare("XYZ")==0 ) { // save to XYZ file + m_scene.savePointsXYZ( fname.data() ); + } else { + viewer->displayMessage( tr("Please select an OFF or XYZ file to open!") ); + } +} + +void MainWindow::on_actionGenerate_Points_triggered() +{ + bool isOk; + int nPoints = QInputDialog::getInteger(this, + "3D Triangulation demo", "Number of points: ", // caption and label + 100, // default value + 4, // min value + 2147483647, // max value + 1, // step value of arrow button + &isOk); // if OK is pressed + + if ( isOk) { + // erase old data + viewer->clear(); + + // generate points + m_scene.generatePoints(nPoints); + // set selectBuffer size (if necessary) + viewer->setSelBuffSize(); + + // update viewer + emit( sceneChanged() ); + }// if(isOk) +} + +void MainWindow::stopAnimation() +{ + if( this->actionIncremental_Construct->isChecked() ) + this->actionIncremental_Construct->setChecked( false ); +} + +void MainWindow::on_actionClear_Scene_triggered() +{ + viewer->clear(); + + // update viewer + emit( sceneChanged() ); +} + +void MainWindow::popupAboutCGAL() +{ + // read contents from .html file + QFile about_CGAL( "documentation/about_CGAL.html" ); + about_CGAL.open(QIODevice::ReadOnly); + QString about_CGAL_txt = QTextStream(&about_CGAL).readAll(); +#ifdef CGAL_VERSION_STR + about_CGAL_txt.replace("", + QString(" (version %1, svn r%2)") + .arg(CGAL_VERSION_STR).arg(CGAL_SVN_REVISION)); +#endif + + // popup a message box + QMessageBox mb(QMessageBox::NoIcon, + tr("About CGAL..."), + about_CGAL_txt, + QMessageBox::Ok, + this); + + // set links to be accessible by mouse or keyboard + QLabel* mb_label = mb.findChild("qt_msgbox_label"); + if(mb_label) { + mb_label->setTextInteractionFlags(mb_label->textInteractionFlags() | + ::Qt::LinksAccessibleByMouse | + ::Qt::LinksAccessibleByKeyboard); + } else { + std::cerr << "Cannot find child \"qt_msgbox_label\" in QMessageBox\n" + << " with Qt version " << QT_VERSION_STR << "!\n"; + } + + mb.exec(); +} diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.h b/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.h new file mode 100644 index 00000000000..a033fbb5b70 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.h @@ -0,0 +1,55 @@ +#ifndef MAIN_WINDOW_H +#define MAIN_WINDOW_H + +#include "ui_MainWindow.h" +#include +#include +#include +#include + +#include + +#include "Scene.h" + +class QWidget; + +class MainWindow : public CGAL::Qt::DemosMainWindow, private Ui::MainWindow +{ + Q_OBJECT + +public: + MainWindow(QWidget* parent = 0); + ~MainWindow() {} + +public slots: + // file menu + void on_actionLoad_Points_triggered(); + void on_actionSave_Points_triggered(); + + // edit menu + void on_actionGenerate_Points_triggered(); + void stopAnimation(); + + // mode menu + void setMode(QAction *a); + + // show menu + void on_actionClear_Scene_triggered(); + + // about menu + void popupAboutCGAL(); + + signals: + void sceneChanged(); + +protected: + void closeEvent(QCloseEvent *event); + +private: + void connectActions(); + +private: + Scene m_scene; +}; + +#endif diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.ui b/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.ui new file mode 100644 index 00000000000..97e9b74f51e --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/MainWindow.ui @@ -0,0 +1,577 @@ + + + MainWindow + + + Qt::NonModal + + + + 0 + 0 + 1100 + 500 + + + + + 0 + 0 + + + + + Arial + + + + PointingHandCursor + + + Triangulation_demo_3 + + + + :/T3_demo/icons/icons/cgal_logo.xpm:/T3_demo/icons/icons/cgal_logo.xpm + + + + + + + + 0 + 0 + + + + PointingHandCursor + + + + + + + + + 0 + 0 + 1010 + 22 + + + + + &File + + + + + + + + + Edit + + + + + + + + + + + Mode + + + + + + + + + + + + Show + + + + + + + + + + + + + + + Help + + + + + + + + + + + + + + toolBar + + + TopToolBarArea + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + :/T3_demo/icons/icons/pointRandom.png:/T3_demo/icons/icons/pointRandom.png + + + Generate Points + + + Generate Points + + + Generate Points + + + Ctrl+G + + + + + + :/T3_demo/icons/icons/fileOpen.png:/T3_demo/icons/icons/fileOpen.png + + + Load Points... + + + Load Points from a file + + + Load Points from a file + + + Ctrl+O + + + + + + :/T3_demo/icons/icons/fileSave.png:/T3_demo/icons/icons/fileSave.png + + + Save Points... + + + Save points to a file + + + Save points to a file + + + Ctrl+S + + + + + true + + + + :/T3_demo/icons/icons/coordinates.jpeg:/T3_demo/icons/icons/coordinates.jpeg + + + Show Axis + + + Show/Hide Axis + + + Show/Hide Axis + + + + + + :/T3_demo/icons/icons/quit.jpeg:/T3_demo/icons/icons/quit.jpeg + + + Quit + + + Quit + + + Quit + + + + + + :/T3_demo/icons/icons/clear.jpeg:/T3_demo/icons/icons/clear.jpeg + + + Clear Scene + + + Clear Scene + + + Clear Scene + + + + + true + + + true + + + + :/T3_demo/icons/icons/show_point.jpeg:/T3_demo/icons/icons/show_point.jpeg + + + Show Vertices + + + Show Vertices + + + Show Vertices + + + + + true + + + true + + + + :/T3_demo/icons/icons/show_delaunay.jpeg:/T3_demo/icons/icons/show_delaunay.jpeg + + + Show Delaunay Edges + + + Show Delaunay edges + + + Show Delaunay edges + + + + + true + + + + :/T3_demo/icons/icons/show_voronoi.jpeg:/T3_demo/icons/icons/show_voronoi.jpeg + + + Show Voronoi Edges + + + Show Voronoi edges + + + Show Voronoi edges + + + + + true + + + + :/T3_demo/icons/icons/show_facet.jpeg:/T3_demo/icons/icons/show_facet.jpeg + + + Show Facets + + + Show Delaunay Facets + + + Show Delaunay Facets + + + + + true + + + + :/T3_demo/icons/icons/flat.png + :/T3_demo/icons/icons/stereo.png:/T3_demo/icons/icons/flat.png + + + Flat + + + Toggle 3D effect + + + Toggle 3D effect + + + + + + :/T3_demo/icons/icons/preferences.jpeg:/T3_demo/icons/icons/preferences.jpeg + + + Preferences... + + + Change Colors, Transparency, etc. + + + Change Colors, Transparency, etc. + + + + + true + + + + :/T3_demo/icons/icons/insert.jpeg:/T3_demo/icons/icons/insert.jpeg + + + Insert Vertex + + + Insert a point and update the triangulation + + + Insert a point and update the triangulation + + + + + true + + + + :/T3_demo/icons/icons/insert_point.jpg:/T3_demo/icons/icons/insert_point.jpg + + + Insert Point + + + Show the conflict region of a point and insert it + + + Show the conflict region of a point and insert it + + + + + true + + + + :/T3_demo/icons/icons/select_hand.jpeg:/T3_demo/icons/icons/select_hand.jpeg + + + Select Vertex + + + Select vertices + + + Select vertices + + + + + true + + + + :/T3_demo/icons/icons/move_1.jpeg:/T3_demo/icons/icons/move_1.jpeg + + + Move Vertex + + + Move a vertex + + + Move a vertex + + + + + true + + + + :/T3_demo/icons/icons/nearest_nb.png:/T3_demo/icons/icons/nearest_nb.png + + + Nearest Neighbor Search + + + Find the nearest neighbor of the query point + + + Find the nearest neighbor of the query point + + + + + true + + + + :/T3_demo/icons/icons/empty_sphere.jpeg:/T3_demo/icons/icons/empty_sphere.jpeg + + + Show Empty Sphere + + + Click to select a cell and show empty sphere of that cell. + + + Locate the query point in a cell and show empty sphere of that cell + + + Locate the query point in a cell and show empty sphere of that cell + + + + + true + + + true + + + + :/T3_demo/icons/icons/normal_view.jpeg:/T3_demo/icons/icons/normal_view.jpeg + + + Normal Mode + + + Normal Mode + + + Normal Mode + + + + + Triangulation_3D Demo Help + + + Triangulation_3D Demo Help + + + Triangulation_3D Demo Help + + + H + + + + + true + + + + :/T3_demo/icons/icons/play.jpeg + :/T3_demo/icons/icons/pause.jpeg:/T3_demo/icons/icons/play.jpeg + + + Insertion Animation + + + Animation of incremental Delaunay triangulation + + + Animation of incremental Delaunay triangulation + + + + + + :/T3_demo/icons/icons/stop.jpeg:/T3_demo/icons/icons/stop.jpeg + + + Stop Animation + + + Stop Animation + + + Stop Animation + + + + + About T3_demo + + + + + + + Viewer + QWidget +
Viewer.h
+ 1 +
+
+ + + + +
diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/PreferenceDlg.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3/PreferenceDlg.cpp new file mode 100644 index 00000000000..dca25d9ce5f --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/PreferenceDlg.cpp @@ -0,0 +1,399 @@ +#include +#include "PreferenceDlg.h" + +#include "PreferenceDlg.moc" // .moc will be the output from moc preprocessor + +PreferenceDlg::PreferenceDlg(QWidget *parent) : QDialog(parent) +{ + /* Vertex */ + + // create groupbox + QGroupBox *groupV = new QGroupBox( tr("Vertex") ); + // create buttons + QPushButton *btnVertex = new QPushButton( tr("Set Color") ); + // create color label + m_labelVertex = new QLabel; + m_labelVertex->setFrameStyle(QFrame::Sunken | QFrame::Panel); + // create size label + QLabel *labelSizeV = new QLabel( tr("Set Size") ); + // create lineedit + m_editSizeV = new QLineEdit; + + // connect to actions + connect( btnVertex, SIGNAL(clicked()), this, SLOT(setVertexColor()) ); + connect( m_editSizeV, SIGNAL(textChanged(const QString&)), this, SLOT(setVertexSize(const QString&)) ); + + // lay out the buttons + QGridLayout *layoutV = new QGridLayout; + layoutV->addWidget( btnVertex, 0, 0 ); + layoutV->addWidget( m_labelVertex, 0, 1 ); + layoutV->addWidget( labelSizeV, 1, 0 ); + layoutV->addWidget( m_editSizeV, 1, 1 ); + groupV->setLayout( layoutV ); + + /* Delaunau Edge */ + + // create groupbox + QGroupBox *groupDE = new QGroupBox( tr("Delaunay Edge") ); + // create button + QPushButton *btnDEdge = new QPushButton( tr("Set Color") ); + // create color label + m_labelDEdge = new QLabel; + m_labelDEdge->setFrameStyle(QFrame::Sunken | QFrame::Panel); + // create size label + QLabel *labelSizeDE = new QLabel( tr("Set Size") ); + // create lineedit + m_editSizeDE = new QLineEdit; + + // connect to actions + connect( btnDEdge, SIGNAL(clicked()), this, SLOT(setDEdgeColor()) ); + connect( m_editSizeDE, SIGNAL(textChanged(const QString&)), this, SLOT(setDEdgeSize(const QString&)) ); + + // lay out the buttons + QGridLayout *layoutDE = new QGridLayout; + layoutDE->addWidget( btnDEdge, 0, 0 ); + layoutDE->addWidget( m_labelDEdge, 0, 1 ); + layoutDE->addWidget( labelSizeDE, 1, 0 ); + layoutDE->addWidget( m_editSizeDE, 1, 1 ); + groupDE->setLayout( layoutDE ); + + /* Voronoi Edge */ + + // create groupbox + QGroupBox *groupVE = new QGroupBox( tr("Voronoi Edge") ); + // create button + QPushButton *btnVEdge = new QPushButton( tr("Set Color") ); + // create color label + m_labelVEdge = new QLabel; + m_labelVEdge->setFrameStyle(QFrame::Sunken | QFrame::Panel); + // create size label + QLabel *labelSizeVE = new QLabel( tr("Set Size") ); + // create lineedit + m_editSizeVE = new QLineEdit; + + // connect to actions + connect( btnVEdge, SIGNAL(clicked()), this, SLOT(setVEdgeColor()) ); + connect( m_editSizeVE, SIGNAL(textChanged(const QString&)), this, SLOT(setVEdgeSize(const QString&)) ); + + // lay out the buttons + QGridLayout *layoutVE = new QGridLayout; + layoutVE->addWidget( btnVEdge, 0, 0 ); + layoutVE->addWidget( m_labelVEdge, 0, 1 ); + layoutVE->addWidget( labelSizeVE, 1, 0 ); + layoutVE->addWidget( m_editSizeVE, 1, 1 ); + groupVE->setLayout( layoutVE ); + + /* Facet */ + + // create groupbox + QGroupBox *groupF = new QGroupBox( tr("Facet") ); + // create button + QPushButton *btnFacet = new QPushButton( tr("Set Color") ); + // create color label + m_labelFacet = new QLabel; + m_labelFacet->setFrameStyle(QFrame::Sunken | QFrame::Panel); + // create label and spinbox + QLabel *labelFacetA = new QLabel( tr("Transparency") ); + m_spinAlphaF = new QSpinBox; + m_spinAlphaF->setRange(0, 255); + + // connect to actions + connect( btnFacet, SIGNAL(clicked()), this, SLOT(setFacetColor()) ); + connect( m_spinAlphaF, SIGNAL(valueChanged(int)), this, SLOT(setFacetAlpha()) ); + + // lay out the buttons + QGridLayout *layoutF = new QGridLayout; + layoutF->addWidget( btnFacet, 0, 0 ); + layoutF->addWidget( m_labelFacet, 0, 1 ); + layoutF->addWidget( labelFacetA, 1, 0 ); + layoutF->addWidget( m_spinAlphaF, 1, 1 ); + groupF->setLayout( layoutF ); + + /* Trackball */ + + // create groupbox + QGroupBox *groupB = new QGroupBox( tr("Trackball") ); + // create button + QPushButton *btnBall = new QPushButton( tr("Set Color") ); + // create color label + m_labelBall = new QLabel; + m_labelBall->setFrameStyle(QFrame::Sunken | QFrame::Panel); + // create label and spinbox + QLabel *labelBallA = new QLabel( tr("Transparency") ); + m_spinAlphaB = new QSpinBox; + m_spinAlphaB->setRange(0, 255); + // create label and spinbox + QLabel *labelStep = new QLabel( tr("Step-long of Resizing") ); + m_spinStep = new QSpinBox; + m_spinStep->setRange(1, 300); + + // connect to actions + connect( btnBall, SIGNAL(clicked()), this, SLOT(setTrackballColor()) ); + connect( m_spinAlphaB, SIGNAL(valueChanged(int)), this, SLOT(setTrackballAlpha()) ); + connect( m_spinStep, SIGNAL(valueChanged(int)), this, SLOT(setStepLong()) ); + + // lay out the buttons + QGridLayout *layoutB = new QGridLayout; + layoutB->addWidget( btnBall, 0, 0 ); + layoutB->addWidget( m_labelBall, 0, 1 ); + layoutB->addWidget( labelBallA, 1, 0 ); + layoutB->addWidget( m_spinAlphaB, 1, 1 ); + layoutB->addWidget( labelStep, 2, 0 ); + layoutB->addWidget( m_spinStep, 2, 1 ); + groupB->setLayout( layoutB ); + + /* Empty Sphere */ + + // create groupbox + QGroupBox *groupS = new QGroupBox( tr("Empty Sphere") ); + // create color label + m_labelSphere = new QLabel; + m_labelSphere->setFrameStyle(QFrame::Sunken | QFrame::Panel); + // create button + QPushButton *btnSphere = new QPushButton( tr("Set Color") ); + // create label and spinbox + QLabel *labelSphereA = new QLabel( tr("Transparency") ); + m_spinAlphaS = new QSpinBox; + m_spinAlphaS->setRange(0, 255); + + // connect to actions + connect( btnSphere, SIGNAL(clicked()), this, SLOT(setEmptySphereColor()) ); + connect( m_spinAlphaS, SIGNAL(valueChanged(int)), this, SLOT(setEmptySphereAlpha()) ); + + // lay out the buttons + QGridLayout *layoutS = new QGridLayout; + layoutS->addWidget( btnSphere, 0, 0 ); + layoutS->addWidget( m_labelSphere, 0, 1 ); + layoutS->addWidget( labelSphereA, 1, 0 ); + layoutS->addWidget( m_spinAlphaS, 1, 1 ); + groupS->setLayout( layoutS ); + + /* OK buttons */ + // create groupbox + QGroupBox *groupBtn = new QGroupBox(); + // buttons + QPushButton *ok = new QPushButton( tr("OK") ); + QPushButton *apply = new QPushButton( tr("Apply") ); + QPushButton *cancel = new QPushButton( tr("Cancel") ); + cancel->setFocus(); + + // connect to actions + connect( ok, SIGNAL(clicked()), this, SLOT(okClicked()) ); + connect( apply, SIGNAL(clicked()), this, SLOT(applyClicked()) ); + connect( cancel, SIGNAL(clicked()), this, SLOT(reject()) ); + + // lay out the buttons + QGridLayout *layoutBtn = new QGridLayout; + layoutBtn->addWidget( ok, 0, 0 ); + layoutBtn->addWidget( cancel, 0, 1 ); + layoutBtn->addWidget( apply, 0, 2 ); + groupBtn->setLayout( layoutBtn ); + + /* dialog layout */ + + // lay out the buttons + QGridLayout *main = new QGridLayout; + main->addWidget( groupV, 0, 1 ); + main->addWidget( groupDE, 0, 2 ); + main->addWidget( groupVE, 0, 3 ); + main->addWidget( groupF, 1, 1 ); + main->addWidget( groupB, 1, 2 ); + main->addWidget( groupS, 1, 3 ); + main->addWidget( groupBtn, 2, 2, 2, 3 ); + setLayout( main ); + + // set dialog title + setWindowTitle( tr("Preferences") ); +} + +void PreferenceDlg::init(QColor clrVt, float sizeV, QColor clrDE, float sizeDE, + QColor clrVE, float sizeVE, + QColor clrF, QColor clrB, QColor clrS, int iStep) +{ + // vertex color + m_colorVertex = clrVt; + // show the color in label + m_labelVertex->setText(m_colorVertex.name()); + m_labelVertex->setPalette( QPalette(m_colorVertex) ); + m_labelVertex->setAutoFillBackground(true); + // vertex size + m_fSizeVertex = sizeV; + m_editSizeV->setText( QString::number( m_fSizeVertex ) ); + + // Delaunay edge color + m_colorDEdge = clrDE; + // show the color in label + m_labelDEdge->setText( m_colorDEdge.name() ); + m_labelDEdge->setPalette( QPalette(m_colorDEdge) ); + m_labelDEdge->setAutoFillBackground(true); + // edge size + m_fSizeDEdge = sizeDE; + m_editSizeDE->setText( QString::number( m_fSizeDEdge ) ); + + // Voronoi edge color + m_colorVEdge = clrVE; + // show the color in label + m_labelVEdge->setText( m_colorVEdge.name() ); + m_labelVEdge->setPalette( QPalette(m_colorVEdge) ); + m_labelVEdge->setAutoFillBackground(true); + // edge size + m_fSizeVEdge = sizeVE; + m_editSizeVE->setText( QString::number( m_fSizeVEdge ) ); + + // facet color + m_colorFacet = clrF; + // show the color in label + m_labelFacet->setText( m_colorFacet.name() ); + m_labelFacet->setPalette( QPalette(m_colorFacet) ); + m_labelFacet->setAutoFillBackground(true); + // facet transparency + m_spinAlphaF->setValue( m_colorFacet.alpha() ); + + // trackball color + m_colorTrackball = clrB; + // show the color in label + m_labelBall->setText(m_colorTrackball.name()); + m_labelBall->setPalette( QPalette(m_colorTrackball) ); + m_labelBall->setAutoFillBackground(true); + // trackball transparency + m_spinAlphaB->setValue( m_colorTrackball.alpha() ); + // trackball resizing fineness + m_spinStep->setValue( iStep ); + + // empty sphere color + m_colorEmptySphere = clrS; + // show the color in label + m_labelSphere->setText(m_colorEmptySphere.name()); + m_labelSphere->setPalette( QPalette(m_colorEmptySphere) ); + m_labelSphere->setAutoFillBackground(true); + // trackball transparency + m_spinAlphaS->setValue( m_colorEmptySphere.alpha() ); +} + +void PreferenceDlg::setVertexColor() +{ + m_colorVertex = QColorDialog::getColor(m_colorVertex, this); + if( m_colorVertex.isValid() ) { + m_labelVertex->setText(m_colorVertex.name()); + m_labelVertex->setPalette( QPalette(m_colorVertex) ); + m_labelVertex->setAutoFillBackground(true); + } +} + +void PreferenceDlg::setVertexSize(const QString& str) +{ + bool ok; + float size = str.toFloat(&ok); + if( ok ) + m_fSizeVertex = size; + else { + QMessageBox mb(QMessageBox::NoIcon, tr("Error!"), + tr("Enter a valid floating number."), + QMessageBox::Ok, this); + mb.exec(); + m_editSizeV->setFocus(); + } +} + +void PreferenceDlg::setDEdgeColor() +{ + m_colorDEdge = QColorDialog::getColor(m_colorDEdge, this); + if( m_colorDEdge.isValid() ) { + m_labelDEdge->setText( m_colorDEdge.name() ); + m_labelDEdge->setPalette( QPalette(m_colorDEdge) ); + m_labelDEdge->setAutoFillBackground(true); + } +} + +void PreferenceDlg::setDEdgeSize(const QString& str) +{ + bool ok; + float size = str.toFloat(&ok); + if( ok ) + m_fSizeDEdge = size; + else { + QMessageBox mb(QMessageBox::NoIcon, tr("Error!"), + tr("Enter a valid floating number."), + QMessageBox::Ok, this); + mb.exec(); + m_editSizeDE->setFocus(); + } +} + +void PreferenceDlg::setVEdgeColor() +{ + m_colorVEdge = QColorDialog::getColor(m_colorVEdge, this); + if( m_colorVEdge.isValid() ) { + m_labelVEdge->setText( m_colorVEdge.name() ); + m_labelVEdge->setPalette( QPalette(m_colorVEdge) ); + m_labelVEdge->setAutoFillBackground(true); + } +} + +void PreferenceDlg::setVEdgeSize(const QString& str) +{ + bool ok; + float size = str.toFloat(&ok); + if( ok ) + m_fSizeVEdge = size; + else { + QMessageBox mb(QMessageBox::NoIcon, tr("Error!"), + tr("Enter a valid floating number."), + QMessageBox::Ok, this); + mb.exec(); + m_editSizeVE->setFocus(); + } +} + +void PreferenceDlg::setFacetColor() +{ + m_colorFacet = QColorDialog::getColor(m_colorFacet, this); + if( m_colorFacet.isValid() ) { + m_labelFacet->setText( m_colorFacet.name() ); + m_colorFacet.setAlpha( m_spinAlphaF->value() ); + m_labelFacet->setPalette( QPalette(m_colorFacet) ); + m_labelFacet->setAutoFillBackground(true); + } +} + +void PreferenceDlg::setFacetAlpha() +{ + m_colorFacet.setAlpha( m_spinAlphaF->value() ); +} + +void PreferenceDlg::setTrackballColor() +{ + m_colorTrackball = QColorDialog::getColor(m_colorTrackball, this); + if( m_colorTrackball.isValid() ) { + m_labelBall->setText( m_colorTrackball.name() ); + m_colorTrackball.setAlpha( m_spinAlphaB->value() ); + m_labelBall->setPalette( QPalette(m_colorTrackball) ); + m_labelBall->setAutoFillBackground(true); + } +} + +void PreferenceDlg::setTrackballAlpha() +{ + m_colorTrackball.setAlpha( m_spinAlphaB->value() ); +} + +void PreferenceDlg::setStepLong() +{ + m_iStep = m_spinStep->value(); +} + +void PreferenceDlg::setEmptySphereColor() +{ + m_colorEmptySphere = QColorDialog::getColor(m_colorEmptySphere, this); + if( m_colorEmptySphere.isValid() ) { + m_labelSphere->setText( m_colorEmptySphere.name() ); + m_colorEmptySphere.setAlpha( m_spinAlphaS->value() ); + m_labelSphere->setPalette( QPalette(m_colorEmptySphere) ); + m_labelSphere->setAutoFillBackground(true); + } +} + +void PreferenceDlg::setEmptySphereAlpha() +{ + m_colorEmptySphere.setAlpha( m_spinAlphaS->value() ); +} diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/PreferenceDlg.h b/Triangulation_3_copy_tds/demo/Triangulation_3/PreferenceDlg.h new file mode 100644 index 00000000000..d4ab184fac1 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/PreferenceDlg.h @@ -0,0 +1,70 @@ +#ifndef PREFERENCE_DLG_H +#define PREFERENCE_DLG_H + +#include + +class QLabel; +class QSpinBox; +class QLineEdit; + +class PreferenceDlg : public QDialog +{ + Q_OBJECT + + friend class Viewer; + +public: + PreferenceDlg(QWidget *parent=0); + +private: + void init(QColor, float, QColor, float, QColor, float, QColor, QColor, QColor, int); + +private slots: + void okClicked() { hide(); emit( applyChanges() ); } + void applyClicked() { emit( applyChanges() ); } + + void setVertexColor(); + void setVertexSize(const QString&); + void setDEdgeColor(); + void setDEdgeSize(const QString&); + void setVEdgeColor(); + void setVEdgeSize(const QString&); + void setFacetColor(); + void setFacetAlpha(); + void setTrackballColor(); + void setTrackballAlpha(); + void setStepLong(); + void setEmptySphereColor(); + void setEmptySphereAlpha(); + + signals: // Signals do not have access specifier + void applyChanges(); + +private: + QLabel *m_labelVertex; + QLineEdit *m_editSizeV; + QLabel *m_labelDEdge; + QLineEdit *m_editSizeDE; + QLabel *m_labelVEdge; + QLineEdit *m_editSizeVE; + QLabel *m_labelFacet; + QSpinBox *m_spinAlphaF; + QLabel *m_labelBall; + QSpinBox *m_spinAlphaB; + QSpinBox *m_spinStep; + QLabel *m_labelSphere; + QSpinBox *m_spinAlphaS; + + float m_fSizeVertex; + float m_fSizeDEdge; + float m_fSizeVEdge; + QColor m_colorVertex; + QColor m_colorDEdge; + QColor m_colorVEdge; + QColor m_colorFacet; + QColor m_colorTrackball; + int m_iStep; + QColor m_colorEmptySphere; +}; + +#endif diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/Scene.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3/Scene.cpp new file mode 100644 index 00000000000..ffb03f63a0b --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/Scene.cpp @@ -0,0 +1,225 @@ +#include "Scene.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +void Scene::generatePoints(int num) +{ + if(num <= 0) return; + + /* Generate 'num' points: */ + /* 1. randomly in the cube [ (-1,-1,-1), (1,1,1) ] --tested */ + CGAL::Random_points_in_cube_3 pts_generator(1.0); + /* 2. randomly on a sphere of radius 1.0 --tested */ + // CGAL::Random_points_in_sphere_3 pts_generator(1.0); + + /* Insert them into the point list: */ + /* 1. use CGAL's copy function --tested */ + list pts; + CGAL::copy_n( pts_generator, num, std::back_inserter(pts) ); + /* 2. use STL's function */ + //for (int i=0; i & points) +{ + ifstream fin; + fin.open( filename ); + // Check whether the file is opened properly + if( !fin ) { + showError( QObject::tr("Error: cannot open file %1 for reading.").arg(filename) ); + return; + } + + istream *pIn = &fin; + + // Use CGAL::File_scanner_OFF to read in data + CGAL::File_scanner_OFF scanner(*pIn); + if( !(*pIn) ) { + showError( QObject::tr("Input error: file %1 is not in OFF format.").arg(filename) ); + return; + } + if( scanner.size_of_vertices() <= 0 ) { + showError( QObject::tr("Input error: file %1 has no vertices.").arg(filename) ); + return; + } + // Get points data from scanner + double x, y, z; + for(int i=0; i pts; + + /* Read point data from file */ + /* 1. use CGAL::File_scanner_OFF to read in data --tested */ + readOFFPointsandFacets( filename, pts ); + + /* 2. use CGAL::read_off_points to read in data -- tested */ + /* Note: read in points only, i.e. normals and faces are ignored */ + /* Note: this function can NOT omit comments (starting with '#') */ +// ifstream fin; +// fin.open( filename ); + // check whether the file is opened properly +// if( !fin ) { +// showError( QObject::tr("Error: cannot open file %1 for reading.").arg(filename) ); +// return; +// } +// if ( !CGAL::read_off_points( fin, // inout ifstream +// back_inserter(pts) ) ) { // output iterator over points +// showError( QObject::tr("Error: cannot read file %1.").arg(filename) ); +// } + + /* Insert the points to build a Delaunay triangulation */ + /* Note: this function returns the number of inserted points; + it is not guaranteed to insert the points following the order of iteraror. */ + m_dt.insert( pts.begin(), pts.end() ); + /* Check the combinatorial validity of the triangulation */ + /* Note: when it is set to be true, + messages describing the first invalidity encountered are printed. */ + if( !m_dt.is_valid() ) // default: false - verbosity off + showError( QObject::tr("Error: fail to build a Delaunay triangulation.") ); + /* Check the dimension */ + if( m_dt.dimension() != 3 ) + showError( QObject::tr("Error: cannot built a 3D triangulation.") ); + /* Store the vertex handles into an array for future usage (move, delete, etc) */ + for(vertices_iterator vit=m_dt.finite_vertices_begin(); + vit!=m_dt.finite_vertices_end(); ++vit) { + m_vhArray.push_back( vit ); + } + assert( m_dt.number_of_vertices() == m_vhArray.size() ); +} + +void Scene::loadPointsXYZ(const char* filename) +{ + ifstream fin; + fin.open( filename ); + // Check whether the file is opened properly + if( !fin ) { + showError( QObject::tr("Error: cannot open file %1 for reading.").arg(filename) ); + return; + } + + /* Use CGAL::read_xyz_points to read in data -- tested */ + /* Note: this function reads in points only (normals are ignored) */ + /* Note: this function can NOT omit comments (starting with '#') */ + list pts; + if( !CGAL::read_xyz_points( fin, // input ifstream + back_inserter(pts) ) ) { // output iterator over points + showError( QObject::tr("Error: cannot read file %1.").arg(filename) ); + } + + /* Insert the points to build a Delaunay triangulation */ + /* Note: this function returns the number of inserted points; + it is not guaranteed to insert the points following the order of iteraror. */ + m_dt.insert( pts.begin(), pts.end() ); + /* Check the combinatorial validity of the triangulation */ + /* Note: when it is set to be true, + messages describing the first invalidity encountered are printed. */ + if( !m_dt.is_valid() ) // default: false - verbosity off + showError( QObject::tr("Error: fail to build a Delaunay triangulation.") ); + /* Check the dimension */ + if( m_dt.dimension() != 3 ) + showError( QObject::tr("Error: cannot build a 3D triangulation.") ); + /* Store the vertex handles into an array for future usage (move, delete, etc) */ + for(vertices_iterator vit=m_dt.finite_vertices_begin(); + vit!=m_dt.finite_vertices_end(); ++vit) { + m_vhArray.push_back( vit ); + } + assert( m_dt.number_of_vertices() == m_vhArray.size() ); +} + +void Scene::savePointsOFF(const char* filename) +{ + ofstream fout; + fout.open( filename ); + if( !fout ) { + showError( QObject::tr("Error: cannot open file %1 for writting.").arg(filename) ); + return; + } + + ostream *pOut = &fout; + + /* Use CGAL::File_writer_OFF to write points */ + // initialize header_OFF + CGAL::File_header_OFF header(false, // true: binary output; false: ASCII + false, // true: no comments in file + false, // true: Geomview SKEL format + true); // true: verbosity on; false: verbosity off + // a simpler way to initialize header_OFF +// CGAL::File_header_OFF header(true); // true: verbosity on +// // (ASCII output, comments, no SKEL) + CGAL::File_writer_OFF writer( header ); + // write header + writer.write_header(*pOut, // output ostream + m_dt.number_of_vertices(), // number of points/vertices + 0, // number of halfedges + 0, // number of facets + false); // true: has normals + // write points (get from point array) + for(vertices_iterator vit=m_dt.finite_vertices_begin(); + vit!=m_dt.finite_vertices_end(); ++vit) { + Point_3& p = vit->point(); + writer.write_vertex( p.x(), p.y(), p.z() ); + } + // write footer + writer.write_footer(); +} + +void Scene::savePointsXYZ(const char* filename) +{ + ofstream fout; + fout.open( filename ); + // Check whether the file is opened properly + if( !fout ) { + showError( QObject::tr("Error: cannot open file %1 for writting.").arg(filename) ); + return; + } + + /* Use CGAL::write_xyz_points to write out data */ + /* Note: this function writes out points only (normals are ignored) */ + if( !CGAL::write_xyz_points( fout, // output ofstream + m_dt.points_begin(), // first output point + m_dt.points_end() ) ) { // past-the-end output point + showError( QObject::tr("Error: cannot read file %1.").arg(filename) ); + } +} diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/Scene.h b/Triangulation_3_copy_tds/demo/Triangulation_3/Scene.h new file mode 100644 index 00000000000..2401e336c3c --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/Scene.h @@ -0,0 +1,40 @@ +#ifndef SCENE_H +#define SCENE_H + +#include "typedefs.h" +#include + +class Scene { + + friend class Viewer; + +public: + Scene() {} + ~Scene() { eraseOldData(); } + +public: + inline void setViewer(QGLViewer* v) { m_viewer = v; } + inline void showError(const QString & msg) { + if(!m_viewer) m_viewer->displayMessage( msg ); + } + inline bool isDTEmpty() { return m_dt.number_of_vertices()==0; } + inline void eraseOldData() { m_dt.clear(); m_vhArray.clear(); } + +public: + void generatePoints(int); + void loadPointsOFF(const char*); + void loadPointsXYZ(const char*); + void savePointsOFF(const char*); + void savePointsXYZ(const char*); + + void readOFFPointsandFacets(const char*, std::list &); + +private: + //added for T3 demo + DT3 m_dt; + QList m_vhArray; + + QGLViewer* m_viewer; +}; + +#endif diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/T3_demo.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3/T3_demo.cpp new file mode 100644 index 00000000000..a79e94031d2 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/T3_demo.cpp @@ -0,0 +1,37 @@ +// Copyright (c) 2010 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL: svn+ssh://sccode@scm.gforge.inria.fr/svn/cgal/branches/experimental-packages/GSoC10-demoT3/demos/Triangulation_demo_3/ $ +// $Id: r58170 2010-08-19 20:46:16 -0400 $ +// +// +// Author(s) : Sophie Fei Che +// +// File Description : Demo of CGAL 3D Triangulation package + +#include "MainWindow.h" +#include + +int main(int argc, char** argv) +{ + QApplication app(argc, argv); + + app.setOrganizationDomain("inria.fr"); + app.setOrganizationName("INRIA"); + app.setApplicationName("3D Triangulation Demo"); + + MainWindow mw; + mw.show(); + + return app.exec(); +} diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/T3_demo.qrc b/Triangulation_3_copy_tds/demo/Triangulation_3/T3_demo.qrc new file mode 100644 index 00000000000..66067aac059 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/T3_demo.qrc @@ -0,0 +1,31 @@ + + + icons/flat.png + icons/stereo.png + icons/pause.jpeg + icons/show_delaunay.jpeg + icons/show_facet.jpeg + icons/show_point.jpeg + icons/show_voronoi.jpeg + icons/play.jpeg + icons/stop.jpeg + icons/empty_sphere.jpeg + icons/normal_view.jpeg + icons/nearest_nb.png + icons/quit.jpeg + icons/insert_point.jpg + icons/clear.jpeg + icons/coordinates.jpeg + icons/fileOpen.png + icons/pointRandom.png + icons/fileSave.png + icons/cgal_logo.xpm + icons/insert.jpeg + icons/move_1.jpeg + icons/select_hand.jpeg + icons/preferences.jpeg + + + icons/about_CGAL.html + + diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/Viewer.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3/Viewer.cpp new file mode 100644 index 00000000000..068ce983961 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/Viewer.cpp @@ -0,0 +1,1297 @@ +#include "Viewer.h" + +using namespace std; + +#include "Viewer.moc" // .moc will be the output from moc preprocessor + +void Viewer::init() +{ + /* Initial timer for playing incremental construction */ + m_pTimer = new QTimer(this); + connect(m_pTimer, SIGNAL(timeout()), this, SLOT(incremental_insert())); + + /* Scene inits */ + setBackgroundColor(::Qt::white); + // scene are defined by a sphere of 2.0, camera at the center, i.e. (0, 0, 0) + setSceneCenter( qglviewer::Vec(-0.,-0.,-0.) ); + setSceneRadius( 2. ); + // show text message + setTextIsEnabled(true); + setForegroundColor(::Qt::red); + setFont(QFont("Arial Black", 16, QFont::Bold)); + + /* OpenGL inits */ + // Increase the material shininess, so that the difference between + // the two versions of the spiral is more visible. + glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 50.0); + GLfloat specular_color[4] = { 0.8f, 0.8f, 0.8f, 1.0 }; + glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specular_color); + // Set Smooth Shading + ::glShadeModel(GL_SMOOTH); + + // depth buffer setup + ::glClearDepth(1.0f); + ::glEnable(GL_DEPTH_TEST); + ::glDepthFunc(GL_LEQUAL); + ::glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); + + // enable semi-transparent culling planes + ::glEnable(GL_BLEND); + ::glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + // anti-aliasing, i.e. reduce jaggedness (if the OpenGL driver permits that) + ::glEnable(GL_POINT_SMOOTH); + ::glHint(GL_POINT_SMOOTH_HINT, GL_NICEST); + ::glEnable(GL_LINE_SMOOTH); + ::glHint(GL_LINE_SMOOTH_HINT, GL_NICEST); + + /* Add mouse and key description */ + setKeyDescription( Qt::CTRL + Qt::Key_G, tr("Generate points") ); + setKeyDescription( Qt::CTRL + Qt::Key_O, tr("Load points") ); + setKeyDescription( Qt::CTRL + Qt::Key_S, tr("Save points") ); + setKeyDescription( Qt::CTRL + Qt::Key_Comma, tr("Preference") ); + setKeyDescription( Qt::CTRL + Qt::Key_H, tr("Hide Kernel Demo") ); + setKeyDescription( Qt::CTRL + Qt::Key_Q, tr("Quit Kernel Demo") ); + setKeyDescription( Qt::Key_Return, + tr("Insert new point to triangulation in Input-Point mode") ); + setKeyDescription( Qt::Key_Escape, + tr("Cancel insertion in Input-Point mode;
") + + tr("Cancel current selection in Select mode") ); + setKeyDescription( Qt::Key_Delete, tr("Delete selected vertices in Select mode") ); + + setMouseBindingDescription( Qt::LeftButton, + tr("Hold to move new point in Input-Point mode;
") + + tr("Hold to move a vertex in Move mode") ); + setMouseBindingDescription( Qt::SHIFT + Qt::LeftButton, + tr("Click to insert a vertex in Input-Vertex mode;
") + + tr("Click to insert a point in Input-Point mode;
") + + tr("Click or Drag to select multiple points in Select mode;
") + + tr("Click to place a query point in Find-Nearest-Neighbor mode;
") + + tr("Click to place a query point in Show-Empty-Sphere mode") ); + setMouseBindingDescription( Qt::CTRL + Qt::LeftButton, + tr("Drag to add vertices to current selection in Select mode") ); +} + +QString Viewer::helpString() const +{ + QString text("

3D Triangulation Demo

"); + + text += "This example illustrates a generic interactive demo for 3D Triangulation in CGAL. "; + text += "This demo could be used as a simple skeleton "; + text += "for potential demos of other 3D packages or for teaching CGAL.

"; + + text += "The key feature is to edit vertices/points with mouse."; + text += "There are several modes:

"; + + text += " - Normal Mode: "; + text += "Rotate, zoom, or translate camera using mouse.
"; + text += " - Insert Vertex: "; + text += "Insert a vertex on the surface of the trackball "; + text += "and the triangulation will be updated correspondingly.
"; + text += " - Insert Point: "; + text += "Insert a point on the surface of the trackball. "; + text += "Its conflict region will be highlighted. "; + text += "When the new point is moving, "; + text += "its conflict region will be updated correspondingly.
"; + text += " - Select: "; + text += "Click or drag mouse left button to select multiple points.
"; + text += " - Move: Hold mouse left button to move a vertex "; + text += "and the triangulation will be updated correspondingly.
"; + text += " - Find Nearest Neighbor: "; + text += "Place a query point and its nearest neighbor will be highlighted.
"; + text += " - Show Empty Sphere: "; + text += "Place a query point, locate the point in a cell "; + text += "and then show the empty sphere of that cell. "; + text += "An empty sphere of a cell is a sphere "; + text += "with all four vertices of the cell lying on it "; + text += "and no other vertices inside it.

"; + text += "Shift+Wheel to resize the trackball when it exists. "; + text += "See Mouse page for more details.

"; + + text += "Other basic features include:
"; + text += " - Randomly generate points,
"; + text += " - Read/Write files,
"; + text += " - Show vertices, Voronoi edges, Delaunay edges, and/or facets,
"; + text += " - Incremental Construct: "; + text += "Re-construct the current triangulation incrementally. "; + text += "If no triangulation exists yet, randomly generate 100 points "; + text += "and construct a Delaunay triangulation of those points.
"; + + return text; +} + +/*************************************************************/ +/* Draw functions */ + +void Viewer::draw() +{ + if( m_pScene == NULL ) return; + + QFont fontPrompt("Arial", 14); + + if( m_showAxis ) { + qglColor(::Qt::black); + drawAxis( sceneRadius() ); + } + + /* Draw vertices */ + if ( m_showVertex && m_pScene->m_dt.number_of_vertices()>0 ) { + for(QList::iterator vit = m_pScene->m_vhArray.begin(); + vit < m_pScene->m_vhArray.end(); ++vit) { + if( m_curMode == SELECT && (*vit)->isSeled() ) continue; + if( (*vit) == m_nearestNb ) continue; + drawVertex( (*vit)->point(), m_colorVertex, m_fSizeVertex ); + }//end-for-points + }//end-if-points + + /* Draw all points during incremental mode */ + if( !m_incrementalPts.isEmpty() ) { + /* draw the rest to-be-inserted vertices */ + for(QList::iterator pit=m_incrementalPts.begin(); + pit < m_incrementalPts.end(); ++pit) { + drawVertex( (*pit), ::Qt::gray, m_fSizeVertex ); + } + + switch( m_curStep ) { + case NEWPT: + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( 10, 20, tr("Highlight the next-to-insert point"), fontPrompt ); + /* Highlight the next-to-insert point */ + drawVertex( m_curIncPt, ::Qt::red, m_fSizeVertex ); + break; + case CELL: // show the tetrahedron that contains the point + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( 10, 20, tr("Show the tetrahedron containing the point"), fontPrompt ); + drawText( 10, 40, tr("(Only finite facets are drawn)"), fontPrompt ); + /* Highlight the next-to-insert vertex */ + drawVertex( m_curIncPt, ::Qt::red, m_fSizeVertex ); + /* Draw the cell containing that point */ + for(int i=0; i<4; ++i) { + if( m_pScene->m_dt.is_infinite(m_cellContain, i) ) continue; + drawFacet( m_pScene->m_dt.triangle( m_cellContain, i ), m_colorFacet ); + }//end-for-facets + break; + case CONFLICT: // show the conflict region + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( 10, 20, tr("Show the conflict region"), fontPrompt ); + /* Highlight the next-to-insert vertex */ + drawVertex( m_curIncPt, ::Qt::red, m_fSizeVertex ); + /* Draw conflict region */ + for(QList::iterator fit = m_boundaryFacets.begin(); + fit < m_boundaryFacets.end(); ++fit) { + if( m_pScene->m_dt.is_infinite(*fit) ) continue; + drawFacet( m_pScene->m_dt.triangle(*fit), QColor(215, 80, 0, 96) ); //semi-transparent purple + }//end-for-facets + break; + default: + break; + }//end-of=switch + }//end-if-incpts + + /* Draw Delaunay edges */ + if( m_showDEdge ) { + for(edges_iterator eit = m_pScene->m_dt.finite_edges_begin(); + eit != m_pScene->m_dt.finite_edges_end(); ++eit) { + Segment_3 seg = m_pScene->m_dt.segment(*eit); + drawEdge( seg.vertex(0), seg.vertex(1), m_colorDEdge, m_fSizeDEdge ); + }//end-for-edges + }//end-if-dt + + /* Draw Voronoi edges */ + if( m_showVEdge ) { + for(facets_iterator fit = m_pScene->m_dt.finite_facets_begin(); + fit != m_pScene->m_dt.finite_facets_end(); ++fit) { + Object_3 o = m_pScene->m_dt.dual(*fit); + if (const Segment_3 *s = CGAL::object_cast(&o)) { + drawEdge( s->vertex(0), s->vertex(1), m_colorVEdge, m_fSizeVEdge ); + } else if (const Ray_3 *r = CGAL::object_cast(&o)) { + drawEdge( r->point(0), // the source of the ray + r->point(1), // another point on the ray, different from the source + m_colorVEdge, m_fSizeVEdge ); + } + }//end-for-edges + }//end-if-vd + + /* Draw facets */ + if( m_showFacet ) { + for(facets_iterator fit = m_pScene->m_dt.finite_facets_begin(); + fit != m_pScene->m_dt.finite_facets_end(); ++fit) { + drawFacet( m_pScene->m_dt.triangle(*fit), m_colorFacet ); + }//end-for-facets + }//end-if-facets + + /* Insert vertex mode */ + if( m_curMode == INSERT_V ) { + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( width()-200, 20, tr("Shift+Left: Insert a vertex"), fontPrompt ); + drawText( width()-200, 40, tr("Shift+Wheel: Resize trackball"), fontPrompt ); + /* Draw the trackball */ + drawSphere( m_fRadius, m_colorTrackball ); + }//end-if-insv + + /* Insert point mode */ + else if( m_curMode == INSERT_PT ) { + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( width()-200, 20, tr("Shift+Left: Insert a point"), fontPrompt ); + drawText( width()-200, 40, tr("Hold Left: Move the point"), fontPrompt ); + drawText( width()-200, 60, tr("Return: Insert to DT"), fontPrompt ); + drawText( width()-200, 80, tr("Escape: Cancel insertion"), fontPrompt ); + drawText( width()-200, 100, tr("Shift+Wheel: Resize trackball"), fontPrompt ); + + /* Draw the trackball */ + drawSphere( m_fRadius, m_colorTrackball ); + + if( m_hasNewPt ) { + /* Draw the newly inserted point */ + drawVertex( m_newPt, ::Qt::red, m_fSizeVertex ); + /* Draw conflict region */ + for(QList::iterator fit = m_boundaryFacets.begin(); + fit < m_boundaryFacets.end(); ++fit) { + if( m_pScene->m_dt.is_infinite(*fit) ) continue; + drawFacet( m_pScene->m_dt.triangle(*fit), QColor(215, 80, 0, 96) ); //semi-transparent purple + }//end-for-facets + }//end-if-shown + }//end-if-inspt + + /* Select mode */ + else if( m_curMode == SELECT) { + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( width()-200, 20, tr("Shift+Left: Select"), fontPrompt ); + drawText( width()-200, 40, tr("Ctrl+Left: Add selection"), + QFont("Arial", 14) ); + drawText( width()-200, 60, tr("Escape: Cancel selection"), fontPrompt ); + drawText( width()-200, 80, tr("DEL: Delete selected"), fontPrompt ); + /* Highlight the selected vertices */ + for(QList::iterator vit=m_vidSeled.begin(); vitm_vhArray.at(*vit)->point(), ::Qt::red, m_fSizeVertex ); + }//end-for-seledpts + /* Draw the multiple selection window */ + if( m_isPress ) { + ::glDisable( GL_LIGHTING ); + startScreenCoordinatesSystem(); + qglColor( QColor(80, 180, 180, 64) ); + ::glBegin(GL_QUADS); + ::glVertex2i(m_rectSel.left(), m_rectSel.top()); + ::glVertex2i(m_rectSel.right(), m_rectSel.top()); + ::glVertex2i(m_rectSel.right(), m_rectSel.bottom()); + ::glVertex2i(m_rectSel.left(), m_rectSel.bottom()); + ::glEnd(); + stopScreenCoordinatesSystem(); + ::glEnable( GL_LIGHTING ); + }//end-if-press + }//end-if-sel + + /* Move mode */ + else if( m_curMode == MOVE ) { + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( width()-200, 20, tr("Left Click: Select"), fontPrompt ); + + if( m_isMoving ) { + drawText( width()-200, 40, tr("Shift+Wheel: Resize trackball"), fontPrompt ); + /* Draw the trackball */ + drawSphere( m_fRadius, m_colorTrackball ); + /* Highlight the moving point */ + drawVertex( m_pScene->m_vhArray.at( m_vidMoving )->point(), ::Qt::red, m_fSizeVertex ); + }//end-if-v + }//end-if-move + + /* FindNb mode */ + else if( m_curMode == FINDNB ) { + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( width()-200, 20, tr("Shift+Left: Place query point"), fontPrompt ); + drawText( width()-200, 40, tr("Shift+Wheel: Resize trackball"), fontPrompt ); + /* Draw the trackball */ + drawSphere( m_fRadius, m_colorTrackball ); + /* Draw the nearest neighbor */ + if( m_nearestNb != NULL ) { + drawVertex( m_queryPt, ::Qt::red, m_fSizeVertex ); + drawVertex( m_nearestNb->point(), ::Qt::red, m_fSizeVertex ); + } + }//end-if-findnb + + /* EmptySphere mode */ + else if( m_curMode == EMPTYSPH ) { + /* Show prompt messages */ + qglColor( ::Qt::black ); + drawText( width()-200, 20, tr("Shift+Left: Place query point"), fontPrompt ); + drawText( width()-200, 40, tr("Press S: Show/Hide trackball"), fontPrompt ); + drawText( width()-200, 60, tr("Shift+Wheel: Resize trackball"), fontPrompt ); + /* Draw the trackball */ + if( m_showTrackball ) + drawSphere( m_fRadius, m_colorTrackball ); + + if( m_hasEmptyS ) { + /* Draw the query point */ + drawVertex( m_queryPt, ::Qt::red, m_fSizeVertex ); + /* Draw the cell containing that point */ + for(int i=0; i<4; ++i) { + if( m_pScene->m_dt.is_infinite(m_cellContain, i) ) continue; + drawFacet( m_pScene->m_dt.triangle( m_cellContain, i ), m_colorFacet ); + }//end-for-facets + /* Draw the sphere */ + drawSphere( m_fREmptyS, m_colorEmptySphere, m_centerPt ); + } + }//end-if-emptyS +} + +void Viewer::drawVertex(const Point_3& p, const QColor& clr, float r) +{ + /* Draw regular points */ + if( m_isFlat ) { + // disable lighting + ::glDisable( GL_LIGHTING ); + + ::glPointSize(8.0); + qglColor( clr ); + + ::glBegin(GL_POINTS); + ::glVertex3f( p.x(), p.y(), p.z() ); + ::glEnd(); + + // resume lighting + ::glEnable( GL_LIGHTING ); + + return; + } + + /* Draw vertices as 3D balls */ + GLboolean lighting, colorMaterial; + ::glGetBooleanv( GL_LIGHTING, &lighting ); + ::glGetBooleanv( GL_COLOR_MATERIAL, &colorMaterial ); + ::glEnable( GL_LIGHTING ); + ::glDisable(GL_COLOR_MATERIAL); + + float color[4]; + color[0] = clr.redF(); + color[1] = clr.greenF(); + color[2] = clr.blueF(); + color[3] = clr.alphaF(); + + // move to the point + ::glPushMatrix(); + ::glTranslatef( p.x(), p.y(), p.z() ); + + // draw + GLUquadricObj* quadratic = ::gluNewQuadric(); // Create A Pointer To The Quadric Object + ::gluQuadricNormals( quadratic, GLU_SMOOTH ); // Create Smooth Normals + ::glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color ); + ::gluSphere( quadratic, r, 16, 16 ); + + // move back to origin + ::glPopMatrix(); + + if ( colorMaterial ) + ::glEnable( GL_COLOR_MATERIAL ); + if ( !lighting ) + ::glDisable( GL_LIGHTING ); +} + +void Viewer::drawEdge(const Point_3& from, const Point_3& to, const QColor& clr, float r) +{ + /* Draw regular lines */ + if( m_isFlat ) { + // disable lighting + ::glDisable( GL_LIGHTING ); + + ::glLineWidth(1.0); + qglColor( clr ); + + ::glBegin(GL_LINES); + ::glVertex3f( from.x(), from.y(), from.z() ); + ::glVertex3f( to.x(), to.y(), to.z() ); + ::glEnd(); + + // resume lighting + ::glEnable( GL_LIGHTING ); + + return; + } + + /* Draw edges as 3D cylinders */ + GLboolean lighting, colorMaterial; + ::glGetBooleanv( GL_LIGHTING, &lighting ); + ::glGetBooleanv( GL_COLOR_MATERIAL, &colorMaterial ); + ::glEnable( GL_LIGHTING ); + ::glDisable(GL_COLOR_MATERIAL); + + float color[4]; + color[0] = clr.redF(); + color[1] = clr.greenF(); + color[2] = clr.blueF(); + color[3] = clr.alphaF(); + + Vector_3 v = to - from; + + // compute the length of the edge + // method 1: +// float length = sqrt( CGAL::squared_distance( from, to ) ); + // method 2: + float length = sqrt( v.squared_length() ); + + // normalize + v = v / length; + // compute the angle: cos theta = v.z/1.0 + GLfloat angle = acos( v.z() ) / 3.1415927 * 180; + + ::glPushMatrix(); + + // move to "from" point + ::glTranslatef( from.x(), from.y(), from.z() ); + // rotate from z-axis to from-->to + // axis: cross product of z-axis and from-->to + ::glRotatef( angle, -v.y(), v.x(), 0.0f ); + // draw + GLUquadricObj* quadratic = ::gluNewQuadric(); // Create A Pointer To The Quadric Object + ::gluQuadricNormals( quadratic, GLU_SMOOTH ); // Create Smooth Normals + ::glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color ); + // gluCylinder draws a cylinder oriented along the z-axis + ::gluCylinder( quadratic, r, r, length, 16, 4 ); + + // move back to origin + ::glPopMatrix(); + + if ( colorMaterial ) + ::glEnable( GL_COLOR_MATERIAL ); + if ( !lighting ) + ::glDisable( GL_LIGHTING ); +} + +void Viewer::drawFacet(const Triangle_3& t, const QColor& clr) +{ + // disable lighting + ::glDisable( GL_LIGHTING ); + + // disable depth buffer writing + ::glDepthMask( GL_FALSE ); + + qglColor( m_colorFacet ); + + ::glBegin(GL_TRIANGLES); + Point_3 p0 = t.vertex(0); + Point_3 p1 = t.vertex(1); + Point_3 p2 = t.vertex(2); + ::glVertex3f( p0.x(), p0.y(), p0.z() ); + ::glVertex3f( p1.x(), p1.y(), p1.z() ); + ::glVertex3f( p2.x(), p2.y(), p2.z() ); + ::glEnd(); + + // resume depth buffer writing + ::glDepthMask( GL_TRUE ); + + // resume lighting + ::glEnable( GL_LIGHTING ); +} + +void Viewer::drawSphere(float r, const QColor& clr, const Point_3& center) +{ + GLboolean lighting, colorMaterial; + ::glGetBooleanv( GL_LIGHTING, &lighting ); + ::glGetBooleanv( GL_COLOR_MATERIAL, &colorMaterial ); + ::glEnable( GL_LIGHTING ); + ::glDisable(GL_COLOR_MATERIAL); + + float color[4]; + color[0] = clr.redF(); + color[1] = clr.greenF(); + color[2] = clr.blueF(); + color[3] = clr.alphaF(); + + ::glPushMatrix(); + + // move to the point + if( center != CGAL::ORIGIN ) ::glTranslatef( center.x(), center.y(), center.z() ); + + // disable depth buffer writing + ::glDepthMask( GL_FALSE ); + // draw + GLUquadricObj* quadratic = ::gluNewQuadric(); // Create A Pointer To The Quadric Object + ::gluQuadricNormals( quadratic, GLU_SMOOTH ); // Create Smooth Normals + ::glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, color ); + ::gluSphere( quadratic, r, 32, 32 ); + // resume depth buffer writing + ::glDepthMask( GL_TRUE ); + + // move back to origin + ::glPopMatrix(); + + if ( colorMaterial ) + ::glEnable( GL_COLOR_MATERIAL ); + if ( !lighting ) + ::glDisable( GL_LIGHTING ); +} + +/*************************************************************/ +/* Select functions */ + +void Viewer::drawWithNames() +{ + for(int i=0; im_vhArray.size(); ++i) { + // push a name for each point onto the name stack + // note: it can NOT be used between glBegin and glEnd + ::glPushName( i ); + + // draw the point + ::glBegin(GL_POINTS); + Point_3& p = m_pScene->m_vhArray.at(i)->point(); + ::glVertex3f(p.x(), p.y(), p.z()); + ::glEnd(); + + // pop one name off the top of the name stack + ::glPopName(); + }//end-for-points + + // push a name for the newly inserted point + if( m_curMode == INSERT_PT && m_hasNewPt ) { + ::glPushName( ::GLuint(-1) ); + ::glBegin(GL_POINTS); + ::glVertex3f(m_newPt.x(), m_newPt.y(), m_newPt.z()); + ::glEnd(); + ::glPopName(); + }//end-if-newPt +} + +void Viewer::endSelection(const QPoint& point) +{ + // flush GL buffers + ::glFlush(); + + // reset GL_RENDER mode (was GL_SELECT) and get the number of selected points + size_t nSel = ::glRenderMode(GL_RENDER); + + /* No selection */ + if( nSel <= 0 ) { + if( m_curMode == SELECT ) + m_isPress = false; + }//end-if-notselected + + // each hit record has 4 data: # of names in name stack, min and max depth of old hits, + // name stack contents [see glSelectBuffer man page for more details] + // i.e. (selectBuffer())[4*i+3] is the id pushed on the stack + + /* Check whether the new point is clicked on */ + else if( m_curMode == INSERT_PT ) { + if( m_hasNewPt && (selectBuffer())[3] == ::GLuint(-1) ) + m_isMoving = true; + }//end-if-inspt + + /* Check whether vertex is clicked on */ + else if( m_curMode == MOVE ) { + m_isMoving = true; + m_vidMoving = (selectBuffer())[3]; + // compute the corresponding size of trackball, i.e. selectedV is on the ball + Point_3 p = m_pScene->m_vhArray.at( m_vidMoving )->point(); + m_fRadius = sqrt( p.x()*p.x() + p.y()*p.y() + p.z()*p.z() ); + }//end-if-move + + /* Store current selections */ + else { // m_curMode == SELECT + if( m_selMode == NORMAL ) { + // remove the old selections + for(QList::iterator vit=m_vidSeled.begin(); + vit < m_vidSeled.end(); ++vit) { + m_pScene->m_vhArray.at(*vit)->setSeled( false ); + } + m_vidSeled.clear(); + + // record the new selections + for(int i=0; im_vhArray.at( m_vidSeled.back() )->setSeled(); + } + } else { + for(int i=0; im_vhArray.at( (selectBuffer())[4*i+3] )->setSeled(); + }//end-if-contain + }//end-for + }//end-if-add + }//end-if-sel +} + +/*************************************************************/ +/* Mouse and Keyboard functions */ + +void Viewer::mousePressEvent(QMouseEvent *event) +{ + // button() holds the button that caused the event + // note: for mouse move event, button() always return Qt::NoButton + // modifiers() holds the keyboard modifier flags at the time of the event + // buttons() holds the button state when the event was generated, + // i.e. all buttons that are pressed down + // pos() holds the mouse cursor's position relative to the receiving widget + + // Get event modifiers key +#if QT_VERSION < 0x040000 + // Bug in Qt : use 0x0f00 instead of Qt::KeyButtonMask with Qt versions < 3.1 + const Qt::ButtonState modifiers = (Qt::ButtonState)(event->state() & Qt::KeyButtonMask); +#else + const Qt::KeyboardModifiers modifiers = event->modifiers(); +#endif + + if( m_curMode == INSERT_V + && event->button() == Qt::LeftButton && modifiers == Qt::SHIFT ) { + m_isPress = true; + }//end-if-insv + + else if(m_curMode == INSERT_PT && event->button() == Qt::LeftButton ) { + /* shift+left to insert */ + if( modifiers == Qt::SHIFT ) { + if( m_pScene->m_dt.is_valid() && m_pScene->m_dt.dimension() == 3 ) + m_isPress = true; + else + displayMessage( tr("There exists no triangulation yet.") ); + m_hasNewPt = false; + } else { /* left button to move */ + m_isMoving = false; + // define selection window (default was 3) + setSelectRegionWidth( 10 ); + setSelectRegionHeight( 10 ); + // perform the selection + select( event->pos() ); + if( m_isMoving ) + // redraw window + updateGL(); + else + // if no point is selected, then regular action (rotation) will be performed + QGLViewer::mousePressEvent(event); + }//end-if-shift + }//end-if-inspt + + else if( m_curMode == SELECT && event->button() == Qt::LeftButton ) { + // set the selection mode + switch( modifiers ) { + case Qt::SHIFT : // select + m_isPress = true; + m_selMode = NORMAL; + // initialize multiple selection window + m_rectSel = QRect( event->pos(), event->pos() ); + // redraw window + updateGL(); + break; + case Qt::CTRL : // add selection + m_isPress = true; + m_selMode = ADD; + // initialize multiple selection window + m_rectSel = QRect( event->pos(), event->pos() ); + // redraw window + updateGL(); + break; + default: // rotate + QGLViewer::mousePressEvent(event); + break; + } + }//end-if-select + + else if(m_curMode == MOVE && event->button() == Qt::LeftButton ) { + m_isMoving = false; + // define selection window (default was 3) + setSelectRegionWidth( 10 ); + setSelectRegionHeight( 10 ); + // perform the selection + select( event->pos() ); + if( m_isMoving ) // redraw window + updateGL(); + else // if no point is selected, then regular action (rotation) will be performed + QGLViewer::mousePressEvent(event); + }//end-if-move + + else if( m_curMode == FINDNB + && event->button() == Qt::LeftButton && modifiers == Qt::SHIFT ) { + if( m_pScene->m_dt.is_valid() && m_pScene->m_dt.dimension() == 3 ) + m_isPress = true; + else + displayMessage( tr("There exists no triangulation yet.") ); + }//end-if-findnb + + else if( m_curMode == EMPTYSPH + && event->button() == Qt::LeftButton && modifiers == Qt::SHIFT ) { + if( m_pScene->m_dt.is_valid() && m_pScene->m_dt.dimension() == 3 ) + m_isPress = true; + else + displayMessage( tr("There exists no triangulation yet.") ); + m_hasEmptyS = false; + }//end-if-emptyS + + else + QGLViewer::mousePressEvent(event); +} + +void Viewer::mouseMoveEvent(QMouseEvent *event) +{ + if( m_curMode == INSERT_PT && m_isMoving ) { + Vec pt; + if( computeIntersect( event->pos(), pt ) ) { + m_newPt = Point_3(pt.x, pt.y, pt.z); + // compute the conflict hole induced by point p + computeConflict( m_newPt ); + }//end-if-compute + + // redraw + updateGL(); + }//end-if-inspt + + else if( m_curMode == SELECT && m_isPress ) { + // update multiple selection window + m_rectSel.setBottomRight( event->pos() ); + // redraw + updateGL(); + }//end-if-sel + + else if( m_curMode == MOVE && m_isMoving ) { + Vec pt; + if( computeIntersect( event->pos(), pt ) ) { + // note: QList::operator[] return a modifiable reference; + // while QList::at return a const reference +#if CGAL_VERSION_NR < 1030700000 + // move_point moves the point stored in v to p while preserving the Delaunay property + // it calls remove(v) followed by insert(p) and return the new handle + // it supposely faster when the point has not moved much + m_pScene->m_vhArray[m_vidMoving] = m_pScene->m_dt.move_if_no_collision( + m_pScene->m_vhArray.at( m_vidMoving ), + Point_3( pt.x, pt.y, pt.z ) ); +#else + // move_if_no_collision moves the point stored in v to pt + // if there is not already another vertex placed on pt, + // the triangulation is modified s.t. the new position of v is pt; + // otherwise, the vertex at point pt is returned. + Vertex_handle vh = m_pScene->m_dt.move_if_no_collision( + m_pScene->m_vhArray.at( m_vidMoving ), + Point_3( pt.x, pt.y, pt.z ) ); + int id1 = m_pScene->m_vhArray.indexOf( vh ); + int id2 = m_pScene->m_vhArray.indexOf( vh, m_vidMoving+1 ); + // remove the duplicate in vhArray + if( id1 != m_vidMoving ) + m_pScene->m_vhArray.removeAt( id1 ); + else if( id2 != -1 ) + m_pScene->m_vhArray.removeAt( id2 ); + m_pScene->m_vhArray[m_vidMoving] = vh; +#endif + }//end-if-compute + + // redraw + updateGL(); + }//end-if-move + + else + QGLViewer::mouseMoveEvent(event); +} + +void Viewer::mouseReleaseEvent(QMouseEvent *event) +{ + /* INS_V mode - Shift+Left: compute and insert a vertex */ + if( m_curMode == INSERT_V && m_isPress ) { + m_isPress = false; + Vec pt; + if( computeIntersect( event->pos(), pt ) ) { + m_pScene->m_vhArray.push_back( m_pScene->m_dt.insert( Point_3( pt.x, pt.y, pt.z ) ) ); + }//end-if-compute + + // redraw + updateGL(); + }//end-if-ins + + /* INS_PT mode - Shift+Left: compute and insert a point */ + else if( m_curMode == INSERT_PT && m_isPress ) { + m_isPress = false; + Vec pt; + if( computeIntersect( event->pos(), pt ) ) { + m_hasNewPt = true; + m_newPt = Point_3(pt.x, pt.y, pt.z); + // compute the conflict hole induced by point p + computeConflict( m_newPt ); + }//end-if-compute + + // redraw + updateGL(); + }//end-if-inspt + + /* INS_PT mode - Left: compute and insert a point */ + else if( m_curMode == INSERT_PT && m_isMoving ) { + m_isMoving = false; + Vec pt; + if( computeIntersect( event->pos(), pt ) ) { + m_newPt = Point_3(pt.x, pt.y, pt.z); + // compute the conflict hole induced by point p + computeConflict( m_newPt ); + }//end-if-compute + + // redraw + updateGL(); + }//end-if-inspt + + /* SEL mode - Left: terminate multiple point selection */ + else if( m_curMode == SELECT && m_isPress ) { + // might swap left/right and top/bottom to make rectanle valid +#if QT_VERSION < 0x040000 + m_rectSel = m_rectSel.normalize(); +#else + m_rectSel = m_rectSel.normalized(); +#endif + + if( m_rectSel.width() == 1 && m_rectSel.height() == 1 ) { /* select a point */ + // set a default selection window + setSelectRegionWidth( 10 ); + setSelectRegionHeight( 10 ); + // compute rectangle center and perform selection + select( m_rectSel.center() ); + if( m_isPress ) { + m_isPress = false; + } else { + displayMessage( tr("No point is selected.") ); + } + } else { /* select multiple points, ie. selection window > 1 */ + // define selection window + if( m_rectSel.width() < 10 ) + setSelectRegionWidth( 10 ); + else + setSelectRegionWidth( m_rectSel.width() ); + if( m_rectSel.height() < 10 ) + setSelectRegionHeight( 10 ); + else + setSelectRegionHeight( m_rectSel.height() ); + // compute rectangle center and perform selection + select( m_rectSel.center() ); + if( m_isPress ) { + m_isPress = false; + displayMessage( QString::number(m_vidSeled.size()) + tr(" points are selected") ); + } else { // empty window will cancel the current selection + for(QList::iterator iit = m_vidSeled.begin(); iit < m_vidSeled.end(); ++iit) + m_pScene->m_vhArray.at(*iit)->setSeled( false ); + m_vidSeled.clear(); + } + }//end-if-selwindow + + // update display to show + updateGL(); + }//end-if-select + + /* MOVE mode - Left: terminate point moving */ + else if( m_curMode == MOVE && m_isMoving ) { + Vec pt; + if( computeIntersect( event->pos(), pt ) ) { + // note: QList::operator[] return a modifiable reference; + // while QList::at return a const reference +#if CGAL_VERSION_NR < 1030700000 + // move_point moves the point stored in v to p while preserving the Delaunay property + // it calls remove(v) followed by insert(p) and return the new handle + // it supposely faster when the point has not moved much + m_pScene->m_vhArray[m_vidMoving] = m_pScene->m_dt.move_if_no_collision( + m_pScene->m_vhArray.at( m_vidMoving ), + Point_3( pt.x, pt.y, pt.z ) ); +#else + // move_if_no_collision moves the point stored in v to pt + // if there is not already another vertex placed on pt, + // the triangulation is modified s.t. the new position of v is pt; + // otherwise, the vertex at point pt is returned. + Vertex_handle vh = m_pScene->m_dt.move_if_no_collision( + m_pScene->m_vhArray.at( m_vidMoving ), + Point_3( pt.x, pt.y, pt.z ) ); + int id1 = m_pScene->m_vhArray.indexOf( vh ); + int id2 = m_pScene->m_vhArray.indexOf( vh, m_vidMoving+1 ); + // remove the duplicate in vhArray + if( id1 != m_vidMoving ) + m_pScene->m_vhArray.removeAt( id1 ); + else if( id2 != -1 ) + m_pScene->m_vhArray.removeAt( id2 ); + m_pScene->m_vhArray[m_vidMoving] = vh; +#endif + }//end-if-compute + + // redraw + updateGL(); + }//end-if-move + + /* FindNb mode - Shift+Left: find the nearest neighbor of the point */ + else if( m_curMode == FINDNB && m_isPress ) { + m_isPress = false; + Vec pt; + if( computeIntersect( event->pos(), pt ) ) { + m_queryPt = Point_3( pt.x, pt.y, pt.z ); + m_nearestNb = m_pScene->m_dt.nearest_vertex( m_queryPt ); + }//end-if-compute + + // redraw + updateGL(); + }//end-if-findnb + + /* EmptySphere mode - Shift+Left: show the empty sphere of the cell */ + else if( m_curMode == EMPTYSPH && m_isPress ) { + m_isPress = false; + Vec pt; + m_hasEmptyS = computeIntersect( event->pos(), pt ); + if( m_hasEmptyS ) { + m_queryPt = Point_3( pt.x, pt.y, pt.z ); + // find the cell that contains point p in its interior + m_cellContain = m_pScene->m_dt.locate( m_queryPt ); + // show error if point is outside the convex hull + if( m_pScene->m_dt.is_infinite( m_cellContain ) ) { + m_hasEmptyS = false; + displayMessage( tr("Query point is outside the convex hull!") ); + } else { /* compute the empty sphere */ + // find the circumcenter of the four vertices of c + m_centerPt = m_pScene->m_dt.dual( m_cellContain ); + // compute the radius of the empty sphere + m_fREmptyS = sqrt( CGAL::squared_distance( m_centerPt, + m_cellContain->vertex(0)->point() ) ); + } + }//end-if-compute + // redraw + updateGL(); + }//end-if-emptysphere + + else + QGLViewer::mouseReleaseEvent(event); +} + +void Viewer::wheelEvent(QWheelEvent *event) +{ + // Get event modifiers key +#if QT_VERSION < 0x040000 + // Bug in Qt : use 0x0f00 instead of Qt::KeyButtonMask with Qt versions < 3.1 + const Qt::ButtonState modifiers = (Qt::ButtonState)(event->state() & Qt::KeyButtonMask); +#else + const Qt::KeyboardModifiers modifiers = event->modifiers(); +#endif + + if( (m_curMode == INSERT_V || m_curMode == FINDNB || m_curMode == EMPTYSPH ) + && modifiers == Qt::SHIFT ) { + // delta() returns the distance that the wheel is rotated, in eighths of a degree. + // note: most mouse types work in steps of 15 degrees + // positive value: rotate forwards away from the user; + // negative value: rotate backwards toward the user. + m_fRadius += (event->delta()*1. / m_iStep ); // inc-/decrease by 0.1 per step + if( m_fRadius < 0.1 ) + m_fRadius = 0.1; + + // redraw + updateGL(); + }//end-if-insv + + else if( m_curMode == INSERT_PT && modifiers == Qt::SHIFT ) { + // delta() returns the distance that the wheel is rotated, in eighths of a degree. + // note: most mouse types work in steps of 15 degrees + // positive value: rotate forwards away from the user; + // negative value: rotate backwards toward the user. + float origR = m_fRadius; + m_fRadius += (event->delta()*1. / m_iStep ); // inc-/decrease by 0.1 per step + if( m_fRadius < 0.1 ) + m_fRadius = 0.1; + // update the new point and its conflict region + if( m_hasNewPt ) { + origR = m_fRadius / origR; + m_newPt = Point_3( m_newPt.x()*origR, m_newPt.y()*origR, m_newPt.z()*origR ); + // compute the conflict hole induced by point p + computeConflict( m_newPt ); + }//end-if-conflict + + // redraw + updateGL(); + }//end-if-inspt + + // resize the trackball when moving a point + else if( m_curMode == MOVE && modifiers == Qt::SHIFT && m_isMoving ) { + float origR = m_fRadius; + m_fRadius += (event->delta()*1. / m_iStep ); // inc-/decrease by 0.1 per step + if( m_fRadius < 0.1 ) + m_fRadius = 0.1; + origR = m_fRadius / origR; + Point_3 pt = m_pScene->m_vhArray.at( m_vidMoving )->point(); + // note: QList::operator[] return a modifiable reference; + // while QList::at return a const reference +#if CGAL_VERSION_NR < 1030700000 + // move_point moves the point stored in v to p while preserving the Delaunay property + // it calls remove(v) followed by insert(p) and return the new handle + // it supposely faster when the point has not moved much + m_pScene->m_vhArray[m_vidMoving] = m_pScene->m_dt.move_if_no_collision( + m_pScene->m_vhArray.at( m_vidMoving ), + Point_3( pt.x()*origR, pt.y()*origR, pt.z()*origR ) ); +#else + // move_if_no_collision moves the point stored in v to pt + // if there is not already another vertex placed on pt, + // the triangulation is modified s.t. the new position of v is pt; + // otherwise, the vertex at point pt is returned. + Vertex_handle vh = m_pScene->m_dt.move_if_no_collision( + m_pScene->m_vhArray.at( m_vidMoving ), + Point_3( pt.x()*origR, pt.y()*origR, pt.z()*origR ) ); + int id1 = m_pScene->m_vhArray.indexOf( vh ); + int id2 = m_pScene->m_vhArray.indexOf( vh, m_vidMoving+1 ); + // remove the duplicate in vhArray + if( id1 != m_vidMoving ) + m_pScene->m_vhArray.removeAt( id1 ); + else if( id2 != -1 ) + m_pScene->m_vhArray.removeAt( id2 ); + m_pScene->m_vhArray[m_vidMoving] = vh; +#endif + + // redraw + updateGL(); + }//end-if-move + + else + QGLViewer::wheelEvent(event); +} + +void Viewer::keyPressEvent(QKeyEvent *event) +{ + // Get event modifiers key +#if QT_VERSION < 0x040000 + // Bug in Qt : use 0x0f00 instead of Qt::KeyButtonMask with Qt versions < 3.1 + const Qt::ButtonState modifiers = (Qt::ButtonState)(event->state() & Qt::KeyButtonMask); +#else + const Qt::KeyboardModifiers modifiers = event->modifiers(); +#endif + + /* Insert the newly inserted point as a vertex */ + if( m_curMode == INSERT_PT && m_hasNewPt + && ( event->key()==Qt::Key_Return || event->key()==Qt::Key_Enter ) + && modifiers==Qt::NoButton ) { + Facet& f = m_boundaryFacets.first(); // a boundary facet, i.e. a pair (cell_handle, i) + // insert_in_hole will create a new vertex by starring a hole + // i.e. delete all conflict cells, create a new vertex, + // and for each boundary facet, create a new cell with the new vertex + // it takes in an iterator range of conflict cells which specifies a hole + // and (begin, i) is a boundary facet that begin is one of the conflict cell + // but begin->neighbor(i) is not + // it returns the handle of the new vertex + m_pScene->m_vhArray.push_back( m_pScene->m_dt.insert_in_hole( m_newPt, // the point + m_conflictCells.begin(), // cell_begin + m_conflictCells.end(), // cell_end + f.first, // cell_handle begin + f.second ) ); // integer i + + m_hasNewPt = false; + // erase old conflict hole info + m_boundaryFacets.clear(); + m_conflictCells.clear(); + + // redraw + updateGL(); + }//end-if-insVertex + + /* Cancel the newly inserted point and its conflict region */ + else if( m_curMode == INSERT_PT && m_hasNewPt + && event->key()==Qt::Key_Escape && modifiers==Qt::NoButton ) { + m_hasNewPt = false; + // erase old conflict hole info + m_boundaryFacets.clear(); + m_conflictCells.clear(); + + // redraw + updateGL(); + }//end-if-escapeIns + + /* Delete selected points */ + else if( m_curMode == SELECT + && event->key()==Qt::Key_Delete && modifiers==Qt::NoButton ) { + // sort selected id's in descending order + qSort(m_vidSeled.begin(), m_vidSeled.end(), qGreater()); + for(QList::iterator vit=m_vidSeled.begin(); vitm_dt.remove( m_pScene->m_vhArray.takeAt( *vit ) ); + } + // clear the selection buffer + m_vidSeled.clear(); + + // redraw + updateGL(); + }//end-if-del + + /* Cancel the selection */ + else if( m_curMode == SELECT + && event->key()==Qt::Key_Escape && modifiers==Qt::NoButton ) { + // clear the selection buffer + for(QList::iterator iit=m_vidSeled.begin(); iitm_vhArray.at(*iit)->setSeled( false ); + } + m_vidSeled.clear(); + + // redraw + updateGL(); + }//end-if-escapeSel + + + /* Show/hide the trackball when drawing the empty sphere */ + else if( m_curMode == EMPTYSPH + && event->key()==Qt::Key_S && modifiers==Qt::NoButton ) { + m_showTrackball = !m_showTrackball; + // redraw + updateGL(); + }//end-if-showBall + + else + QGLViewer::keyPressEvent(event); +} + +/*************************************************************/ +/* Computation functions */ + +bool Viewer::computeIntersect( const QPoint & pos, Vec & pt ) +{ + Vec eye, dir; + // Compute eye position and direction to the clicked point, + // used to draw a representation of the intersecting line + camera()->convertClickToLine( pos, eye, dir ); + // Compute the intersection point with the sphere + // note that the center of the sphere is at the origin (0, 0, 0) + // thus, (1) pt = eye + t*dir and (2) dist( pt, origin ) = radius + // i.e. (x_eye + t*x_dir)^2 + (y_eye + t*y_dir)^2 + (z_eye + t*z_dir)^2 = r^2 + // --> t^2( dir*dir ) + 2t( eye*dir ) + eye*eye - r^2 = 0 + // where "dir*dir" is the dot product of vector dir + // we need to solve t and the smaller t (nearer to eye position) is what we want + float a = dir*dir; + float b = eye*dir; + float c = eye*eye - m_fRadius*m_fRadius; + float delta = b*b - a*c; + if( delta < 0 ) { + displayMessage( tr("Point is not on the sphere!") ); + return false; + } else { + float t = ( (-1.)*b - sqrt(delta) ) / a; + pt = eye + t*dir; + return true; + } +} + +void Viewer::computeConflict( Point_3 pt ) +{ + // find the cell that contains point p in its interior + m_cellContain = m_pScene->m_dt.locate( pt ); + // erase old conflict hole info + m_boundaryFacets.clear(); + m_conflictCells.clear(); + // show msg if point is outside the convex hull + if( m_pScene->m_dt.is_infinite( m_cellContain ) ) + displayMessage( tr("Note: point is outside the convex hull.") ); + // compute the conflict hole induced by point p + m_pScene->m_dt.find_conflicts( pt, // the point + m_cellContain, // starting cell that must be in conflict + std::back_inserter(m_boundaryFacets), // the facets on the boundary + std::back_inserter(m_conflictCells) ); // the cells in conflict +} + +/*************************************************************/ +/* Animation functions */ + +void Viewer::toggleIncremental(bool on) { + if( on ) { // play + if( m_incrementalPts.isEmpty() ) { + /* start play */ + if( m_pScene->m_dt.number_of_vertices() == 0 ) { + CGAL::Random_points_in_cube_3 pts_generator(1.0); + CGAL::copy_n( pts_generator, 100, std::back_inserter(m_incrementalPts) ); + } else { + for(QList::iterator vit = m_pScene->m_vhArray.begin(); + vit < m_pScene->m_vhArray.end(); ++vit) { + m_incrementalPts.push_back( (*vit)->point() ); + }//end-for + // erase existing vertices + initClean(); + }//end-if-pts + // sorts points in a way that improves space locality + CGAL::spatial_sort( m_incrementalPts.begin(), m_incrementalPts.end() ); + // set the current to "hightlight the new point" + m_curStep = INIT; + }/* else resume play */ + + // set up the timer + m_pTimer->start(1000); + } else { // pause + m_pTimer->stop(); + } + + // redraw + updateGL(); +} + +void Viewer::stopIncremental() { + if( !m_incrementalPts.isEmpty() ) { + // will call toggleIncremental to stop the timer + emit( stopIncAnimation() ); + + // insert the rest points + for(QList::iterator pit=m_incrementalPts.begin(); + pit < m_incrementalPts.end(); ++pit) { + Vertex_handle hint; + if( m_pScene->m_vhArray.isEmpty() ) { + hint = m_pScene->m_dt.insert( *pit ); + } else { + hint = m_pScene->m_vhArray.last(); + hint = m_pScene->m_dt.insert( *pit, hint ); + } + m_pScene->m_vhArray.push_back( hint ); + } + m_incrementalPts.clear(); + } + + // redraw + updateGL(); +} + +void Viewer::incremental_insert() { + Vertex_handle hint; + if( !m_incrementalPts.isEmpty() ) { + switch( m_curStep ) { + case INIT: // end of INIT: get the next-to-insert point + m_curIncPt = m_incrementalPts.at(0); + m_curStep = NEWPT; + break; + case NEWPT: // end of NEWPT: locate the cell containing the point + if( m_pScene->m_dt.is_valid() && m_pScene->m_dt.dimension() == 3 ) { + computeConflict( m_curIncPt ); + m_curStep = CELL; + } + else { + // popup the first point and insert it + m_curIncPt = m_incrementalPts.takeFirst(); + if( m_pScene->m_vhArray.isEmpty() ) { + hint = m_pScene->m_dt.insert( m_curIncPt ); + } + else { + hint = m_pScene->m_vhArray.last(); + hint = m_pScene->m_dt.insert( m_curIncPt, hint ); + } + m_pScene->m_vhArray.push_back( hint ); + m_curStep = INIT; + } + break; + case CELL: // end of CELL: compute the conflict region + m_curStep = CONFLICT; + break; + case CONFLICT: // end of CONFLICT: do the insertion and go back to INIT + // popup the first point and insert it + m_curIncPt = m_incrementalPts.takeFirst(); + if( m_pScene->m_vhArray.isEmpty() ) { + hint = m_pScene->m_dt.insert( m_curIncPt ); + } else { + hint = m_pScene->m_vhArray.last(); + hint = m_pScene->m_dt.insert( m_curIncPt, hint ); + } + m_pScene->m_vhArray.push_back( hint ); + m_curStep = INIT; + break; + }//end-of-switch + } else { + /* if finished, then start over */ + for(QList::iterator vit = m_pScene->m_vhArray.begin(); + vit < m_pScene->m_vhArray.end(); ++vit) { + m_incrementalPts.push_back( (*vit)->point() ); + }//end-for + // erase existing vertices + initClean(); + // set the current to "hightlight the new point" + m_curStep = INIT; + } + + // redraw + updateGL(); +} diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/Viewer.h b/Triangulation_3_copy_tds/demo/Triangulation_3/Viewer.h new file mode 100644 index 00000000000..ddf9151d646 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/Viewer.h @@ -0,0 +1,290 @@ +#ifndef VIEWER_H +#define VIEWER_H + +#include "Scene.h" +#include +#include +#include +#include +#include "PreferenceDlg.h" + +#include +using namespace qglviewer; + +class MainWindow; + +class Viewer : public QGLViewer { + + Q_OBJECT + +public: + Viewer(QWidget* parent) + : QGLViewer(parent) + , m_showAxis(false) + , m_showVertex(true) + , m_showDEdge(true) + , m_showVEdge(false) + , m_showFacet(false) + , m_isFlat(false) + , m_fRadius(1.) + , m_curMode(NONE) + , m_selMode(NORMAL) + , m_isPress(false) + , m_isMoving(false) + , m_hasNewPt(false) + , m_nearestNb(NULL) + , m_hasEmptyS(false) + , m_showTrackball(true) + , m_pDlgPrefer(NULL) + {} + + enum Mode { NONE, INSERT_V, INSERT_PT, MOVE, SELECT, FINDNB, EMPTYSPH }; + +public: + inline void setScene(Scene* pScene) { m_pScene = pScene; } + + // set current mode + inline void setMode(Mode m) { + m_curMode = m; + m_isMoving = false; + m_hasEmptyS = false; + m_nearestNb = NULL; + updateGL(); + } + + // set selectBuffer size (if necessary) + inline void setSelBuffSize() { + // Default selectBuffer size is 4000 + // (i.e. 1000 objects in selection region, since each object pushes 4 values). + if( m_pScene->m_vhArray.size() > 900 ) + // The previous selectBuffer is deleted and a new one is created. + setSelectBufferSize( 4*(m_pScene->m_vhArray.size() + 100) ); + } + + void readSettings() { + // read from an .ini file + QSettings settings("settings.ini", QSettings::IniFormat); + // QVariant value ( const QString & key, const QVariant & defaultValue = QVariant() ) + // Because QVariant is part of the QtCore library, + // it cannot provide conversion functions to data types such as QColor and QImage, + // which are part of QtGui. + // In other words, there is no toColor(), toImage(), or toPixmap() functions in QVariant. + // Instead, use the QVariant::value() or the qVariantValue() template function + m_colorVertex = settings.value( "Show/vertexcolor", QColor(255, 150, 0) ).value(); +#if QT_VERSION >= 0x040600 + m_fSizeVertex = settings.value( "Show/vertexsize", 0.04f ).toFloat(); +#else + m_fSizeVertex = settings.value( "Show/vertexsize", 0.04f ).value(); +#endif + m_colorDEdge = settings.value( "Show/dedgecolor", QColor(0, 255, 0) ).value(); +#if QT_VERSION >= 0x040600 + m_fSizeDEdge = settings.value( "Show/dedgesize", 0.01f ).toFloat(); +#else + m_fSizeDEdge = settings.value( "Show/dedgesize", 0.01f ).value(); +#endif + m_colorVEdge = settings.value( "Show/vedgecolor", QColor(0, 0, 255) ).value(); +#if QT_VERSION >= 0x040600 + m_fSizeVEdge = settings.value( "Show/vedgesize", 0.01f ).toFloat(); +#else + m_fSizeVEdge = settings.value( "Show/vedgesize", 0.01f ).value(); +#endif + m_colorFacet = settings.value( "Show/facetcolor", + QColor(255, 255, 0, 96) ).value(); + m_colorTrackball = settings.value( "Show/ballcolor", + QColor(150, 150, 150, 128) ).value(); + m_iStep = settings.value( "Show/ballstep", 4000 ).toInt(); + m_colorEmptySphere = settings.value( "Show/spherecolor", + QColor(180, 50, 180, 64) ).value(); + } + + void writeSettings() { + // write to an .ini file + QSettings settings("settings.ini", QSettings::IniFormat); + // The inverse conversion (e.g., from QColor to QVariant) is automatic + // for all data types supported by QVariant, including GUI-related types + settings.setValue("Show/vertexcolor", m_colorVertex); + settings.setValue("Show/vertexsize", m_fSizeVertex); + settings.setValue("Show/dedgecolor", m_colorDEdge); + settings.setValue("Show/dedgesize", m_fSizeDEdge); + settings.setValue("Show/vedgecolor", m_colorVEdge); + settings.setValue("Show/vedgesize", m_fSizeVEdge); + settings.setValue("Show/facetcolor", m_colorFacet); + settings.setValue("Show/ballcolor", m_colorTrackball); + settings.setValue("Show/ballstep", m_iStep); + settings.setValue("Show/spherecolor", m_colorEmptySphere); + } + +public slots : + // clear scene + void clear() { + m_pScene->eraseOldData(); + m_hasNewPt = false; + m_boundaryFacets.clear(); + m_conflictCells.clear(); + m_vidSeled.clear(); + m_isMoving = false; + m_nearestNb = NULL; + m_hasEmptyS = false; + if( !m_incrementalPts.isEmpty() ) { + emit( stopIncAnimation() ); + m_incrementalPts.clear(); + } + } + + // play/pause incremental construction + void toggleIncremental(bool on); + // clean up old data and information + void initClean() { + m_pScene->eraseOldData(); + m_hasNewPt = false; + m_boundaryFacets.clear(); + m_conflictCells.clear(); + m_vidSeled.clear(); + m_isMoving = false; + m_nearestNb = NULL; + m_hasEmptyS = false; + } + // stop incremental construction + void stopIncremental(); + // incremental insert a vertex (invoked by Timer) + void incremental_insert(); + + // show options + inline void toggleShowAxis(bool flag) { m_showAxis = flag; updateGL(); } + inline void toggleShowVertex(bool flag) { m_showVertex = flag; updateGL(); } + inline void toggleShowDEdge(bool flag) { m_showDEdge = flag; updateGL(); } + inline void toggleShowVEdge(bool flag) { m_showVEdge = flag; updateGL(); } + inline void toggleShowFacet(bool flag) { m_showFacet = flag; updateGL(); } + inline void toggleFlat(bool flag) { m_isFlat = flag; updateGL(); } + + // set preferences + void setPreferences() { + if (!m_pDlgPrefer) { + m_pDlgPrefer = new PreferenceDlg(this); + m_pDlgPrefer->init( m_colorVertex, m_fSizeVertex, m_colorDEdge, m_fSizeDEdge, m_colorVEdge, m_fSizeVEdge, + m_colorFacet, m_colorTrackball, m_colorEmptySphere, m_iStep/40 ); // 5*8, 5 degrees of wheel + connect(m_pDlgPrefer, SIGNAL(applyChanges()), this, SLOT(acceptChanges()) ); + } + m_pDlgPrefer->show(); + m_pDlgPrefer->raise(); + m_pDlgPrefer->activateWindow(); + } + + void acceptChanges() { + m_colorVertex = m_pDlgPrefer->m_colorVertex; + m_fSizeVertex = m_pDlgPrefer->m_fSizeVertex; + m_colorDEdge = m_pDlgPrefer->m_colorDEdge; + m_fSizeDEdge = m_pDlgPrefer->m_fSizeDEdge; + m_colorVEdge = m_pDlgPrefer->m_colorVEdge; + m_fSizeVEdge = m_pDlgPrefer->m_fSizeVEdge; + m_colorFacet = m_pDlgPrefer->m_colorFacet; + m_colorTrackball = m_pDlgPrefer->m_colorTrackball; + m_iStep = m_pDlgPrefer->m_iStep*40; + m_colorEmptySphere = m_pDlgPrefer->m_colorEmptySphere; + // redraw + updateGL(); + } + + signals: + void stopIncAnimation(); + +// overloading QGLViewer virtual functions +protected: + // initialize Viewer OpenGL context + // Note: the default implement is empty and this is overloading. + void init(); + // draw points, segments, and polygons + void draw(); + + // customize selection process + void drawWithNames(); + void endSelection(const QPoint& point); + // customize mouse events + void mousePressEvent(QMouseEvent *event); + void mouseMoveEvent(QMouseEvent *event); + void mouseReleaseEvent(QMouseEvent *event); + void wheelEvent(QWheelEvent *event); + // customize key events + void keyPressEvent(QKeyEvent *event); + + // customize help message + QString helpString() const; + +private: + // draw a 3d effect vertex + void drawVertex(const Point_3& p, const QColor& clr, float r); + // draw a 3d effect edge + void drawEdge(const Point_3& from, const Point_3& to, const QColor& clr, float r); + // draw a facet + void drawFacet(const Triangle_3& t, const QColor& clr); + // draw a sphere with/without Axis + void drawSphere(float r, const QColor& clr, const Point_3& center=CGAL::ORIGIN); + + // test whether the give 3D point is on the sphere + inline bool isOnSphere( const Point_3 & pt ) { + return ( (pt.x()*pt.x() + pt.y()*pt.y() + pt.z()*pt.z()) == (m_fRadius*m_fRadius) ); + } + + // compute the intersection point with the sphere + bool computeIntersect( const QPoint & pos, Vec & pt ); + // compute the conflict region + void computeConflict( Point_3 pt ); + +private: + Scene* m_pScene; + // play timer + QTimer* m_pTimer; + Point_3 m_curIncPt; + QList m_incrementalPts; + enum Step { INIT, NEWPT, CELL, CONFLICT }; + Step m_curStep; + Cell_handle m_cellContain; + QList m_boundaryFacets; + QList m_conflictCells; + // show options + bool m_showAxis; + bool m_showVertex; + bool m_showDEdge; + bool m_showVEdge; + bool m_showFacet; + bool m_isFlat; + // trackball + float m_fRadius; + // mode + Mode m_curMode; + bool m_isPress; + bool m_isMoving; + // insert point + bool m_hasNewPt; + Point_3 m_newPt; + // select vertex + enum selectionMode { NORMAL, ADD }; + selectionMode m_selMode; + QRect m_rectSel; + QList m_vidSeled; + // move vertex/point + int m_vidMoving; + // nearest neighbor + Point_3 m_queryPt; + Vertex_handle m_nearestNb; + // empty sphere + bool m_hasEmptyS; + bool m_showTrackball; + Point_3 m_centerPt; + float m_fREmptyS; + // change colors + PreferenceDlg* m_pDlgPrefer; + float m_fSizeVertex; + float m_fSizeDEdge; + float m_fSizeVEdge; + QColor m_colorVertex; + QColor m_colorDEdge; + QColor m_colorVEdge; + QColor m_colorFacet; + QColor m_colorTrackball; + QColor m_colorEmptySphere; + // trackball resizing fineness + int m_iStep; +}; + +#endif diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/documentation/about.html b/Triangulation_3_copy_tds/demo/Triangulation_3/documentation/about.html new file mode 100644 index 00000000000..4149acaf9d5 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/documentation/about.html @@ -0,0 +1,13 @@ + + +

CGAL Triangulation_3 Demo

+

Copyright ©2010-2011
+ INRIA Sophia Antipolis - Mediterranee

+

This application illustrates an interactive demo for 3D Delaunay Triangulation package + of CGAL.

+

See also the package manual:
+ + 3D Triangulations +

+ + diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/documentation/about_CGAL.html b/Triangulation_3_copy_tds/demo/Triangulation_3/documentation/about_CGAL.html new file mode 100644 index 00000000000..b8a610ce41e --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/documentation/about_CGAL.html @@ -0,0 +1,7 @@ + + +

Computational Geometry Algorithms Library

+

CGAL provides efficient and reliable geometric algorithms in the form of a C++ library.

+

For more information visit www.cgal.org.

+ + diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/about_CGAL.html b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/about_CGAL.html new file mode 100644 index 00000000000..d87503a3469 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/about_CGAL.html @@ -0,0 +1,8 @@ + + +

+

Computational Geometry Algorithms Library

+

CGAL provides efficient and reliable geometric algorithms in the form of a C++ library.

+

For more information visit www.cgal.org

+ + diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/cgal_logo.xpm b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/cgal_logo.xpm new file mode 100644 index 00000000000..6a69b3d67e1 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/cgal_logo.xpm @@ -0,0 +1,24 @@ +/* XPM */ +const char * demoicon_xpm[] = { +/* columns rows colors chars-per-pixel */ +"16 16 3 1", +" c None", +". c #FFFF00", +"+ c #000000", +/* pixels */ +"................", +"...++++...++++..", +"..+....+.+....+.", +"..+......+......", +"..+......+..+++.", +"..+......+....+.", +"..+....+.+....+.", +"...++++...++++..", +"................", +"...++++...+.....", +"..+....+..+.....", +"..+....+..+.....", +"..++++++..+.....", +"..+....+..+.....", +"..+....+..+++++.", +"................"}; diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/clear.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/clear.jpeg new file mode 100644 index 00000000000..af5d1221412 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/clear.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/coordinates.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/coordinates.jpeg new file mode 100644 index 00000000000..184203abe49 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/coordinates.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/empty_sphere.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/empty_sphere.jpeg new file mode 100644 index 00000000000..5fba96bae22 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/empty_sphere.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/fileOpen.png b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/fileOpen.png new file mode 100644 index 00000000000..fc6f17e9774 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/fileOpen.png differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/fileSave.png b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/fileSave.png new file mode 100644 index 00000000000..8feec99bee8 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/fileSave.png differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/flat.png b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/flat.png new file mode 100644 index 00000000000..e48d6fc39a4 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/flat.png differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/grid.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/grid.jpeg new file mode 100644 index 00000000000..3df03a6a790 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/grid.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/insert.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/insert.jpeg new file mode 100644 index 00000000000..1deebcf0ee0 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/insert.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/insert_point.jpg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/insert_point.jpg new file mode 100644 index 00000000000..abe16e2250e Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/insert_point.jpg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/move_1.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/move_1.jpeg new file mode 100644 index 00000000000..1c1654dcac5 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/move_1.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/nearest_nb.png b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/nearest_nb.png new file mode 100644 index 00000000000..7fcfcba4ad5 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/nearest_nb.png differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/normal_view.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/normal_view.jpeg new file mode 100644 index 00000000000..8d4d74044aa Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/normal_view.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/pause.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/pause.jpeg new file mode 100644 index 00000000000..1da108b76f8 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/pause.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/play.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/play.jpeg new file mode 100644 index 00000000000..c039554ae98 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/play.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/pointRandom.png b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/pointRandom.png new file mode 100644 index 00000000000..a296047db38 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/pointRandom.png differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/preferences.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/preferences.jpeg new file mode 100644 index 00000000000..f20011b8dbf Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/preferences.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/quit.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/quit.jpeg new file mode 100644 index 00000000000..aff16901583 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/quit.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/select_hand.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/select_hand.jpeg new file mode 100644 index 00000000000..c5501d750b0 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/select_hand.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_delaunay.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_delaunay.jpeg new file mode 100644 index 00000000000..505e2c847a1 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_delaunay.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_facet.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_facet.jpeg new file mode 100644 index 00000000000..bb8c2701bf9 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_facet.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_point.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_point.jpeg new file mode 100644 index 00000000000..8c79e3b92ab Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_point.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_voronoi.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_voronoi.jpeg new file mode 100644 index 00000000000..52eb2ee0f3d Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/show_voronoi.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/stereo.png b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/stereo.png new file mode 100644 index 00000000000..74788d10028 Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/stereo.png differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/icons/stop.jpeg b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/stop.jpeg new file mode 100644 index 00000000000..36919b9edbf Binary files /dev/null and b/Triangulation_3_copy_tds/demo/Triangulation_3/icons/stop.jpeg differ diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/typedefs.h b/Triangulation_3_copy_tds/demo/Triangulation_3/typedefs.h new file mode 100644 index 00000000000..f754ff5a400 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/typedefs.h @@ -0,0 +1,101 @@ +#ifndef TYPEDEFS_H +#define TYPEDEFS_H + +#include //dynamic array +#include //linked list + +// CGAL +#include +#include + +// Added for T3 demo +#include +#include + +// Use EPEC as Kernel +// Note: the computation of VD requires exact constructions; +// while computing the triangulation only requires exact predicates. +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +// Ddefine field type +typedef Kernel::FT FT; + +typedef Kernel::Vector_3 Vector_3; +typedef Kernel::Direction_3 Direction_3; + +//typedef Kernel::Point_3 Point_3; +//typedef Kernel::Vector_3 Vector_3; +//typedef Kernel::Segment_3 Segment_3; +//typedef Kernel::Triangle_3 Triangle_3; + +// Added for T3 demo + +/* + * The user has several ways to add his own data in the vertex + * and cell base classes used by the TDS. He can either: * 1. use the classes Triangulation vertex base with info + * and Triangulation cell base with info, which allow to + * add one data member of a user provided type, and give access to it. * 2. derive his own classes from the default base classes + * Triangulation ds vertex base, and Triangulation ds cell base + * (or the geometric versions typically used by the geometric layer, + * Triangulation vertex base, and Triangulation cell base). * 3. write his own base classes following the requirements given by the concepts + * TriangulationCellBase 3 and TriangulationVertexBase 3 + * (described in page 2494 and page 2495). + */ +/* add index and color to vertex class */ +template < class GT, class Vb=CGAL::Triangulation_vertex_base_3 > +class Vertex_base : public Vb +{ +public: + typedef typename Vb::Point Point; + typedef typename Vb::Vertex_handle Vertex_handle; + typedef typename Vb::Cell_handle Cell_handle; + + template < class TDS2 > + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef Vertex_base< GT, Vb2 > Other; + }; + Vertex_base() + : m_isSelected(false) {} + Vertex_base(const Point& p) + : Vb(p), m_isSelected(false) {} + Vertex_base(const Point& p, Cell_handle c) + : Vb(p, c), m_isSelected(false) {} + + inline bool isSeled() const { return m_isSelected; } + inline void setSeled(bool flag=true) { m_isSelected = flag; } + +private: + bool m_isSelected; // whether it is selected +}; + +typedef CGAL::Triangulation_data_structure_3< Vertex_base > Tds; +/* + * Delaunay_triangulation_3 + * arg1: a model of the DelaunayTriangulationTraits_3 concept + * arg2: a model of the TriangulationDataStructure_3 concept + * default: Triangulation_data_structure_3 + * arg3: Fast_location or Compact_location (default) + * Fast_location offers O(logn) time point location, using additional data structure, + * good for fast point locations or random point insertions + * Compact_location saves memory by avoiding the separate data structure + * and point location is then O(n^(1/3)) time + */ +typedef CGAL::Delaunay_triangulation_3 DT3; + +typedef DT3::Object Object_3; +typedef DT3::Point Point_3; +typedef DT3::Segment Segment_3; +typedef DT3::Ray Ray_3; +typedef DT3::Triangle Triangle_3; + +typedef DT3::Vertex_handle Vertex_handle; +typedef DT3::Finite_vertices_iterator vertices_iterator; +typedef DT3::Edge Edge; +typedef DT3::Finite_edges_iterator edges_iterator; +typedef DT3::Facet Facet; +typedef DT3::Finite_facets_iterator facets_iterator; +typedef DT3::Cell_handle Cell_handle; +typedef DT3::Finite_cells_iterator cells_iterator; + +#endif diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3/ui_MainWindow.h b/Triangulation_3_copy_tds/demo/Triangulation_3/ui_MainWindow.h new file mode 100644 index 00000000000..2e7cf4df3b2 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3/ui_MainWindow.h @@ -0,0 +1,584 @@ +/******************************************************************************** +** Form generated from reading ui file 'MainWindow.ui' +** +** Created: Mon Dec 20 14:14:32 2010 +** by: Qt User Interface Compiler version 4.4.1 +** +** WARNING! All changes made in this file will be lost when recompiling ui file! +********************************************************************************/ + +#ifndef UI_MAINWINDOW_H +#define UI_MAINWINDOW_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "Viewer.h" + +QT_BEGIN_NAMESPACE + +class Ui_MainWindow +{ +public: + QAction *actionGenerate_Points; + QAction *actionLoad_Points; + QAction *actionSave_Points; + QAction *actionShow_Axis; + QAction *actionQuit; + QAction *actionClear_Scene; + QAction *actionShow_Vertex; + QAction *actionShow_DEdge; + QAction *actionShow_VEdge; + QAction *actionShow_Facet; + QAction *actionFlat; + QAction *actionPreferences; + QAction *actionInsert_Vertex; + QAction *actionInsert_Point; + QAction *actionSelect_Vertex; + QAction *actionMove_Vertex; + QAction *actionFind_NearestNb; + QAction *actionEmpty_Sphere; + QAction *actionNormal_View; + QAction *actionDemo_Help; + QAction *actionIncremental_Construct; + QAction *actionStop_Animation; + QAction *actionAbout_T3_demo; + QWidget *centralwidget; + QHBoxLayout *horizontalLayout; + Viewer *viewer; + QMenuBar *menubar; + QMenu *menuFile; + QMenu *menuEdit; + QMenu *menuMode; + QMenu *menuShow; + QMenu *menuHelp; + QStatusBar *statusbar; + QToolBar *toolBar; + + void setupUi(QMainWindow *MainWindow) + { + if (MainWindow->objectName().isEmpty()) + MainWindow->setObjectName(QString::fromUtf8("MainWindow")); + MainWindow->setWindowModality(Qt::NonModal); + MainWindow->resize(1100, 500); + QSizePolicy sizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred); + sizePolicy.setHorizontalStretch(0); + sizePolicy.setVerticalStretch(0); + sizePolicy.setHeightForWidth(MainWindow->sizePolicy().hasHeightForWidth()); + MainWindow->setSizePolicy(sizePolicy); + QFont font; + font.setFamily(QString::fromUtf8("Arial")); + MainWindow->setFont(font); + MainWindow->setCursor(QCursor(Qt::PointingHandCursor)); + QIcon icon; + icon.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/cgal_logo.xpm")), QIcon::Normal, QIcon::Off); + MainWindow->setWindowIcon(icon); + actionGenerate_Points = new QAction(MainWindow); + actionGenerate_Points->setObjectName(QString::fromUtf8("actionGenerate_Points")); + QIcon icon1; + icon1.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/pointRandom.png")), QIcon::Normal, QIcon::Off); + actionGenerate_Points->setIcon(icon1); + actionLoad_Points = new QAction(MainWindow); + actionLoad_Points->setObjectName(QString::fromUtf8("actionLoad_Points")); + QIcon icon2; + icon2.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/fileOpen.png")), QIcon::Normal, QIcon::Off); + actionLoad_Points->setIcon(icon2); + actionSave_Points = new QAction(MainWindow); + actionSave_Points->setObjectName(QString::fromUtf8("actionSave_Points")); + QIcon icon3; + icon3.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/fileSave.png")), QIcon::Normal, QIcon::Off); + actionSave_Points->setIcon(icon3); + actionShow_Axis = new QAction(MainWindow); + actionShow_Axis->setObjectName(QString::fromUtf8("actionShow_Axis")); + actionShow_Axis->setCheckable(true); + QIcon icon4; + icon4.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/coordinates.jpeg")), QIcon::Normal, QIcon::Off); + actionShow_Axis->setIcon(icon4); + actionQuit = new QAction(MainWindow); + actionQuit->setObjectName(QString::fromUtf8("actionQuit")); + QIcon icon5; + icon5.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/quit.jpeg")), QIcon::Normal, QIcon::Off); + actionQuit->setIcon(icon5); + actionClear_Scene = new QAction(MainWindow); + actionClear_Scene->setObjectName(QString::fromUtf8("actionClear_Scene")); + QIcon icon6; + icon6.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/clear.jpeg")), QIcon::Normal, QIcon::Off); + actionClear_Scene->setIcon(icon6); + actionShow_Vertex = new QAction(MainWindow); + actionShow_Vertex->setObjectName(QString::fromUtf8("actionShow_Vertex")); + actionShow_Vertex->setCheckable(true); + actionShow_Vertex->setChecked(true); + QIcon icon7; + icon7.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/show_point.jpeg")), QIcon::Normal, QIcon::Off); + actionShow_Vertex->setIcon(icon7); + actionShow_DEdge = new QAction(MainWindow); + actionShow_DEdge->setObjectName(QString::fromUtf8("actionShow_DEdge")); + actionShow_DEdge->setCheckable(true); + actionShow_DEdge->setChecked(true); + QIcon icon8; + icon8.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/show_delaunay.jpeg")), QIcon::Normal, QIcon::Off); + actionShow_DEdge->setIcon(icon8); + actionShow_VEdge = new QAction(MainWindow); + actionShow_VEdge->setObjectName(QString::fromUtf8("actionShow_VEdge")); + actionShow_VEdge->setCheckable(true); + QIcon icon9; + icon9.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/show_voronoi.jpeg")), QIcon::Normal, QIcon::Off); + actionShow_VEdge->setIcon(icon9); + actionShow_Facet = new QAction(MainWindow); + actionShow_Facet->setObjectName(QString::fromUtf8("actionShow_Facet")); + actionShow_Facet->setCheckable(true); + QIcon icon10; + icon10.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/show_facet.jpeg")), QIcon::Normal, QIcon::Off); + actionShow_Facet->setIcon(icon10); + actionFlat = new QAction(MainWindow); + actionFlat->setObjectName(QString::fromUtf8("actionFlat")); + actionFlat->setCheckable(true); + QIcon icon11; + icon11.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/flat.png")), QIcon::Normal, QIcon::Off); + icon11.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/stereo.png")), QIcon::Normal, QIcon::On); + actionFlat->setIcon(icon11); + actionPreferences = new QAction(MainWindow); + actionPreferences->setObjectName(QString::fromUtf8("actionPreferences")); + QIcon icon12; + icon12.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/preferences.jpeg")), QIcon::Normal, QIcon::Off); + actionPreferences->setIcon(icon12); + actionInsert_Vertex = new QAction(MainWindow); + actionInsert_Vertex->setObjectName(QString::fromUtf8("actionInsert_Vertex")); + actionInsert_Vertex->setCheckable(true); + QIcon icon13; + icon13.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/insert.jpeg")), QIcon::Normal, QIcon::Off); + actionInsert_Vertex->setIcon(icon13); + actionInsert_Point = new QAction(MainWindow); + actionInsert_Point->setObjectName(QString::fromUtf8("actionInsert_Point")); + actionInsert_Point->setCheckable(true); + QIcon icon14; + icon14.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/insert_point.jpg")), QIcon::Normal, QIcon::Off); + actionInsert_Point->setIcon(icon14); + actionSelect_Vertex = new QAction(MainWindow); + actionSelect_Vertex->setObjectName(QString::fromUtf8("actionSelect_Vertex")); + actionSelect_Vertex->setCheckable(true); + QIcon icon15; + icon15.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/select_hand.jpeg")), QIcon::Normal, QIcon::Off); + actionSelect_Vertex->setIcon(icon15); + actionMove_Vertex = new QAction(MainWindow); + actionMove_Vertex->setObjectName(QString::fromUtf8("actionMove_Vertex")); + actionMove_Vertex->setCheckable(true); + QIcon icon16; + icon16.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/move_1.jpeg")), QIcon::Normal, QIcon::Off); + actionMove_Vertex->setIcon(icon16); + actionFind_NearestNb = new QAction(MainWindow); + actionFind_NearestNb->setObjectName(QString::fromUtf8("actionFind_NearestNb")); + actionFind_NearestNb->setCheckable(true); + QIcon icon17; + icon17.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/nearest_nb.png")), QIcon::Normal, QIcon::Off); + actionFind_NearestNb->setIcon(icon17); + actionEmpty_Sphere = new QAction(MainWindow); + actionEmpty_Sphere->setObjectName(QString::fromUtf8("actionEmpty_Sphere")); + actionEmpty_Sphere->setCheckable(true); + QIcon icon18; + icon18.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/empty_sphere.jpeg")), QIcon::Normal, QIcon::Off); + actionEmpty_Sphere->setIcon(icon18); + actionNormal_View = new QAction(MainWindow); + actionNormal_View->setObjectName(QString::fromUtf8("actionNormal_View")); + actionNormal_View->setCheckable(true); + actionNormal_View->setChecked(true); + QIcon icon19; + icon19.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/normal_view.jpeg")), QIcon::Normal, QIcon::Off); + actionNormal_View->setIcon(icon19); + actionDemo_Help = new QAction(MainWindow); + actionDemo_Help->setObjectName(QString::fromUtf8("actionDemo_Help")); + actionIncremental_Construct = new QAction(MainWindow); + actionIncremental_Construct->setObjectName(QString::fromUtf8("actionIncremental_Construct")); + actionIncremental_Construct->setCheckable(true); + QIcon icon20; + icon20.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/play.jpeg")), QIcon::Normal, QIcon::Off); + icon20.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/pause.jpeg")), QIcon::Normal, QIcon::On); + actionIncremental_Construct->setIcon(icon20); + actionStop_Animation = new QAction(MainWindow); + actionStop_Animation->setObjectName(QString::fromUtf8("actionStop_Animation")); + QIcon icon21; + icon21.addPixmap(QPixmap(QString::fromUtf8(":/T3_demo/icons/icons/stop.jpeg")), QIcon::Normal, QIcon::Off); + actionStop_Animation->setIcon(icon21); + actionAbout_T3_demo = new QAction(MainWindow); + actionAbout_T3_demo->setObjectName(QString::fromUtf8("actionAbout_T3_demo")); + centralwidget = new QWidget(MainWindow); + centralwidget->setObjectName(QString::fromUtf8("centralwidget")); + horizontalLayout = new QHBoxLayout(centralwidget); + horizontalLayout->setSpacing(3); + horizontalLayout->setMargin(1); + horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout")); + viewer = new Viewer(centralwidget); + viewer->setObjectName(QString::fromUtf8("viewer")); + sizePolicy.setHeightForWidth(viewer->sizePolicy().hasHeightForWidth()); + viewer->setSizePolicy(sizePolicy); + viewer->setCursor(QCursor(Qt::PointingHandCursor)); + + horizontalLayout->addWidget(viewer); + + MainWindow->setCentralWidget(centralwidget); + menubar = new QMenuBar(MainWindow); + menubar->setObjectName(QString::fromUtf8("menubar")); + menubar->setGeometry(QRect(0, 0, 1010, 22)); + menuFile = new QMenu(menubar); + menuFile->setObjectName(QString::fromUtf8("menuFile")); + menuEdit = new QMenu(menubar); + menuEdit->setObjectName(QString::fromUtf8("menuEdit")); + menuMode = new QMenu(menubar); + menuMode->setObjectName(QString::fromUtf8("menuMode")); + menuShow = new QMenu(menubar); + menuShow->setObjectName(QString::fromUtf8("menuShow")); + menuHelp = new QMenu(menubar); + menuHelp->setObjectName(QString::fromUtf8("menuHelp")); + MainWindow->setMenuBar(menubar); + statusbar = new QStatusBar(MainWindow); + statusbar->setObjectName(QString::fromUtf8("statusbar")); + MainWindow->setStatusBar(statusbar); + toolBar = new QToolBar(MainWindow); + toolBar->setObjectName(QString::fromUtf8("toolBar")); + MainWindow->addToolBar(Qt::TopToolBarArea, toolBar); + + menubar->addAction(menuFile->menuAction()); + menubar->addAction(menuEdit->menuAction()); + menubar->addAction(menuMode->menuAction()); + menubar->addAction(menuShow->menuAction()); + menubar->addAction(menuHelp->menuAction()); + menuFile->addAction(actionLoad_Points); + menuFile->addAction(actionSave_Points); + menuFile->addSeparator(); + menuFile->addAction(actionQuit); + menuEdit->addAction(actionGenerate_Points); + menuEdit->addSeparator(); + menuEdit->addAction(actionIncremental_Construct); + menuEdit->addAction(actionStop_Animation); + menuEdit->addSeparator(); + menuEdit->addAction(actionClear_Scene); + menuMode->addAction(actionNormal_View); + menuMode->addAction(actionInsert_Vertex); + menuMode->addAction(actionInsert_Point); + menuMode->addAction(actionSelect_Vertex); + menuMode->addAction(actionMove_Vertex); + menuMode->addAction(actionFind_NearestNb); + menuMode->addAction(actionEmpty_Sphere); + menuShow->addAction(actionShow_Axis); + menuShow->addSeparator(); + menuShow->addAction(actionShow_Vertex); + menuShow->addAction(actionShow_DEdge); + menuShow->addAction(actionShow_VEdge); + menuShow->addAction(actionShow_Facet); + menuShow->addSeparator(); + menuShow->addAction(actionFlat); + menuShow->addSeparator(); + menuShow->addAction(actionPreferences); + menuHelp->addAction(actionDemo_Help); + menuHelp->addAction(actionAbout_T3_demo); + toolBar->addAction(actionLoad_Points); + toolBar->addAction(actionSave_Points); + toolBar->addSeparator(); + toolBar->addAction(actionGenerate_Points); + toolBar->addAction(actionClear_Scene); + toolBar->addSeparator(); + toolBar->addAction(actionIncremental_Construct); + toolBar->addAction(actionStop_Animation); + toolBar->addSeparator(); + toolBar->addAction(actionShow_Axis); + toolBar->addSeparator(); + toolBar->addAction(actionFlat); + toolBar->addSeparator(); + toolBar->addAction(actionShow_Vertex); + toolBar->addAction(actionShow_DEdge); + toolBar->addAction(actionShow_VEdge); + toolBar->addAction(actionShow_Facet); + toolBar->addSeparator(); + toolBar->addAction(actionNormal_View); + toolBar->addAction(actionInsert_Vertex); + toolBar->addAction(actionInsert_Point); + toolBar->addAction(actionSelect_Vertex); + toolBar->addAction(actionMove_Vertex); + toolBar->addAction(actionFind_NearestNb); + toolBar->addAction(actionEmpty_Sphere); + toolBar->addSeparator(); + toolBar->addAction(actionPreferences); + toolBar->addSeparator(); + toolBar->addAction(actionQuit); + + retranslateUi(MainWindow); + + QMetaObject::connectSlotsByName(MainWindow); + } // setupUi + + void retranslateUi(QMainWindow *MainWindow) + { + MainWindow->setWindowTitle(QApplication::translate("MainWindow", "Triangulation_demo_3", 0, QApplication::UnicodeUTF8)); + actionGenerate_Points->setText(QApplication::translate("MainWindow", "Generate Points", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionGenerate_Points->setToolTip(QApplication::translate("MainWindow", "Generate Points", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionGenerate_Points->setStatusTip(QApplication::translate("MainWindow", "Generate Points", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionGenerate_Points->setShortcut(QApplication::translate("MainWindow", "Ctrl+G", 0, QApplication::UnicodeUTF8)); + actionLoad_Points->setText(QApplication::translate("MainWindow", "Load Points...", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionLoad_Points->setToolTip(QApplication::translate("MainWindow", "Load Points from a file", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionLoad_Points->setStatusTip(QApplication::translate("MainWindow", "Load Points from a file", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionLoad_Points->setShortcut(QApplication::translate("MainWindow", "Ctrl+O", 0, QApplication::UnicodeUTF8)); + actionSave_Points->setText(QApplication::translate("MainWindow", "Save Points...", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionSave_Points->setToolTip(QApplication::translate("MainWindow", "Save points to a file", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionSave_Points->setStatusTip(QApplication::translate("MainWindow", "Save points to a file", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionSave_Points->setShortcut(QApplication::translate("MainWindow", "Ctrl+S", 0, QApplication::UnicodeUTF8)); + actionShow_Axis->setText(QApplication::translate("MainWindow", "Show Axis", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionShow_Axis->setToolTip(QApplication::translate("MainWindow", "Show/Hide Axis", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionShow_Axis->setStatusTip(QApplication::translate("MainWindow", "Show/Hide Axis", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionQuit->setText(QApplication::translate("MainWindow", "Quit", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionQuit->setToolTip(QApplication::translate("MainWindow", "Quit", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionQuit->setStatusTip(QApplication::translate("MainWindow", "Quit", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionClear_Scene->setText(QApplication::translate("MainWindow", "Clear Scene", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionClear_Scene->setToolTip(QApplication::translate("MainWindow", "Clear Scene", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionClear_Scene->setStatusTip(QApplication::translate("MainWindow", "Clear Scene", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionShow_Vertex->setText(QApplication::translate("MainWindow", "Show Vertices", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionShow_Vertex->setToolTip(QApplication::translate("MainWindow", "Show Vertices", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionShow_Vertex->setStatusTip(QApplication::translate("MainWindow", "Show Vertices", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionShow_DEdge->setText(QApplication::translate("MainWindow", "Show Delaunay Edges", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionShow_DEdge->setToolTip(QApplication::translate("MainWindow", "Show Delaunay edges", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionShow_DEdge->setStatusTip(QApplication::translate("MainWindow", "Show Delaunay edges", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionShow_VEdge->setText(QApplication::translate("MainWindow", "Show Voronoi Edges", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionShow_VEdge->setToolTip(QApplication::translate("MainWindow", "Show Voronoi edges", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionShow_VEdge->setStatusTip(QApplication::translate("MainWindow", "Show Voronoi edges", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionShow_Facet->setText(QApplication::translate("MainWindow", "Show Facets", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionShow_Facet->setToolTip(QApplication::translate("MainWindow", "Show Delaunay Facets", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionShow_Facet->setStatusTip(QApplication::translate("MainWindow", "Show Delaunay Facets", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionFlat->setText(QApplication::translate("MainWindow", "Flat", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionFlat->setToolTip(QApplication::translate("MainWindow", "Toggle 3D effect", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionFlat->setStatusTip(QApplication::translate("MainWindow", "Toggle 3D effect", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionPreferences->setText(QApplication::translate("MainWindow", "Preferences...", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionPreferences->setToolTip(QApplication::translate("MainWindow", "Change Colors, Transparency, etc.", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionPreferences->setStatusTip(QApplication::translate("MainWindow", "Change Colors, Transparency, etc.", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionInsert_Vertex->setText(QApplication::translate("MainWindow", "Insert Vertex", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionInsert_Vertex->setToolTip(QApplication::translate("MainWindow", "Insert a vertex and update the triangulation", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionInsert_Vertex->setStatusTip(QApplication::translate("MainWindow", "Insert a vertex and update the triangulation", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionInsert_Point->setText(QApplication::translate("MainWindow", "Insert Point", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionInsert_Point->setToolTip(QApplication::translate("MainWindow", "Insert a point and show its conflict region", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionInsert_Point->setStatusTip(QApplication::translate("MainWindow", "Insert a point and show its conflict region", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionSelect_Vertex->setText(QApplication::translate("MainWindow", "Select Vertex", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionSelect_Vertex->setToolTip(QApplication::translate("MainWindow", "Select vertices", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionSelect_Vertex->setStatusTip(QApplication::translate("MainWindow", "Select vertices", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionMove_Vertex->setText(QApplication::translate("MainWindow", "Move Vertex", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionMove_Vertex->setToolTip(QApplication::translate("MainWindow", "Move a vertex", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionMove_Vertex->setStatusTip(QApplication::translate("MainWindow", "Move a vertex", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionFind_NearestNb->setText(QApplication::translate("MainWindow", "Nearest Neighbor Search", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionFind_NearestNb->setToolTip(QApplication::translate("MainWindow", "Find the nearest neighbor of the query point", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionFind_NearestNb->setStatusTip(QApplication::translate("MainWindow", "Find the nearest neighbor of the query point", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionEmpty_Sphere->setText(QApplication::translate("MainWindow", "Show Empty Sphere", 0, QApplication::UnicodeUTF8)); + actionEmpty_Sphere->setIconText(QApplication::translate("MainWindow", "Click to select a cell and show empty sphere of that cell.", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionEmpty_Sphere->setToolTip(QApplication::translate("MainWindow", "Locate the query point in a cell and show empty sphere of that cell", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionEmpty_Sphere->setStatusTip(QApplication::translate("MainWindow", "Locate the query point in a cell and show empty sphere of that cell", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionNormal_View->setText(QApplication::translate("MainWindow", "Normal Mode", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionNormal_View->setToolTip(QApplication::translate("MainWindow", "Normal Mode", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionNormal_View->setStatusTip(QApplication::translate("MainWindow", "Normal Mode", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionDemo_Help->setText(QApplication::translate("MainWindow", "Triangulation_3D Demo Help", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionDemo_Help->setToolTip(QApplication::translate("MainWindow", "Triangulation_3D Demo Help", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionDemo_Help->setStatusTip(QApplication::translate("MainWindow", "Triangulation_3D Demo Help", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionDemo_Help->setShortcut(QApplication::translate("MainWindow", "H", 0, QApplication::UnicodeUTF8)); + actionIncremental_Construct->setText(QApplication::translate("MainWindow", "Insertion Animation", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionIncremental_Construct->setToolTip(QApplication::translate("MainWindow", "Animation of incremental Delaunay triangulation", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionIncremental_Construct->setStatusTip(QApplication::translate("MainWindow", "Animation of incremental Delaunay triangulation", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionStop_Animation->setText(QApplication::translate("MainWindow", "Stop Animation", 0, QApplication::UnicodeUTF8)); + +#ifndef QT_NO_TOOLTIP + actionStop_Animation->setToolTip(QApplication::translate("MainWindow", "Stop Animation", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_TOOLTIP + + +#ifndef QT_NO_STATUSTIP + actionStop_Animation->setStatusTip(QApplication::translate("MainWindow", "Stop Animation", 0, QApplication::UnicodeUTF8)); +#endif // QT_NO_STATUSTIP + + actionAbout_T3_demo->setText(QApplication::translate("MainWindow", "About T3_demo", 0, QApplication::UnicodeUTF8)); + menuFile->setTitle(QApplication::translate("MainWindow", "&File", 0, QApplication::UnicodeUTF8)); + menuEdit->setTitle(QApplication::translate("MainWindow", "Edit", 0, QApplication::UnicodeUTF8)); + menuMode->setTitle(QApplication::translate("MainWindow", "Mode", 0, QApplication::UnicodeUTF8)); + menuShow->setTitle(QApplication::translate("MainWindow", "Show", 0, QApplication::UnicodeUTF8)); + menuHelp->setTitle(QApplication::translate("MainWindow", "Help", 0, QApplication::UnicodeUTF8)); + toolBar->setWindowTitle(QApplication::translate("MainWindow", "toolBar", 0, QApplication::UnicodeUTF8)); + } // retranslateUi + +}; + +namespace Ui { + class MainWindow: public Ui_MainWindow {}; +} // namespace Ui + +QT_END_NAMESPACE + +#endif // UI_MAINWINDOW_H diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/CMakeLists.txt b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/CMakeLists.txt new file mode 100644 index 00000000000..3b6cb7ba399 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/CMakeLists.txt @@ -0,0 +1,33 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + + +project( Triangulation_3_Demo ) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4.5) + +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +if ( COMMAND cmake_policy ) + cmake_policy( SET CMP0003 NEW ) +endif() + +find_package(CGAL QUIET COMPONENTS Core ) + +if ( CGAL_FOUND ) + + include( ${CGAL_USE_FILE} ) + + include( CGAL_CreateSingleSourceCGALProgram ) + + create_single_source_cgal_program( "Triangulation_3_demo.cpp" ) + create_single_source_cgal_program( "Triangulation_3_color_demo.cpp" ) + create_single_source_cgal_program( "Triangulation_3_remove_demo.cpp" ) + create_single_source_cgal_program( "Triangulation_3_voronoi_demo.cpp" ) + +else() + + message(STATUS "This program requires the CGAL library, and will not be compiled.") + +endif() + diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/README b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/README new file mode 100644 index 00000000000..2a2042cfc89 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/README @@ -0,0 +1,39 @@ +The demos use Geomview +[see the chapter Geomview in the cgal manual - support library: +Geomview 1.8.1 is required. The geomview command must be in the user's $PATH, +otherwise the program will not be able to execute.] + +------- demo ------------------------------------------------- +Construction of a Delaunay triangulation. + +Needs an input file "data/points" containing points (given by x y z) + +Draws the triangulation (vertices and edges) in geomview + +Locates a point a shows the cell containing it + +Draws the triangulation (edges and cells) in geomview, +then the user can move one of the two displayed versions +of the triangulation. +-------------------------------------------------------------- + +------- demo_color ------------------------------------------- +Constructs a Delaunay triangulation with a special Vertex base class +containing a color (white by default). + +Sets the color of degree 6 vertices to red. + +Displays the triangulation where each vertex has its own color. +-------------------------------------------------------------- + +------- demo_voronoi ------------------------------------------ +Constructs a Delaunay triangulation for points on a grid. + +Displays the Voronoi edges of the set of points +-------------------------------------------------------------- + +------- demo_remove ------------------------------------------ +Constructs a Delaunay triangulation for points on a grid. + +Then removes all the vertices in random order +-------------------------------------------------------------- diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp new file mode 100644 index 00000000000..4b1765b0124 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_color_demo.cpp @@ -0,0 +1,86 @@ +// Copyright (c) 2001, 2002, 2003, 2004, 2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Monique Teillaud + +#include + +#ifndef CGAL_USE_GEOMVIEW +#include +int main() +{ + std::cerr << "Geomview doesn't work on this platform," + " so this demo doesn't work" << std::endl; + return 0; +} +#else + +#include + +#include +#include + +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef CGAL::Triangulation_vertex_base_with_info_3 Vb; +typedef CGAL::Triangulation_data_structure_3 Tds; +typedef CGAL::Delaunay_triangulation_3 Delaunay; + +typedef Delaunay::Point Point; + +int main() +{ + CGAL::Geomview_stream gv(CGAL::Bbox_3(0,0,0, 2, 2, 2)); + gv.set_bg_color(CGAL::Color(0, 200, 200)); + gv.clear(); + + Delaunay T; + + T.insert(Point(0,0,0)); + T.insert(Point(1,0,0)); + T.insert(Point(0,1,0)); + T.insert(Point(0,0,1)); + T.insert(Point(2,2,2)); + T.insert(Point(-1,0,1)); + + // Set the color of finite vertices of degree 6 to red. + Delaunay::Finite_vertices_iterator vit; + for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) + if (T.degree(vit) == 6) + vit->info() = CGAL::RED; + + std::cout << " Visualization of T" << std::endl; + gv.set_wired(true); + gv << T; + + std::cout << " Vertices of T with their own color" << std::endl + << " red for degree 6 (counting infinite vertex)" + << std::endl + << " white otherwise" << std::endl; + for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) + gv << vit->info() << vit->point(); + + std::cout << "Enter any character to quit" << std::endl; + char ch; + std::cin >> ch; + + return 0; +} + +#endif // CGAL_USE_GEOMVIEW diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp new file mode 100644 index 00000000000..73b0016dfae --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_demo.cpp @@ -0,0 +1,188 @@ +// Copyright (c) 1999, 2000, 2001, 2002, 2003, 2004, 2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Monique Teillaud + +#include + +#ifndef CGAL_USE_GEOMVIEW +#include +int main() +{ + std::cerr << "Geomview doesn't work on this platform," + " so this demo doesn't work" << std::endl; + return 0; +} +#else + +#include + +#include + +#include + +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef CGAL::Delaunay_triangulation_3 Triangulation; + +typedef Triangulation::Finite_vertices_iterator Finite_vertices_iterator; +typedef Triangulation::Cell_handle Cell_handle; +typedef Triangulation::Locate_type Locate_type; +typedef Triangulation::Point Point; + +////////////////////// +// VISU GEOMVIEW +////////////////////// +template +void visu_cell(CGAL::Geomview_stream & os, const TRIANGULATION & T, + Cell_handle c) +{ + if ( ! T.is_infinite(c) ) + os << T.tetrahedron(c); + else + os << T.triangle(c,c->index(T.infinite_vertex())); +} +template +void visu_facet(CGAL::Geomview_stream & os, const TRIANGULATION & T, + Cell_handle c, int i) +{ + if ( ! T.is_infinite(c,i) ) + os << T.triangle(c,i); +} +template +void visu_edge(CGAL::Geomview_stream & os, const TRIANGULATION & T, + Cell_handle c, int i, int j) +{ + if ( ! T.is_infinite(c,i,j) ) + os << T.segment(c,i,j); +} +template +void visu_vertices(CGAL::Geomview_stream & os, const TRIANGULATION & T) +{ + Finite_vertices_iterator vit = T.finite_vertices_begin(); + Finite_vertices_iterator vdone = T.finite_vertices_end(); + + if ( vit == vdone ) { std::cout << "no vertex" << std::endl ;} + else { + while(vit != vdone) { + os << vit->point(); + ++vit; + } + } +} +template +void visu_vertex(CGAL::Geomview_stream & os, const TRIANGULATION & T, + Cell_handle c, int i) +{ + if ( ! T.is_infinite(c->vertex(i)) ) + os << c->vertex(i)->point(); +} + +////////////////////// + +int main() +{ + CGAL::Geomview_stream gv(CGAL::Bbox_3(0,0,0, 2, 2, 2)); + gv.set_bg_color(CGAL::Color(0, 200, 200)); + gv.clear(); + + Triangulation T; + + std::ifstream iFile("data/points",std::ios::in); + + if (! iFile) { + std::cout <<"A file named points in directory data" + <<" containing points should be provided," << std::endl + <<"see README"< begin (iFile), end; + T.insert (begin, end); + } + + T.is_valid(true); + + std::cout <<" Visualizing vertices and edges" << std::endl; + visu_vertices(gv,T); + gv.set_wired(true); + gv << T; + gv.set_wired(false); + + sleep(3); + + std::cout <<" Locating point (1,1,1) :" << std::endl; + Point p(1,1,1); + gv.set_vertex_color(CGAL::ORANGE); + gv << p; + Locate_type lt; + int li, lj; + Cell_handle c = T.locate(p,lt,li,lj); + + sleep(3); + + gv << CGAL::VIOLET; + if ( lt == Triangulation::CELL ) { + std::cout <<" CELL" << std::endl; + visu_cell(gv,T,c); + } + if ( lt == Triangulation::FACET ) { + std::cout <<" FACET" << std::endl; + visu_facet(gv,T,c,li); + } + if ( lt == Triangulation::EDGE ) { + std::cout <<" EDGE" << std::endl; + visu_edge(gv,T,c,li,lj); + } + if ( lt == Triangulation::VERTEX ) { + std::cout <<" VERTEX" << std::endl; + visu_vertex(gv,T,c,li); + } + if ( lt == Triangulation::OUTSIDE_CONVEX_HULL ) + std::cout <<" OUTSIDE_CONVEX_HULL" << std::endl; + if ( lt == Triangulation::OUTSIDE_AFFINE_HULL ) + std::cout <<" OUTSIDE_AFFINE_HULL" << std::endl; + + sleep(6); + + std::cout <<" Visualizing T" << std::endl; + gv.clear(); + std::cout <<" - facets" << std::endl; + gv << T; + std::cout <<" - edges only" << std::endl; + gv.set_wired(true); + gv << T; + gv.set_wired(false); + std::cout <<" You can move one of the" <> ch; + + return 0; +} + +#endif // CGAL_USE_GEOMVIEW diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_remove_demo.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_remove_demo.cpp new file mode 100644 index 00000000000..0e83e2ea57b --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_remove_demo.cpp @@ -0,0 +1,146 @@ +// Copyright (c) 2001, 2002, 2003, 2004, 2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Monique Teillaud + +#include + +#ifndef CGAL_USE_GEOMVIEW +#include +int main() +{ + std::cerr << "Geomview doesn't work on this platform," + " so this demo doesn't work" << std::endl; + return 0; +} +#else + +#include + +#include + +#include + +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Delaunay_triangulation_3 Dt; + +typedef Dt::Vertex_iterator Vertex_iterator; +typedef Dt::Vertex_handle Vertex_handle; +typedef Dt::Cell_handle Cell_handle; +typedef Dt::Point Point; + +////////////////////// +// VISU GEOMVIEW +////////////////////// +template +void visu_cell(CGAL::Geomview_stream & os, const TRIANGULATION & T, + Cell_handle c) +{ + if ( ! T.is_infinite(c) ) + os << T.tetrahedron(c); + else + os << T.triangle(c,c->index(T.infinite_vertex())); +} +template +void visu_facet(CGAL::Geomview_stream & os, const TRIANGULATION & T, + Cell_handle c, int i) +{ + if ( ! T.is_infinite(c,i) ) + os << T.triangle(c,i); +} +template +void visu_edge(CGAL::Geomview_stream & os, const TRIANGULATION & T, + Cell_handle c, int i, int j) +{ + if ( ! T.is_infinite(c,i,j) ) + os << T.segment(c,i,j); +} +template +void visu_vertices(CGAL::Geomview_stream & os, const TRIANGULATION & T) +{ + Vertex_iterator vit = T.finite_vertices_begin(); + Vertex_iterator vdone = T.vertices_end(); + + if ( vit == vdone ) { std::cout << "no vertex" << std::endl ;} + else { + while(vit != vdone) { + os << vit->point(); + ++vit; + } + } +} +template +void visu_vertex(CGAL::Geomview_stream & os, const TRIANGULATION & T, + Cell_handle c, int i) +{ + if ( ! T.is_infinite(c->vertex(i)) ) + os << c->vertex(i)->point(); +} + +////////////////////// + +int main() +{ + CGAL::Geomview_stream gv(CGAL::Bbox_3(0,0,0, 5, 5, 5)); + gv.set_bg_color(CGAL::Color(0, 200, 200)); + gv.set_wired(true); + gv.clear(); + + Dt T; + + std::cout <<" Inserting points" << std::endl ; + int x,y,z; + std::vector V(125); + int i=0; + + for (z=0 ; z<5 ; z++) + for (y=0 ; y<5 ; y++) + for (x=0 ; x<5 ; x++) + V[i++] = T.insert(Point(x,y,z)); + + assert( T.is_valid() ); + assert( T.number_of_vertices() == 125 ); + assert( T.dimension() == 3 ); + + std::cout <<" Visualizing edges" << std::endl; + gv << T; + + sleep(3); + + std::cout <<" Removing vertices in random order" << std::endl; + + std::random_shuffle(V.begin(), V.end()); + + for (i=0; i<125; ++i) { + T.remove(V[i]); + gv.clear(); + gv << T; + } + + char ch; + std::cout << "Enter any character to quit" << std::endl; + std::cin >> ch; + + return 0; +} + +#endif // CGAL_USE_GEOMVIEW diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp new file mode 100644 index 00000000000..3a70f88a605 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/Triangulation_3_voronoi_demo.cpp @@ -0,0 +1,85 @@ +// Copyright (c) 2001, 2002, 2003, 2004, 2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Monique Teillaud + +#include + +#ifndef CGAL_USE_GEOMVIEW +#include +int main() +{ + std::cerr << "Geomview doesn't work on this platform," + " so this demo doesn't work" + << std::endl; + return 0; +} +#else + +#include + +#include +#include + +#include + +#include + +// exact constructions (circumcenter computations) are needed in this +// demo, not only predicates +typedef CGAL::Exact_predicates_exact_constructions_kernel K; + +typedef CGAL::Triangulation_vertex_base_3 Vb; +typedef CGAL::Triangulation_cell_base_with_circumcenter_3 Cb; +typedef CGAL::Triangulation_data_structure_3 TDS; +typedef CGAL::Delaunay_triangulation_3 Triangulation; +// typedef CGAL::Delaunay_triangulation_3 Triangulation; + +typedef Triangulation::Point Point; + +int main() +{ + CGAL::Geomview_stream gv(CGAL::Bbox_3(0,0,0, 3, 3, 3)); + gv.set_bg_color(CGAL::Color(0, 200, 200)); + gv.clear(); + + Triangulation T; + + std::cout <<" Inserting points" << std::endl ; + for (int z=0 ; z<3 ; z++) + for (int y=0 ; y<3 ; y++) + for (int x=0 ; x<3 ; x++) + T.insert(Point(x, y, z)); + + T.is_valid(true); + + std::cout <<" Visualizing T" << std::endl; + gv.set_wired(true); + gv << T; + + std::cout <<" Visualizing the Voronoi edges" << std::endl; + gv << CGAL::RED; + T.draw_dual(gv); + + char ch; + std::cout << "Enter any character to quit" << std::endl; + std::cin >> ch; + + return 0; +} + +#endif // CGAL_USE_GEOMVIEW diff --git a/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/data/points b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/data/points new file mode 100644 index 00000000000..b50bfb6eee4 --- /dev/null +++ b/Triangulation_3_copy_tds/demo/Triangulation_3_Geomview_demos/data/points @@ -0,0 +1,7 @@ +0 0 0 +1 0 0 +0 1 0 +0 0 1 +2 2 2 +-1 0 1 + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/PkgDescription.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/PkgDescription.tex new file mode 100644 index 00000000000..c881d1bd775 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/PkgDescription.tex @@ -0,0 +1,15 @@ + +\begin{ccPkgDescription}{3D Triangulation Data Structure \label{Pkg:TDS3}} +\ccPkgHowToCiteCgal{cgal:pt-tds3-10} +\ccPkgSummary{ +This package provides a data structure to store a three-dimensional +triangulation that has the topology of a three-dimensional sphere. +The package acts as a container for the vertices +and cells of the triangulation +and provides basic combinatorial operations on the triangulation.} + +%\ccPkgDependsOn{} +\ccPkgIntroducedInCGAL{2.1} +\ccPkgLicense{\ccLicenseQPL} +\ccPkgIllustration{TriangulationDS_3/tds3_small.png}{TriangulationDS_3/tds3_small.png} +\end{ccPkgDescription} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/TDS3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/TDS3.tex new file mode 100644 index 00000000000..e4ff1beb7d2 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/TDS3.tex @@ -0,0 +1,386 @@ +% file : doc_tex/basic/TriangulationDS_3/TDS3.tex +% revision : $Id$ +% +% author(s) : Monique Teillaud + +A geometric triangulation has two aspects: the combinatorial structure, which +gives the incidence and adjacency relations between faces, and the +geometric information related to the position of vertices. + +\cgal\ provides 3D geometric triangulations in which these +two aspects are clearly separated. +As described in Chapter~\ref{chapter-Triangulation3}, a geometric +triangulation of a set of points in $\R^d$, $d\leq 3$ is a partition of the +whole space $\R^d$ into cells having $d+1$ vertices. Some of them +are infinite, they are obtained by linking an additional vertex at +infinity to each facet of the convex hull of the points (see +Section~\ref{Triangulation3-sec-intro}). +The underlying combinatorial graph of such a triangulation +without boundary of $\R^d$ can be seen as a triangulation of the +topological sphere $S^d$ in $\R^{d+1}$. + +This chapter deals with 3D-triangulation data structures, meant to +maintain the combinatorial information for 3D-geometric +triangulations. The reader interested in geometric triangulations of +$\R^3$ is advised to read Chapter~\ref{chapter-Triangulation3}. + +\section{Representation\label{TDS3-sec-intro}} + +In \cgal, a 3D triangulation data structure is a +container of cells ($3$-faces) and vertices ($0$-faces). + +Following the standard vocabulary of simplicial complexes, an $i$-face +$f_i$ and a $j$-face $f_j$ $(0 \leq j < i \leq 3)$ are said to be +\textit{incident} in the triangulation if $f_j$ is a (sub)face of $f_i$, and +two $i$-faces $(0 \leq i \leq 3)$ are said to be \textit{adjacent} if +they share a commun incident (sub)face. + +Each cell gives access to its four incident vertices and to its four +adjacent cells. Each vertex gives direct access to one of its incident +cells, which is sufficient to retrieve all the incident cells when +needed. + +The four vertices of a cell are indexed with 0, 1, 2 and 3. The +neighbors of a cell are also indexed with 0, 1, 2, 3 +in such a way that the neighbor indexed by $i$ is opposite to the vertex +with the same index (see Figure~\ref{TDS3-fig-repres}). + +\begin{figure} +\begin{ccTexOnly} +\begin{center} +\includegraphics{TriangulationDS_3/repres} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+Representation +
+\end{ccHtmlOnly} +\caption{Representation. +\label{TDS3-fig-repres}} +\end{figure} + +Edges ($1$-faces) and facets ($2$-faces) are not explicitly +represented: a facet is given by a cell and an index (the facet +\ccc{i} of a cell \ccc{c} is the facet of \ccc{c} that is opposite to +the vertex of index \ccc{i}) and an edge is given by a cell and two +indices (the edge \ccc{(i,j)} of a cell \ccc{c} is the edge +whose endpoints are the vertices of indices \ccc{i} and \ccc{j} of +\ccc{c}). + +\paragraph{Degenerate Dimensions} +As \cgal\ explicitly deals with all degenerate cases, a +3D-triangulation data structure in \cgal\ can handle the cases when +the dimension of the triangulation is lower than~3. + +Thus, a 3D-triangulation data structure can store a triangulation of a +topological sphere $S^d$ of $\R^{d+1}$, for any $d \in \{-1,0,1,2,3\}$. + +Let us give, for each dimension, the example corresponding to the +triangulation data structure having a minimal number of vertices, i.e. a +simplex. These examples are illustrated by presenting their usual +geometric embedding. +\begin{itemize} +\item \emph{dimension 3.} The triangulation data structure consists of +the boundary of a 4-dimensional simplex, which has 5 vertices. A +geometric embedding consists in choosing one of these vertices to be +infinite, thus four of the five 3-cells become infinite: the geometric +triangulation has one finite tetrahedron remaining, each of its facets +being incident to an infinite cell. See Figure~\ref{TDS3-fig-topo-simplex4}. +\begin{figure} +\begin{ccTexOnly} +\begin{center} +\includegraphics{TriangulationDS_3/topo-simplex4} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+ +
+\end{ccHtmlOnly} +\caption{4D simplex and a 3D geometric embedding. +\label{TDS3-fig-topo-simplex4}} +\end{figure} +\item \emph{dimension 2.} We have 4 vertices forming one 3-dimensional +simplex, i.e. the boundary of a tetrahedron. The geometric embedding in +the plane results from choosing one of these vertices to be infinite, +then the geometric triangulation has one finite triangle whose edges are +incident to the infinite triangles. See Figure~\ref{TDS3-fig-topo-simplex3}. +\begin{figure} +\begin{ccTexOnly} +\begin{center} +\includegraphics{TriangulationDS_3/topo-simplex3} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+ +
+\end{ccHtmlOnly} +\caption{3D simplex and a 2D geometric embedding. +\label{TDS3-fig-topo-simplex3}} +\end{figure} +\item \emph{dimension 1.} A 2-dimensional simplex (a triangle) has 3 +vertices. The geometric embedding is an edge whose vertices are linked +to an infinite point. See Figure~\ref{TDS3-fig-topo-simplex2}. +\begin{figure} +\begin{ccTexOnly} +\begin{center} +\includegraphics{TriangulationDS_3/topo-simplex2} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+ +
+\end{ccHtmlOnly} +\caption{2D simplex and a 1D geometric embedding. +\label{TDS3-fig-topo-simplex2}} +\end{figure} +\end{itemize} + +The last three cases are defined uniquely: +\begin{itemize} +\item \emph{dimension 0.} A 0-dimensional triangulation is +combinatorially equivalent to the boundary of a 1-dimensional simplex +(an edge), which consists of 2 vertices. One of them becomes infinite +in the geometric embedding, and there is only one finite vertex +remaining. The two vertices are adjacent. +\item \emph{dimension -1.} This dimension is a convention to represent a +0-dimensional simplex, that is a sole vertex, which will be +geometrically embedded as an ``empty'' triangulation, having only one +infinite vertex. +\item \emph{dimension -2.} This is also a convention. The +triangulation data structure has no vertex. There is no associated +geometric triangulation. +\end{itemize} + +Note that the notion of infinite vertex has no meaning for the +triangulation data structure. The infinite vertex of the geometric +embedding is a vertex that cannot be distinguished from the other +vertices in the combinatorial triangulation. + +The same cell class is used in all cases: triangular faces in +2D can be considered as degenerate cells, having only three vertices +(resp. neighbors) numbered $(0,1,2)$; +edges in 1D have only two vertices (resp. neighbors) numbered $0$ and $1$. + +The implicit representation of facets (resp. edges) still holds +for degenerate ($< 3$) dimensions : in dimension~2, each cell has only one +facet of index 3, and 3 edges $(0,1)$, $(1,2)$ and $(2,0)$; in +dimension~1, each cell has one edge $(0,1)$. + +\paragraph{Validity} +A 3D combinatorial triangulation is said to be \ccc{locally valid} +iff the following is true: + +{\bf (a)} When a cell $c$ has a neighbor pointer to another cell $c'$, +then reciprocally this cell $c'$ has a neighbor pointer to $c$, and +$c$ and $c'$ have three vertices in common. These cells are called +adjacent. +% Two adjacent cells have reciprocal neighbor pointers to each +% other and they have three vertices in common. + +{\bf (b)} The cells have a coherent orientation: if two cells $c_1$ +and $c_2$ are adjacent and share a facet with vertices $u,v,w$, then +the vertices of $c_1$ are numbered $(v_0^1 = u, v_1^1 = v, v_2^1 = w, +v_3^1)$, and the vertices of $c_2$ are numbered $(v_0^2 = v, v_1^2 = u, +v_2^2 = w, v_3^2)$, up to positive permutations of $(0,1,2,3)$. In +other words, if we embed the triangulation in $\R^3$, then the fourth +vertices $v_3^1$ and $v_3^2$ of $c_1$ and $c_2$ see the common facet +in opposite orientations. See Figure~\ref{TDS3-fig-comborient}. + +The set {\Large $\sigma$}$_4$ of permutations of +$(0,1,2,3)$ has cardinality 24, and the set of positive permutations +$A_4$ has cardinality 12. Thus, for a given orientation, there +are up to 12 different orderings of the four vertices of a cell. Note +that cyclic permutations are negative and so do not preserve the +orientation of a cell. + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{TriangulationDS_3/comborient} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+Orientation of a cell (3-dimensional case) +
+\end{ccHtmlOnly} +\caption{Coherent orientations of two cells (3-dimensional case). +\label{TDS3-fig-comborient}} +\end{figure} + +The \ccc{is_valid()} method provided by +\ccc{Triangulation_data_structure_3} checks the local validity of a +given triangulation data structure. + +\section{Software Design\label{TDS3-sec-design}} + +The 3D-triangulation data structure class of \cgal, +\ccc{Triangulation_data_structure_3}, is designed to be used as a combinatorial +layer upon which a geometric layer can be built \cite{k-ddsps-98}. This +geometric layer is typically one of the 3D-triangulation classes of \cgal: +\ccc{Triangulation_3}, \ccc{Delaunay_triangulation_3} and +\ccc{Regular_triangulation_3}. This relation is described in more details in +Chapter~\ref{chapter-Triangulation3}, where the +Section~\ref{Triangulation3-sec-design} explains other important parts of the +design related to the geometry. + +We focus here on the design of the triangulation data structure (TDS) +itself, which the Figure~\ref{TDS3-fig-layers} illustrates. + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics[width=14cm]{TriangulationDS_3/design_tds} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+Triangulation Data Structure software design +
+\end{ccHtmlOnly} +\caption{Triangulation Data Structure software design. +\label{TDS3-fig-layers}} +\end{figure} + +\subsection{Flexibility of the Design} + +In order for the user to be able to add his own data in the vertices and cells, +the design of the TDS is split into two layers: + +\begin{itemize} +\item{} In the bottom layer, the (vertex and cell) base classes store +elementary incidence and adjacency (and possibly geometric or other) +information. These classes are parameterized by the TDS which provides the +handle types. (They can also be parameterized by a geometric traits class or +anything else.) A vertex stores a \ccc{Cell_handle}, and a cell stores four +\ccc{Vertex_handle}s and four \ccc{Cell_handle}s. + +\item{} The middle layer is the TDS, which is purely combinatorial. It +provides operations such as insertion of a new vertex in a given cell, on a $1$ +or $2$-face. It also allows one, if the dimension of the triangulation is +smaller than $3$, to insert a vertex so that the dimension of the triangulation +is increased by one. The TDS is responsible for the combinatorial integrity of +the eventual geometric triangulation built on top of it (the upper layer, +see Chapter~\ref{chapter-Triangulation3}). +\end{itemize} + +The user has several ways to add his own data in the vertex and cell base classes used by the TDS. He can either: +\begin{itemize} +\item{} use the classes \ccc{Triangulation_vertex_base_with_info} +and \ccc{Triangulation_cell_base_with_info}, which allow to add one data member +of a user provided type, and give access to it. +\item{} derive his own classes from the default base classes +\ccc{Triangulation_ds_vertex_base}, and \ccc{Triangulation_ds_cell_base} (or +the geometric versions typically used by the geometric layer, +\ccc{Triangulation_vertex_base}, and \ccc{Triangulation_cell_base}). +\item{} write his own base classes following the requirements given by the +concepts \ccc{TriangulationCellBase_3} and \ccc{TriangulationVertexBase_3} +\lcTex{(described in \ccRefPage{TriangulationCellBase_3} and +\ccRefPage{TriangulationVertexBase_3})}. +\end{itemize} + +\subsection{Cyclic Dependency\label{tds3-cyclic}} + +Since adjacency relations are stored in the vertices and cells, it means that +the vertex and cell base classes have to be able to store handles (an entity +akin to pointers) to their neighbors in the TDS. This in turns means that the +vertex and cell base classes have to know the types of these handles, which are +provided by the TDS. So in a sense, the base classes are parameterized by the +TDS, and the TDS is parameterized by the vertex and cell base classes ! +This is a cycle which cannot be resolved easily. + +The solution that we have chosen is similar to the mechanism used by the +standard class \ccc{std::allocator}: the vertex and cell base classes are +initially given a fake or dummy TDS template parameter, whose unique purpose +is to provide the types that can be used by the vertex and cell base classes +(such as handles). Then, inside the TDS itself, these base classes are +\textit{rebound} to the real TDS type, that is we obtain the same vertex +and cell base classes, but parameterized with the real TDS instead of the dummy +one. Rebinding is performed by a nested template class of the vertex and cell +base classes (see code below), which provides a type which is the rebound +vertex or cell base class\footnote{It is logically equivalent to a mechanism +that does not exist yet in the C++ language: \textit{template typedef} or +\textit{template aliasing}}. + +Here is how it works, schematically: + +\begin{ccExampleCode} +template < class Vb, class Cb > +class TDS +{ + typedef TDS Self; + + // Rebind the vertex and cell base to the actual TDS (Self). + typedef typename Vb::template Rebind_TDS::Other VertexBase; + typedef typename Cb::template Rebind_TDS::Other CellBase; + + // ... further internal machinery leads to the final public types: +public: + typedef ... Vertex; + typedef ... Cell; + typedef ... Vertex_handle; + typedef ... Cell_handle; +}; + +template < class TDS = ... > // The default is some internal type faking a TDS +class Triangulation_ds_vertex_base_3 +{ +public: + template < class TDS2 > + struct Rebind_TDS { + typedef Triangulation_ds_vertex_base_3 Other; + }; +... +}; +\end{ccExampleCode} + +When derivation is used for the vertex or cell base classes, which is the +case at the geometric level with \ccc{Triangulation_vertex_base_3}, then +it gets slightly more involved because its base class has to be rebound as +well: + +\begin{ccExampleCode} +template < class GT, class Vb = Triangulation_ds_vertex_base_3<> > +class Triangulation_vertex_base_3 : public Vb +{ +public: + template < class TDS2 > + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef Triangulation_vertex_base_3 Other; + }; +... +}; +\end{ccExampleCode} + +\section{Examples\label{TDS3-sec-examples}} + +\subsection{Incremental Construction} +The following example shows how to construct a 3D triangulation data +structure by inserting vertices. + +\ccIncludeExampleCode{Triangulation_3/tds.cpp} + +\subsection{Cross-Linking Between a 2D and a 3D Data Structures} +This example program illustrates how to setup a 2D and a 3D triangulation data +structures whose vertices respectively store vertex handles of the other one. + +\ccIncludeExampleCode{Triangulation_3/linking_2d_and_3d.cpp} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Design and Implementation History} + +Monique Teillaud introduced the triangulation of the topological +sphere $S^d$ in $\R^{d+1}$ to manage the underlying graph of geometric +triangulations and handle degenerate dimensions \cite{t-tdtc-99}. + +Sylvain Pion improved the software in several ways, in particular +regarding the memory management. diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.gif new file mode 100644 index 00000000000..00d1b5580fa Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.pdf new file mode 100644 index 00000000000..08f78a8b27d Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.xml b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.xml new file mode 100644 index 00000000000..8ef11410e36 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/comborient.xml @@ -0,0 +1,50 @@ + + + + + + +-111.778 375.245 m +-152.403 305.344 l + + +-111.778 375.245 m +-58.153 352.486 l + + +-152.403 305.344 m +-58.153 352.486 l + + +-152.403 305.344 m +-67.903 270.394 l +-111.778 375.245 l + + +-58.153 352.486 m +-67.903 270.394 l + + +-111.778 375.245 m +-164.591 413.446 l +-152.403 305.344 l + + +-164.591 413.446 m +-58.153 352.486 l + +$v_3^1$ +$v_3^2$ +$v_0^2 = v_1^1 = v$ +$v_1^2 = v_0^1 = u$ +$v_2^2 = v_2^1 = w$ + +-50.8405 282.586 m +20.9708 0 0 20.9708 -67.903 270.394 -88.0664 264.631 a + + +-141.029 415.072 m +21.9574 0 0 21.9574 -154.841 398.003 -174.479 388.18 a + + + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.fig b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.fig new file mode 100644 index 00000000000..07dfb1ae818 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.fig @@ -0,0 +1,130 @@ +#FIG 3.2 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +6 3870 2070 7335 2430 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 4995 2340 4410 2160 3900 2355 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 6300 2340 6855 2115 7335 2310 + 0.000 -1.000 0.000 +4 0 0 50 0 0 16 0.0000 4 165 1065 5130 2430 Derivation\001 +-6 +6 585 6705 1890 7290 +4 0 0 50 0 0 12 0.0000 4 180 1065 720 6840 Optional User\001 +4 0 0 50 0 0 12 0.0000 4 135 1305 585 7065 and/or Geometric\001 +4 0 0 50 0 0 12 0.0000 4 135 735 855 7290 Additions\001 +-6 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 1350 900 1350 5850 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 7425 2880 7425 1350 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 13 + 2250 5850 2250 5400 5400 5400 5400 5850 5850 5850 5850 5400 + 9000 5400 9000 5850 9900 5850 9900 900 450 900 450 5850 + 2250 5850 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 3825 6750 3825 5400 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 7425 6750 7425 5400 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 90.00 180.00 + 3825 900 3825 450 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 90.00 180.00 + 7425 900 7425 450 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 7425 5400 7425 3330 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 6750 900 8100 900 8100 1350 6750 1350 6750 900 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 3150 900 4500 900 4500 1350 3150 1350 3150 900 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3825 2880 3825 1350 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5850 2880 9000 2880 9000 3330 5850 3330 5850 2880 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2250 2880 5400 2880 5400 3330 2250 3330 2250 2880 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 3825 5400 3825 3330 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 3825 8550 3825 7200 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 7425 8550 7425 7200 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2250 8550 5400 8550 5400 9000 2250 9000 2250 8550 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5850 8550 9000 8550 9000 9000 5850 9000 5850 8550 +2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 + 2250 6750 5400 6750 5400 7200 2250 7200 2250 6750 +2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 + 5850 6750 9000 6750 9000 7200 5850 7200 5850 6750 +2 2 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 2205 2835 5445 2835 5445 3375 2205 3375 2205 2835 +2 2 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 5805 2835 9045 2835 9045 3375 5805 3375 5805 2835 +2 2 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 3105 900 4545 900 4545 1395 3105 1395 3105 900 +2 2 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 6705 900 8145 900 8145 1395 6705 1395 6705 900 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 4950 4365 4485 4185 3915 4365 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 6465 4365 6915 4185 7305 4335 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 5985 1170 6255 1080 6615 1080 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 5205 1215 4905 1125 4590 1125 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 4995 8055 4410 7875 3900 8070 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 6300 8055 6855 7830 7335 8025 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 6780 6255 7020 6165 7335 6165 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 4590 6255 4230 6120 3870 6165 + 0.000 -1.000 0.000 +4 0 0 50 0 0 24 1.5708 4 330 4245 990 5445 Triangulation Data Structure\001 +4 0 0 50 0 0 20 0.0000 4 195 780 3420 1215 Vertex\001 +4 0 0 50 0 0 20 0.0000 4 195 465 7200 1215 Cell\001 +4 0 0 50 0 0 16 0.0000 4 195 1290 5085 4455 Rebind_TDS\001 +4 0 0 50 0 0 16 0.0000 4 225 585 5310 1260 Types\001 +4 0 0 50 0 0 16 0.0000 4 165 1065 5130 8145 Derivation\001 +4 0 0 50 0 0 16 0.0000 4 225 2070 4635 6300 Template parameters\001 +4 0 0 50 0 0 15 0.0000 4 180 2790 2333 3187 UserVB<...,DSVB >\001 +4 0 0 50 0 0 16 0.0000 4 225 3135 2295 8865 DSVertexBase\001 +4 0 0 50 0 0 16 0.0000 4 225 2880 6030 8865 DSCellBase\001 +4 0 0 50 0 0 13 0.0000 4 195 3210 2295 7065 UserVB<...,DSVB >\001 +4 0 0 50 0 0 13 0.0000 4 195 3240 5940 7065 UserCB<...,DSCB >\001 +4 0 0 50 0 0 15 0.0000 4 180 2820 5940 3195 UserCB<...,DSCB >\001 diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.gif new file mode 100644 index 00000000000..d502baaf455 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.pdf new file mode 100644 index 00000000000..4b74b31a543 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/design_tds.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.gif new file mode 100644 index 00000000000..60156fcaddd Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.pdf new file mode 100644 index 00000000000..870912cc86d Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.xml b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.xml new file mode 100644 index 00000000000..005e8107260 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/flips.xml @@ -0,0 +1,67 @@ + + + + + + +-8.1225 76.95 m +38.1758 52.65 l +84.474 93.15 l +h + + + +-122.65 172.53 m +-156.764 -26.73 l +-125.899 52.65 l +h + + +-172.197 76.95 m +-79.6005 93.15 l + + +-122.65 172.53 m +-156.764 -26.73 l + + +-122.65 172.53 m +-172.197 76.95 l +-125.899 52.65 l +-79.6005 93.15 l +-122.65 172.53 l +-125.899 52.65 l +-156.764 -26.73 l +-79.6005 93.15 l + + +-172.197 76.95 m +-156.764 -26.73 l + + + +-8.1225 76.95 m +84.474 93.15 l + + +41.4248 172.53 m +-8.1225 76.95 l +38.1758 52.65 l +84.474 93.15 l +41.4248 172.53 l +38.1758 52.65 l +7.31025 -26.73 l +84.474 93.15 l + + +-8.1225 76.95 m +7.31025 -26.73 l + + +-25.1797 80.19 m +32.1918 0 0 32.1918 -46.6754 56.2266 -69.0413 79.3799 a + +3 tetrahedra +2 tetrahedra + + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/main.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/main.tex new file mode 100644 index 00000000000..dc265978617 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/main.tex @@ -0,0 +1,9 @@ +\ccUserChapter{3D Triangulation Data Structure\label{chapter-TDS3}} +\ccChapterAuthor{Sylvain Pion \and Monique Teillaud} + +\input{TriangulationDS_3/PkgDescription} + +\minitoc + +\input{TriangulationDS_3/TDS3} + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.gif new file mode 100644 index 00000000000..6e8dbb54e62 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.pdf new file mode 100644 index 00000000000..e1379ab3611 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.xml b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.xml new file mode 100644 index 00000000000..da22a5aa593 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/repres.xml @@ -0,0 +1,64 @@ + + + + + +vextex 0 +vertex 1 +vertex 2 +vertex 3 + +-16.245 27.54 m +-64.1677 51.03 l +-38.1758 -8.1 l +h + + +-64.1677 51.03 m +-92.5965 -9.72 l +-38.1758 -8.1 l + + +-92.5965 -9.72 m +-16.245 27.54 l + +facet 0 + +-64.1677 51.03 m +-30.0532 80.19 l +-38.1758 -8.1 l +-16.245 27.54 l +-30.0532 80.19 l + +neighbor 0 +edge $(1,3)$ + +7.31028 -0.81007 m +48.7338 0 0 48.7338 -35.966 -23.2187 -42.237 25.1099 a + + +-104.78 37.26 m +30.3329 0 0 30.3329 -78.6585 52.6788 -57.6698 30.78 a + + +-78.7882 72.09 m +-64.1677 51.03 l + + +-34.1145 -31.59 m +-38.1758 -8.1 l + + +-111.278 -28.35 m +-92.5965 -9.72 l + + +4.06125 42.93 m +-16.245 27.54 l + + +-29.6619 60.0906 m +60.4585 0 0 60.4585 -28.8736 120.544 15.4631 79.4406 a + + + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/tds3_small.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/tds3_small.pdf new file mode 100644 index 00000000000..1cdebc5f6f4 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/tds3_small.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/tds3_small.png b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/tds3_small.png new file mode 100644 index 00000000000..92a9d4d5571 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/tds3_small.png differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.gif new file mode 100644 index 00000000000..ded6b264414 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.pdf new file mode 100644 index 00000000000..2d1f6281ca2 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.xml b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.xml new file mode 100644 index 00000000000..1bb642329dc --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex2.xml @@ -0,0 +1,34 @@ + + + + + + +48.0739 0 0 48.0739 -117.794 261.666 e + + + + +$v_0$ +$v_1$ +$v_2$ + +-26.9262 268.887 m +147.708 270.405 l + + + +$\infty$ +$\infty$ +$p_0$ +$p_1$ + +138.57 292.68 m +383.284 0 0 383.284 -36.0222 -48.5299 -112.214 327.105 a + + +-38.0946 290.149 m +55.7192 0 0 55.7192 -91.7888 275.264 -112.213 327.105 a + + + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.gif new file mode 100644 index 00000000000..a84905e5121 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.pdf new file mode 100644 index 00000000000..8d7f3280770 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.xml b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.xml new file mode 100644 index 00000000000..1edb54d3e25 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex3.xml @@ -0,0 +1,101 @@ + + + + + + +67.3355 225.217 m +83.5755 257.852 l + + +61.0952 192.965 m +107.951 170.069 l + + +23.1352 182.041 m +-7.02484 160.713 l + +$\infty$ +$\infty$ +$\infty$ + +22.6345 181.072 m +60.5943 191.996 l +66.8343 224.248 l +22.6345 181.072 l + + + + +$p_1$ +$p_2$ +$p_0$ +$v_0$ +$v_1$ +$v_2$ +$v_3$ + +51.1524 0 0 51.1524 -98.729 221.878 e + + +-102.282 189.477 m +20.4215 0 0 20.4215 -120.558 198.59 -101.992 190.084 a + + +-124.619 203.653 m +34.6684 0 0 34.6684 -105.013 232.245 -84.0066 204.666 a + + +-105.013 232.244 m +24.0712 0 0 24.0712 -101.042 208.503 -124.619 203.653 a + + +-84.007 204.666 m +33.6269 0 0 33.6269 -117.433 200.996 -105.013 232.245 a + + +-143.664 197.436 m +21.6103 0 0 21.6103 -140.084 218.748 -124.619 203.653 a + + +-84.007 204.666 m +30.2533 0 0 30.2533 -57.8262 219.826 -59.0489 189.597 a + + +-92.3377 256.019 m +24.3954 0 0 24.3954 -116.202 250.956 -105.027 272.641 a + + +-92.3374 256.019 m +36.6504 0 0 36.6504 -68.5987 228.095 -105.013 232.245 a + + +-105.026 272.641 m +71.753 0 0 71.753 -72.7761 208.544 -143.664 197.436 a + + +-59.0486 189.597 m +98.0382 0 0 98.0382 -154.137 213.465 -70.4186 264.482 a + + +-70.4195 264.482 m +67.9292 0 0 67.9292 -57.2788 197.836 -92.3381 256.019 a + + + + + + +109.633 180.293 m +104.199 0 0 104.199 6.0939 192.002 -75.1533 257.242 a + + +-75.1533 257.241 m +272.961 0 0 272.961 183.418 344.697 -15.2519 157.513 a + + +59.8832 265.85 m +165.466 0 0 165.466 1.96907 110.85 -75.1535 257.244 a + + + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.gif new file mode 100644 index 00000000000..0898bdb7198 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.pdf new file mode 100644 index 00000000000..aedfd34d19d Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.xml b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.xml new file mode 100644 index 00000000000..407b0a9cba6 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3/topo-simplex4.xml @@ -0,0 +1,102 @@ + + + + + + +-81.2454 271.418 m +-106.628 208.137 l +-42.6635 209.655 l +-81.2454 271.418 l +-28.9568 257.749 l +-42.6635 209.655 l + + +-106.628 208.137 m +-28.9568 257.749 l + + +-79.2149 322.548 m +88.1957 0 0 88.1957 -29.0183 250.031 -106.628 208.136 a + + +-79.2154 322.548 m +421.773 0 0 421.773 340.434 280.277 -81.2459 271.415 a + + +-28.9565 257.749 m +73.1042 0 0 73.1042 -101.91 253.057 -79.2145 322.549 a + + +-42.6635 209.656 m +59.5577 0 0 59.5577 -65.8704 264.506 -79.2143 322.55 a + + + + + + +$v_0$ +$v_1$ +$v_2$ +$v_3$ +$v_4$ + +79.6817 269.393 m +54.2988 206.112 l +118.264 207.63 l +79.6817 269.393 l +131.97 255.724 l +118.264 207.63 l + + +54.2988 206.112 m +131.97 255.724 l + + +79.6817 269.393 m +79.6817 309.893 l +79.6817 309.893 l + + +131.97 255.724 m +155.83 267.874 l + + +118.264 207.63 m +144.154 171.18 l + + +54.2988 206.112 m +19.2706 183.33 l + + + + + +$p_0$ +$p_1$ +$p_2$ +$p_3$ + +74.0975 315.968 m +126.287 0 0 126.287 -6.86057 219.044 -79.2145 322.549 a + + +159.383 176.749 m +143.066 0 0 143.066 24.2582 223.75 -79.2152 322.548 a + + +153.292 274.962 m +147.512 0 0 147.512 19.4676 212.906 -79.2142 322.549 a + + +24.3472 199.024 m +81.2765 0 0 81.2765 -35.4707 254.048 -79.2147 322.549 a + +$\infty$ +$\infty$ +$\infty$ +$\infty$ + + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Tds_cell_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Tds_cell_3.tex new file mode 100644 index 00000000000..08384028754 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Tds_cell_3.tex @@ -0,0 +1,119 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Tds_cell_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTdscellRev}{$Id$} +\RCSdefDate{\RCSTdscellDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}[TriangulationDataStructure_3::]{Cell} + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[concept]{} %% add further index entries + +\ccDefinition + +The concept \ccRefName\ stores +four \ccc{Vertex_handle}s to its four vertices and four \ccc{Cell_handle}s +to its four neighbors. The vertices are indexed 0, 1, 2, and 3 in consistent +order. The neighbor indexed $i$ lies opposite to vertex \ccc{i}. + +In degenerate dimensions, cells are used to store faces of maximal +dimension: in dimension~2, each cell represents only one +facet of index 3, and 3 edges $(0,1)$, $(1,2)$ and $(2,0)$; in +dimension~1, each cell represents one edge $(0,1)$. (See also +Section~\ref{TDS3-sec-intro}.) + +\ccTypes +\ccThree{typedef TriangulationDataStructure_3::Vertex_handle}{Facet }{} +\ccThreeToTwo +The class \ccRefName\ defines the following types. + +\ccTypedef{typedef TriangulationDataStructure_3 Triangulation_data_structure;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Vertex_handle Vertex_handle;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Cell_handle Cell_handle;}{} + +\ccCreation +\ccCreationVariable{c} %% choose variable name +\ccThree{Vertex_handle}{c.set_vertices(Vertex_handle v)xxxxxxx;}{} + +In order to obtain new cells or destruct unused cells, the user must call the +\ccc{create_cell()} and \ccc{delete_cell()} methods of the triangulation data +structure. + +\ccOperations + +\ccAccessFunctions + +\ccMethod{Vertex_handle vertex(int i) const;} +{Returns the vertex \ccc{i} of \ccVar. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{int index(Vertex_handle v) const;} +{Returns the index of vertex \ccc{v} in \ccVar. +\ccPrecond{\ccc{v} is a vertex of \ccVar}.} +\ccGlue +\ccMethod{bool has_vertex(Vertex_handle v) const;} +{Returns \ccc{true} if \ccc{v} is a vertex of \ccVar.} +\ccGlue +\ccMethod{bool has_vertex(Vertex_handle v, int & i) const;} +{Returns \ccc{true} if \ccc{v} is a vertex of \ccVar, and +computes its index \ccc{i} in \ccVar.} + +\ccMethod{Cell_handle neighbor(int i) const;} +{Returns the neighbor \ccc{i} of \ccVar. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{int index(Cell_handle n) const;} +{Returns the index corresponding to neighboring cell \ccc{n}. +\ccPrecond{\ccc{n} is a neighbor of \ccVar.}} +\ccGlue +\ccMethod{bool has_neighbor(Cell_handle n) const;} +{Returns \ccc{true} if \ccc{n} is a neighbor of \ccVar.} +\ccGlue +\ccMethod{bool has_neighbor(Cell_handle n, int & i) const;} +{Returns \ccc{true} if \ccc{n} is a neighbor of \ccVar, and +computes its index \ccc{i} in \ccVar.} + +\ccHeading{Setting} + +\ccMethod{void set_vertex(int i, Vertex_handle v);} +{Sets vertex \ccc{i} to \ccc{v}. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{void set_vertices(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2, + Vertex_handle v3);} +{Sets the vertex pointers.} + +\ccMethod{void set_neighbor(int i, Cell_handle n);} +{Sets neighbor \ccc{i} to \ccc{n}. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{void set_neighbors(Cell_handle n0, + Cell_handle n1, + Cell_handle n2, + Cell_handle n3);} +{Sets the neighbors pointers.} + +\begin{ccDebug} +\ccHeading{Checking} +\ccThree{Vertex_handle}{c.set_vertices(v);}{} + +\ccMethod{bool is_valid(bool verbose = false, int level = 0) const;} +{User defined local validity checking function.} +\end{ccDebug} + +\ccSeeAlso + +\ccc{TriangulationDataStructure_3::Vertex}. + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Tds_vertex_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Tds_vertex_3.tex new file mode 100644 index 00000000000..fd7ddc8505c --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Tds_vertex_3.tex @@ -0,0 +1,95 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Tds_vertex_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTdsvertexRev}{$Id$} +\RCSdefDate{\RCSTdsvertexDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}[TriangulationDataStructure_3::]{Vertex} + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[concept]{} %% add further index entries + +\ccDefinition + +The concept \ccRefName\ represents the vertex class of a 3D-triangulation +data structure. It must define +the types and operations listed in this section. Some of these +requirements are of geometric nature, they are \textit{optional} +when using the triangulation data structure class alone. They become +compulsory when the triangulation data structure is used as a layer +for the geometric triangulation class. (See Section~\ref{TDS3-sec-design}.) + +\ccTypes +\ccThree{typedef TriangulationDataStructure_3::}{Facet }{} +\ccThreeToTwo +\ccNestedType{Point}{\textit{Optional for the triangulation data +structure alone.}} + +The class \ccRefName\ defines types that are the same as some of the +types defined by the triangulation data structure class +\ccc{TriangulationDataStructure_3}. + +\ccThree{typedef TriangulationDataStructure_3::Vertex_handle}{Facet }{} + +\ccTypedef{typedef TriangulationDataStructure_3 Triangulation_data_structure;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Vertex_handle Vertex_handle;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Cell_handle Cell_handle;}{} + +\ccCreation +\ccCreationVariable{v} %% choose variable name + +In order to obtain new vertices or destruct unused vertices, the user must +call the \ccc{create_vertex()} and \ccc{delete_vertex()} methods of the +triangulation data structure. + +\ccOperations +\ccThree{Vertex_handle}{v.set_point(Vertex_handle v)}{} + +\ccAccessFunctions + +\ccMethod{Cell_handle cell() const;} +{Returns a cell of the triangulation having \ccVar\ as vertex.} + +\ccMethod{Point point() const;} +{Returns the point stored in the vertex. +{\textit{Optional for the triangulation data structure alone.}}} + +\ccHeading{Setting} + +\ccMethod{void set_cell(Cell_handle c);} +{Sets the incident cell to \ccc{c}.} + +\ccMethod{void set_point(const Point & p);} +{Sets the point to \ccc{p}. {\textit{Optional for the +triangulation data structure alone.}}} + +\begin{ccDebug} +\ccHeading{Checking} + +\ccMethod{bool is_valid(bool verbose = false) const;} +{Checks the validity of the vertex. Must check that its incident cell +has this vertex. The validity of the base vertex is also checked.\\ +When \ccc{verbose} is set to \ccc{true}, messages are printed to give +a precise indication on the kind of invalidity encountered.} +\end{ccDebug} + +\ccSeeAlso + +\ccc{TriangulationDataStructure_3::Cell}. + +\end{ccRefConcept} + +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +% EOF +% +------------------------------------------------------------------------+ + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDSCellBase_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDSCellBase_3.tex new file mode 100644 index 00000000000..f08fce60139 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDSCellBase_3.tex @@ -0,0 +1,189 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: TriangulationDSCellBase_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationcbRev}{$Id$} +\RCSdefDate{\RCSTriangulationcbDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{TriangulationDSCellBase_3} + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[concept]{} %% add further index entries + +\ccDefinition + +At the base level +(see Sections~\ref{Triangulation3-sec-design} and~\ref{TDS3-sec-design}), +a cell stores handles to its four vertices and to its four neighbor cells. +The vertices and neighbors are indexed 0, 1, 2 and 3. Neighbor $i$ +lies opposite to vertex $i$. + +Since the Triangulation data structure is the class which defines the handle +types, the cell base class has to be somehow parameterized by the Triangulation +data structure. But since it is itself parameterized by the cell and vertex +base classes, there is a cycle in the definition of these classes. In order +to break the cycle, the base classes for vertex and cell which are given as +arguments for the Triangulation data structure use \ccc{void} as Triangulation +data structure parameter, and the Triangulation data structure then uses a +{\it rebind}-like mechanism (similar to the one specified in +\ccc{std::allocator}) in order to put itself as parameter to the vertex and +cell classes. The {\it rebound} base classes so obtained are the classes +which are used as base classes for the final vertex and cell classes. +More information can be found in Section~\ref{TDS3-sec-design}. + +\ccTypes +\ccThree{typedef TriangulationDataStructure_3::Vertex_handle}{}{} +\ccThreeToTwo +The concept \ccRefName\ has to provide the following types. + +\ccNestedType{ + template + struct Rebind_TDS} +{This nested template class has to define a type \ccc{Other} which is the +{\it rebound} cell, that is, the one whose \ccc{Triangulation_data_structure} +will be the actually used one. The \ccc{Other} type will be the real base +class of \ccc{Triangulation_data_structure_3::Cell}.} + +\ccTypedef{typedef TriangulationDataStructure_3 Triangulation_data_structure;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Vertex_handle Vertex_handle;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Cell_handle Cell_handle;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Cell_data TDS_data;}{} + +\ccCreation +\ccCreationVariable{c} %% choose variable name + +\ccConstructor{Cell_base();} +{Default constructor} +\ccGlue +\ccConstructor{Cell_base( Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3);} +{Initializes the vertices with \ccc{v0, v1, v2, v3}. Neighbors are +initialized to the default constructed handle.} +\ccGlue +\ccConstructor{Cell_base( Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3)} +{Initializes the vertices with \ccc{v0, v1, v2, v3} and the neighbors with +\ccc{n0, n1, n2, n3}.} + +\ccAccessFunctions +\ccThree{Vertex_handlex}{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}{} + +\ccMethod{Vertex_handle vertex(int i) const;} +{Returns the vertex \ccc{i} of \ccVar. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{int index(Vertex_handle v) const;} +{Returns the index of \ccc{v}. +\ccPrecond{\ccc{v} is a vertex of \ccVar}} +\ccGlue +\ccMethod{bool has_vertex(Vertex_handle v);} +{True iff \ccc{v} is a vertex of \ccVar.} +\ccGlue +\ccMethod{bool has_vertex(Vertex_handle v, int & i) const;} +{Returns \ccc{true} if \ccc{v} is a vertex of \ccVar, and +computes its index \ccc{i} in \ccVar.} + +\ccMethod{Cell_handle neighbor(int i) const;} +{Returns the neighbor \ccc{i} of \ccVar. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{int index(Cell_handle n) const;} +{Returns the index of cell \ccc{n} in \ccVar. +\ccPrecond{\ccc{n} is a neighbor of \ccVar.}} +\ccGlue +\ccMethod{bool has_neighbor(Cell_handle n);} +{Returns \ccc{true} if \ccc{n} is a neighbor of \ccVar.} +\ccGlue +\ccMethod{bool has_neighbor(Cell_handle n, int & i) const;} +{Returns \ccc{true} if \ccc{n} is a neighbor of \ccVar, and +computes its index \ccc{i} in \ccVar.} + +\ccHeading{Setting} + +\ccMethod{void set_vertex(int i, Vertex_handle v);} +{Sets vertex \ccc{i} to \ccc{v}. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{ void set_vertices();} +{Sets the vertices to the default constructed handle.} +\ccGlue +\ccMethod{void set_vertices( Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3);} +{Sets the vertices.} + +\ccMethod{void set_neighbor(int i, Cell_handle n);} +{Sets neighbor \ccc{i} to \ccc{n}. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{void set_neighbors();} +{Sets the neighbors to the default constructed handle.} +\ccGlue +\ccMethod{void set_neighbors(Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3);} +{Sets the neighbors.} + +\begin{ccDebug} +\ccHeading{Checking} +\ccMethod{bool is_valid(bool verbose = false, int level = 0) const;} +{Performs any desired geometric test on a cell.\\ +When \ccc{verbose} is set to \ccc{true}, messages are printed to give +a precise indication of the kind of invalidity encountered. \ccc{level} +increases the level of testing.} +\end{ccDebug} + +\begin{ccAdvanced} + +\ccHeading{Various} + +\ccMethod{void * for_compact_container() const;}{} +\ccGlue +\ccMethod{void * & for_compact_container();}{} +{ These member functions are required by \ccc{Triangulation_data_structure_3} + because it uses \ccc{Compact_container} to store its cells. See the + documentation of \ccc{Compact_container} for the exact requirements.} + +\ccMethod{TDS_data& tds_data();}{} +\ccGlue +\ccMethod{const TDS_data& tds_data() const;}{} +{ These functions are used internally by the triangulation data structure. The user is +not encouraged to use them directly as they may change in the future.} + +\end{ccAdvanced} + +\ccHeading{I/O} + +\ccFunction{istream& operator>> (istream& is, TriangulationDSCellBase_3 & c);} +{Inputs the possible non combinatorial information given by the cell.} +\ccGlue +\ccFunction{ostream& operator<< (ostream& os, const TriangulationDSCellBase_3 & c);} +{Outputs the possible non combinatorial information given by the cell.} + +\ccHasModels + +\ccc{CGAL::Triangulation_ds_cell_base_3}\\ +\ccc{CGAL::Triangulation_cell_base_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_info_3} + +\ccSeeAlso + +\ccc{TriangulationDSVertexBase_3}\\ +\ccc{TriangulationVertexBase_3}\\ +\ccc{TriangulationHierarchyVertexBase_3}\\ +\ccc{TriangulationCellBase_3} + +%% \ccExample + +%% \ccIncludeExampleCode{Triangulation3/Triangulation_cb_3_prog.C} + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDSVertexBase_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDSVertexBase_3.tex new file mode 100644 index 00000000000..89956537485 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDSVertexBase_3.tex @@ -0,0 +1,132 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: TriangulationDSVertexBase_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationvbRev}{$Id$} +\RCSdefDate{\RCSTriangulationvbDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{TriangulationDSVertexBase_3} + +\ccDefinition + +At the bottom level of 3D-triangulations +(see Sections~\ref{Triangulation3-sec-design} and~\ref{TDS3-sec-design}), +a vertex provides access to one of its incident cells through a handle. + +Note that when you use the triangulation data structure as parameter of a +geometric triangulation, the vertex base class has additional geometric +requirements : it has to match the \ccc{TriangulationVertexBase_3} concept. + +Since the Triangulation data structure is the class which defines the handle +types, the vertex base class has to be somehow parameterized by the +Triangulation data structure. But since it is itself parameterized by the cell +and vertex base classes, there is a cycle in the definition of these classes. +In order to break the cycle, the base classes for vertex and cell which are +given as arguments for the Triangulation data structure use \ccc{void} as +Triangulation data structure parameter, and the Triangulation data structure +then uses a {\it rebind}-like mechanism (similar to the one specified in +\ccc{std::allocator}) in order to put itself as parameter to the vertex and +cell classes. The {\it rebound} base classes so obtained are the classes which +are used as base classes for the final vertex and cell classes. +More information can be found in Section~\ref{TDS3-sec-design}. + +\ccTypes +\ccThree{typedef TriangulationDataStructure_3::Vertex_handle}{}{} +\ccThreeToTwo +The class \ccRefName\ has to define the following types. + +\ccNestedType{ + template + struct Rebind_TDS} +{This nested template class has to define a type \ccc{Other} which is the +{\it rebound} vertex, that is, the one whose \ccc{Triangulation_data_structure} +will be the actually used one. The \ccc{Other} type will be the real base +class of \ccc{Triangulation_data_structure_3::Vertex}.} + +\ccTypedef{typedef TriangulationDataStructure_3 Triangulation_data_structure;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Vertex_handle Vertex_handle;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Cell_handle Cell_handle;}{} + + +\ccCreation +\ccCreationVariable{v} %% choose variable name + +\ccThree{Triangulation}{Facetxxxxxxxxxxxxxxxxxxxxxxxxx}{} + +\ccConstructor{TriangulationVertexBase_3();} +{Default constructor.} +\ccGlue +\ccConstructor{TriangulationVertexBase_3(Cell_handle c);} +{Constructs a vertex pointing to cell \ccc{c}.} + +\ccOperations + +\ccAccessFunctions + +\ccMethod{Cell_handle cell() const;} +{Returns the pointer to an incident cell} + +\ccHeading{Setting} + +\ccMethod{void set_cell(Cell_handle c);} +{Sets the incident cell.} + +\begin{ccDebug} +\ccHeading{Checking} +\ccMethod{bool is_valid(bool verbose=false, int level=0) const;} +{Performs any desired test on a vertex. Checks that the +pointer to an incident cell is not the default constructed handle.} +\end{ccDebug} + +\ccHeading{Various} + +\ccMethod{void * for_compact_container() const;}{} +\ccGlue +\ccMethod{void * & for_compact_container();}{} +{ These member functions are required by \ccc{Triangulation_data_structure_3} + because it uses \ccc{Compact_container} to store its cells. See the + documentation of \ccc{Compact_container} for the exact requirements.} + +\ccHeading{I/O} + +\ccFunction{istream& operator>> +(istream& is, TriangulationDSVertexBase_3 & v);} +{Inputs the non-combinatorial information given by the vertex.} +%\ccPrecond{The point and the other information have a corresponding +%operator \ccc{>>}. \textit{This precondition is optional for the +%triangulation data structure alone.}}} + +\ccFunction{ostream& operator<< (ostream& os, + const TriangulationDSVertexBase_3 & v);} +{Outputs the non-combinatorial information given by the vertex.} +%\ccPrecond{The point and the other information have a corresponding +%operator \ccc{<<}. \textit{This precondition is optional for the +%triangulation data structure alone.}}} + +\ccHasModels + +\ccc{CGAL::Triangulation_ds_vertex_base_3}\\ +\ccc{CGAL::Triangulation_vertex_base_3}\\ +\ccc{CGAL::Triangulation_vertex_base_with_info_3}\\ +\ccc{CGAL::Triangulation_hierarchy_vertex_base_3} + +\ccSeeAlso + +\ccc{TriangulationVertexBase_3}\\ +\ccc{TriangulationHierarchyVertexBase_3}\\ +\ccc{TriangulationDSCellBase_3}\\ +\ccc{TriangulationCellBase_3} + +%% \ccExample + +%% \ccIncludeExampleCode{Triangulation3/Triangulation_vb_prog.C} + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDataStructure_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDataStructure_3.tex new file mode 100644 index 00000000000..fbd6775295e --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/TriangulationDataStructure_3.tex @@ -0,0 +1,736 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: TriangulationDataStructure_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTdsRev}{$Id$} +\RCSdefDate{\RCSTdsDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{TriangulationDataStructure_3} + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[concept]{} %% add further index entries + +\ccDefinition + +3D-triangulation data structures are meant to maintain the +combinatorial information for 3D-geometric triangulations. + +In \cgal, a triangulation data structure is a container of cells +($3$-faces) and vertices ($0$-faces). Following the standard +vocabulary of simplicial complexes, an $i$-face $f_i$ and a $j$-face +$f_j$ $(0 \leq j < i \leq 3)$ are said to be \textit{incident} in the +triangulation if $f_j$ is a (sub)face of $f_i$, and two $i$-faces $(0 +\leq i \leq 3)$ are said to be \textit{adjacent} if they share a +common incident (sub)face. + +Each cell gives +access to its four incident vertices and to its four adjacent +cells. Each vertex gives direct access to one of its incident cells, which is +sufficient to retrieve all the incident cells when needed. + +The four vertices of a cell are indexed with 0, 1, 2 and 3. The +neighbors of a cell are also indexed with 0, 1, 2, 3 +in such a way that the neighbor indexed by $i$ is opposite to the vertex +with the same index (see Figure~\ref{TDS3-fig-repres}). + +Edges ($1$-faces) and facets ($2$-faces) are not explicitly +represented: a facet is given by a cell and an index (the facet +\ccc{i} of a cell \ccc{c} is the facet of \ccc{c} that is opposite to +the vertex of index \ccc{i}) and an edge is given by a cell and two +indices (the edge \ccc{(i,j)} of a cell \ccc{c} is the edge +whose endpoints are the vertices of indices \ccc{i} and \ccc{j} of +\ccc{c}). + +As \cgal\ explicitly deals with all degenerate cases, a +3D-triangulation data structure in \cgal\ can handle the cases when +the dimension of the triangulation is lower than~3 +(see Section~\ref{TDS3-sec-intro}). + +Thus, a 3D-triangulation data structure can store a triangulation of a +topological sphere $S^d$ of $\R^{d+1}$, for any $d \in \{-1,0,1,2,3\}$. + +\bigskip + +The second template parameter of the basic triangulation class +(see Chapter~\ref{chapter-Triangulation3} +\lcTex{, \ccRefPage{CGAL::Triangulation_3}}) +\ccc{Triangulation_3} is a triangulation data structure class. (See +Chapter~\ref{chapter-TDS3}.) + +To ensure all the \textbf{flexibility} of the class \ccc{Triangulation_3}, a +model of a triangulation data structure must be templated by the base vertex +and the base cell classes (see~\ref{TDS3-sec-intro}): +\ccc{TriangulationDataStructure_3}. +The optional functionalities related to geometry are compulsory for +this use as a template parameter of \ccc{Triangulation_3}. + +\bigskip + +A class that satisfies the requirements for a triangulation data structure +class must provide the following types and operations. + +\ccTypes +\ccThree{typedef Triple }{Facet; }{} +\ccThreeToTwo + +\ccNestedType{Vertex}{Vertex type} +\ccGlue +\ccNestedType{Cell}{Cell type} + +\ccNestedType{size_type}{Size type (unsigned integral type)} +\ccGlue +\ccNestedType{difference_type}{Difference type (signed integral type)} + +Vertices and cells are usually manipulated via \ccc{handles}, which support +the two dereference operators \ccc{operator*} and \ccc{operator->}. + +\ccNestedType{Vertex_handle}{} +\ccGlue +\ccNestedType{Cell_handle}{} + +Requirements for \ccc{Vertex} and \ccc{Cell} are described in +\ccc{TriangulationDataStructure_3::Vertex} and +\ccc{TriangulationDataStructure_3::Cell} \lcTex{( +\ccRefPage{TriangulationDataStructure_3::Vertex} and +\ccRefPage{TriangulationDataStructure_3::Cell})}. + +\begin{ccAdvanced} +\ccNestedType{template struct Rebind_vertex} +{This nested template class allows to get the type of a triangulation +data structure that only changes the vertex type. It has to define a type +\ccc{Other} which is a {\it rebound} triangulation data structure, that is, the +one whose \ccc{TriangulationDSVertexBase_3} will be \ccc{Vb2}.} +\ccGlue +\ccNestedType{template struct Rebind_cell} +{This nested template class allows to get the type of a triangulation +data structure that only changes the cell type. It has to define a type +\ccc{Other} which is a {\it rebound} triangulation data structure, that is, the +one whose \ccc{TriangulationDSCellBase_3} will be \ccc{Cb2}.} +\end{ccAdvanced} + + +\ccTypedef{typedef Triple Edge;}{\ccc{(c,i,j)} is the +edge of cell \ccc{c} whose vertices indices are \ccc{i} and +\ccc{j}. (See Section~\ref{TDS3-sec-intro}.)} +\ccGlue +\ccTypedef{typedef std::pair Facet;}{\ccc{(c,i)} is the facet +of \ccc{c} opposite to the vertex of index \ccc{i}. (See +Section~\ref{TDS3-sec-intro}.)} + +The following iterators allow one to visit all the vertices, edges, facets +and cells of the triangulation data structure. They are all +bidirectional, non-mutable iterators. + +\ccNestedType{Cell_iterator}{} +\ccGlue +\ccNestedType{Facet_iterator}{} +\ccGlue +\ccNestedType{Edge_iterator}{} +\ccGlue +\ccNestedType{Vertex_iterator}{} + +The following circulators allow us to visit all the cells and facets +incident to a given edge. They are bidirectional and non-mutable. + +\ccNestedType{Facet_circulator}{} +\ccGlue +\ccNestedType{Cell_circulator}{} + +Iterators and circulators are convertible to the corresponding handles, thus +the user can pass them directly as arguments to the functions. + +\ccCreation +\ccCreationVariable{tds} %% choose variable name +\ccThree{TriangulationDataStructxure_3;}{tds.set_number}{} +\ccThreeToTwo + +\ccConstructor{TriangulationDataStructure_3();} +{Default constructor.} + +\ccConstructor{TriangulationDataStructure_3(const TriangulationDataStructure_3 & tds1);} +{Copy constructor. All vertices and cells are duplicated.} + +\ccMethod{TriangulationDataStructure_3& operator= (const TriangulationDataStructure_3 & tds1);} +{Assignment operator. All vertices and cells are duplicated, and the former +data structure of \ccc{tds} is deleted.} + +\ccThree{Vertex_handle_}{tds.insert_in_facet}{} + +\ccMethod{Vertex_handle +copy_tds(const TriangulationDataStructure_3 & tds1, + Vertex_handle v = Vertex_handle());} +{\ccc{tds1} is copied into \ccVar. If \ccc{v != Vertex_handle()}, +the vertex of \ccVar\ corresponding to \ccc{v} is returned, +otherwise \ccc{Vertex_handle()} is returned. +\ccPrecond{The optional argument \ccc{v} is a vertex of \ccc{tds1}.}} + +\ccMethod{void swap(TriangulationDataStructure_3 & tds1);} +{Swaps \ccVar\ and \ccc{tds1}. There is no copy of cells and vertices, +thus this method runs in constant time. This method should be preferred to +\ccVar=\ccc{tds1} or \ccVar(\ccc{tds1}) when \ccc{tds1} is deleted after +that.} +\ccGlue +\ccMethod{void clear();} +{Deletes all cells and vertices. \ccVar\ is reset as a triangulation +data structure constructed by the default constructor.} + +\ccOperations + +\ccAccessFunctions +\ccThree{size_type}{tds.insert_in_facet()xxxxxxxxxxx}{} + +\ccMethod{int dimension() const;} +{The dimension of the triangulated topological sphere.} +\ccGlue +\ccMethod{size_type number_of_vertices() const;} +{The number of vertices. Note that the triangulation data structure has one +more vertex than an associated geometric triangulation, if there is +one, since the infinite vertex is a standard vertex and is thus also +counted.} +\ccGlue +\ccMethod{size_type number_of_cells() const;} +{The number of cells. Returns 0 if \ccVar.\ccc{dimension()}$<3$.} + +\ccHeading{Non constant-time access functions} +\ccMethod{size_type number_of_facets() const;} +{The number of facets. Returns 0 if \ccVar.\ccc{dimension()}$<2$.} +\ccGlue +\ccMethod{size_type number_of_edges() const;} +{The number of edges. Returns 0 if \ccVar.\ccc{dimension()}$<1$.} + +\begin{ccAdvanced} +\ccHeading{Setting} +\ccMethod{void set_dimension(int n);} +{Sets the dimension to \ccc{n}.} +\end{ccAdvanced} + +\ccHeading{Queries} + +\ccMethod{bool is_vertex(Vertex_handle v) const;} +{Tests whether \ccc{v} is a vertex of \ccVar.} + +\ccMethod{bool is_edge(Cell_handle c, int i, int j) const;} +{Tests whether \ccc{(c,i,j)} is an edge of \ccVar. Answers \ccc{false} when +\ccc{dimension()} $<1$ . +\ccPrecond{$i,j \in \{0,1,2,3\}$}} +\ccGlue +\ccMethod{bool is_edge(Vertex_handle u, Vertex_handle v, + Cell_handle & c, int & i, int & j) const;} +{Tests whether \ccc{(u,v)} is an edge of \ccVar. If the edge is found, +it computes a cell \ccc{c} having this edge and the indices \ccc{i} +and \ccc{j} of the vertices \ccc{u} and \ccc{v}, in this order.} +\ccGlue +\ccMethod{bool is_edge(Vertex_handle u, Vertex_handle v) const;} +{Tests whether \ccc{(u,v)} is an edge of \ccVar.} + +\ccMethod{ bool is_facet(Cell_handle c, int i) const;} +{Tests whether \ccc{(c,i)} is a facet of \ccVar. Answers \ccc{false} when +\ccc{dimension()} $<2$ . +\ccPrecond{$i \in \{0,1,2,3\}$}} +\ccGlue +\ccMethod{bool is_facet(Vertex_handle u, Vertex_handle v, Vertex_handle w, + Cell_handle & c, int & i, int & j, int & k) const;} +{Tests whether \ccc{(u,v,w)} is a facet of \ccVar. If the facet is found, +it computes a cell \ccc{c} having this facet and the indices \ccc{i}, +\ccc{j} and \ccc{k} of the vertices \ccc{u}, \ccc{v} and \ccc{w}, in +this order.} + +\ccMethod{bool is_cell(Cell_handle c) const;} +{Tests whether \ccc{c} is a cell of \ccVar. Answers \ccc{false} when +\ccc{dimension()} $<3$ .} +\ccMethod{bool is_cell(Vertex_handle u, Vertex_handle v, Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const;} +{Tests whether \ccc{(u,v,w,t)} is a cell of \ccVar. If the cell +\ccc{c} is found, it computes the indices \ccc{i}, \ccc{j}, \ccc{k} +and \ccc{l} of the vertices \ccc{u}, \ccc{v}, \ccc{w} and \ccc{t} in +\ccc{c}, in this order.} + +There is a method \ccc{has_vertex} in the cell class. The analogous +methods for facets are defined here. + +\ccMethod{bool has_vertex(const Facet & f, Vertex_handle v, int & j) const;} +{If \ccc{v} is a vertex of \ccc{f}, then \ccc{j} is the index of +\ccc{v} in the cell \ccc{f.first}, and the method returns \ccc{true}. +\ccPrecond{\ccVar.dimension()=3}} +\ccGlue +\ccMethod{bool has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const;} +{Same for facet \ccc{(c,i)}. Computes the index \ccc{j} of \ccc{v} in +\ccc{c}.} +\ccGlue +\ccMethod{bool has_vertex(const Facet & f, Vertex_handle v) const;} +{} +\ccGlue +\ccMethod{bool has_vertex(Cell_handle c, int i, Vertex_handle v) const;} +{Same as the first two methods, but these two methods do not return the +index of the vertex.} + +The following three methods test whether two facets have the same +vertices. + +\ccMethod{bool are_equal(const Facet & f, const Facet & g) const;} +{} +\ccGlue +\ccMethod{bool are_equal(Cell_handle c, int i, Cell_handle n, int j) const;} +{} +\ccGlue +\ccMethod{bool are_equal(const Facet & f, Cell_handle n, int j) const;} +{For these three methods: \ccPrecond{\ccVar.dimension()=3}.} + +\ccHeading{Flips} + +Two kinds of flips exist for a three-dimensional triangulation. They +are reciprocal. To be flipped, an edge must be incident to three +tetrahedra. During the flip, these three tetrahedra disappear and two +tetrahedra appear. Figure~\ref{TDS3-fig-flips}(left) shows the +edge that is flipped as bold dashed, and one of its three incident +facets is shaded. On the right, the facet shared by the two new +tetrahedra is shaded. + +%Flips are possible only if the tetrahedra to be created do not already +%exist. + +\begin{figure} +\begin{ccTexOnly} +\begin{center} +\includegraphics{TriangulationDS_3/flips} +\end{center} +\end{ccTexOnly} +\caption{Flips. +\label{TDS3-fig-flips}} +\begin{ccHtmlOnly} +
+Flips +
+\end{ccHtmlOnly} +\end{figure} + +The following methods guarantee the validity of the resulting 3D +combinatorial triangulation. Moreover the flip operations do not +invalidate the vertex handles, and only invalidate the cell +handles of the affected cells. + +\textit{Flips for a 2d triangulation are not implemented yet} + +\ccMethod{bool flip(Edge e);}{} +\ccGlue +\ccMethod{bool flip(Cell_handle c, int i, int j);} +{Before flipping, these methods check that edge \ccc{e=(c,i,j)} is +flippable (which is quite expensive). They return \ccc{false} or +\ccc{true} according to this test.} + +\ccMethod{void flip_flippable(Edge e);}{} +\ccGlue +\ccMethod{void flip_flippable(Cell_handle c, int i, int j);} +{Should be preferred to the previous methods when the edge is +known to be flippable. +\ccPrecond{The edge is flippable.}} + +\ccMethod{bool flip(Facet f);}{} +\ccGlue +\ccMethod{bool flip(Cell_handle c, int i);} +{Before flipping, these methods check that facet \ccc{f=(c,i)} is +flippable (which is quite expensive). They return \ccc{false} or +\ccc{true} according to this test.} + +\ccMethod{void flip_flippable(Facet f);}{} +\ccGlue +\ccMethod{void flip_flippable(Cell_handle c, int i);} +{Should be preferred to the previous methods when the facet is +known to be flippable. +\ccPrecond{The facet is flippable.}} + +\ccHeading{Insertions} +\ccThree{Vertex_handle}{tds.insert_in_facet()xxxxx}{} + +The following modifier member functions guarantee +the combinatorial validity of the resulting triangulation. + +\ccMethod{Vertex_handle insert_in_cell(Cell_handle c);} +{Creates a new vertex, inserts it in cell \ccc{c} and returns its handle. +The cell \ccc{c} is split into four new cells, each of these cells being +formed by the new vertex and a facet of \ccc{c}. +\ccPrecond{\ccVar.\ccc{dimension()} $= 3$ and \ccc{c} is a cell of \ccVar.}} + +\ccMethod{Vertex_handle insert_in_facet(const Facet & f);} +{Creates a new vertex, inserts it in facet \ccc{f} and returns its handle. +In dimension 3, the two incident cells are split into 3 new cells; +in dimension 2, the facet is split into 3 facets. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and \ccc{f} is a +facet of \ccVar.}} + +\ccMethod{Vertex_handle insert_in_facet(Cell_handle c, int i);} +{Creates a new vertex, inserts it in facet \ccc{i} of \ccc{c} and returns its +handle. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, $i \in \{0,1,2,3\}$ +in dimension~3, $i=3$ in dimension~2 and \ccc{(c,i)} is a facet of +\ccVar.}} + +\ccMethod{Vertex_handle insert_in_edge(Edge e);} +{Creates a new vertex, inserts it in edge \ccc{e} and returns its handle. +In dimension 3, all the +incident cells are split into 2 new cells; in dimension 2, the 2 +incident facets are split into 2 new facets; in dimension 1, the edge is +split into 2 new edges. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 1$ and \ccc{e} is an edge of +\ccVar.}} + +\ccMethod{Vertex_handle insert_in_edge(Cell_handle c, int i, int j);} +{Creates a new vertex, inserts it in edge $(i,j)$ of \ccc{c} and returns its +handle. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 1$. $i\neq j$, $i,j \in +\{0,1,2,3\}$ in dimension~3, $i,j \in \{0,1,2\}$ in dimension~2, $i,j +\in \{0,1\}$ in dimension~1 and \ccc{(c,i,j)} is an edge of \ccVar.}} + +\ccMethod{Vertex_handle + insert_increase_dimension(Vertex_handle star = Vertex_handle());} +{Transforms a triangulation of the sphere $S^d$ of $\R^{d+1}$ into the +triangulation of the sphere $S^{d+1}$ of $\R^{d+2}$ by adding a new vertex +\ccc{v}: +\ccc{v} is linked to all the vertices to triangulate one of the two +half-spheres of dimension $(d+1)$. Vertex \ccc{star} is used to +triangulate the second half-sphere (when there is an associated +geometric triangulation, \ccc{star} is in fact the vertex associated with +its infinite vertex). +See Figure~\ref{TDS3-fig-topo-insert_outside_affine_hull}.\\ +The numbering of the cells is such that, if \ccc{f} was a face of +maximal dimension in the initial triangulation, then \ccc{(f,v)} (in +this order) is the corresponding face in the new triangulation. +This method can be used to insert the first two vertices in an empty +triangulation.\\ +A handle to \ccc{v} is returned. +\ccPrecond{\ccVar.\ccc{dimension()} $= d < 3$. When +\ccVar.\ccc{number_of_vertices()} $>0$, $star \neq$ \ccc{Vertex_handle()} and +\ccc{star} is a vertex of \ccVar.}} + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{TriangulationDS_3_ref/topo-insert_outside_affine_hull} +\end{center} +\end{ccTexOnly} +\caption{\protect\ccc{insert_increase_dimension} (1-dimensional case). +\label{TDS3-fig-topo-insert_outside_affine_hull}} +\begin{ccHtmlOnly} +
+ +
+\end{ccHtmlOnly} +\end{figure} + +\ccMethod{template + Vertex_handle insert_in_hole(CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i);} +{Creates a new vertex by starring a hole. It takes an iterator range +[\ccc{cell_begin}; \ccc{cell_end}[ of \ccc{Cell_handles} which specifies a set +of connected cells (resp. facets in dimension 2) describing a hole. +(\ccc{begin}, \ccc{i}) is a facet (resp. an edge) on the boundary of the hole, +that is, \ccc{begin} belongs to the set of cells (resp. facets) previously +described, and \ccc{begin->neighbor(i)} does not. Then this function deletes +all the cells (resp. facets) describing the hole, creates a new vertex +\ccc{v}, and for each facet (resp. edge) on the boundary of the hole, creates +a new cell (resp. facet) with \ccc{v} as vertex. \ccc{v} is returned. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, the set of cells (resp. facets) +is connected, and its boundary is connected.}} + +\ccMethod{template + Vertex_handle insert_in_hole(CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv);} +{ Same as above, except that \ccc{newv} will be used as the new vertex, which + must have been allocated previously with e.g. \ccc{create_vertex}.} + +\ccHeading{Removal} + +\ccMethod{void remove_decrease_dimension(Vertex_handle v, Vertex_handle w = v);} +{This operation is the reciprocal of \ccc{insert_increase_dimension()}. +It transforms a triangulation of the sphere $S^d$ of $\R^{d+1}$ into the +triangulation of the sphere $S^{d-1}$ of $\R^{d}$ by removing the vertex +\ccc{v}. Delete the cells incident to \ccc{w}, keep the others. +\ccPrecond{\ccVar.\ccc{dimension()} $= d \geq -1$. +\ccVar.\ccc{degree(v)} $=$ \ccc{degree(w)} $=$ \ccVar.\ccc{number_of_vertices()} $-1$.} +} + +\ccMethod{Cell_handle remove_from_maximal_dimension_simplex(Vertex_handle v);} +{Removes \ccc{v}. The incident simplices of maximal dimension incident to +\ccc{v} are replaced by a single simplex of the same dimension. This +operation is exactly the reciprocal to \ccVar.\ccc{insert_in_cell(v)} in +dimension 3, \ccVar.\ccc{insert_in_facet(v)} in dimension 2, and +\ccVar.\ccc{insert_in_edge(v)} in dimension 1. +\ccPrecond{\ccVar.\ccc{degree(v)} $=$ \ccVar.\ccc{dimension()+1}.} +} + +\newpage + +\ccHeading{Dimension Manipulation} + +The following operation, \texttt{decrease\_dimension}, is necessary when the displacement of a vertex decreases +the dimension of the triangulation. + +\ccMethod{void decrease_dimension(Cell_handle c, int i);} +{The link of a vertex $v$ is formed by the facets +disjoint from $v$ that are included in the cells incident to $v$. When the link of \ccc{v = c->vertex(i)} contains all the other vertices, \ccc{decrease\_dimension} crushes the +triangulation of the sphere $S^d$ of $\R^{d+1}$ onto the +triangulation of the sphere $S^{d-1}$ of $\R^{d}$ formed by the link of \ccc{v} +augmented with the vertex \ccc{v} itself, for $d$==2,3; this one is placed on the facet \ccc{(c, i)} +(see Fig. \ref{TDS3-dim_down}). +\ccPrecond{ The dimension must be 2 or 3. The degree of \ccc{v} must be equal to the total number of vertices of the triangulation data structure minus 1.} +} + +\begin{figure} +\begin{ccTexOnly} +\begin{center} +\includegraphics[width=1.0\textwidth]{TriangulationDS_3_ref/tds-dim_down} +\end{center} +\end{ccTexOnly} +\caption{From an $S^d$ data structure to an $S^{d-1}$ data structure (top: $d==2$, bottom: $d==3$).\label{TDS3-dim_down}} +\begin{ccHtmlOnly} +
+Lowering dimension from 3D to 2D +
+\end{ccHtmlOnly} +\end{figure} + +\begin{ccAdvanced} +\ccHeading{Other modifiers} +The following modifiers can affect the validity of the triangulation +data structure. + +\ccMethod{void reorient();} +{Changes the orientation of all cells of the triangulation data structure. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 1$.}} + +\ccMethod{Vertex_handle create_vertex(const Vertex &v = Vertex());} +{Adds a copy of the vertex \ccc{v} to the triangulation data structure.} + +\ccMethod{Vertex_handle create_vertex(Vertex_handle v);} +{Creates a vertex which is a copy of the one pointed to by \ccc{v} +and adds it to the triangulation data structure.} + +\ccMethod{Cell_handle create_cell(const Cell &c = Cell());} +{Adds a copy of the cell \ccc{c} to the triangulation data structure.} + +\ccMethod{Cell_handle create_cell(Cell_handle c);} +{Creates a cell which is a copy of the one pointed to by \ccc{c} +and adds it to the triangulation data structure.} + +\ccMethod{Cell_handle create_cell(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3);} +{Creates a cell and adds it into the triangulation data +structure. Initializes the vertices of the cell, its neighbor handles +being initialized with the default constructed handle.} + +\ccMethod{Cell_handle create_cell( Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3);} +{Creates a cell, initializes its vertices and neighbors, and adds it +into the triangulation data structure.} + +\ccMethod{void delete_vertex( Vertex_handle v );} +{Removes the vertex from the triangulation data structure. +\ccPrecond{The vertex is a vertex of \ccVar.}} + +\ccMethod{void delete_cell( Cell_handle c );} +{Removes the cell from the triangulation data structure. +\ccPrecond{The cell is a cell of \ccVar.}} + +\ccMethod{template + void delete_vertices(VertexIt first, VertexIt last);} +{Calls \ccc{delete_vertex} over an iterator range of value type +\ccc{Vertex_handle}.} + +\ccMethod{template + void delete_cells(CellIt first, CellIt last);} +{Calls \ccc{delete_cell} over an iterator range of value type +\ccc{Cell_handle}.} + +\end{ccAdvanced} + +\ccHeading{Traversing the triangulation} +\ccThree{Facet_circulator}{tds.vertices_begin()()}{} + +\ccMethod{Cell_iterator cells_begin() const;} +{Returns \ccc{cells_end()} when \ccVar.\ccc{dimension()}~$<3$.} +\ccGlue +\ccMethod{Cell_iterator cells_end() const;}{} +\ccGlue +\ccMethod{Cell_iterator raw_cells_begin() const;} +{Low-level access to the cells, does not return \ccc{cells_end()} +when \ccVar.\ccc{dimension()}~$<3$.} +\ccGlue +\ccMethod{Cell_iterator raw_cells_end() const;}{} +\ccGlue +\ccMethod{Facet_iterator facets_begin() const;} +{Returns \ccc{facets_end()} when \ccVar.\ccc{dimension()}~$<2$.} +\ccGlue +\ccMethod{Facet_iterator facets_end() const;}{} +\ccGlue +\ccMethod{Edge_iterator edges_begin() const;} +{Returns \ccc{edges_end()} when \ccVar.\ccc{dimension()}~$<1$.} +\ccGlue +\ccMethod{Edge_iterator edges_end() const;}{} +\ccGlue +\ccMethod{Vertex_iterator vertices_begin() const;}{} +\ccGlue +\ccMethod{Vertex_iterator vertices_end() const;}{} + +\ccThree{Facet_circulator}{tds.inciden__cells}{} + +\ccHeading{Cell and facet circulators} +\ccThree{Facet_circulator}{tds.incident_facets(Cell_handle c, int i, int j)x}{} + +\ccMethod{Cell_circulator incident_cells(const Edge & e) const;} +{Starts at an arbitrary cell incident to \ccc{e}. +\ccPrecond{\ccVar.\ccc{dimension()}~$=3$}} +\ccGlue +\ccMethod{Cell_circulator incident_cells(Cell_handle c, int i, int j) const;} +{As above for edge \ccc{(i,j)} of \ccc{c}.} +\ccGlue +\ccMethod{Cell_circulator incident_cells(const Edge & e, Cell_handle start) const;} +{Starts at cell \ccc{start}. +\ccPrecond{\ccVar.\ccc{dimension()}~$=3$ and \ccc{start} is incident to +\ccc{e}.}} +\ccGlue +\ccMethod{Cell_circulator incident_cells(Cell_handle c, int i, int j, Cell_handle start) +const;} +{As above for edge \ccc{(i,j)} of \ccc{c}.} + +The following circulators on facets are defined only in dimension~3, +though facets are defined also in dimension~2: there are only two +facets sharing an edge in dimension~2. +\ccMethod{Facet_circulator incident_facets(Edge e) const;} +{Starts at an arbitrary facet incident to \ccc{e}. +\ccPrecond{\ccVar.\ccc{dimension()}~$=3$}} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Cell_handle c, int i, int j) const;} +{As above for edge \ccc{(i,j)} of \ccc{c}.} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Edge e, Facet start) const;} +{Starts at facet \ccc{start}. +\ccPrecond{\ccc{start} is incident to \ccc{e}.}} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Edge e, Cell_handle start, int f) const;} +{Starts at facet of index \ccc{f} in \ccc{start}.} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Cell_handle c, int i, int j, +Facet start) const;} +{As above for edge \ccc{(i,j)} of \ccc{c}.} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Cell_handle c, int i, int j, +Cell_handle start, int f) const;} +{As above for edge \ccc{(i,j)} of \ccc{c} and facet \ccc{(start,f)}.} + +\ccHeading{Traversal of the incident cells, facets and edges, and the +adjacent vertices of a given vertex} + +\ccThree{void_circulator}{tds.facets_begin()toto}{} + +\ccMethod{template + OutputIterator + incident_cells(Vertex_handle v, OutputIterator cells) const;} +{Copies the \ccc{Cell_handle}s of all cells incident to \ccc{v} to the +output iterator \ccc{cells}. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + incident_facets(Vertex_handle v, OutputIterator facets) const;} +{Copies the \ccc{Facet}s incident to \ccc{v} to the output iterator +\ccc{facets}. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $>1$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + incident_edges(Vertex_handle v, OutputIterator edges) const;} +{Copies all \ccc{Edge}s incident to \ccc{v} to the +output iterator \ccc{edges}. Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $>0$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + adjacent_vertices(Vertex_handle v, OutputIterator vertices) const;} +{Copies the \ccc{Vertex_handle}s of all vertices adjacent to \ccc{v} to the +output iterator \ccc{vertices}. If \ccVar.\ccc{dimension()} $<0$, then do +nothing. Returns the resulting output iterator. +\ccPrecond{\ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{size_type degree(Vertex_handle v) const;} +{Returns the degree of a vertex, that is, the number of incident vertices. +\ccPrecond{\ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccHeading{Traversal between adjacent cells} +\ccThree{Vertex_handle}{mirror_vertex(Cell_handle c, int i)x}{} + +\ccMethod{int mirror_index(Cell_handle c, int i) const;} +{Returns the index of \ccc{c} in its $i^{th}$ neighbor. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{Vertex_handle mirror_vertex(Cell_handle c, int i) const;} +{Returns the vertex of the $i^{th}$ neighbor of \ccc{c} that is opposite to +\ccc{c}. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{Facet mirror_facet(Facet f) const;} +{Returns the same facet seen from the other adjacent cell.} + + +\begin{ccDebug} +\ccHeading{Checking} + +\ccMethod{bool is_valid(bool verbose = false) const;} +{Checks the combinatorial validity of the triangulation by checking +the local validity of all its cells and vertices (see functions below). +(See Section~\ref{TDS3-sec-intro}.) Moreover, the Euler relation is +tested.\\ +When \ccc{verbose} is set to \ccc{true}, messages are printed to give +a precise indication on the kind of invalidity encountered.} + +\ccMethod{bool is_valid(Vertex_handle v, bool verbose = false) const;} +{Checks the local validity of the adjacency relations of the triangulation. +It also calls the \ccc{is_valid} member function of the vertex. +When \ccc{verbose} is set to \ccc{true}, messages are printed to give +a precise indication on the kind of invalidity encountered.} + +\ccMethod{bool is_valid(Cell_handle c, bool verbose = false) const;} +{Checks the local validity of the adjacency relations of the triangulation. +It also calls the \ccc{is_valid} member function of the cell. +When \ccc{verbose} is set to \ccc{true}, messages are printed to give +a precise indication on the kind of invalidity encountered.} + +\end{ccDebug} + +\ccHeading{I/O} + +\ccFunction{istream& operator>> + (istream& is, TriangulationDataStructure_3 & tds);} +{Reads a combinatorial triangulation from \ccc{is} and assigns it to \ccc{tds}} + +\ccFunction{ostream& operator<< + (ostream& os, const TriangulationDataStructure_3 & tds);} +{Writes \ccc{tds} into the stream \ccc{os}} + +The information stored in the \ccc{iostream} is: +the dimension, the number of vertices, the number of cells, +the indices of the vertices of each cell, then the indices of the +neighbors of each cell, where the index corresponds to the preceding +list of cells. When dimension $<$ 3, the same information is stored +for faces of maximal dimension instead of cells. + +\ccHasModels + +\ccc{CGAL::Triangulation_data_structure_3} + +\ccSeeAlso + +\ccc{TriangulationDataStructure_3::Vertex}\\ +\ccc{TriangulationDataStructure_3::Cell} + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_data_structure_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_data_structure_3.tex new file mode 100644 index 00000000000..748d00587e8 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_data_structure_3.tex @@ -0,0 +1,82 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_data_structure_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationdatastructureRev}{$Id$} +\RCSdefDate{\RCSTriangulationdatastructureDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_data_structure_3} + +\ccDefinition +The class \ccc{Triangulation_data_structure_3} stores a 3D-triangulation data +structure and provides the optional +geometric functionalities to be used as a parameter for a +3D-geometric triangulation (see Chapter~\ref{chapter-Triangulation3}). + +The vertices and cells are stored in two nested containers, which are +implemented using \ccc{CGAL::Compact_container}. The class may offer some +flexibility for the choice of container in the future, in the form of +additional template parameters. + +\ccInclude{CGAL/Triangulation_data_structure_3.h} + +\ccParameters +It is parameterized by base classes for vertices and cells which have to match +the requirements for the concepts \ccc{TriangulationDSCellBase_3} and +\ccc{TriangulationDSVertexBase_3} respectively +\lcTex{(see \ccRefPage{TriangulationDSCellBase_3} +and \ccRefPage{TriangulationDSVertexBase_3})}. + +They have the default values \ccc{Triangulation_ds_vertex_base_3<>} and +\ccc{Triangulation_ds_cell_base_3<>} respectively. + +\ccIsModel \ccc{TriangulationDataStructure_3} + +\ccInheritsFrom{\ccc{CGAL::Triangulation_utils_3}} + +The class \ccc{Triangulation_utils_3} defines basic computations on +indices of vertices and neighbors of cells. + +\begin{ccAdvanced} + +\ccCreationVariable{tds} + +In addition to the interface documented in the concept, the class offers the +following types and functions. + +\ccTypes + +\ccTypedef{typedef CGAL::Compact_container Vertex_range;}{Vertex container type.} +\ccGlue +\ccTypedef{typedef CGAL::Compact_container Cell_range;}{Cell container type.} + +\ccOperations + +\ccMethod{Cell_range & cells() const;} +{Returns a reference to the container of cells.} +\ccGlue +\ccMethod{Cell_range & cells();} +{Returns a reference to the container of cells.} +\ccGlue +\ccMethod{Vertex_range & vertices() const;} +{Returns a reference to the container of vertices.} +\ccGlue +\ccMethod{Vertex_range & vertices();} +{Returns a reference to the container of vertices.} + +\end{ccAdvanced} + +\ccSeeAlso + +\ccc{CGAL::Triangulation_ds_vertex_base_3}\\ +\ccc{CGAL::Triangulation_ds_cell_base_3}\\ +\ccc{CGAL::Triangulation_vertex_base_with_info_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_info_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_ds_cell_base_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_ds_cell_base_3.tex new file mode 100644 index 00000000000..3d1f6d7e4af --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_ds_cell_base_3.tex @@ -0,0 +1,47 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_cell_base_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationcellbaseRev}{$Id$} +\RCSdefDate{\RCSTriangulationcellbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_ds_cell_base_3<>} + +\ccDefinition + +The class \ccc{Triangulation_ds_cell_base_3} is a model for the concept +\ccc{TriangulationDSCellBase_3} to be used by +\ccc{Triangulation_data_structure_3}. + +% Note : this is commented as it's not kosher to mention geometry in the TDS. +% +% It also provides a template member function \ccc{circumcenter()} which allows +% it to be used as \ccc{TriangulationCellBase} in the +% \ccc{Delaunay_triangulation_3} class when the \ccc{dual()} member function is +% called. + +\ccInclude{CGAL/Triangulation_ds_cell_base_3.h} + +\ccIsModel + +\ccc{TriangulationDSCellBase_3} + +% \ccCreationVariable{c} +% +% \ccMethod{template Traits::Point_3 circumcenter( +% const Traits>) const;} +% {Returns the circumcenter.} + +\ccSeeAlso + +\ccc{CGAL::Triangulation_cell_base_3}\\ +\ccc{CGAL::Triangulation_ds_vertex_base_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_info_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_ds_vertex_base_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_ds_vertex_base_3.tex new file mode 100644 index 00000000000..eb5d340326e --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_ds_vertex_base_3.tex @@ -0,0 +1,44 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_vertex_base_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationvertexbaseRev}{$Id$} +\RCSdefDate{\RCSTriangulationvertexbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_ds_vertex_base_3<>} + +\ccDefinition + +The class \ccc{Triangulation_ds_vertex_base_3} can be used as the base vertex +for a 3D-triangulation data structure, it is a model of the concept +\ccc{TriangulationDSVertexBase_3}. + +Note that if the triangulation data structure is used as a parameter of a +geometric triangulation (Section~\ref{TDS3-sec-design} and +Chapter~\ref{chapter-Triangulation3}), then the vertex base class has to +fulfill additional geometric requirements, i.e. it has to be a model of the +concept \ccc{TriangulationVertexBase_3}. + +This base class can be used directly or can serve as a base to derive +other base classes with some additional attributes (a color for +example) tuned for a specific application. + +\ccInclude{CGAL/Triangulation_ds_vertex_base_3.h} + +\ccIsModel + +\ccc{TriangulationDSVertexBase_3} + +\ccSeeAlso + +\ccc{CGAL::Triangulation_vertex_base_3}\\ +\ccc{CGAL::Triangulation_ds_cell_base_3}\\ +\ccc{CGAL::Triangulation_vertex_base_with_info_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_utils_3.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_utils_3.tex new file mode 100644 index 00000000000..83127e6b5dc --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/Triangulation_utils_3.tex @@ -0,0 +1,61 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_utils_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationutilsRev}{$Id$} +\RCSdefDate{\RCSTriangulationutilsDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_utils_3} + +\ccDefinition + +The class \ccRefName\ defines operations on the indices of vertices +and neighbors within a cell. + +\ccInclude{CGAL/Triangulation_utils_3.h} + +\ccOperations + +\ccThree{unsigned int}{ccw(unsigned int i)toto}{} + +\ccFunction{unsigned int next_around_edge(unsigned int i, + unsigned int j) const;} +{In dimension~3, index of the neighbor \ccc{n} that is next to the current cell, +when turning positively around an oriented edge whose endpoints are +indexed \ccc{i} and \ccc{j}. According to the usual numbering of +vertices and neighbors in a given cell, it is also the index of the vertex +opposite to this neighbor \ccc{n}. (see Figure~\ref{Triangulation3-fig-utils}). +\ccPrecond{\ccc{( i < 4 ) && ( j < 4 ) && ( i != j )}.}} + +\ccFunction{unsigned int ccw(unsigned int i) const;} +{Has a meaning only in dimension~2.\\ + Computes the index of the vertex that is next to the vertex numbered +\ccc{i} in counterclockwise direction. (see +Figure~\ref{Triangulation3-fig-utils}). +\ccPrecond{\ccc{i<3}.}} +\ccGlue +\ccFunction{unsigned int cw(unsigned int i) const;} +{Same for clockwise.} + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{TriangulationDS_3_ref/utils} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+Operations on indices +
+\end{ccHtmlOnly} +\caption{Operations on indices. +\label{Triangulation3-fig-utils}} +\end{figure} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/flips.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/flips.gif new file mode 100644 index 00000000000..60156fcaddd Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/flips.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/flips.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/flips.pdf new file mode 100644 index 00000000000..870912cc86d Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/flips.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/intro.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/intro.tex new file mode 100644 index 00000000000..58046262cef --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/intro.tex @@ -0,0 +1,75 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_data_structure/intro.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationcellRev}{$Id$} +\RCSdefDate{\RCSTriangulationcellDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ +%\clearpage +%\section{Reference pages for 3D-Triangulation data structure} +\ccRefChapter{3D Triangulation Data Structure} +\ccChapterAuthor{Sylvain Pion \and Monique Teillaud} + +The triangulation data structure is able to represent a +triangulation of a topological sphere $S^d$ of $\R^{d+1}$, for +$d \in \{-1,0,1,2,3\}$. (See~\ref{TDS3-sec-intro}.) + +The vertex class of a 3D-triangulation data structure must define +a number of types and operations. +The requirements that are of geometric nature are required only when +the triangulation data structure is used as a layer for the geometric +triangulation classes. (See Section~\ref{TDS3-sec-design}.) + +The cell class of a triangulation data structure stores +four handles to its four vertices and four handles to its four +neighbors. The vertices are indexed 0, 1, 2, and 3 in a consistent order. +The neighbor indexed $i$ lies opposite to vertex \ccc{i}. + +In degenerate dimensions, cells are used to store faces of maximal +dimension: in dimension~2, each cell represents only one +facet of index 3, and 3 edges $(0,1)$, $(1,2)$ and $(2,0)$; in +dimension~1, each cell represents one edge $(0,1)$. (See +Section~\ref{TDS3-sec-intro}.) + + +\section{Classified Reference Pages} + +\subsection*{Concepts} + +\ccRefConceptPage{TriangulationDataStructure_3} + +\ccRefConceptPage{TriangulationDataStructure_3::Cell} \\ +\ccRefConceptPage{TriangulationDataStructure_3::Vertex} + +\ccRefConceptPage{TriangulationDSCellBase_3} \\ +\ccRefConceptPage{TriangulationDSVertexBase_3} + +\subsection*{Classes} + +\ccRefIdfierPage{CGAL::Triangulation_data_structure_3} + +This class is a model for the concept of the 3D-triangulation data +structure \ccc{TriangulationDataStructure_3}. +It is templated by base classes for vertices and cells. + +\cgal\ provides base vertex classes and base cell classes: + +\ccRefIdfierPage{CGAL::Triangulation_ds_cell_base_3<>}\\ +\ccRefIdfierPage{CGAL::Triangulation_ds_vertex_base_3<>}\\ +\ccRefIdfierPage{CGAL::Triangulation_cell_base_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_vertex_base_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_hierarchy_vertex_base_3} + +\subsubsection*{Helper Classes} + +\ccRefIdfierPage{CGAL::Triangulation_utils_3} + +It defines operations on the indices of vertices and neighbors within +a cell of a triangulation. + + + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/main.tex b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/main.tex new file mode 100644 index 00000000000..95dd17af165 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/main.tex @@ -0,0 +1,19 @@ +% +------------------------------------------------------------------------+ +% | CBP Reference Manual: main.tex +% +------------------------------------------------------------------------+ +% | Automatically generated driver file for the reference manual chapter +% | of this package. Do not edit manually, you may loose your changes. +% +------------------------------------------------------------------------+ + +\input{TriangulationDS_3_ref/intro.tex} + +\input{TriangulationDS_3_ref/TriangulationDataStructure_3.tex} +\input{TriangulationDS_3_ref/Tds_cell_3.tex} +\input{TriangulationDS_3_ref/Tds_vertex_3.tex} +\input{TriangulationDS_3_ref/TriangulationDSCellBase_3.tex} +\input{TriangulationDS_3_ref/TriangulationDSVertexBase_3.tex} +\input{TriangulationDS_3_ref/Triangulation_data_structure_3.tex} +\input{TriangulationDS_3_ref/Triangulation_ds_cell_base_3.tex} +\input{TriangulationDS_3_ref/Triangulation_ds_vertex_base_3.tex} +\input{TriangulationDS_3_ref/Triangulation_utils_3.tex} + diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.eps b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.eps new file mode 100644 index 00000000000..e7144ce252f --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.eps @@ -0,0 +1,575 @@ +%!PS-Adobe-3.0 EPSF-3.0 +%%BoundingBox: 78 304 378 515 +%%HiResBoundingBox: 78.650000 304.112109 377.250000 514.150000 +%................................... +%%Creator: GPL Ghostscript 857 (epswrite) +%%CreationDate: 2010/04/26 13:46:43 +%%DocumentData: Clean7Bit +%%LanguageLevel: 2 +%%EndComments +%%BeginProlog +% This copyright applies to everything between here and the %%EndProlog: +% Copyright (C) 2007 artofcode LLC, Benicia, CA. All rights reserved. +%%BeginResource: procset GS_epswrite_2_0_1001 +/GS_epswrite_2_0_1001 80 dict dup begin +/PageSize 2 array def/setpagesize{ PageSize aload pop 3 index eq exch +4 index eq and{ pop pop pop}{ PageSize dup 1 +5 -1 roll put 0 4 -1 roll put dup null eq {false} {dup where} ifelse{ exch get exec} +{ pop/setpagedevice where +{ pop 1 dict dup /PageSize PageSize put setpagedevice} +{ /setpage where{ pop PageSize aload pop pageparams 3 {exch pop} repeat +setpage}if}ifelse}ifelse}ifelse} bind def +/!{bind def}bind def/#{load def}!/N/counttomark # +/rG{3{3 -1 roll 255 div}repeat setrgbcolor}!/G{255 div setgray}!/K{0 G}! +/r6{dup 3 -1 roll rG}!/r5{dup 3 1 roll rG}!/r3{dup rG}! +/w/setlinewidth #/J/setlinecap # +/j/setlinejoin #/M/setmiterlimit #/d/setdash #/i/setflat # +/m/moveto #/l/lineto #/c/rcurveto # +/p{N 2 idiv{N -2 roll rlineto}repeat}! +/P{N 0 gt{N -2 roll moveto p}if}! +/h{p closepath}!/H{P closepath}! +/lx{0 rlineto}!/ly{0 exch rlineto}!/v{0 0 6 2 roll c}!/y{2 copy c}! +/re{4 -2 roll m exch dup lx exch ly neg lx h}! +/^{3 index neg 3 index neg}! +/f{P fill}!/f*{P eofill}!/s{H stroke}!/S{P stroke}! +/q/gsave #/Q/grestore #/rf{re fill}! +/Y{P clip newpath}!/Y*{P eoclip newpath}!/rY{re Y}! +/|={pop exch 4 1 roll 1 array astore cvx 3 array astore cvx exch 1 index def exec}! +/|{exch string readstring |=}! +/+{dup type/nametype eq{2 index 7 add -3 bitshift 2 index mul}if}! +/@/currentfile #/${+ @ |}! +/B{{2 copy string{readstring pop}aload pop 4 array astore cvx +3 1 roll}repeat pop pop true}! +/Ix{[1 0 0 1 11 -2 roll exch neg exch neg]exch}! +/,{true exch Ix imagemask}!/If{false exch Ix imagemask}!/I{exch Ix image}! +/Ic{exch Ix false 3 colorimage}! +/F{/Columns counttomark 3 add -2 roll/Rows exch/K -1/BlackIs1 true>> +/CCITTFaxDecode filter}!/FX{<+ +, +1395 4661 58 64 /2O +$C +-,RJ0cQF6,"1XK6;*,e2Q-Xhg^!O5QCKXpAb$)pAO`6hdjRZ#AlQZqqHI8 +gU?L]A=[RGL6]0$(ePW!8f36d'Gr4~> +, +12 w +2020.89 4825.31 491.13 0 S +2512.02 4825.31 -100 33.33 0 -66.66 f* +2512.02 4825.31 -100 33.33 0 -66.66 H +S +4 w +255 0 r6 +804.53 4472.31 637.23 646.34 S +1441.76 5118.65 641.79 -646.34 S +2083.55 4472.31 -1279.02 0 S +1287.01 4631.62 -477.93 -159.31 S +1441.76 4795.48 -632.68 -323.17 S +1605.62 4627.07 -801.09 -154.76 S +1441.76 4790.93 0 327.72 S +1441.76 4790.93 637.24 -314.07 S +1601.07 4627.07 482.48 -154.76 S +K +1823 4904 53 62 /7J +$C +-,kH?HkM'*-_U)g6Lpe%+S.l(e'dJFIo[)VYX-_V" +, +1884 4904 40 45 /2U +$C +.E%bXLdAn"*BGA+kR`&+\d@V,3aU>`Zp3"7%<:k97S`pY?aoE@>?bfG>VrN!9#kZ` +, +1936 4904 40 45 /7N +$C +.De@QKH)-!_K8(,i.8HGkr+aVPLcfe&+mX:s1A0mg&&Is!C@K_,UgSE~> +, +1980 4905 51 44 /2Y +$C +4:PMup85+ps8W-!s6p!&^V0"!p7<2`@u"]IL(..DHo9d-@79<)~> +, +2041 4904 2U , +2085 4904 54 45 /0C +$C +,6C.B@-S;2QpI_jU)&Xml5l-m%nkCOs8MnEq[]q.+QR?i+0i`$_<"d3OW^q\5O0R8;d+ZDL#A7H +euU9.6'+M8~> +, +2145 4904 40 45 /3C +$C +0$OLI"@G=+K>]qA+bVs#Hm%:<=1s)i^9h[!q8KB$@u%_oqE9-LfBI8&I<\Ys8LU, +L).UZa*;sIOO-15%b(~> +, +2198 4904 2U , +3.98 w +2250.18 4906.63 31.38 0 S +2280 4904 7J , +2340 4905 39 61 /0G +$C +0H,'5C/^2ns8W-!s8W-!s8SPtQ2fR!q+flRl2U-q@6a~> +, +2384 4905 53 44 /3G +$C +0Fi%5fHiB'[K!/YBrUY-8HcC"s8W-!s8W-!s8W-!s8W-!s8T_2s53_JrAEE\^b2)&O!0fMaALF[ +R^CFV+bU\/~> +, +2444 4904 2U , +2489 4905 53 44 /0K +$C +2@[q9c)/7j9h>F3#QOi(s8W-!s8W-!s8V!Vn,E9^^C=ej\4VO<>]ms?KqQp]Jq*~> +, +2549 4904 3C , +2601 4905 0G , +2654 4904 41 45 /3K +$C +2$jBq&9+0F:5E8!&8m\V60U?):$LtiJ(ErCs8W,R9E3`&[^WB@['mC[9#Cs;X&-[@$n*f+~> +, +2698 4905 0K , +3078 4685 7D , +4 w +255 0 r6 +2470.44 4481.41 637.23 646.34 S +3107.67 5127.75 641.79 -646.34 S +20 w +255 0 r3 +3266.98 4640.72 -314.06 4.55 S +4 w +255 0 r6 +2952.92 4640.72 -477.93 -159.31 S +3266.98 4636.17 482.48 -154.76 S +K +1456.76 5104.99 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +6 w +1456.76 5104.99 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +1456.76 4790.93 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +1456.76 4790.93 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +819.53 4467.76 m +0 8.28 -6.71 15 -15 15 c +-8.29 0 -15 -6.72 -15 -15 c +0 -8.28 6.71 -15 15 -15 c +8.29 0 15 6.72 15 15 c +f* +819.53 4467.76 m +0 8.28 -6.71 15 -15 15 c +-8.29 0 -15 -6.72 -15 -15 c +0 -8.28 6.71 -15 15 -15 c +8.29 0 15 6.72 15 15 c +h +S +1302.01 4631.62 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +1302.01 4631.62 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +1616.07 4627.07 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +1616.07 4627.07 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +2098.55 4467.76 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +2098.55 4467.76 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +2494.54 4481.41 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +2494.54 4481.41 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +3127.22 5123.2 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +3127.22 5123.2 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +3769.01 4481.41 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +3769.01 4481.41 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +3286.53 4636.17 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +3286.53 4636.17 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +3131.77 4645.27 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +3131.77 4645.27 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +2967.91 4649.82 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +2967.91 4649.82 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +1871 4703 43 45 /0Q +$C +.E;Q$M.<32FIT=Z]f0<-hqrp5gOHumhtsmtpV"?1n!CZ@pV6`Wh5C-rn$fL$Fgp]oR^$*OK2;~> +, +1953 4723 51 23 /3Q +$C +1BuQTrMrfqR=f?;Iat@~> +, +2046 4703 41 45 /0U +$C +2$jBq&MFWG"s"i(W,G?jL@j;+n*O<=s53hQrqlHGb'.\eG4#1]GBUlYlGHh?6OY7L<#@"~> +, +2097 4731 41 7 /3U +$C +/fM+]qc9?~> +, +2150 4710 41 49 /0Y +$C +02Qa3nEnkI_m^%9E5Sp=\7+$/h1lHW%`=%g_dUE8WBsPu+JC7l&tkp%#uFHMV$JPIJtT)OC;R3J~> +, +2194 4704 52 43 /3Y +$C +.`Y?6q(_QWl0EiJFoS?)rf_j1-NEp:s7Df\kr8XjDuZWjkCJ58@[_fGdng~> +, +2254 4703 2U , +2299 4704 2Y , +2351 4703 47 56 /1C +$C +.0P5-#Wd(ljA0k/DbjHbn,NEqa8c2>s8W-!kCZg-rm]L`s8W,d5Q~> +, +2411 4703 2U , +2456 4704 52 43 /4C +$C +49QQ''\!*UR[j`8>?dqAXejV& +, +2524 4696 30 77 /1G +$C +.d0V@9!kNH<2_9GWHqOO>ut%XV>W(IV>pSqs7ZKi^\7Zq]C+RcDg/[._maO$[sMP^C&~> +, +2568 4704 0G , +2620 4696 29 77 /4G +$C +2c+aGgc&ZrLUV0W^M_m%IG]8Bs0r%%s8W,Is8$*Np!n1j=1Pq#Uq.SuG=Kk^~> +, +1010.37 3327.85 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.28 0 15 6.71 15 15 c +f* +1010.37 3327.85 m +0 8.28 -6.72 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.28 0 15 6.71 15 15 c +h +S +1401.81 3796.67 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.29 0 15 6.71 15 15 c +f* +1401.81 3796.67 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.29 0 15 6.71 15 15 c +h +S +1483.74 3104.82 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.29 0 15 6.71 15 15 c +f* +1483.74 3104.82 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.29 0 15 6.71 15 15 c +h +S +1720.43 3587.29 m +0 8.29 -6.72 15 -15 15 c +-8.29 0 -15 -6.71 -15 -15 c +0 -8.28 6.71 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +1720.43 3587.29 m +0 8.29 -6.72 15 -15 15 c +-8.29 0 -15 -6.71 -15 -15 c +0 -8.28 6.71 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +20 w +255 0 r3 +1391.36 3792.12 77.38 -687.3 S +[ 40 ] 0 d +995.37 3318.74 710.06 264 S +[ ] 0 d +12 w +K +2007.23 3664.64 491.13 0 S +2498.36 3664.64 -100 33.33 0 -66.67 f* +2498.36 3664.64 -100 33.33 0 -66.67 H +S +1810 3743 7J , +1870 3743 2U , +1922 3743 7N , +1967 3744 2Y , +2027 3743 2U , +2071 3743 0C , +2132 3743 3C , +2184 3743 2U , +3.98 w +2236.53 3745.96 31.38 0 S +2266 3743 7J , +2326 3744 0G , +2371 3744 3G , +2431 3743 2U , +2475 3744 0K , +2535 3743 3C , +2588 3744 0G , +2640 3743 3K , +2684 3744 0K , +1857 3543 0Q , +1939 3563 3Q , +2032 3543 0U , +2084 3571 3U , +2136 3550 0Y , +2180 3544 3Y , +2241 3543 2U , +2285 3544 2Y , +2337 3543 1C , +2398 3543 2U , +2442 3544 4C , +2510 3536 1G , +2555 3544 0G , +2607 3536 4G , +2790.07 3282.33 m +0 8.29 -6.72 15 -15 15 c +-8.29 0 -15 -6.71 -15 -15 c +0 -8.28 6.71 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +6 w +2790.07 3282.33 m +0 8.29 -6.72 15 -15 15 c +-8.29 0 -15 -6.71 -15 -15 c +0 -8.28 6.71 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +3186.06 3295.99 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.29 0 15 6.71 15 15 c +f* +3186.06 3295.99 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.29 0 15 6.71 15 15 c +h +S +3263.44 3059.3 m +0 8.29 -6.72 15 -15 15 c +-8.28 0 -15 -6.71 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +3263.44 3059.3 m +0 8.29 -6.72 15 -15 15 c +-8.28 0 -15 -6.71 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +3500.13 3541.77 m +0 8.29 -6.72 15 -15 15 c +-8.28 0 -15 -6.71 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +f* +3500.13 3541.77 m +0 8.29 -6.72 15 -15 15 c +-8.28 0 -15 -6.71 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.28 0 15 6.72 15 15 c +h +S +1253 3797 7D , +1281 3501 2O , +3117 3329 7D , +4 w +255 0 r6 +1385.23 4287.04 -393.06 -962.31 S +1471.07 3103.35 -76.81 1188.21 S +K +1401.81 4292.8 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.29 0 15 6.72 15 15 c +f* +6 w +1401.81 4292.8 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.28 6.72 -15 15 -15 c +8.29 0 15 6.72 15 15 c +h +S +4 w +255 0 r6 +3255.64 3049.13 -87.93 1196.67 S +K +3181.51 4247.28 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.29 0 15 6.71 15 15 c +f* +6 w +3181.51 4247.28 m +0 8.28 -6.71 15 -15 15 c +-8.28 0 -15 -6.72 -15 -15 c +0 -8.29 6.72 -15 15 -15 c +8.29 0 15 6.71 15 15 c +h +S +cleartomark end end pagesave restore + showpage +%%PageTrailer +%%Trailer +%%Pages: 1 diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.gif new file mode 100644 index 00000000000..4ba7983bc8e Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.pdf new file mode 100644 index 00000000000..ec0320f7b42 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.png b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.png new file mode 100644 index 00000000000..63d84f107e3 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/tds-dim_down.png differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/topo-insert_outside_affine_hull.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/topo-insert_outside_affine_hull.gif new file mode 100644 index 00000000000..823ab679010 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/topo-insert_outside_affine_hull.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/topo-insert_outside_affine_hull.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/topo-insert_outside_affine_hull.pdf new file mode 100644 index 00000000000..59d4346a34f Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/topo-insert_outside_affine_hull.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.gif b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.gif new file mode 100644 index 00000000000..26257631796 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.pdf b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.pdf new file mode 100644 index 00000000000..fb50d3ff6fe Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.xml b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.xml new file mode 100644 index 00000000000..d29192cbeeb --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/TriangulationDS_3_ref/utils.xml @@ -0,0 +1,80 @@ + + + + + + +-141.856 157.46 m +-174.947 77.6599 l + + +-174.947 77.6599 m +-126.212 129.86 l +-188.786 146.06 l +-174.947 77.6599 l + + +-205.031 168.86 m +8.06774 0 0 8.06774 -197.811 165.26 -192.098 170.957 a + + +-174.947 77.6599 m +-188.786 146.06 l +-131.026 99.2599 l +-174.947 77.6599 l + + +-188.786 146.06 m +-126.212 129.86 l +-131.026 99.2599 l + + +-174.947 77.6599 m +-126.212 129.86 l + + +-174.947 77.6599 m +-188.786 146.06 l + +vertex $i$ +vertex $j$ +vertex \textit{next\_around\_edge(i,j)} + +facet \textit{next\_around\_edge(i,j)} + +-122.602 143.66 m +-138.847 126.26 l + + +-188.786 146.06 m +-126.212 129.86 l +-141.856 157.46 l +-188.786 146.06 l + +cell \textit{next\_around\_edge(i,j)} + +-139.449 171.26 m +-151.482 149.66 l + + +-210.446 93.2599 m +-149.677 99.2599 l + +current cell +dimension 3 + +34.4326 153.26 m +-2.87072 79.4599 l +81.9643 89.0599 l +34.4326 153.26 l + +vertex $i$ + +31.4243 110.06 m +8.06774 0 0 8.06774 38.6443 106.46 44.3569 112.157 a + +vertex \textit{ccw(i)} +vertex \textit{cw(i)} +dimension 2 + + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/PkgDescription.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/PkgDescription.tex new file mode 100644 index 00000000000..9e7b9dccc81 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/PkgDescription.tex @@ -0,0 +1,24 @@ + +\begin{ccPkgDescription}{3D Triangulations\label{Pkg:Triangulation3}} +\ccPkgHowToCiteCgal{cgal:pt-t3-10} +\ccPkgSummary{ +This package allows to build and handle +triangulations for point sets in three dimensions. +Any \cgal\ triangulation covers the convex hull of its +vertices. Triangulations are build incrementally +and can be modified by insertion, displacements or removal of vertices. +They offer point location facilities. + +The package provides plain triangulation (whose faces +depends on the insertion order of the vertices) and +Delaunay triangulations. Regular triangulations are +also provided for sets of weighted points. +Delaunay and regular +triangulations offer nearest neighbor queries +and primitives to build the dual Voronoi and power diagrams.} + +%\ccPkgDependsOn{} +\ccPkgIntroducedInCGAL{2.1} +\ccPkgLicense{\ccLicenseQPL} +\ccPkgIllustration{Triangulation_3/fig/twotets.png}{Triangulation_3/fig/Delaunay_3.jpg} +\end{ccPkgDescription} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/Triang3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/Triang3.tex new file mode 100644 index 00000000000..73a9a5acb39 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/Triang3.tex @@ -0,0 +1,810 @@ +% file : doc_tex/basic/Triangulation_3/Triang3.tex +% revision : $Id$ +% +% author(s) : Monique Teillaud + +\begin{ccTexOnly} +%\vspace*{-1cm} +\begin{center} +\includegraphics[width=15cm]{Triangulation_3/triangulation3} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +3D triangulation picture +\end{ccHtmlOnly} + +The basic 3D-triangulation class of \cgal\ is primarily designed to +represent the triangulations of a set of points $A$ in $\R^3$. It is +a partition of the convex hull of {$A$} into tetrahedra whose vertices +are the points of {$A$}. Together with the unbounded cell having the +convex hull boundary as its frontier, the triangulation forms a +partition of $\R^3$. Its cells ($3$-faces) are such that two cells +either do not intersect or share a common facet ($2$-face), edge +($1$-face) or vertex ($0$-face). + +\section{Representation\label{Triangulation3-sec-intro}} + +In order to deal +only with tetrahedra, which is convenient for many applications, the +unbounded cell can be subdivided into tetrahedra by considering that +each convex hull facet is incident to an \ccc{infinite cell} having as +fourth vertex an auxiliary vertex called the \ccc{infinite vertex}. In +that way, each facet is incident to exactly two cells and special cases +at the boundary of the convex hull are simple to deal with. + +The class \ccc{Triangulation_3} of \cgal\ implements this +point of view and therefore considers the triangulation of the set +of points as a set of finite and infinite tetrahedra. Notice that the +infinite vertex has no significant coordinates and that no +geometric predicate can be applied on it. + +A triangulation is a collection of vertices and cells that are linked +together through incidence and adjacency relations. Each cell gives +access to its four incident vertices and to its four adjacent +cells. Each vertex gives access to one of its incident cells. + +The four vertices of a cell are indexed with 0, 1, 2 and 3 in positive +orientation, the positive orientation being defined by the orientation +of the underlying Euclidean space $\R^3$ (see +Figure~\ref{Triangulation3-fig-orient}). The neighbors of a cell are also +indexed with 0, 1, 2, 3 in such a way that the neighbor indexed by $i$ +is opposite to the vertex with the same index. + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{Triangulation_3/orient} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+Orientation of a cell 
+(3-dimensional case) +
+\end{ccHtmlOnly} +\caption{Orientation of a cell (3-dimensional case). +\label{Triangulation3-fig-orient}} +\end{figure} + +As in the underlying combinatorial triangulation (see +Chapter~\ref{chapter-TDS3}), edges ($1$-faces) and facets ($2$-faces) +are not explicitly +represented: a facet is given by a cell and an index (the facet +\ccc{i} of a cell \ccc{c} is the facet of \ccc{c} that is opposite to +the vertex with index \ccc{i}) and an edge is given by a cell and two +indices (the edge \ccc{(i,j)} of a cell \ccc{c} is the edge whose +endpoints are the vertices of \ccc{c} with indices \ccc{i} and +\ccc{j}). See Figure~\ref{TDS3-fig-repres}. + +\paragraph{Degenerate Dimensions} +The class \ccc{Triangulation_3} can also deal with +triangulations whose dimension $d$ is less than~3. A triangulation of a +set of points in $\R^d$ covers the whole space $\R^d$ and consists of +cells having $d+1$ vertices: some of them are infinite, they are +obtained by linking the additional infinite vertex to each facet of +the convex hull of the points. +\begin{itemize} +\item {} \emph{dimension 2:} when a triangulation only contains +coplanar points (which is the case when there are only three points), +it consists of triangular faces. +\item {} \emph{dimension 1:} the triangulation contains only collinear +points (which is the case when there are only two points), it consists +of edges. +\item {} \emph{dimension 0:} the triangulation contains only one +finite point. +\item {} \emph{dimension -1:} this is a convention to handle the case +when the only vertex of the triangulation is the infinite one. +\end{itemize} + +The same cell class is used in all cases: triangular faces in +2D can be considered as degenerate cells, having only three vertices +(resp. neighbors) numbered $(0,1,2)$; +edges in 1D have only two vertices (resp. neighbors) numbered $0$ and $1$. + +The implicit representation of facets (resp. edges) still holds +for degenerate dimensions (\textit{i.e.} dimensions $<3$): in +dimension~2, each cell has only one facet of index 3, and 3 edges +$(0,1)$, $(1,2)$ and $(2,0)$; in dimension~1, each cell has one edge +$(0,1)$. + +\paragraph{Validity} +A triangulation of $\R^3$ is said to be \ccc{locally valid} iff + +{\bf (a)-(b)} Its underlying combinatorial graph, the triangulation +data structure, is \ccc{locally valid} +(see Section~\ref{TDS3-sec-intro} of Chapter~\ref{chapter-TDS3})\\ +{\bf (c)} Any cell has its vertices ordered according to positive +orientation. See Figure~\ref{Triangulation3-fig-orient}. + +When the triangulation is degenerated into a triangulation of +dimension~2, the geometric validity reduces to: + +{\bf (c-2D)} For any two adjacent triangles $(u,v,w_1)$ and $(u,v,w_2)$ with +common edge $(u,v)$, $w_1$ and $w_2$ lie on opposite sides of $(u,v)$ +in the plane. + +When all the points are collinear, this condition becomes: + +{\bf (c-1D)} For any two adjacent edges $(u,v)$ and $(v,w)$, $u$ and +$w$ lie on opposite sides of the common vertex $v$ on the line. + +The \ccc{is_valid()} method provided in \ccc{Triangulation_3} checks +the local validity of a given triangulation. This does not always +ensure global validity \cite{mnssssu-cgpvg-96,dlpt-ccpps-98} but it is +sufficient for practical cases. + + +\section{Delaunay Triangulation} + +The class \ccc{Delaunay_triangulation_3} represents a three-dimensional +Delaunay triangulation. + +Delaunay triangulations have the specific \textit{empty sphere property}, +that is, the circumscribing sphere of each cell of such a triangulation +does not contain any other vertex of the triangulation in its interior. +These triangulations are uniquely defined except in degenerate cases +where five points are co-spherical. Note however that the \cgal\ implementation +computes a unique triangulation even in these cases. + +This implementation is fully dynamic: it supports insertions of points, vertex removals +and displacements of points. + + +\section{Regular Triangulation\label{Triangulation3-sec-class-Regulartriangulation}} + +The class \ccc{Regular_triangulation_3} implements incremental regular +triangulations, also known as weighted Delaunay triangulations. + +Let ${S}^{(w)}$ be a set of weighted points in $\R^3$. Let +${p}^{(w)}=(p,w_p), p\in\R^3, w_p\in\R$ and +${z}^{(w)}=(z,w_z), z\in\R^3, w_z\in\R$ be two weighted points. +A weighted point +${p}^{(w)}=(p,w_p)$ can also be seen as a sphere of center $p$ and +radius $\sqrt{w_p}$. +The \textit{power product} between ${p}^{(w)}$ and ${z}^{(w)}$ is +defined as +\[\Pi({p}^{(w)},{z}^{(w)}) = {\|{p-z}\|^2-w_p-w_z}\] +where $\|{p-z}\|$ is the Euclidean distance between $p$ and $z$. + ${p}^{(w)}$ and ${z}^{(w)}$ +are said to be \textit{orthogonal} iff $\Pi{({p}^{(w)},{z}^{(w)})} += 0$ (see Figure~\ref{Triangulation3-fig-ortho}). + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{Triangulation_3/ortho} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+Orthogonal weighted
+points (picture in 2D) +
+\end{ccHtmlOnly} +\caption{Orthogonal weighted points (picture in 2D). +\label{Triangulation3-fig-ortho}} +\end{figure} + +Four weighted points have a unique common orthogonal weighted point +called the \textit{power sphere}. The weighted point orthogonal to +three weighted points in the plane defined by these three points is +called the \textit{power circle}. The +\textit{power segment} will denote the weighted point orthogonal to +two weighted points on the line defined by these two points. + +A sphere ${z}^{(w)}$ is said to be +\textit{regular} if $\forall {p}^{(w)}\in{S}^{(w)}, +\Pi{({p}^{(w)},{z}^{(w)})}\geq 0$. + +A triangulation of ${S}^{(w)}$ is \textit{regular} if the power spheres +of all simplices are regular. + +The regular triangulation of +${S}^{(w)}$ is in fact the projection onto $\R^3$ of the convex hull +of the four-dimensional points $(p,\|p-O\|^2-w_p),$ for +${p}^{(w)}=(p,w_p)\in{S}^{(w)}$. +Note that all points of ${S}^{(w)}$ do not +necessarily appear as vertices of the regular +triangulation. To know more about regular triangulations, see for +example \cite{es-itfwr-96}. + +When all weights are 0, power spheres are nothing more than +circumscribing spheres, and the regular triangulation is exactly the +Delaunay triangulation. + +The implementation of 3D regular triangulation supports insertions of weighted points, and vertex removals. Displacements are not supported in the current implementation. + +\section{Software Design\label{Triangulation3-sec-design}} + +The main classes \ccc{Triangulation_3}, \ccc{Delaunay_triangulation_3} and +\ccc{Regular_triangulation_3} are connected to each other by the +derivation diagram shown in Figure~\ref{t3_derivation}. This diagram +also shows another class: \ccc{Triangulation_utils_3}\lcTex{ +(\ccRefPage{CGAL::Triangulation_utils_3})}, which provides +a set of tools operating on the indices of vertices in cells. + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{Triangulation_3/derivation} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+ +
+\end{ccHtmlOnly} +\caption{Derivation diagram of the 3D triangulation classes. +\label{t3_derivation}} +\end{figure} + +The three main classes (\ccc{Triangulation_3}, \ccc{Delaunay_triangulation_3} +and \ccc{Regular_triangulation_3}) provide high-level geometric functionality +such as location of a point in the triangulation~\cite{cgal:dpt-wt-02}, insertion +and possibly removal of a point~\cite{cgal:dt-pvr3d-03}, and are responsible for the +geometric validity. They are built as layers on top of a triangulation data +structure, which stores their combinatorial structure. This separation between +the geometry and the combinatorics is reflected in the software design by the +fact that these three triangulation classes take the following template parameters : + +\begin{itemize} +\item {} the \textbf{geometric traits} class, which provides the type of points +to use as well as the elementary operations on them (predicates and +constructions). The concepts for these parameters are described in more +details in Section~\ref{Triangulation3-sec-Traits}\lcTex{ and in +\ccRefPage{TriangulationTraits_3}}. +\item {} the \textbf{triangulation data structure} class, which stores their +combinatorial structure, described in Section~\ref{TDS3-sec-design} of +Chapter~\ref{chapter-TDS3}. +\item {} the \textbf{location policy} tag, which is supported only by the Delaunay +triangulation class, described in Section~\ref{Triangulation3-sec-locpol}. +\end{itemize} + + +\subsection{The Geometric Traits Parameter\label{Triangulation3-sec-Traits}} + +The first template parameter of the triangulation class +\ccc{Triangulation_3} +is the geometric traits class, described by the concept +\ccc{TriangulationTraits_3}. It must define the types of the geometric objects +(points, segments, triangles and tetrahedra) forming the triangulation together +with a few geometric predicates on these objects: orientation in space, +orientation in case of coplanar points, order of collinear points. + +In addition to the requirements described before, the geometric traits +class of \ccc{Delaunay_triangulation_3} must define predicates to test for the +\textit{empty sphere property}. It is described by the concept +\ccc{DelaunayTriangulationTraits_3}, which refines \ccc{TriangulationTraits_3}. + +The kernels provided by \cgal: \ccc{Cartesian}, \ccc{Homogeneous}, +\ccc{Simple_cartesian}, \ccc{Simple_homogeneous} and +\ccc{Filtered_kernel} can all be used as models for the geometric traits +parameter. +They supply the user with all the functionalities described for the concepts +\ccc{TriangulationTraits_3}\lcTex{ +(\ccRefPage{TriangulationTraits_3})} and +\ccc{DelaunayTriangulationTraits_3}\lcTex{ +(\ccRefPage{DelaunayTriangulationTraits_3})}. +In addition, the predefined kernels +\ccc{Exact_predicates_inexact_constructions_kernel}\lcTex{ +(\ccRefPage{Exact_predicates_inexact_constructions_kernel})} and +\ccc{Exact_predicates_exact_constructions_kernel}\lcTex{ +(\ccRefPage{Exact_predicates_exact_constructions_kernel})} +can also be used, the latter being recommended when the dual construction is +used. + +In order to be used as the traits class for \ccc{Regular_triangulation_3}, +a class must provide functions to compute the \textit{power tests} +(see Section~\ref{Triangulation3-sec-class-Regulartriangulation}). +\ccc{Regular_triangulation_euclidean_traits_3} is a traits class + designed to be used by the class +\ccc{Regular_triangulation_3}. It provides +\ccc{Weighted_point}, a class for weighted points +needed by the regular triangulation, which derives from the three dimensional +point class \ccc{K::Point_3}. +It supplies the user with all the functionalities +described for the concept \ccc{RegularTriangulationTraits_3}\lcTex{ +(\ccRefPage{RegularTriangulationTraits_3})}. +It can be used as a traits class for +\ccc{Regular_triangulation_3}. + +Note that for regular triangulations, plugging a filtered kernel such +as \ccc{Exact_predicates_inexact_constructions_kernel} or +\ccc{Exact_predicates_exact_constructions_kernel} in +\ccc{Regular_triangulation_euclidean_traits_3} will +provide exact and efficient filtered predicates. + + +\subsection{The Triangulation Data Structure Parameter\label{Triangulation3-sec-tds}} + +The second template parameter of the main classes (\ccc{Triangulation_3}, +\ccc{Delaunay_triangulation_3} and \ccc{Regular_triangulation_3}) is a +triangulation data structure class. This class can be seen as a container for +the cells and vertices maintaining incidence and adjacency relations (see +Chapter~\ref{chapter-TDS3}). A model of this triangulation data structure is +\ccc{Triangulation_data_structure_3}\lcTex{ +(\ccRefPage{CGAL::Triangulation_data_structure_3})}, +and it is described by the \ccc{TriangulationDataStructure_3} concept +\lcTex{(\ccRefPage{TriangulationDataStructure_3})}. This model is itself +parameterized by a vertex base and a cell base classes, which gives the +possibility to customize the vertices and cells used by the triangulation data +structure, and hence by the geometric triangulation using it. Depending on the +kind of triangulation used, the requirements on the vertex and cell base +classes vary, and are expressed by various concepts, following the refinement +diagram shown in Figure~\ref{T3-concept-hierarchy}. + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics[width=13cm]{Triangulation_3/concept_hierarchy} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+ +
+\end{ccHtmlOnly} +\caption{Concepts refinement hierarchy for the vertex and cell base classes +parameters. +\label{T3-concept-hierarchy}} +\end{figure} + +A default value for the triangulation data structure parameter is provided in +all the triangulation classes, so it need not be specified by the user unless +he wants to use a different triangulation data structure or a different vertex +or cell base class. + +\subsection{The Location Policy Parameter\label{Triangulation3-sec-locpol}} + +The Delaunay triangulation class supports an optional feature which maintains +an additional data structure for fast point location queries. +The fast location policy should be used when the user inserts points in a random +order or needs to do many unrelated queries. +If the user is able to give a good hint to help the point location of + its queries (and its newly inserted points), then it should prefer the default + policy. In such a case where good hints are provided, +the default policy save some memory (few percents), and is faster. +Notice that if points are not inserted one by one, but as a range, then a good hint is +automatically computed using spatial sort. + +Reading Section~\ref{Triangulation3-sec-complexity} on complexity and +performance can help making an informed choice for this parameter. + +The point location strategy can be selected with the third template argument of +\ccc{Delaunay_triangulation_3}, \ccc{LocationPolicy}, which enables a fast +point location data structure when set to \ccc{Fast_location}. By default, it +uses \ccc{Compact_location}. + +Note that you can specify the \ccc{LocationPolicy} parameter without specifying +the triangulation data structure, in case you are fine with the default there. +In this case, the \ccc{LocationPolicy} appears as a second parameter after the +geometric traits.\footnote{The mechanism used behind the scenes to allow this +syntactical convenience is called \textit{deduced parameters}.} + +The \ccc{Fast_location} policy is implemented using a hierarchy of +triangulations; it changes the behavior of functions \ccc{locate}, +\ccc{insert}, \ccc{move}, and \ccc{remove}. +As proved in~\cite{cgal:d-dh-02}, this structure has an +optimal behavior when it is built for Delaunay triangulations. + +In this setting, if you build a triangulation by iteratively inserting points, +you should try to shuffle the points beforehand, as the time complexity is +guaranteed only for a randomized order. For example, inserting points in +lexicographic order is typically much slower. Note that this shuffling is +performed internally by the constructor taking a range of points. + +Prior to \cgal\ 3.6, this functionality was available through the +\ccc{Triangulation_hierarchy_3} class, which is now deprecated. + +\subsection{Flexibility of the Design} + +In order to satisfy as many uses as possible, a design has been selected that +allows to exchange different parts to meet the users' needs, while still +re-using a maximum of the provided functionalities. We have already seen that +the main triangulation classes are parameterized by a geometric traits class +and a triangulation data structure (TDS), so that each of them can be +interchanged with alternate implementations. + +The most useful flexibility is the ability given to the user to add his own +data in the vertices and cells by providing his own vertex and cell base +classes to \ccc{Triangulation_data_structure_3}. The +Figure~\ref{T3-fig-layers} shows in more detail the flexibility that is +provided, and the place where the user can insert his own vertex and/or cell +base classes. + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics[width=13cm]{Triangulation_3/design} +\end{center} +\end{ccTexOnly} +\begin{ccHtmlOnly} +
+Triangulation software design +
+\end{ccHtmlOnly} +\caption{Triangulation software design. +\label{T3-fig-layers}} +\end{figure} + + +The design of the triangulation data structure gives the possibility to store +any kind of data, including handles (an entity akin to pointers) directly in +the vertex and cell base classes. + +To do so, there are three possibilities. The simplest one is to use the +class \ccc{Triangulation_vertex_base_with_info_3}, and this approach is +illustrated in a following subsection~\ref{Triangulation3-sec-examples-color}. +The most complicated one, and probably useless for almost all cases, is to +write a vertex base class from scratch, following the documented requirements. +This is mostly useless because most of the time it is enough to derive from +the models that \cgal\ provides, and add the desired features. +In this case, when the user needs to access some type that depends on the +triangulation data structure (typically handles), then he should write +something like: +\begin{ccExampleCode} +... +template < class GT, class Vb = Triangulation_vertex_base > +class My_vertex + : public Vb +{ +public: + typedef typename Vb::Point Point; + typedef typename Vb::Cell_handle Cell_handle; + + template < class TDS2 > + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef My_vertex Other; + }; + + My_vertex() {} + My_vertex(const Point&p) : Vb(p) {} + My_vertex(const Point&p, Cell_handle c) : Vb(p, c) {} +... +}; +... // The rest has not changed +\end{ccExampleCode} + +The situation is exactly similar for cell base classes. +Section~\ref{TDS3-sec-design} provides more detailed information. + + +\section{Examples\label{Triangulation3-sec-examples}} +\subsection{Basic Example} +This example shows the incremental construction of a 3D triangulation, the +location of a point and how to perform elementary operations on indices in a +cell. It uses the default parameter of the \ccc{Triangulation_3} class. + +\ccIncludeExampleCode{Triangulation_3/simple_triangulation_3.cpp} + +\subsection{Changing the Vertex Base} +The following two examples show how the user can plug his own vertex base in a +triangulation. Changing the cell base is similar. + +\subsubsection{Adding a Color\label{Triangulation3-sec-examples-color}} +When the user doesn't need to add a type in a vertex which depends on the +\ccc{TriangulationDataStructure_3} (e.g. a \ccc{Vertex_handle} or +\ccc{Cell_handle}), then he can use the +\ccc{Triangulation_vertex_base_with_info_3} class to add his own information +easily in the vertices. The example below shows how to add a \ccc{CGAL::Color} +this way. + +\ccIncludeExampleCode{Triangulation_3/color.cpp} + +\subsubsection{Adding Handles} +When the user needs to add a type in a vertex which depends on the +\ccc{TriangulationDataStructure_3} (e.g. a \ccc{Vertex_handle} or +\ccc{Cell_handle}), then he has to derive his own vertex base class, +as the following example shows. + +\ccIncludeExampleCode{Triangulation_3/adding_handles_3.cpp} + +\subsection{The Simplex Class\label{Triangulation3-sec-simplex}} +The triangulation defines a \ccc{Simplex} class that represents a +simplex (vertex, edge, facet or cell). This example demonstrates how +simplices can be stored in a set. + +\ccIncludeExampleCode{Triangulation_3/simplex.cpp} + + +\subsection{Fast Point Location for Delaunay Triangulations\label{Triangulation3-ex-fast-location}} + +\ccIncludeExampleCode{Triangulation_3/fast_location_3.cpp} + +\subsection{Finding the Cells in Conflict with a Point in a Delaunay +Triangulation} + +\ccIncludeExampleCode{Triangulation_3/find_conflicts_3.cpp} + +\subsection{Regular Triangulation} +This example shows the building of a regular triangulation. In this +triangulation, points have an associated weight, and some points can +be hidden and do not result in vertices in the triangulation. +Another difference is that a specific traits class has to be used +(at least at the moment). + +\ccIncludeExampleCode{Triangulation_3/regular_3.cpp} + +\section{Complexity and Performance\label{Triangulation3-sec-complexity}} + +In 3D, the worst case complexity of a triangulation is quadratic in the number +of points. For Delaunay triangulations, this bound is reached in cases such as +points equally distributed on two non-coplanar lines. However, the good news +is that, in many cases, the complexity of a Delaunay triangulation is linear or +close to linear in the number of points. Several +articles~\cite{d-hdvdl-89,e-dpssdt-02,geometrica-5986i,prisme-4453a,prisme-abl-03} +have proved such good complexity bounds for specific point distributions, such +as points distributed on surfaces under some conditions. + +\subsection{Running Time} + +There are several algorithms provided in this package. We will focus here on +the following ones and give practical numbers on their efficiency~: +\begin{itemize} +\item construction of a triangulation from a range of points, +\item location of a point (using the \ccc{locate} function), +\item removal of a vertex (using the \ccc{remove} function). +\end{itemize} + +We will use the following types of triangulations, using +\ccc{Exact_predicates_inexact_constructions_kernel} as geometric traits +(combined with \ccc{Regular_triangulation_euclidean_traits_3} in the weighted +case)~: +\begin{itemize} +\item \textbf{Delaunay} : \ccc{Delaunay_triangulation_3} +\item \textbf{Delaunay - Fast location} : \ccc{Delaunay_triangulation_3} with \ccc{Fast_location} +\item \textbf{Regular} : \ccc{Regular_triangulation_3} (default setting : memorize hidden points) +\item \textbf{Regular - No hidden points} : \ccc{Regular_triangulation_3} with hidden points discarded (using + \ccc{Triangulation_cell_base_3} instead of \ccc{Regular_triangulation_cell_base_3}). +\end{itemize} + +Figure~\ref{Triangulation3-fig-benchmarks} shows, for all these types of +triangulations, the times in seconds taken to build a triangulation from a +given number of points, then the average time to perform one point location in +triangulations of various sizes, and the average time to perform one vertex +removal (which is largely independent on the size of the triangulation). + +The data sets used here are points randomly distributed in the unit cube (the +coordinates are generated using the \texttt{drand48} C function). In the +weighted case, the weights are all zero, which means that there are actually no +hidden points during execution. + +The measurements have been performed using \cgal\ 3.6, using the \gnu\ \CC\ compiler +version 4.3.2, under Linux (Fedora 10 distribution), with the compilation options +\texttt{-O3 -DCGAL\_NDEBUG}. The computer used was equipped with a 64bit Intel +Xeon 3GHz processor and 32GB of RAM (a recent desktop machine as of 2009). +% Note : it's "tigre" that I used. + +\begin{figure}[htbp] +\begin{center} +\begin{tabular}{|l||r|r|r|r|} +\hline +& \textbf{Delaunay} & \textbf{Delaunay} & \textbf{Regular} & \textbf{Regular} \\ +& & \textbf{Fast location} & & \textbf{No hidden points} \\ +\hline\hline +Construction from $10^2$ points & 0.00054 & 0.000576 & 0.000948 & 0.000955 \\ +Construction from $10^3$ points & 0.00724 & 0.00748 & 0.0114 & 0.0111\\ +Construction from $10^4$ points & 0.0785 & 0.0838 & 0.122 & 0.117 \\ +Construction from $10^5$ points & 0.827 & 0.878 & 1.25 & 1.19 \\ +Construction from $10^6$ points & 8.5 & 9.07 & 12.6 & 12.2 \\ +Construction from $10^7$ points & 87.4 & 92.5 & 129 & 125 \\ +\hline +Point location in $10^2$ points & 9.93e-07 & 1.06e-06 & 7.19e-06 & 6.99e-06 \\ +Point location in $10^3$ points & 2.25e-06 & 1.93e-06 & 1.73e-05 & 1.76e-05 \\ +Point location in $10^4$ points & 4.79e-06 & 3.09e-06 & 3.96e-05 & 3.76e-05 \\ +Point location in $10^5$ points & 2.98e-05 & 6.12e-06 & 1.06e-04 & 1.06e-04 \\ +Point location in $10^6$ points & 1e-04 & 9.65e-06 & 2.7e-04 & 2.67e-04 \\ +Point location in $10^7$ points & 2.59e-04 & 1.33e-05 & 6.25e-04 & 6.25e-04 \\ +\hline +Vertex removal & 1e-04 & 1.03e-04 & 1.42e-04 & 1.38e-04 \\ +\hline +\end{tabular} +\end{center} +\caption{Running times in seconds for algorithms on 3D triangulations. +\label{Triangulation3-fig-benchmarks}} +\end{figure} + +More benchmarks comparing \cgal\ to other software can be found +in~\cite{msri52:liu-snoeyink-05}. + + +\subsection{Memory Usage} + +We give here some indication about the memory usage of the triangulations. +Those structures being intensively based on pointers, the size almost doubles +on 64bit platforms compared to 32bit. + +The size also depends on the size of the point type which is copied in the +vertices (hence on the kernel). Obviously, any user data added to vertices +and cells also affect the memory used. + +More specifically, the memory space used to store a triangulation is first +a function of the size of its \ccc{Vertex} and \ccc{Cell} types times their +numbers (and for volumic distribution, one sees about 6.7 times more cells than +vertices). However, these are stored in memory using \ccc{Compact_container}, +which allocates them in lists of blocks of growing size, and this requires some +additional overhead for bookkeeping. Moreover, memory is only released to the +system when clearing or destroying the triangulation. This can be important +for algorithms like simplifications of data sets which will produce fragmented +memory usage (doing fresh copies of the data structures are one way out in such +cases). The asymptotic memory overhead of \ccc{Compact_container} for its +internal bookkeeping is otherwise on the order of $O(\sqrt{n})$. + +Figure~\ref{Triangulation3-fig-memory} shows the number of bytes used per +points, as measured empirically using \ccc{Memory_sizer} for large triangulations +($10^6$ random points). + +\begin{figure}[htbp] +\begin{center} +\begin{tabular}{|l||r|r|r|r|} +\hline +& \textbf{Delaunay} & \textbf{Delaunay} & \textbf{Regular} & \textbf{Regular} \\ +& & \textbf{Fast location} & & \textbf{No hidden points} \\ +\hline\hline +32bit & 274 & 291 & 336 & 282 \\ +\hline +64bit & 519 & 553 & 635 & 527 \\ +\hline +\end{tabular} +\end{center} +\caption{Memory usage in bytes per point for large data sets. +\label{Triangulation3-fig-memory}} +\end{figure} + + +\subsection{Variability Depending on the Data Sets and the Kernel} + +Besides the complexity of the Delaunay triangulation that varies with the +distribution of the points, another critical aspect affects the efficiency~: +the degeneracy of the data sets. These algorithms are quite sensitive to +numerical accuracy and it is important to run them using exact predicates. + +Using a kernel with no exact predicates will quickly lead to crashes or +infinite loops once they are executed on non-random data sets. More precisely, +problems appear with data sets which contain (nearly) degenerate cases for the +\ccc{orientation} and \ccc{side_of_oriented_sphere} predicates, namely when +there are (nearly) coplanar or (nearly) cospherical points. This unfortunately +happens often in practice with data coming from various kinds of scanners or +other automatic acquisition devices. + +Using an inexact kernel such as \ccc{Simple_cartesian} would lead +to optimal performance, which is only about 30\% better than +\ccc{Exact_predicates_inexact_constructions_kernel}. The latter is strongly +recommended since it takes care about potential robustness issues. The former +can be used for benchmarking purposes mostly, or when you really know that your +data sets won't exhibit any robustness issue. + +Exact predicates take more time to compute when they hit (nearly) degenerate +cases. Depending on the data set, this can have a visible impact on the +overall performance of the algorithm or not. + +Sometimes you need exact constructions as well, so +\ccc{Exact_predicates_exact_constructions_kernel} is a must. This is the case +for example when you need the \ccc{dual} functions to be exact, or when your +input is stored in points of such a kernel for other reasons (because it is the +output of another algorithm which has this requirement, for example). This +will slow down the computations by a factor of 4 to 5 at least, and it can be +much more. + +Figure~\ref{Triangulation3-fig-kernels-and-data-sets} gives more detailed +timings about various kernels one the following data sets~: random points in a +cube, random points on the surface of an ellipsoid, points scanned on the +surface of a Buddha statue, points on a molecular surface, and points scanned +on a dryer handle. See Figure~\ref{Triangulation3-fig-data-sets} for pictures of +the last 3 objects, which respectively illustrate volumic data, surfacic data, +and data with many degenerate cases. This last data set exhibits an infinite +loop with an inexact kernel, and of course we are not sure whether what is +computed for the other data sets with this inexact kernel is a Delaunay +triangulation. General introductory information about these robustness issues +can be found in~\cite{cgta-kmpsy-08}. More benchmarks around this issue can +also be found in~\cite{cgal:dp-eegpd-03}. + +\begin{figure}[htbp] +\begin{center} +\begin{tabular}{|l||r|r|r|r|r|} +\hline + & \textbf{Random} & \textbf{Ellipsoid} & \textbf{Buddha} & \textbf{Molecule} & \textbf{Dryer} \\ + & & & & & \textbf{Handle} \\ +\#points & \textbf{100000} & \textbf{100000} & \textbf{542548} & \textbf{525296} & \textbf{49787} \\ +\hline\hline +\ccc{Simple_cartesian} & 0.69 & 0.627 & 4.21 & 3.8 & $\infty$-loop \\ +\hline +\ccc{Exact_predicates_inexact_constructions_kernel} & 0.824 & 0.749 & 4.99 & 4.64 & 1.68 \\ +\hline +\ccc{Exact_predicates_exact_constructions_kernel} & 4.59 & 3.85 & 30.1 & 26.4 & 4.57 \\ +\hline +\ccc{Simple_cartesian} & 492 & 534 & 1120 & 1030 & 75.2 \\ +\hline +\end{tabular} +\end{center} +\caption{Running times (seconds) for various kernels and data sets. +\label{Triangulation3-fig-kernels-and-data-sets}} +\end{figure} + + +\begin{figure}[htbp] +\begin{center} +\begin{ccTexOnly} +\includegraphics[width=5cm]{Triangulation_3/fig/api1_01} +\includegraphics[width=5cm]{Triangulation_3/fig/b35-1} +\includegraphics[width=5cm]{Triangulation_3/fig/HD} +\end{ccTexOnly} +\begin{ccHtmlOnly} + + +
Buddha statue +Molecule +Dryer Handle +
+\end{ccHtmlOnly} +\end{center} +\caption{Data sets used in the benchmark of Figure~\ref{Triangulation3-fig-kernels-and-data-sets}. +\label{Triangulation3-fig-data-sets}} +\end{figure} + + + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\section{Design and Implementation History} + +Monique Teillaud started to work on the 3D triangulation packages in +1997, following the design of the 2D triangulation packages. The +notions of degenerate dimensions and infinite vertex were formalized +\cite{t-tdtc-99} and induced changes in the 2D triangulation +packages. The packages were first released in \cgal\ 2.1. They contained +basic functionalities on triangulations, Delaunay triangulations, +regular triangulations. + +A first version of removal of a vertex from a Delaunay triangulation +was released in \cgal\ 2.2. However, this removal became really robust +only in \cgal\ 2.3, after some research that allowed to deal with +degenerate cases quite easily \cite{cgal:dt-pvr3d-03}. Andreas Fabri +implemented this revised version of the removal, and a faster removal +algorithm for \cgal\ 3.0. + +The latter algorithm was proposed by Mariette Yvinec, who contributed +in several ways to the package, first since she was maintaining the +close 2D triangulation package and participated in many discussions, +she also wrote the traits classes for regular triangulations. + +In 2000, Sylvain Pion started working on these packages. He improved +the efficiency of triangulations in \cgal\ 2.3 and 2.4 in several ways +\cite{cgal:bdpty-tc-02}: he implemented the Delaunay hierarchy +\cite{cgal:d-dh-02} in 2.3, he improved the memory footprint in 2.4 +and 3.0, he also performed work on arithmetic filters +\cite{cgal:dp-eegpd-03} (see \ccc{Filtered_kernel}) to improve +the speed of triangulations. He changed the design in \cgal\ 3.0, +allowing users to add handles in their own vertices and cells. + +Olivier Devillers, co-author of preliminary versions of the \cgal\ 2d +triangulations, participated in many discussions, in particular about +the perturbations, and more concretely in the implementation of the +Delaunay hierarchy. + +In 2005, Christophe Delage implemented the vertex removal function for +regular triangulations, using the symbolic perturbation proposed +in~\cite{cgal:dt-pvrdr-06}, which allowed to release this +functionality in \cgal\ 3.2. + +In 2006, Nico Kruithof wrote the \ccc{Triangulation_simplex_3} class +that can store simplices of any dimension and improved the internal +organization of the code. + +As of March 2007, Christophe Delage made the iterator range insert methods and +constructors use \ccc{spatial_sort} to improve efficiency. + +In 2008, Camille Wormser added a few more iterators in +the package that were integrated in release~3.4. + +In 2009, Sylvain Pion simplified the design of the Delaunay hierarchy +so that it became the simple \ccc{Fast_location} policy in release~3.6. + +In 2010, Pedro de Castro and Olivier Devillers added the point displacement. + +The authors wish to thank Lutz Kettner for inspiring discussions about +the design of CGAL. Jean-Daniel Boissonnat is also acknowledged +\cite{bdty-tcgal-00}. diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.fig b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.fig new file mode 100644 index 00000000000..80d87e64ea3 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.fig @@ -0,0 +1,33 @@ +#FIG 3.2 Produced by xfig version 3.2.5 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5175 1125 8325 1125 8325 1575 5175 1575 5175 1125 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5175 2250 8325 2250 8325 2700 5175 2700 5175 2250 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1125 1125 4275 1125 4275 1575 1125 1575 1125 1125 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1125 2250 4275 2250 4275 2700 1125 2700 1125 2250 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2700 2250 2700 1575 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 6750 2250 6750 1575 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 1125 3375 4275 3375 4275 3825 1125 3825 1125 3375 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 2700 3375 2700 2700 +4 0 0 50 0 0 12 0.0000 4 195 2640 5580 1395 TriangulationDSVertexBase_3\001 +4 0 0 50 0 0 12 0.0000 4 195 2370 5760 2565 TriangulationVertexBase_3\001 +4 0 0 50 0 0 12 0.0000 4 195 2130 1800 2520 TriangulationCellBase_3\001 +4 0 0 50 0 0 12 0.0000 4 195 2400 1665 1440 TriangulationDSCellBase_3\001 +4 0 0 50 0 0 12 0.0000 4 195 2805 1305 3645 RegularTriangulationCellBase_3\001 diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.gif new file mode 100644 index 00000000000..af05591d5be Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.pdf new file mode 100644 index 00000000000..cb98814db6f Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/concept_hierarchy.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.fig b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.fig new file mode 100644 index 00000000000..a17a70708d5 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.fig @@ -0,0 +1,30 @@ +#FIG 3.2 Produced by xfig version 3.2.5 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 4275 2475 4725 2025 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 6075 2475 5625 2025 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 60.00 120.00 + 5175 1575 5175 1125 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5400 2475 7875 2475 7875 2925 5400 2925 5400 2475 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2475 2475 4950 2475 4950 2925 2475 2925 2475 2475 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 4050 1575 6300 1575 6300 2025 4050 2025 4050 1575 +2 2 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 4050 675 6300 675 6300 1125 4050 1125 4050 675 +4 0 0 50 0 0 12 0.0000 4 195 2205 2655 2790 Delaunay_triangulation_3\001 +4 0 0 50 0 0 12 0.0000 4 195 2055 5580 2790 Regular_triangulation_3\001 +4 0 0 50 0 0 12 0.0000 4 195 1350 4500 1845 Triangulation_3\001 +4 0 0 50 0 0 12 0.0000 4 195 1800 4275 945 Triangulation_utils_3\001 diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.gif new file mode 100644 index 00000000000..97578f4fe52 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.pdf new file mode 100644 index 00000000000..ec6c07f1b6f Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/derivation.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.fig b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.fig new file mode 100644 index 00000000000..fbfe6c68e7f --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.fig @@ -0,0 +1,132 @@ +#FIG 3.2 +Landscape +Center +Metric +A4 +100.00 +Single +-2 +1200 2 +6 4320 4005 5085 4545 +4 0 0 50 0 0 12 0.0000 4 180 645 4365 4140 Optional\001 +4 0 0 50 0 0 12 0.0000 4 135 375 4500 4365 User\001 +4 0 0 50 0 0 12 0.0000 4 135 735 4320 4545 Additions\001 +-6 +6 3870 2250 5490 2925 +4 0 0 50 0 0 18 0.0000 4 255 1500 3960 2835 Functionality\001 +4 0 0 50 0 0 18 0.0000 4 195 1620 3870 2475 Combinatorial\001 +-6 +6 -1395 5355 495 6345 +6 -1395 5355 495 6345 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + -1350 5400 450 5400 450 6300 -1350 6300 -1350 5400 +4 0 0 50 0 0 22 0.0000 4 225 1365 -1080 5760 Geometric\001 +4 0 0 50 0 0 22 0.0000 4 225 795 -810 6165 Traits\001 +-6 +-6 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 13 + 2250 3600 2250 3150 4050 3150 4050 3600 5400 3600 5400 3150 + 7200 3150 7200 3600 7650 3600 7650 1350 900 1350 900 3600 + 2250 3600 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + 1800 1350 1800 3600 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 13 + 7650 900 8100 900 8100 -1800 -2700 -1800 -2700 900 -1350 900 + -1350 450 450 450 450 900 900 900 900 450 7650 450 + 7650 900 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + -450 5400 -450 450 +2 1 0 1 0 7 50 0 -1 0.000 0 0 -1 0 0 2 + -1800 -1800 -1800 900 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 3150 4050 3150 3150 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 6300 4005 6300 3150 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 4725 1350 4725 450 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 3150 4050 3150 3150 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 6300 4050 6300 3150 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2250 5400 4050 5400 4050 5850 2250 5850 2250 5400 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5400 5400 7200 5400 7200 5850 5400 5850 5400 5400 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 3150 5400 3150 4500 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 6300 5400 6300 4500 +2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 + 2250 4050 4050 4050 4050 4500 2250 4500 2250 4050 +2 2 1 2 0 7 50 0 -1 6.000 0 0 -1 0 0 5 + 5400 4050 7200 4050 7200 4500 5400 4500 5400 4050 +2 2 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 2205 1350 4095 1350 4095 1845 2205 1845 2205 1350 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 2250 1350 4050 1350 4050 1800 2250 1800 2250 1350 +2 2 1 1 0 7 50 0 -1 4.000 0 0 -1 0 0 5 + 5355 1350 7245 1350 7245 1845 5355 1845 5355 1350 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + 5400 1350 7200 1350 7200 1800 5400 1800 5400 1350 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 90.00 180.00 + 3150 1350 3150 -2070 +2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 90.00 180.00 + 6300 1350 6300 -2070 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 4 + 1 1 1.00 240.00 480.00 + 450 6075 4500 6075 4500 5580 5400 5580 +2 1 0 3 0 7 50 0 -1 0.000 0 0 -1 1 0 2 + 1 1 1.00 240.00 480.00 + 450 5625 2250 5625 +2 2 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 5 + -900 -1800 1125 -1800 1125 -1350 -900 -1350 -900 -1800 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 4185 5040 3780 4860 3285 5040 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 5175 5040 5670 4860 6120 5040 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 1170 5040 1215 5265 1260 5490 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 945 4500 360 4185 -360 4230 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 1305 4500 2025 3960 2970 3735 + 0.000 -1.000 0.000 +3 2 1 1 0 7 50 0 -1 4.000 0 1 0 3 + 1 1 1.00 60.00 120.00 + 1665 5040 2250 5130 2925 5130 + 0.000 -1.000 0.000 +4 0 0 50 0 0 20 1.5708 4 195 1740 1665 3375 Data Structure\001 +4 0 0 50 0 0 20 1.5708 4 255 1590 1260 3285 Triangulation\001 +4 0 0 50 0 0 24 1.5708 4 330 2010 -2115 540 Triangulation\001 +4 0 0 50 0 0 18 0.0000 4 195 1290 2520 5715 VertexBase\001 +4 0 0 50 0 0 18 0.0000 4 195 975 5850 5715 CellBase\001 +4 0 0 50 0 0 18 0.0000 4 195 900 2655 4365 UserVB\001 +4 0 0 50 0 0 18 0.0000 4 195 885 5895 4365 UserCB\001 +4 0 0 50 0 0 20 0.0000 4 195 780 2745 1665 Vertex\001 +4 0 0 50 0 0 20 0.0000 4 195 465 6075 1665 Cell\001 +4 0 0 50 0 0 12 0.0000 4 135 795 4230 5130 Derivation\001 +4 0 0 50 0 0 16 0.0000 4 225 930 630 4725 Template\001 +4 0 0 50 0 0 16 0.0000 4 165 1095 585 4950 Parameters\001 +4 0 0 50 0 0 18 0.0000 4 255 1500 -585 -585 Functionality\001 +4 0 0 50 0 0 18 0.0000 4 195 1200 -450 -900 Geometric\001 +4 0 0 50 0 0 14 0.0000 4 195 1530 -585 -1530 locate(), insert()...\001 +4 0 0 50 0 0 16 0.0000 4 225 585 4500 -1440 Types\001 diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.gif new file mode 100644 index 00000000000..268f24a37eb Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.pdf new file mode 100644 index 00000000000..97795c9d0c0 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/design.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/Delaunay_3.jpg b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/Delaunay_3.jpg new file mode 100644 index 00000000000..ac2b4fc3ae4 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/Delaunay_3.jpg differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/HD.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/HD.gif new file mode 100644 index 00000000000..20b718446c3 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/HD.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/HD.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/HD.pdf new file mode 100644 index 00000000000..10283b2cf27 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/HD.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/api1_01.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/api1_01.gif new file mode 100644 index 00000000000..8e219eb56d1 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/api1_01.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/api1_01.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/api1_01.pdf new file mode 100644 index 00000000000..e7fa1329b86 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/api1_01.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/b35-1.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/b35-1.gif new file mode 100644 index 00000000000..062a1732e94 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/b35-1.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/b35-1.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/b35-1.pdf new file mode 100644 index 00000000000..94f0d4ccd58 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/b35-1.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/twotets.png b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/twotets.png new file mode 100644 index 00000000000..ecb754e1aed Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/fig/twotets.png differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.gif new file mode 100644 index 00000000000..6ee04d717cf Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.pdf new file mode 100644 index 00000000000..58ce71b391c Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.xml b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.xml new file mode 100644 index 00000000000..2f21f23ca2f --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_affine_hull.xml @@ -0,0 +1,76 @@ + + + + + + + + +-162.5 99.1616 m +-201.5 20.32 l +-95.875 20.32 l + + + + + + + + +-151.125 47.9552 m +-103.188 76.4032 l +-97.5 57.7088 l +-151.125 47.9552 l +-99.9375 34.1376 l +-97.5 57.7088 l +-47.125 39.0144 l +-99.9375 34.1376 l +-97.5 57.7088 l +-103.188 76.4032 l +-30.0625 73.152 l +-97.5 57.7088 l +-13.8125 55.2704 l +-30.0625 73.152 l +21.9375 52.0192 l +-13.8125 55.2704 l +-47.125 39.0144 l +21.9375 52.0192 l +21.9375 52.0192 l + + +$p$ + +-28.4375 163.373 m +-151.125 47.9552 l + + +-28.4375 163.373 m +-103.188 76.4032 l + + +-28.4375 163.373 m +-30.0625 73.152 l + + +-28.4375 163.373 m +-97.5 57.7088 l + + +-28.4375 163.373 m +-99.9375 34.1376 l + + +-28.4375 163.373 m +-47.125 39.0144 l + + +-28.4375 163.373 m +-13.8125 55.2704 l + + +-28.4375 163.373 m +21.9375 52.0192 l + +The infinite cells are not shown + + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.gif new file mode 100644 index 00000000000..3e21752d3ff Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.pdf new file mode 100644 index 00000000000..df40343b31e Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.xml b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.xml new file mode 100644 index 00000000000..8758c3facee --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/insert_outside_convex_hull.xml @@ -0,0 +1,114 @@ + + + + + +$p$ + + + + + + + + + + + + + + + + + + +-43.7921 83.208 m +-126.372 74.758 l +-159.535 29.908 l +-128.973 -26.642 l +-75.6539 -40.942 l +-43.7921 -18.8419 l +-15.1816 26.6581 l +-22.9844 55.908 l +-35.339 72.158 l +h + + +-75.6539 -40.942 m +-98.4124 -20.7919 l +-128.973 -26.642 l +-125.722 8.45801 l +-159.535 29.908 l +-130.274 26.6581 l +-97.762 18.2081 l +-125.722 8.45801 l +-98.4124 -20.7919 l +-91.91 -3.24199 l +-61.9988 -8.44195 l +-75.6539 -40.942 l +-91.91 -3.24199 l +-125.722 8.45801 l +-97.762 18.2081 l +-91.91 -3.24199 l +-62.6491 29.908 l +-61.9988 -8.44195 l +-38.5902 17.5581 l +-62.6491 29.908 l +-97.762 18.2081 l +-102.314 42.908 l +-130.274 26.6581 l +-126.372 49.408 l +-159.535 29.908 l +-126.372 74.758 l +-126.372 49.408 l +-102.314 42.908 l +-73.7031 50.058 l +-97.762 18.2081 l +-62.6491 29.908 l +-73.7031 50.058 l +-81.506 70.858 l +-38.5902 17.5581 l +-62.6491 29.908 l +-81.506 70.858 l +-43.7921 83.208 l +-126.372 74.758 l +-102.314 42.908 l +-81.506 70.858 l +-126.372 74.758 l + + + +-61.9988 -8.44195 m +-43.7921 -18.8419 l +-38.5902 17.5581 l +-15.1816 26.6581 l +-81.506 70.858 l +-22.9844 55.908 l + + +-75.6539 -40.942 m +49.8426 6.50801 l + + +-43.7921 -18.8419 m +49.8426 6.50801 l + + +-15.1816 26.6581 m +49.8426 6.50801 l + + +-22.9844 55.908 m +49.8426 6.50801 l +-43.7921 83.208 l + + +-130.274 26.6581 m +-125.722 8.45801 l + + + + +$c$ + + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/main.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/main.tex new file mode 100644 index 00000000000..9839d0a9e50 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/main.tex @@ -0,0 +1,9 @@ +\ccUserChapter{3D Triangulations\label{chapter-Triangulation3}} +\ccChapterAuthor{Sylvain Pion \and Monique Teillaud} + +\input{Triangulation_3/PkgDescription} + +\minitoc + +\input{Triangulation_3/Triang3} + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.gif new file mode 100644 index 00000000000..2d565e0e615 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.pdf new file mode 100644 index 00000000000..d594251bf36 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.xml b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.xml new file mode 100644 index 00000000000..80ab9fb698f --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/orient.xml @@ -0,0 +1,43 @@ + + + + + + +-90.2995 268.418 m +-37.487 238.345 l +-2.5495 287.113 l +-62.6745 327.752 l +-37.487 238.345 l +-90.2995 268.418 l +-62.6745 327.752 l + + +-90.2995 268.418 m +-2.5495 287.113 l + +0 +1 +2 +3 + +-51.2994 269.231 m +10.1915 0 0 10.1915 -42.7169 263.735 -37.487 272.482 a + + +-153.216 235.443 m +-176.778 211.872 l + + +-153.216 235.443 m +-120.716 235.443 l + + +-153.216 235.443 m +-153.216 270.394 l + +$x$ +$y$ +$z$ + + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.gif new file mode 100644 index 00000000000..c37e3ad5b05 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.pdf new file mode 100644 index 00000000000..61acccb70ec Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.xml b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.xml new file mode 100644 index 00000000000..b2848c41383 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/ortho.xml @@ -0,0 +1,38 @@ + + + + + + +-38.1753 133.65 m +-82.0373 56.7 l + + +-38.1753 133.65 m +97.47 55.89 l + + +5.68567 46.17 m +88.3527 0 0 88.3527 -82.0373 56.7 -88.5224 144.814 a + + +-13.8076 162.81 m +154.32 0 0 154.32 97.47 55.89 -55.8662 73.2873 a + + +-82.0373 56.7 m +97.47 55.89 l + + + +$p$ +$z$ +$w_p$ +$w_z$ + +-43.8615 122.31 m +-31.6777 115.02 l +-23.5553 125.55 l + + + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.gif new file mode 100644 index 00000000000..671807d1fbc Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.pdf new file mode 100644 index 00000000000..3ac6f7ae1e3 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.xml b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.xml new file mode 100644 index 00000000000..01ca1096d56 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/remimpos.xml @@ -0,0 +1,54 @@ + + + + + + +-144 96 m +-104 88 l +-64 96 l +h + + +-144 96 m +-144 -8 l +-104 -24 l +-104 88 l +-144 96 l +-64 96 l +-104 88 l + + +-64 96 m +-64 -8 l +-104 -24 l + + +-144 96 m +-104 -24 l + + +-104 88 m +-64 -8 l + + +-64 96 m +-144 -8 l + + + +-104 -24 m +-64 96 l + +any tetrahedron formed with the upper facet +and any other vertex of the hole would violate +a facet of the polyhedron + +-144 -8 m +-64 -8 l + + +9.6455 0 0 9.6455 -83.2593 38.2222 e + + + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.gif new file mode 100644 index 00000000000..d0e019929fa Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.pdf new file mode 100644 index 00000000000..184c522e968 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.xml b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.xml new file mode 100644 index 00000000000..8118c7b98cd --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/sidedim2.xml @@ -0,0 +1,122 @@ + + + + + + +-31.0962 133.009 m +-43.112 106.876 l + + +-31.0962 133.009 m +6.06326 106.6 l + + +-43.112 106.876 m +6.06326 106.6 l + + +27.9852 53.9124 m +18.2924 62.1975 l + +orthocircle of $f$ + + +$p$ +$w_p$ + +28.7636 0 0 28.7636 -43.112 106.876 e + + + + +$w_z$ + +45.5878 0 0 45.5878 6.06326 106.6 e + +$z$ + + +$w_z$ + +45.5878 0 0 45.5878 -142.956 106.6 e + +$z$ + +-142.956 106.6 m +-113.474 141.372 l + + +-173.009 106.876 m +-150.983 125.374 l + + +$p$ +$w_p$ + +28.7636 0 0 28.7636 -173.009 106.876 e + + +$w_z$ + +45.5878 0 0 45.5878 177.071 106.6 e + +$z$ + +$p$ +$w_p$ + +28.7636 0 0 28.7636 106.405 106.876 e + + +177.071 106.6 m +186.14 151.277 l + + +106.405 106.876 m +114.313 134.531 l + + +-178.534 135.104 m +-216.871 127.17 l + + +-178.534 135.104 m +-157.577 157.95 l + + +132.931 117.999 m +116.964 149.04 l + + +132.931 117.999 m +144.581 153.09 l + + +-165.323 149.506 m +19.5434 0 0 19.5434 -178.534 135.104 -197.672 131.144 a + + +140.383 140.445 m +23.6511 0 0 23.6511 132.931 117.999 122.113 139.031 a + +$>\pi/2$ +$<\pi/2$ +ON\_BOUNDED\_SIDE +ON\_BOUNDARY +ON\_UNBOUNDED\_SIDE + +-31.0962 133.009 m +-13.8082 159.57 l + + +-31.0962 133.009 m +-56.8575 148.23 l + + +-20.4275 149.4 m +19.5573 0 0 19.5573 -31.0962 133.009 -47.9342 142.957 a + +$\pi/2$ + + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.gif new file mode 100644 index 00000000000..823ab679010 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.pdf new file mode 100644 index 00000000000..a3363a51b07 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.xml b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.xml new file mode 100644 index 00000000000..0ccf9839fbd --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/topo-insert_outside_affine_hull.xml @@ -0,0 +1,101 @@ + + + + + + +107.61 0 0 107.61 -40.625 164.186 e + + +-124.313 99.1617 m +207.578 0 0 207.578 -173.875 300.736 26.8636 247.89 a + + + + + +$star$ + +$p$ + +26.8649 247.891 m +229.736 0 0 229.736 89.375 26.8224 -128.231 100.486 a + + + + +1.99683 190.472 m +199.37 0 0 199.37 -179.562 108.102 -62.6197 269.573 a + + +-62.6203 269.574 m +184.379 0 0 184.379 116.188 314.554 -40.0821 216.701 a + + +1.99599 190.472 m +237.076 0 0 237.076 -99.9375 -23.5712 -137.855 210.453 a + + +-137.854 210.451 m +216.518 0 0 216.518 59.3125 299.923 -101.29 154.71 a + + +1.99447 190.471 m +299.051 0 0 299.051 196.625 -36.576 -46.8552 137.058 a + + +1.99517 190.472 m +212.518 0 0 212.518 89.375 -3.2512 -88.8091 112.569 a + + +19.5037 225.283 m +128.804 0 0 128.804 127.783 155.526 3.67918 190.004 a + + +55.3277 181.491 m +166.471 0 0 166.471 4.28317 23.0393 2.00913 189.495 a + + +58.5 176.378 m +3.17764e-14 0 0 3.17764e-14 58.5 176.378 58.5 176.378 a + + +55.3277 181.492 m +40.2425 0 0 40.2425 15.0896 182.089 17.2504 222.273 a + + +-46.5197 136.818 m +119.341 0 0 119.341 -38.0125 255.855 55.3277 181.492 a + + +-86.9377 111.354 m +96.6885 0 0 96.6885 -40.2616 196.03 55.3277 181.492 a + + +55.3276 181.492 m +46.9863 0 0 46.9863 10.922 196.849 54.3626 214.755 a + + +53.6751 216.026 m +85.4916 0 0 85.4916 6.36227 144.82 -40.5658 216.28 a + + +2.74432 65.7027 m +139.962 0 0 139.962 -84.4909 175.153 55.3275 181.492 a + + +-101.29 154.71 m +83.4958 0 0 83.4958 -18.196 146.529 2.74495 65.7019 a + + +-150.904 49.8617 m +-113.891 102.014 l + +triangulation of $S^1$ + +23.7832 44.9849 m +1.03317 127.89 l + +triangulation of $S^2$ + + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3/triangulation3.png b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/triangulation3.png new file mode 100644 index 00000000000..74c4ed59dc9 Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3/triangulation3.png differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/DelaunayTriangulationTraits_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/DelaunayTriangulationTraits_3.tex new file mode 100644 index 00000000000..271c05d19cb --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/DelaunayTriangulationTraits_3.tex @@ -0,0 +1,148 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_Traits_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationTraitsRev}{$Id$} +\RCSdefDate{\RCSTriangulationTraitsDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{DelaunayTriangulationTraits_3} + +\ccDefinition +The concept \ccRefName\ is the first template parameter of the class +\ccc{Delaunay_triangulation_3}. It defines the geometric objects (points, +segments...) forming the triangulation together with a few geometric +predicates and constructions on these objects. + +\ccRefines \ccc{TriangulationTraits_3} + +In addition to the requirements described for the traits class of +\ccc{Triangulation_3}, the geometric traits class of a +Delaunay triangulation must fulfill the following requirements: + +\ccTypes +\ccTwo{DelaunayTriangulationTraits_3::Object_3_xxxxx}{} + +\ccNestedType{Line_3}{The line type.} +\ccGlue +\ccNestedType{Object_3}{The object type.} +\ccGlue +%\ccNestedType{Plane_3}{The plane type.} +%\ccGlue +\ccNestedType{Ray_3}{The ray type.} + +\ccTwo{DelaunayTriangulationTraits}{} + +\ccNestedType{Coplanar_side_of_bounded_circle_3} +{A predicate object that must provide the function operator\\ +\ccc{Bounded_side operator()(Point p, Point q, Point r, Point s)},\\ +which determines the bounded side of the circle defined +by \ccc{p}, \ccc{q}, and \ccc{r} on which \ccc{s} lies. +\ccPrecond \ccc{p}, \ccc{q}, \ccc{r}, and \ccc{s} are coplanar and +\ccc{p}, \ccc{q}, and \ccc{r} are not collinear.} +\ccGlue +\ccNestedType{Side_of_oriented_sphere_3} +{A predicate object that must provide the function operator\\ +\ccc{Oriented_side operator()(Point p, Point q, Point r, Point s, Point t)},\\ +which determines on which side of the oriented sphere circumscribing +\ccc{p, q, r, s} the point \ccc{t} lies.} + +\ccNestedType{Compare_distance_3} +{A predicate object that must provide the function operator\\ +\ccc{Comparison_result operator()(Point p, Point q, Point r)},\\ +which compares the distance between \ccc{p} and \ccc{q} to the distance +between \ccc{p} and \ccc{r}.\\ +It is only needed when using the \ccc{Fast_location} policy or the +\ccc{nearest_vertex} function.} + +In addition, only when the dual operations are used, the traits class +must provide the following constructor objects: + +\ccTwo{DelaunayTriangulationTraits_3}{} +\ccNestedType{Construct_circumcenter_3} +{A constructor object that must provide the function operator\\ +\ccc{Point_3 operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)},\\ +which constructs the circumcenter of four points. +\ccPrecond{\ccc{p}, \ccc{q}, \ccc{r} and \ccc{s} must be non coplanar.}\\ +It must also provide the function operator\\ +\ccc{Point_3 operator()(Point_3 p, Point_3 q, Point_3 r)},\\ +which constructs the circumcenter of three points. +\ccPrecond{\ccc{p}, \ccc{q} and \ccc{r} must be non collinear.}} +\ccGlue +\ccNestedType{Construct_object_3} +{A constructor object that must provide the function operators\\ +\ccc{Object_3 operator()(Point_3 p)},\\ +\ccc{Object_3 operator()(Segment_3 s)} and\\ +\ccc{Object_3 operator()(Ray_3 r)}\\ +that construct an object respectively from a point, a segment and a ray.} +\ccGlue +\ccNestedType{Construct_equidistant_line_3} +{A constructor object that must provide the function operator\\ +\ccc{Line_3 operator()(Point_3 p1, Point_3 p2, Point_3 p3)},\\ +which constructs the line which is at the same distance from the three points. +\ccPrecond{\ccc{p1}, \ccc{p2} and \ccc{p3} must be non collinear.}} +\ccGlue +%\ccNestedType{Construct_perpendicular_line_3} +%{A constructor object that must provide the function operator\\ +%\ccc{Line_3 operator()(Plane_3 pl, Point_3 p)},\\ +%which constructs the line perpendicular to \ccc{pl} passing through \ccc{p}.} +%\ccGlue +%\ccNestedType{Construct_plane_3} +%{A constructor object that must provide the function operator\\ +%\ccc{Plane_3 operator()(Point_3 p, Point_3 q, Point_3 r)},\\ +%which constructs the plane passing through \ccc{p}, \ccc{q} and \ccc{r}. +%\ccPrecond{\ccc{p}, \ccc{q} and \ccc{r} are non collinear.}} +%\ccGlue +\ccNestedType{Construct_ray_3} +{A constructor object that must provide the function operator\\ +\ccc{Ray_3 operator()(Point_3 p, Line_3 l)},\\ +which constructs the ray starting at \ccc{p} with direction given by \ccc{l}.} + + +\ccOperations + +The following functions give access to the predicate and construction objects: + +\ccThree{coplanar_side_of_bounded_circle_3xxx}{gt.xxxxxxxxx(Point p0, Point p1)x}{} +\ccCreationVariable{traits} + +\ccMethod{Coplanar_side_of_bounded_circle_3 coplanar_side_of_bounded_circle_3_object();}{} +\ccGlue +\ccMethod{Side_of_oriented_sphere_3 side_of_oriented_sphere_3_object();}{} + +When using the \ccc{Fast_location} policy or the \ccc{nearest_vertex} function, +the traits must provide: + +\ccMethod{Compare_distance_3 compare_distance_3_object();}{} + +The following functions must be provided only if the methods of +\ccc{Delaunay_triangulation_3} returning elements of the Voronoi diagram +are instantiated: + +\ccMethod{Construct_circumcenter_3 construct_circumcenter_3_object();}{} +\ccGlue +\ccMethod{Construct_object_3 construct_object_3_object();}{} +\ccGlue +\ccMethod{Construct_perpendicular_line_3 construct_perpendicular_line_object();}{} +\ccGlue +\ccMethod{Construct_plane_3 construct_plane_3_object();}{} +\ccGlue +\ccMethod{Construct_ray_3 construct_ray_3_object();}{} + +\ccHasModels + +\ccc{CGAL::Exact_predicates_inexact_constructions_kernel} (recommended)\\ +\ccc{CGAL::Exact_predicates_exact_constructions_kernel} (recommended for +Voronoi)\\ +\ccc{CGAL::Filtered_kernel}\\ +\ccc{CGAL::Cartesian}\\ +\ccc{CGAL::Simple_cartesian}\\ +\ccc{CGAL::Homogeneous}\\ +\ccc{CGAL::Simple_homogeneous} + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Delaunay_triangulation_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Delaunay_triangulation_3.tex new file mode 100644 index 00000000000..61c49eaddb9 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Delaunay_triangulation_3.tex @@ -0,0 +1,391 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Delaunay_triangulation_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSDelaunaytriangulationRev}{$Id$} +\RCSdefDate{\RCSDelaunaytriangulationDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Delaunay_triangulation_3} + +\ccDefinition + +The class \ccc{Delaunay_triangulation_3} represents a three-dimensional +Delaunay triangulation. + +\ccInclude{CGAL/Delaunay_triangulation_3.h} + +\ccParameters + +The first template argument must be a model of the +\ccc{DelaunayTriangulationTraits_3} concept. + +The second template argument must be a model of the +\ccc{TriangulationDataStructure_3} concept. +It has the default value \ccc{Triangulation_data_structure_3, Triangulation_cell_base_3 >}. + +The third template argument is a tag which must be a \ccc{Location_policy} : +either \ccc{Fast_location} or \ccc{Compact_location}. +\ccc{Fast_location} offers faster ($O(\log n)$ time) point +location, which can be beneficial when performing point locations or random +point insertions (with no good location hint) in large data sets. +It is currently implemented using an additional triangulation +hierarchy data structure~\cite{cgal:d-dh-02}. +The default is \ccc{Compact_location}, which saves memory (3-5\%) by avoiding the need for this +separate data structure, and point location is then performed roughly in +$O(n^{1/3})$ time. +Note that this argument can also come in second position, which can be useful when +the default value for the \ccc{TriangulationDataStructure_3} parameter is +satisfactory (this is using so-called deduced parameters). +Note that this argument replaces the functionality +provided before \cgal\ 3.6 by \ccc{Triangulation_hierarchy_3}. +An example of use can be found in the user +manual~\ref{Triangulation3-ex-fast-location}. + + +\ccInheritsFrom{\ccc{Triangulation_3}} + +\ccTypes + +\ccThree{typedef DelaunayTriangulationTraits_3::Object_3 Object;}{} +\ccThreeToTwo + +\ccTypedef{typedef LocationPolicy Location_policy;}{} + +In addition to those inherited, the following types are defined, for use by the +construction of the Voronoi diagram: + +\ccTypedef{typedef DelaunayTriangulationTraits_3::Line_3 Line;}{} +\ccGlue +\ccTypedef{typedef DelaunayTriangulationTraits_3::Ray_3 Ray;}{} +\ccGlue +\ccTypedef{typedef DelaunayTriangulationTraits_3::Plane_3 Plane;}{} +\ccGlue +\ccTypedef{typedef DelaunayTriangulationTraits_3::Object_3 Object;}{} + +\ccCreation +\ccCreationVariable{dt} +\ccThree{OutputIterator}{dt.remove(Point p)toto}{} + +\ccConstructor{Delaunay_triangulation_3 +(const DelaunayTriangulationTraits_3& traits = DelaunayTriangulationTraits_3())} +{Creates an empty Delaunay triangulation, possibly specifying a traits class +\ccc{traits}.} + +\ccConstructor{Delaunay_triangulation_3 (const Delaunay_triangulation_3 & dt1)} +{Copy constructor.} + +\ccConstructor{template < class InputIterator > + Delaunay_triangulation_3 (InputIterator first, InputIterator last, + const DelaunayTriangulationTraits_3& traits = DelaunayTriangulationTraits_3())} +{Equivalent to constructing an empty triangulation with the optional +traits class argument and calling \ccc{insert(first,last)}.} + +\ccOperations + +\ccHeading{Insertion} + +The following methods overload the corresponding methods of +triangulations to ensure the empty sphere property of Delaunay +triangulations. + +In the degenerate case when there are co-spherical points, the Delaunay +triangulation is known not to be uniquely defined. In this case, \cgal\ +chooses a particular Delaunay triangulation using a symbolic perturbation +scheme~\cite{cgal:dt-pvr3d-03}. + +\ccThree{OutputIterator}{dt.remove()}{} + +\ccMethod{Vertex_handle insert(const Point & p, + Cell_handle start = Cell_handle() );} +{Inserts point \ccc{p} in the triangulation and returns the corresponding + vertex. Similar to the insertion in a triangulation, but ensures in +addition the empty sphere property of all the created faces. +The optional argument \ccc{start} is used as a starting place for the search.} + +\ccMethod{Vertex_handle insert(const Point & p, Vertex_handle hint);} +{ Same as above but uses \ccc{hint} as a starting place for the search. } + +\ccMethod{Vertex_handle insert(const Point & p, Locate_type lt, + Cell_handle loc, int li, int lj);} +{Inserts point \ccc{p} in the triangulation and returns the corresponding + vertex. Similar to the above \ccc{insert()} function, but takes as additional + parameter the return values of a previous location query. See description of + \ccc{Triangulation_3::locate()}.} + +The following method allows one to insert several points. It returns the +number of inserted points. + +\ccMethod{template < class InputIterator > + std::ptrdiff_t + insert(InputIterator first, InputIterator last);} +{Inserts the points in the iterator range $\left[\right.$\ccc{first}, +\ccc{last}$\left.\right)$. Returns the number of inserted points. +Note that this function is not guaranteed to insert the points +following the order of \ccc{InputIterator}, as \ccc{spatial_sort} +is used to improve efficiency. +\ccPrecond{The \ccc{value_type} of \ccc{first} and \ccc{last} is +\ccc{Point}.}} + +\ccHeading{Displacement} + +\ccMethod{Vertex_handle move_if_no_collision(Vertex_handle v, const Point & p);} +{ if there is not already another vertex placed on \ccc{p}, +the triangulation is modified such that the new position of vertex \ccc{v} +is \ccc{p}, and \ccc{v} is returned. Otherwise, the triangulation is not +modified and the vertex at point \ccc{p} is returned. +\ccPrecond Vertex \ccc{v} must be finite.} + +\ccMethod{Vertex_handle move(Vertex_handle v, const Point & p);} +{same as above if there is no collision. Otherwise, \ccc{v} +is deleted and the vertex placed on \ccc{p} is returned. + \ccPrecond Vertex \ccc{v} must be finite.} + +\ccHeading{Removal} + +When a vertex \ccc{v} is removed from a triangulation, all the cells +incident to \ccc{v} must be removed, and the polyhedral region +consisting of all the tetrahedra that are incident to \ccc{v} must be +re-triangulated. +So, the problem reduces to triangulating a polyhedral +region, while preserving its boundary, or to compute a +\textit{constrained} triangulation. This is known to be sometimes +impossible: the Sch\"onhardt polyhedron cannot be triangulated +\cite{cgal:s-cgehd-98}. + +However, when dealing with Delaunay triangulations, the case of such +polyhedra that cannot be re-triangulated cannot happen, so \cgal\ +proposes a vertex removal. + +\ccMethod{void remove(Vertex_handle v);} +{Removes the vertex \ccc{v} from the triangulation. +\ccPrecond{\ccc{v} is a finite vertex of the triangulation.}} + +\ccMethod{template < typename InputIterator > + int remove(InputIterator first, InputIterator beyond);} +{Removes the vertices specified by the iterator range [\ccStyle{first, beyond}) +of value type \ccc{Vertex_handle}. +\ccc{remove()} is called over each element of the range. +The number of vertices removed is returned. +\ccPrecond{(i) all vertices of the range are finite vertices of the triangulation; and (ii) no vertices are repeated in the range.}} + +\ccMethod{template < typename InputIterator > + int remove_cluster(InputIterator first, InputIterator beyond);} +{This function has exactly the same result and the same preconditions as \ccc{remove(first, beyond)}. +The difference is in the implementation and efficiency. This version does not re-triangulate the hole after each +point removal but only after removing all vertices. This is more efficient if (and only if) the removed points +are organized in a small number of connected components of the Delaunay triangulation.} + +If, due to some point removals, the size of the Delaunay triangulation decreases drastically, it might be interesting to defragment the +\ccc{CGAL::Compact_container} (used by the \ccc{Triangulation_data_structure_3}). + +\ccHeading{Queries} + +\ccMethod{Bounded_side + side_of_sphere(Cell_handle c, const Point & p) const;} +{Returns a value indicating on which side of the circumscribed sphere +of \ccc{c} the point \ccc{p} lies. More precisely, it returns:\\ +- \ccc{ON_BOUNDED_SIDE} if \ccc{p} is inside the sphere. For an infinite +cell this means that \ccc{p} lies strictly either in the half space +limited by its finite facet and not containing any other point of the +triangulation, or in the interior of the disk circumscribing the +\textit{finite} facet. \\ +- \ccc{ON_BOUNDARY} if p on the boundary of the sphere. For an infinite +cell this means that \ccc{p} lies on the circle circumscribing +the \textit{finite} facet.\\ +- \ccc{ON_UNBOUNDED_SIDE} if \ccc{p} lies outside the sphere. For an +infinite cell this means that \ccc{p} does not satisfy either of the +two previous conditions. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$.}} +\ccMethod{Bounded_side + side_of_circle(const Facet & f, const Point & p) const;} +{Returns a value indicating on which side of the circumscribed circle +of \ccc{f} the point \ccc{p} lies. More precisely, it returns:\\ +- in dimension~3:\\ +-- For a finite facet, \ccc{ON_BOUNDARY} if \ccc{p} lies +on the circle, \ccc{ON_UNBOUNDED_SIDE} when it lies in the exterior of +the disk, \ccc{ON_BOUNDED_SIDE} when it lies in its interior.\\ +-- For an infinite facet, it considers the plane defined by the finite +facet of the same cell, and does the same as in dimension~2 in this +plane.\\ +- in dimension~2:\\ +-- For a finite facet, \ccc{ON_BOUNDARY} if \ccc{p} lies +on the circle, \ccc{ON_UNBOUNDED_SIDE} when it lies in the exterior of +the disk, \ccc{ON_BOUNDED_SIDE} when it lies in its interior.\\ +-- For an infinite facet, \ccc{ON_BOUNDARY} if the +point lies on the finite edge of \ccc{f} (endpoints included), +\ccc{ON_BOUNDED_SIDE} for a point in the open half plane defined +by \ccc{f} and not containing any other point of the triangulation, +\ccc{ON_UNBOUNDED_SIDE} elsewhere. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and in dimension 3, +\ccc{p} is coplanar with \ccc{f}.}} + +\ccMethod{Bounded_side + side_of_circle(Cell_handle c, int i, const Point & p);} +{Same as the previous method for facet \ccc{i} of cell \ccc{c}.} + +\ccMethod{Vertex_handle nearest_vertex(Point p, + Cell_handle c = Cell_handle());} +{Returns any nearest vertex to the point \ccc{p}, or the default constructed +handle if the triangulation is empty. The optional argument \ccc{c} is a hint +specifying where to start the search. +\ccPrecond{\ccc{c} is a cell of \ccVar.} +} + +\ccMethod{Vertex_handle nearest_vertex_in_cell(Point p, + Cell_handle c);} +{Returns the vertex of the cell \ccc{c} that is +nearest to $p$. +} + +A point \ccc{p} is said to be in conflict with a cell \ccc{c} in dimension 3 +(resp. a facet \ccc{f} in dimension 2) iff \ccVar.\ccc{side_of_sphere(c, p)} +(resp. \ccVar.\ccc{side_of_circle(f, p)}) returns \ccc{ON_BOUNDED_SIDE}. +The set of cells (resp. facets in dimension 2) which are in conflict with +\ccc{p} is connected, and it forms a hole. + +\ccMethod{template + std::pair + find_conflicts(Point p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit);} +{Computes the conflict hole induced by \ccc{p}. The starting cell +(resp. facet) \ccc{c} must be in conflict. Then this function returns +respectively in the output iterators:\\ +-- \ccc{cit}: the cells (resp. facets) in conflict.\\ +-- \ccc{bfit}: the facets (resp. edges) on the boundary, that is, the facets +(resp. edges) \ccc{(t, i)} where the cell (resp. facet) \ccc{t} is in +conflict, but \ccc{t->neighbor(i)} is not.\\ +This function can be used in conjunction with \ccc{insert_in_hole()} in order +to decide the insertion of a point after seeing which elements of the +triangulation are affected. +Returns the pair composed of the resulting output iterators. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, and \ccc{c} is in conflict +with \ccc{p}.} +} + +\ccMethod{template + Triple + find_conflicts(Point p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit, + OutputIteratorInternalFacets ifit);} +{Same as the other \ccc{find_conflicts()} function, except that it also +computes the internal facets, i.e. the facets common to two cells which +are in conflict with \ccc{p}. +Then this function returns respectively in the output iterators:\\ +-- \ccc{cit}: the cells (resp. facets) in conflict.\\ +-- \ccc{bfit}: the facets (resp. edges) on the boundary, that is, the facets +(resp. edges) \ccc{(t, i)} where the cell (resp. facet) \ccc{t} is in +conflict, but \ccc{t->neighbor(i)} is not.\\ +-- \ccc{ifit}: the facets (resp. edges) inside the hole, that is, delimiting +two cells (resp facets) in conflict.\\ +Returns the \ccc{Triple} composed of the resulting output iterators. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, and \ccc{c} is in conflict +with \ccc{p}.} +} + +\begin{ccDeprecated} +\ccMethod{template + OutputIterator + vertices_in_conflict(Point p, Cell_handle c, + OutputIterator res);} +{This function is renamed \ccc{vertices_on_conflict_zone_boundary} since CGAL-3.8.} +\end{ccDeprecated} +\ccMethod{template + OutputIterator + vertices_on_conflict_zone_boundary(Point p, Cell_handle c, + OutputIterator res);} +{Similar to \ccc{find_conflicts()}, but reports the vertices which are on the +boundary of the conflict hole of \ccc{p}, in the output iterator \ccc{res}. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, and \ccc{c} is in conflict +with \ccc{p}.} +} + +A face (cell, facet or edge) is said to be a Gabriel face iff +its smallest circumscribing sphere do not enclose +any vertex of the triangulation. Any Gabriel face belongs to the +Delaunay triangulation, but the reciprocal is not true. +The following member functions test the Gabriel property of +Delaunay faces. +\ccMethod{bool is_Gabriel(Cell_handle c, int i);}{} +\ccGlue +\ccMethod{bool is_Gabriel(Cell_handle c, int i, int j);}{} +\ccGlue +\ccMethod{bool is_Gabriel(const Facet& f);}{} +\ccGlue +\ccMethod{bool is_Gabriel(const Edge& e);} {} + + +\ccHeading{Voronoi diagram} +\ccIndexMainItem{Voronoi diagram} +\cgal\ offers several functionalities to display the Voronoi diagram of +a set of points in 3D. + +Note that the user should use a kernel with exact constructions in order +to guarantee the computation of the Voronoi diagram (as opposed to computing +the triangulation only, which requires only exact predicates). + +\ccMethod{Point dual(Cell_handle c) const;} +{Returns the circumcenter of the four vertices of c. +\ccPrecond{\ccVar.\ccc{dimension()}$=3$ and \ccc{c} is not infinite.}} + +\ccMethod{Object dual(Facet f) const;} +{Returns the dual of facet \ccc{f}, which is \\ +in dimension 3: either a segment, if the two cells incident to \ccc{f} +are finite, or a ray, if one of them is infinite;\\ +in dimension 2: a point. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and \ccc{f} is not infinite.}} + +\ccMethod{Object dual(Cell_handle c, int i) const;} +{same as the previous method for facet \ccc{(c,i)}.} + +\ccMethod{Line dual_support(Cell_handle c, int i) const;} +{returns the line supporting the dual of the facet. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and \ccc{f} is not infinite.}} + +\ccMethod{template Stream & draw_dual(Stream & os);} +{Sends the set of duals to all the facets of \ccVar\ into \ccc{os}.} + + +\begin{ccDebug} +\ccHeading{Checking} +\ccMethod{bool + is_valid(bool verbose = false) const;} +{Checks the combinatorial validity of the triangulation and the +validity of its geometric embedding (see +Section~\ref{Triangulation3-sec-intro}). Also checks that all the +circumscribing spheres (resp. circles in dimension~2) of cells +(resp. facets in dimension~2) are empty.\\ When \ccc{verbose} is set to +true, messages describing the first invalidity encountered are +printed.} + +\ccMethod{bool + is_valid(Cell_handle c, bool verbose = false) const;} +{Checks the combinatorial and geometric validity of the cell (see +Section~\ref{Triangulation3-sec-intro}). Also checks that the +circumscribing sphere (resp. circle in dimension~2) of cells +(resp. facet in dimension~2) is empty.\\ + When \ccc{verbose} is set to +true, messages are printed to give +a precise indication of the kind of invalidity encountered.} + +These methods are mainly a debugging help for the users of advanced features. +\end{ccDebug} + +\ccSeeAlso + +\ccc{CGAL::Regular_triangulation_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/RegularCellBase_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/RegularCellBase_3.tex new file mode 100644 index 00000000000..bae65f3d8f9 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/RegularCellBase_3.tex @@ -0,0 +1,89 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: RegularCellBase_3.tex +% +------------------------------------------------------------------------+ +% | 12.04.2000 Author +% | Package: Package +% | +\RCSdef{\RCSRegularcellbaseRev}{$Id$} +\RCSdefDate{\RCSRegularcellbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{RegularTriangulationCellBase_3} + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[concept]{} %% add further index entries + +\ccDefinition + +The regular triangulation of a set of weighted points does not +necessarily +have one vertex for each of the input points. Some of the input +weighted points have no cell in the dual power diagrams +and therefore do not correspond to a vertex of the regular +triangulation. +Those weighted points are said to be {\it hidden} points. +A point which is hidden at a given time may appear later as a vertex of +the regular triangulation upon removal on some other weighted point. +Therefore, hidden points have to be stored somewhere. +The regular triangulation stores those hidden points +in its cells. + +A hidden point can appear as vertex of the triangulation +only when the +three dimensional cell where its point component is located +(the cell which hides it) +is removed. Therefore we decided to store +in each cell of a regular triangulation +the list of hidden points that are located in the face. +Thus points hidden by a face are easily reinserted in the triangulation +when the face is removed. + +The base cell of a regular triangulation +has to be a model +of the concept \ccRefName, which refines +the concept \ccc{TriangulationCellBase_3} by adding +in the cell a container to store hidden points. + +\ccRefines +\ccc{TriangulationCellBase_3} + +\ccTypes +\ccNestedType{Point} +{Must be the same as the point type \ccc{TriangulationTraits_3::Point_3} +defined by the geometric traits class of the triangulation.} + +\ccTypes +\ccNestedType{Point_iterator} +{Iterator of value type Point} + + +\ccCreationVariable{rcb} %% choose variable name + + +\ccHeading{Access Functions} +\ccMethod{Point_iterator hidden_points_begin();} +{Returns an iterator pointing to the first hidden point.} + +\ccMethod{Point_iterator hidden_points_end();} +{Returns a past-the-end iterator.} + +\ccHeading{Setting} +\ccMethod{void hide_point(const Point & p);} +{Adds \ccc{p} to the set of hidden points of the cell.} + +\ccHasModels +\ccc{CGAL::Regular_triangulation_cell_base_3} + +\ccSeeAlso +\ccc{TriangulationCellBase_3} + +\end{ccRefConcept} + +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +% EOF +% +------------------------------------------------------------------------+ + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/RegularTriangulationTraits_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/RegularTriangulationTraits_3.tex new file mode 100644 index 00000000000..eab9b4165a5 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/RegularTriangulationTraits_3.tex @@ -0,0 +1,198 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_Traits_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationTraitsRev}{$Id$} +\RCSdefDate{\RCSTriangulationTraitsDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{RegularTriangulationTraits_3} + +\ccDefinition +The concept \ccRefName\ is the first template parameter of the class +\ccc{Regular_triangulation_3}. It defines the geometric objects (points, +segments...) forming the triangulation together with a few geometric +predicates and constructions on these objects. + +\ccRefines \ccc{TriangulationTraits_3} + +In addition to the requirements described for the traits class of +\ccc{Triangulation_3}, the geometric traits class of +\ccc{Regular_triangulation_3} must fulfill the following requirements. +%It must provide definitions for the \textit{power tests}. + + +\ccTypes +\ccTwo{DelaunayTriangulationTraits_3::Object_3_xxxxx}{} + +\ccNestedType{Line_3}{The line type.} +\ccGlue +\ccNestedType{Object_3}{The object type.} +\ccGlue +\ccNestedType{Plane_3}{The plane type.} +\ccGlue +\ccNestedType{Ray_3}{The ray type.} + + + + +We use here the same notation as in +Section~\ref{Triangulation3-sec-class-Regulartriangulation}. +To simplify notation, $p$ will often denote in the sequel either the +point $p\in\R^3$ or the weighted point ${p}^{(w)}=(p,w_p)$. + +\ccTwo{RegularTriangulationTraits_3::Weighted_point_3xx}{} +\ccNestedType{Weighted_point_3}{The weighted point type.} + +\ccTwo{Regular}{} +\ccNestedType{Power_test_3} +{A predicate object which must provide the following function operators: +% +\\ +\\ +\ccc{Oriented_side operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s, + Weighted_point_3 t)},\\ +which performs the following:\\ +Let ${z(p,q,r,s)}^{(w)}$ be the power sphere of the weighted points +$(p,q,r,s)$. Returns \\ +\ccc{ON_ORIENTED_BOUNDARY} if \ccc{t} is orthogonal to +${z(p,q,r,s)}^{(w)}$,\\ +\ccc{ON_NEGATIVE_SIDE} if \ccc{t} lies outside the oriented sphere of +center $z(p,q,r,s)$ and radius $\sqrt{ w_{z(p,q,r,s)}^2 + w_t^2 }$ +(which is equivalent to $\Pi({t}^{(w)},{z(p,q,r,s)}^{(w)} >0$)),\\ +\ccc{ON_POSITIVE_SIDE} if \ccc{t} lies inside this oriented sphere. +\ccPrecond{\ccc{p, q, r, s} are not coplanar.} +% +Note that with this definition, if all the points have a weight equal +to 0, then +\ccc{power_test_3(p,q,r,s,t)} = \ccc{side_of_oriented_sphere(p,q,r,s,t)}. +% +% +\\ +\\ +\ccc{Oriented_side operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 t)},\\ +which has an +definition analogous to the previous method, for coplanar points, +with the power circle ${z(p,q,r)}^{(w)}$. +\ccPrecond{\ccc{p, q, r} are not collinear and \ccc{p, q, r, t} are +coplanar.} +% +If all the points have a weight equal to 0, then +\ccc{power_test_3(p,q,r,t)} = \ccc{side_of_oriented_circle(p,q,r,t)}. +% +\\ +\\ +\ccc{Oriented_side operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 t)},\\ +which is the same for collinear points, where ${z(p,q)}^{(w)}$ is the +power segment of \ccc{p} and \ccc{q}. +\ccPrecond{\ccc{p} and \ccc{q} have different Bare\_points, and +\ccc{p, q, t} are collinear.} +% +If all points have a weight equal to 0, then +\ccc{power_test_3(p,q,t)} gives the same answer as the kernel predicate +\ccc{s(p,q).has_on(t)} would give, where \ccc{s(p,q)} denotes the +segment with endpoints \ccc{p} and \ccc{q}. +% +\\ +\\ +\ccc{Oriented_side operator()( Weighted_point_3 p, Weighted_point_3 q)},\\ +which is the same for equal points, that is when \ccc{p} and \ccc{q} +have equal coordinates, then it returns the comparison of the weights +(\ccc{ON_POSITIVE_SIDE} when \ccc{q} is heavier than \ccc{p}). +\ccPrecond{\ccc{p} and \ccc{q} have equal Bare\_points.} +} + +The following predicate is required if a call to +\ccc{nearest_power_vertex} +or \ccc{nearest_power_vertex_in_cell} is issued: + +\ccNestedType{Compare_power_distance_3} +{A predicate object that must provide the function operator\\ +\ccc{Comparison_result operator()(Point_3 p, Weighted_point_3 q, +Weighted_point_3 r)},\\ +which compares the power distance between \ccc{p} and \ccc{q} +to the power distance +between \ccc{p} and \ccc{r}.} + +In addition, only when the dual operations are used, the traits class +must provide the following constructor objects: + +\ccTwo{DelaunayTriangulationTraits_3}{} +\ccNestedType{Construct_weighted_circumcenter_3} +{A constructor type. The operator() constructs the bare point + which is the center of the smallest orthogonal sphere to the input +weighted points. \\ +\ccc{Bare_point operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s);} +} +\ccGlue +\ccNestedType{Construct_object_3} +{A constructor object that must provide the function operators\\ +\ccc{Object_3 operator()(Point_3 p)},\\ +\ccc{Object_3 operator()(Segment_3 s)} and\\ +\ccc{Object_3 operator()(Ray_3 r)}\\ +that construct an object respectively from a point, a segment and a ray.} +\ccGlue +\ccNestedType{Construct_perpendicular_line_3} +{A constructor object that must provide the function operator\\ +\ccc{Line_3 operator()(Plane_3 pl, Point_3 p)},\\ +which constructs the line perpendicular to \ccc{pl} passing through \ccc{p}.} +\ccGlue +\ccNestedType{Construct_plane_3} +{A constructor object that must provide the function operator\\ +\ccc{Plane_3 operator()(Point_3 p, Point_3 q, Point_3 r)},\\ +which constructs the plane passing through \ccc{p}, \ccc{q} and \ccc{r}. +\ccPrecond{\ccc{p}, \ccc{q} and \ccc{r} are non collinear.}} +\ccGlue +\ccNestedType{Construct_ray_3} +{A constructor object that must provide the function operator\\ +\ccc{Ray_3 operator()(Point_3 p, Line_3 l)},\\ +which constructs the ray starting at \ccc{p} with direction given by \ccc{l}.} + + + + + +\ccOperations + +The following function gives access to the predicate object: +\ccThree{coplanar_side_of_bounded}{gt.xxxxxxxxx(Point p0, Point p1)x}{} +\ccCreationVariable{traits} %% choose variable name + +\ccMethod{Power_test_3 power_test_3_object();}{} + +The following functions must be provided only if the member functions + of \ccc{Regular_triangulation_3} returning elements of the dual diagram +are called: + +\ccMethod{Construct_weighted_circumcenter_3 construct_weighted_circumcenter_3_object();}{} +\ccGlue +\ccMethod{Construct_object_3 construct_object_3_object();}{} +\ccGlue +\ccMethod{Construct_perpendicular_line_3 construct_perpendicular_line_object();}{} +\ccGlue +\ccMethod{Construct_plane_3 construct_plane_3_object();}{} +\ccGlue +\ccMethod{Construct_ray_3 construct_ray_3_object();}{} + +\ccHasModels + +\ccc{CGAL::Regular_triangulation_euclidean_traits_3}\\ + + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_3.tex new file mode 100644 index 00000000000..0ae9b2d4942 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_3.tex @@ -0,0 +1,426 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Regular_triangulation_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSRegulartriangulationRev}{$Id$} +\RCSdefDate{\RCSRegulartriangulationDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Regular_triangulation_3} + +\ccDefinition + Let ${S}^{(w)}$ be a set of weighted points in $\R^3$. Let +${p}^{(w)}=(p,w_p), p\in\R^3, w_p\in\R$ and +${z}^{(w)}=(z,w_z), z\in\R^3, w_z\in\R$ be two weighted points. +A weighted point +${p}^{(w)}=(p,w_p)$ can also be seen as a sphere of center $p$ and +radius $\sqrt{w_p}$. +The \textit{power product} (or \textit{power distance} ) +between ${p}^{(w)}$ and ${z}^{(w)}$ is +defined as +\[\Pi({p}^{(w)},{z}^{(w)}) = {\|{p-z}\|^2-w_p-w_z}\] +where $\|{p-z}\|$ is the Euclidean distance between $p$ and $z$. + ${p}^{(w)}$ and ${z}^{(w)}$ +are said to be \textit{orthogonal} if $\Pi{({p}^{(w)}-{z}^{(w)})} += 0$ (see Figure~\ref{Triangulation3-fig-ortho}). + +Four weighted points have a unique common orthogonal weighted point called +the \textit{power sphere}. A sphere ${z}^{(w)}$ is said to be +\textit{regular} if $\forall {p}^{(w)}\in{S}^{(w)}, +\Pi{({p}^{(w)}-{z}^{(w)})}\geq 0$. + +A triangulation of ${S}^{(w)}$ is \textit{regular} if the power spheres +of all simplices are regular. + +\ccInclude{CGAL/Regular_triangulation_3.h} + +\ccParameters + +The first template argument must be a model of the +\ccc{RegularTriangulationTraits_3} concept. + +The second template argument must be a model of the +\ccc{TriangulationDataStructure_3} concept. +It has the default value \ccc{Triangulation_data_structure_3, Regular_triangulation_cell_base_3 >}. + + +\ccInheritsFrom{\ccc{Triangulation_3}} + +\ccTypes +\ccThree{typedef RegularTriangulationTraits_3::Weighted_point_3}{Weighted_point}{} + +\ccTypedef{typedef RegularTriangulationTraits_3::Bare_point Bare_point;} +{The type for points +\ccc{p} of weighted points ${p}^{(w)}=(p,w_p)$} +\ccGlue +\ccTypedef{typedef RegularTriangulationTraits_3::Weighted_point_3 Weighted_point;}{} + +\ccCreation +\ccCreationVariable{rt} + + +\ccThree{Regular_triangulation_3} +{rt( RegularTriangulationTraits_3 traits );xxx}{} + +\ccConstructor{Regular_triangulation_3 +(const RegularTriangulationTraits_3 & traits = RegularTriangulationTraits_3())} +{Creates an empty regular triangulation, possibly specifying a traits class +\ccc{traits}.} + +\ccConstructor{Regular_triangulation_3 +(const Regular_triangulation_3 & rt1)} {Copy constructor.} + +\ccConstructor{template < class InputIterator > + Regular_triangulation_3 (InputIterator first, InputIterator last, + const RegularTriangulationTraits_3& traits = RegularTriangulationTraits_3())} +{Equivalent to constructing an empty triangulation with the optional +traits class argument and calling \ccc{insert(first,last)}.} + +\ccOperations + + +\ccHeading{Insertion} +\ccThree{OutputIterator}{dt.insertxx}{} + +The following methods, which already exist in \ccc{Triangulation_3}, are +overloaded to ensure the property that all power spheres are regular. + +\ccMethod{Vertex_handle insert(const Weighted_point & p, + Cell_handle start = Cell_handle() );} +{Inserts weighted point \ccc{p} in the triangulation. The optional +argument \ccc{start} is used as a starting place for the search.\\ +If this insertion creates a vertex, this vertex is returned.\\ +If \ccc{p} coincides with an existing vertex and has a greater weight, +then the existing weighted point becomes hidden (see +\ccc{RegularTriangulationCellBase_3}) and \ccc{p} replaces it as vertex +of the triangulation.\\ +If \ccc{p} coincides with an already existing vertex (both point and +weights being equal), then this vertex is returned and the triangulation +remains unchanged.\\ +Otherwise if \ccc{p} does not appear as a vertex of the triangulation, +then it is stored as a hidden point and this method returns the default +constructed handle.} + +\ccMethod{Vertex_handle insert(const Weighted_point & p, Vertex_handle hint);} +{ Same as above but uses \ccc{hint} as a starting place for the search. } + +\ccMethod{Vertex_handle insert(const Weighted_point & p, Locate_type lt, + Cell_handle loc, int li, int lj);} +{Inserts weighted point \ccc{p} in the triangulation and returns the corresponding + vertex. Similar to the above \ccc{insert()} function, but takes as additional + parameter the return values of a previous location query. See description of + \ccc{Triangulation_3::locate()}.} + +The following method allows one to insert several points. + +\ccMethod{template < class InputIterator > + std::ptrdiff_t + insert(InputIterator first, InputIterator last);} +{Inserts the weighted points in the range $\left[\right.$\ccc{first}, +\ccc{last}$\left.\right)$. +Note that this function is not guaranteed to insert the points +following the order of \ccc{InputIterator}. +It returns the difference of the number of vertices between after and +before the insertions (it may be negative due to hidden points). +\ccPrecond{The \ccc{value_type} of \ccc{first} and \ccc{last} is +\ccc{Weighted_point}.}} + +The following methods, which already exist in \ccc{Triangulation_3}, are +overloaded to ensure that hidden points are well created and maintained. + +\ccMethod{template + Vertex_handle insert_in_hole(Weighted_point p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i);} +{Creates a new vertex by starring a hole. It takes an iterator range +[\ccc{cell_begin}; \ccc{cell_end}[ of \ccc{Cell_handle}s which specifies +a hole: a set of connected cells (resp. facets in dimension 2) which is +star-shaped wrt \ccc{p}. +(\ccc{begin}, \ccc{i}) is a facet (resp. an edge) on the boundary of the hole, +that is, \ccc{begin} belongs to the set of cells (resp. facets) previously +described, and \ccc{begin->neighbor(i)} does not. Then this function deletes +all the cells (resp. facets) describing the hole, creates a new vertex +\ccc{v}, and for each facet (resp. edge) on the boundary of the hole, creates +a new cell (resp. facet) with \ccc{v} as vertex. Then \ccc{v->set_point(p)} +is called and \ccc{v} is returned.\\ +If the hole contains interior vertices, each of them is hidden by the insertion +of \ccc{p} and is stored in the new cell which contains it. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, the set of cells (resp. facets in +dimension 2) is connected, not empty, its boundary is connected, and \ccc{p} +lies inside the hole, which is star-shaped wrt \ccc{p}}.} + +\ccMethod{template + Vertex_handle insert_in_hole(Weighted_point p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv);} +{ Same as above, except that \ccc{newv} will be used as the new vertex, which + must have been allocated previously with e.g. \ccc{create_vertex}.} + + +\ccHeading{Removal} + +\ccMethod{void remove(Vertex_handle v);} +{Removes the vertex \ccc{v} from the triangulation.} + +\ccHeading{Queries} +\ccThree{OutputIterator}{rt.side of powerxx}{} + +Let us remark that +\[\Pi({p}^{(w)}-{z}^{(w)}) > 0\] +is equivalent to\\ +\centerline{\ccc{p} lies outside the sphere with center \ccc{z} and radius +$\sqrt{w_p^2+w_z^2}$.}\\ +This remark helps provide an intuition about the following predicates. + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{Triangulation_3_ref/sidedim2} +\end{center} +\end{ccTexOnly} +\caption{side\_of\_power\_circle. +\label{Triangulation3-fig-sidedim2}} +\begin{ccHtmlOnly} +
+side_of_power_circle +
+\end{ccHtmlOnly} +\end{figure} + +\ccMethod{Bounded_side + side_of_power_sphere(Cell_handle c, const Weighted_point & p) const;} +{Returns the position of the weighted point $p$ with respect to the +power sphere of \ccc{c}. More precisely, it returns:\\ +- \ccc{ON_BOUNDED_SIDE} if $\Pi({p}^{(w)}-{z(c)}^{(w)})<0$ where +${z(c)}^{(w)}$ is the power sphere of \ccc{c}. For an +infinite cell this means either that \ccc{p} lies strictly in the half +space limited by its finite facet and not containing any other point +of the triangulation, or that the angle +between \ccc{p} and the power circle of the \textit{finite} facet of \ccc{c} +is greater than $\pi/2$. \\ +- \ccc{ON_BOUNDARY} if p is orthogonal to the power sphere of \ccc{c} +i.e. $\Pi({p}^{(w)}-{z(c)}^{(w)})=0$. For an infinite cell this means +that \ccc{p} is orthogonal to the power circle of its \textit{finite} facet.\\ +- \ccc{ON_UNBOUNDED_SIDE} if $\Pi({p}^{(w)}-{z(c)}^{(w)})>0$ +i.e. the angle between the weighted point \ccc{p} and the power sphere +of \ccc{c} is less than $\pi/2$ or if these two spheres do not +intersect. For an +infinite cell this means that \ccc{p} does not satisfy either of the +two previous conditions. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$.}} + +\ccMethod{Bounded_side + side_of_power_circle(const Facet & f, + const Weighted_point & p) const;} +{Returns the position of the point \ccc{p} with respect to the +power circle of \ccc{f}. More precisely, it returns:\\ +--- in dimension~3:\\ +-- For a finite facet,\\ +\ccc{ON_BOUNDARY} if \ccc{p} is orthogonal to the power circle in the +plane of the facet,\\ +\ccc{ON_UNBOUNDED_SIDE} when their angle is less than $\pi/2$,\\ +\ccc{ON_BOUNDED_SIDE} when it is greater than $\pi/2$ (see +Figure~\ref{Triangulation3-fig-sidedim2}).\\ +-- For an infinite facet, it considers the plane defined by the finite +facet of the cell \ccc{f.first}, and does the same as in +dimension~2 in this plane.\\ +--- in dimension~2:\\ +-- For a finite facet,\\ +\ccc{ON_BOUNDARY} if \ccc{p} is orthogonal to the circle,\\ +\ccc{ON_UNBOUNDED_SIDE} when the angle between \ccc{p} and the +power circle of \ccc{f} is less than $\pi/2$, +\ccc{ON_BOUNDED_SIDE} when it is greater than $\pi/2$.\\ +-- For an infinite facet,\\ +\ccc{ON_BOUNDED_SIDE} for a point in the open half plane defined by +\ccc{f} and not containing any other point of the triangulation,\\ +\ccc{ON_UNBOUNDED_SIDE} in the other open half plane.\\ +If the point \ccc{p} is collinear with the finite edge \ccc{e} of +\ccc{f}, it returns:\\ +\ccc{ON_BOUNDED_SIDE} if $\Pi({p}^{(w)}-{z(e)}^{(w)})<0$, where +${z(e)}^{(w)}$ is the power segment of \ccc{e} in the line supporting +\ccc{e},\\ +\ccc{ON_BOUNDARY} if $\Pi({p}^{(w)}-{z(e)}^{(w)})=0$,\\ +\ccc{ON_UNBOUNDED_SIDE} if $\Pi({p}^{(w)}-{z(e)}^{(w)})>0$ . +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$.}} + +\ccMethod{Bounded_side + side_of_power_circle(Cell_handle c, int i, + const Weighted_point & p) const;} +{Same as the previous method for facet \ccc{i} of cell \ccc{c}.} + +\ccMethod{Bounded_side + side_of_power_segment(Cell_handle c, const Weighted_point & p) +const;} +{In dimension~1, returns\\ +\ccc{ON_BOUNDED_SIDE} if $\Pi({p}^{(w)}-{z(c)}^{(w)})<0$, where +${z(c)}^{(w)}$ is the power segment of the edge represented by +\ccc{c},\\ +\ccc{ON_BOUNDARY} if $\Pi({p}^{(w)}-{z(c)}^{(w)})=0$,\\ +\ccc{ON_UNBOUNDED_SIDE} if $\Pi({p}^{(w)}-{z(c)}^{(w)})>0$ . +\ccPrecond{\ccVar.\ccc{dimension()} $= 1$.}} + +\ccMethod{Vertex_handle nearest_power_vertex(Weighted_point p, + Cell_handle c = Cell_handle());} +{Returns the vertex of the triangulation which is nearest to $p$ +with respect to the power distance. This means that the power +of the query point \ccc{p} with respect to the weighted point in +the returned vertex is smaller than the power of \ccc{p} + with respect to the weighted point +in any other vertex. Ties are broken arbitrarily. +The default constructed +handle is returned if the triangulation is empty. +The optional argument \ccc{c} is a hint +specifying where to start the search. +\ccPrecond{\ccc{c} is a cell of \ccVar.} +} + + +\ccMethod{Vertex_handle nearest_power_vertex_in_cell(Weighted_point p, + Cell_handle c);} +{Returns the vertex of the cell \ccc{c} +that is nearest to $p$ +with respect to the power distance. +} + +A weighted point \ccc{p} is said to be in conflict +with a cell \ccc{c} in dimension 3 +(resp. with a facet \ccc{f} in dimension 2) +if it has a negative power distance +to the power sphere of \ccc{c} +(resp. to the power circle of \ccc{f}). +The set of cells (resp. facets in dimension 2) which are in conflict with +\ccc{p} is connected. + +\ccMethod{template + Triple + find_conflicts(const Weighted_point p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit, + OutputIteratorInternalFacets ifit);} +{ Compute the conflicts with \ccc{p}. + The starting cell +(resp. facet) \ccc{c} must be in conflict with \ccc{p}. +Then this function returns +respectively in the output iterators:\\ +-- \ccc{cit}: the cells (resp. facets) in conflict with \ccc{p}.\\ +-- \ccc{bfit}: the facets (resp. edges) on the boundary of the +conflict zone, that is, the facets +(resp. edges) \ccc{(t, i)} where the cell (resp. facet) \ccc{t} is in +conflict, but \ccc{t->neighbor(i)} is not.\\ +-- \ccc{ifit}: the facets (resp. edges) inside the conflict zone, +that facets incident to two cells (resp facets) in conflict.\\ +Returns the \ccc{Triple} composed of the resulting output iterators. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, and \ccc{c} is in conflict +with \ccc{p}.} +} + +\begin{ccDeprecated} +\ccMethod{template + OutputIterator + vertices_in_conflict(Weighted_point p, Cell_handle c, + OutputIterator res);} +{This function is renamed \ccc{vertices_on_conflict_zone_boundary} since CGAL-3.8.} +\end{ccDeprecated} +\ccMethod{template + OutputIterator + vertices_on_conflict_zone_boundary(Weighted_point p, Cell_handle c, + OutputIterator res);} +{Similar to \ccc{find_conflicts()}, but reports the vertices which are on the +boundary of the conflict zone of \ccc{p}, in the output iterator \ccc{res}. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, and \ccc{c} is a cell containing + \ccc{p}.} +} + +\ccMethod{template + OutputIterator + vertices_inside_conflict_zone(Weighted_point p, Cell_handle c, + OutputIterator res);} +{Similar to \ccc{find_conflicts()}, but reports the vertices which are in + the interior of the conflict zone of \ccc{p}, in the output iterator + \ccc{res}. The vertices that are on the boundary of the conflict zone are + not reported. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, and \ccc{c} is a cell containing + \ccc{p}.} +} + +In the weighted setting, a face (cell, facet, edge or vertex) +is said to be a Gabriel face iff +the smallest sphere orthogonal to the weighted +points associated to its vertices, +has a positive power product with the weighted point +of any other vertex of the triangulation. +Any weighted Gabriel face belongs to the +regular triangulation, but the reciprocal is not true. +The following member functions test the Gabriel property of the +faces of the regular triangulation. +\ccMethod{bool is_Gabriel(Cell_handle c, int i);}{} +\ccGlue +\ccMethod{bool is_Gabriel(Cell_handle c, int i, int j);}{} +\ccGlue +\ccMethod{bool is_Gabriel(const Facet& f);}{} +\ccGlue +\ccMethod{bool is_Gabriel(const Edge& e);} {} +\ccGlue +\ccMethod{bool is_Gabriel(Vertex_handle v);}{} + + +\ccHeading{Power diagram} +\ccIndexMainItem{Power diagram} +\cgal\ offers several functionalities to display the Power diagram of +a set of points in 3D. + +Note that the user should use a kernel with exact constructions in order +to guarantee the computation of the Voronoi diagram (as opposed to computing +the triangulation only, which requires only exact predicates). + +\ccMethod{Weighted_point dual(Cell_handle c) const;} +{Returns the weighted circumcenter of the four vertices of c. +\ccPrecond{\ccVar.\ccc{dimension()}$=3$ and \ccc{c} is not infinite.}} + +\ccMethod{Object dual(Facet f) const;} +{Returns the dual of facet \ccc{f}, which is \\ +in dimension 3: either a segment, if the two cells incident to \ccc{f} +are finite, or a ray, if one of them is infinite;\\ +in dimension 2: a point. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and \ccc{f} is not infinite.}} + +\ccMethod{Object dual(Cell_handle c, int i) const;} +{same as the previous method for facet \ccc{(c,i)}.} + +\ccMethod{template Stream & draw_dual(Stream & os);} +{Sends the set of duals to all the facets of \ccVar\ into \ccc{os}.} + + +\begin{ccDebug} +\ccHeading{Checking} +\ccMethod{bool + is_valid(bool verbose = false) const;} +{Checks the combinatorial validity of the triangulation and the +validity of its geometric embedding (see +Section~\ref{Triangulation3-sec-intro}). Also checks that all the +power spheres (resp. power circles in dimension~2, power segments in +dimension~1) of cells (resp. facets in dimension~2, edges in +dimension~1) are regular. When \ccc{verbose} +is set to true, messages describing the first invalidity encountered +are printed.\\ This method is mainly a debugging help for the users of +advanced features. +} + +\end{ccDebug} + +%\ccSeeAlso + +%% \ccExample + +%% \ccIncludeExampleCode{Triangulation3/Regular_triangulation_3_prog.cpp} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_cell_base_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_cell_base_3.tex new file mode 100644 index 00000000000..3c2cbafa987 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_cell_base_3.tex @@ -0,0 +1,55 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Regular_triangulation_face_base_2.tex +% +------------------------------------------------------------------------+ +% | 12.04.2000 Author +% | Package: Package +% | +\RCSdef{\RCSRegulartriangulationcellbaseRev}{$Id$} +\RCSdefDate{\RCSRegulartriangulationcellbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Regular_triangulation_cell_base_3} %% add template arg's if necessary + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[class]{} %% add further index entries + +\ccDefinition +The class \ccRefName\ is a model of the concept +\ccc{RegularTriangulationCellBase_3}. It is the default face base class +of regular triangulations. + +\ccInclude{CGAL/Regular_triangulation_cell_base_3.h} + + +\ccParameters +The template parameters \ccc{Traits} has to be a model +of \ccc{RegularTriangulationTraits_3}. + +The template parameter \ccc{Cb} has to be a model +of \ccc{TriangulationCellBase_3}. By default, this parameter is +instantiated by +\ccc{CGAL::Triangulation_cell_base_3}. + + +\ccIsModel +\ccc{RegularTriangulationCellBase_3} + +\ccInheritsFrom +\ccc{Cb} + +\ccSeeAlso +\ccc{RegularTriangulationCellBase_3} \\ +\ccc{RegularTriangulationTraits_3} \\ +\ccc{CGAL::Regular_triangulation_3} + + +\end{ccRefClass} + +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +% EOF +% +------------------------------------------------------------------------+ + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_euclidean_traits_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_euclidean_traits_3.tex new file mode 100644 index 00000000000..ae012b1f475 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_euclidean_traits_3.tex @@ -0,0 +1,273 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Regular_triangulation_euclidean_traits_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSRegulartriangulationeuclideantraitsRev}{$Id$} +\RCSdefDate{\RCSRegulartriangulationeuclideantraitsDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Regular_triangulation_euclidean_traits_3} %% add template arg's if necessary + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[class]{} %% add further index entries + +\ccDefinition + +The class \ccRefName\ is designed as a default traits class for the +class \ccc{Regular_triangulation_3}. +It provides \ccc{Weighted_point_3}, a class for weighted points, which derives +from the three dimensional point class \ccc{K::Point_3}. + +The first argument \ccc{K} must be a model of the \ccc{Kernel} concept. + +The second argument \ccc{Weight} of the class +\ccc{Regular_triangulation_euclidean_traits_3} is in fact +optional: if is it not provided, \ccc{K::RT} will be used. + +The class is a model of the concept \ccc{RegularTriangulationTraits_3} +but it also contains predicates and constructors on weighted points +that are not required in the +concept \ccc{RegularTriangulationTraits_3}. + +Note that filtered predicates are automatically used if the +boolean \ccc{Has_filtered_predicates} in the kernel provided as template parameter +of that class is set to \ccc{true}. + +% Note that this template class is specialized for +% \ccc{CGAL::Exact_predicates_inexact_constructions_kernel}, so that it is as if +% \ccc{Regular_triangulation_filtered_traits_3} was used, i.e. you get +% filtered predicates automatically. + + + + +\ccInclude{CGAL/Regular_triangulation_euclidean_traits_3.h} + +\ccIsModel +\ccc{RegularTriangulationTraits_3} + +\ccInheritsFrom{\ccc{K}} + +\ccTypes +\ccThree{typedef Weighted_point }{Weighted_point_3;}{} + +\ccTypedef{typedef K::Point_3 Bare_point;} +{The type for point $p$ of a weighted point ${p}^{(w)}=(p,w_p)$.} +\ccGlue +\ccTypedef{typedef Weighted_point +Weighted_point_3;} +{The type for weighted points.} + +\ccHeading{Types for predicate functors} +\ccTwo{Regular}{} +\ccNestedType{Power_test_3} +{A predicate type for power test. Belongs to the +\ccc{RegularTriangulationTraits_3} concept.} + +\ccNestedType{Compare_power_distance_3} +{A predicate type to compare power distance. Belongs to the +\ccc{RegularTriangulationTraits_3} concept.} + + +\ccNestedType{Compare_weighted_squared_radius_3} +{A predicate type. The operator() takes weighted point(s) as arguments, +together with one weight. It compares the weight of the smallest sphere +orthogonal to the weighted points with the input weight.\\ +\ccc{Comparison_result operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s, + FT w) ;} \\ +\ccc{Comparison_result operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + FT w) ;} \\ +\ccc{Comparison_result operator()( Weighted_point_3 p, + Weighted_point_3 q, + FT w) ;} \\ +\ccc{Comparison_result operator()( Weighted_point_3 p, + FT w) ;} \\ +} + + +\ccNestedType{In_smallest_orthogonal_sphere_3} +{A predicate type. The operator() takes weighted points as arguments + and returns the sign of the power distance of the last one +with respect to the smallest sphere orthogonal to the others. \\ +\ccc{Sign operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s, + Weighted_point_3 t) ;} \\ +\ccc{Sign operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s) ;} \\ +\ccc{Sign operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r) ;} \\ +\ccc{Sign operator()( Weighted_point_3 p, + Weighted_point_3 q) ;} \\ +} + + +\ccNestedType{Side_of_bounded_orthogonal_sphere_3} +{A predicate type. The operator() is similar to the operator() of +\ccc{In_smallest_orthogonal_sphere_3} +except that the returned type is not a \ccc{Sign} +but belongs to the enum \ccc{Bounded_side} +(A \ccc{NEGATIVE}, \ccc{ZERO} and \ccc{POSITIVE}) + corresponding respectively to +\ccc{ON_BOUNDED_SIDE}, \ccc{ON_BOUNDARY} and \ccc{ON_UNBOUNDED_SIDE})). + \\ +\ccc{Bounded_side operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s, + Weighted_point_3 t) ; } \\ +\ccc{Bounded_side operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s) ; } \\ +\ccc{Bounded_side operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r) ; } +} + + +\ccNestedType{Does_simplex_intersect_dual_support_3} +{A predicate type. The operator() +takes weighted points as arguments, +considers the subspace of points with equal power distance +with respect to its arguments +and the intersection of this subspace with the affine hull of the bare +points associated to the arguments. +The operator() returns \ccc{ON_BOUNDED_SIDE}, +\ccc{ON_BOUNDARY} or \ccc{ON_UNBOUNDED_SIDE} +according to the position of this intersection +with respect to the simplex formed by the bare +points. +This predicate is useful for flow computations. \\ +\ccc{Bounded_side operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s) ; } \\ +\ccc{Bounded_side operator()( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r) ; }\\ +\ccc{Bounded_side operator()( Weighted_point_3 p, + Weighted_point_3 q) ; } +} + +\ccHeading{Types for constructor functors} + +\ccNestedType{Construct_weighted_circumcenter_3} +{A constructor type. The operator() constructs the bare point + which is the center of the smallest orthogonal sphere to the input +weighted points. \\ +\ccc{Bare_point operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s);} \\ +\ccc{Bare_point operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r);} \\ +\ccc{Bare_point operator() ( Weighted_point_3 p, + Weighted_point_3 q);} +} + + + +\ccNestedType{Compute_power_product_3} +{A functor type. The operator() computes the power distance between its +arguments. \\ +\ccc{FT operator() ( Weighted_point_3 p, + Weighted_point_3 q) ; } +} + + +\ccNestedType{Compute_squared_radius_smallest_orthogonal_sphere_3} +{A functor type. The operator() computes the squared radius of the +smallest sphere orthogonal to the argument(s). +\\ +\ccc{FT operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s);} \\ +\ccc{FT operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r);} \\ +\ccc{FT operator() ( Weighted_point_3 p, + Weighted_point_3 q);} \\ +\ccc{FT operator() ( Weighted_point_3 p);} \\ +} + +\ccNestedType{Compute_critical_squared_radius_3} +{A functor type. The operator() takes weighted points as arguments +and computes the squared radius +of the sphere centered in the last point and orthogonal +to the other weighted points. The last argument is a weighted point +but its weight does not matter. +This construction is ad hoc for pumping slivers. +For robustness issue, a predicate to compare critical squared radii +for a given last point should be needed. \\ +\ccc{FT operator() ( Weighted_point_3 p, + Weighted_point_3 q, + Weighted_point_3 r, + Weighted_point_3 s, + Weighted_point_3 t);} +} + + + + + +\ccOperations +The following functions give access to the predicate and constructor +functors. +\ccCreationVariable{traits} + +\ccThree{Does_simplex_intersect_dual_support_3} +{does_simplex_intersect_dual_support_3_object()}{} +\ccMethod{Power_test_3 power_test_3_object();}{} +\ccGlue +\ccMethod{Compare_power_distance_3 +compare_power_distance_3_object();}{} +\ccGlue +\ccMethod{Compare_weighted_squared_radius_3 +compare_weighted_squared_radius_3_object();}{} +\ccGlue +\ccMethod{In_smallest_orthogonal_sphere_3 + in_smallest_orthogonal_sphere_3_object();}{} +\ccGlue +\ccMethod{Side_of_bounded_orthogonal_sphere_3 + side_of_bounded_orthogonal_sphere_3_object();}{} +\ccGlue +\ccMethod{Does_simplex_intersect_dual_support_3 + does_simplex_intersect_dual_support_3_object();}{} +\ccGlue +\ccMethod{Construct_weighted_circumcenter_3 + construct_weighted_circumcenter_3_object();}{} +\ccGlue +\ccMethod{Compute_power_product_3 + compute_power_product_3_object() ;}{} +\ccGlue +\ccMethod{Compute_squared_radius_smallest_orthogonal_sphere_3 + compute_squared_radius_smallest_orthogonal_sphere_3_object() ;}{} +\ccGlue +\ccMethod{Compute_critical_squared_radius_3 + compute_critical_squared_radius_3_object();}{} + + +%% \ccExample + +%% \ccIncludeExampleCode{Triangulation3/Regular_triangulation_euclidean_traits_3_prog.cpp} + + + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_filtered_traits_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_filtered_traits_3.tex new file mode 100644 index 00000000000..8cb29f8e78f --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Regular_triangulation_filtered_traits_3.tex @@ -0,0 +1,46 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Regular_triangulation_filtered_traits_3.tex +% +------------------------------------------------------------------------+ +% | September 2004 Sylvain Pion +% | Package: Triangulation_3 +% | +\RCSdef{\RCSRegulartriangulationfilteredtraitsRev}{$Id$} +\RCSdefDate{\RCSRegulartriangulationfilteredtraitsDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Regular_triangulation_filtered_traits_3} + +\begin{ccDeprecated} + +{\em Note} : this class is deprecated since \cgal\ 3.6. +The class \ccc{CGAL::Regular_triangulation_euclidean_traits_3} should be used instead. +Filtered predicates are automatically used if the boolean \ccc{Has_filtered_predicates} +in the kernel provided as template parameter of that class is set to \ccc{true}. + +\ccDefinition + +The class \ccRefName\ is designed as a traits class for the +class \ccc{Regular_triangulation_3}. +Its difference with \ccc{Regular_triangulation_euclidean_traits_3} is that it +provides filtered predicates which are meant to be fast and exact. + +The first argument \ccc{FK} must be a model of the \ccc{Kernel} concept, and +it is also restricted to be a instance of the \ccc{Filtered_kernel} template. + +\ccInclude{CGAL/Regular_triangulation_filtered_traits_3.h} + +\ccIsModel +\ccc{RegularTriangulationTraits_3} + +\ccInheritsFrom{\ccc{Regular_triangulation_euclidean_traits_3}} + +\ccSeeAlso + +\ccc{CGAL::Regular_triangulation_euclidean_traits_3}. + +\end{ccDeprecated} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationCellBase_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationCellBase_3.tex new file mode 100644 index 00000000000..702c64b16f7 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationCellBase_3.tex @@ -0,0 +1,49 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: TriangulationCellBase_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationcbRev}{$Id$} +\RCSdefDate{\RCSTriangulationcbDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{TriangulationCellBase_3} + +\ccDefinition + +The cell base required by the basic triangulation does not need to store any +geometric information, so only the requirements of the triangulation data +structure apply. + +However, for the Delaunay triangulation, the ability to store the circumcenter +is provided (for optimization reasons), hence an additional requirement only +in this case, and only when the dual functions are called. + +\ccRefines \ccc{TriangulationDSCellBase_3} + +\ccCreationVariable{c} + +\ccMethod{const DelaunayTriangulationTraits_3::Point_3& circumcenter( + const DelaunayTriangulationTraits_3> = DelaunayTriangulationTraits_3()) const;} +{Returns the circumcenter.} + + +\ccHasModels + +\ccc{CGAL::Triangulation_cell_base_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_info_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_circumcenter_3} + +\ccSeeAlso + +\ccc{TriangulationVertexBase_3} + +%% \ccExample + +%% \ccIncludeExampleCode{Triangulation3/Triangulation_cb_3_prog.cpp} + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationHierarchyVertexBase_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationHierarchyVertexBase_3.tex new file mode 100644 index 00000000000..72b311a6673 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationHierarchyVertexBase_3.tex @@ -0,0 +1,55 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: TriangulationHierarchyVertexBase_3.tex +% +------------------------------------------------------------------------+ +% | +\RCSdef{\RCSTriangulationvbRev}{$Id$} +\RCSdefDate{\RCSTriangulationvbDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + +\begin{ccRefConcept}{TriangulationHierarchyVertexBase_3} + +\begin{ccDeprecated} + +{\em Note} : this concept is deprecated since \cgal\ 3.6, as the only class using +it, \ccc{Triangulation_hierarchy_3} has been deprecated as well. + +\ccDefinition + +The vertex base used by \ccc{Triangulation_hierarchy_3} must provide +access to two vertex handles for linking between the levels of the hierarchy. + +\ccRefines{\ccc{TriangulationVertexBase_3}} + +\ccCreationVariable{v} + +\ccAccessFunctions +\ccThree{Triangulatixon}{Facetxxxxxxxxxxxxx}{} +\ccTagFullDeclarations + +\ccMethod{Vertex_handle up() const;} +{Returns the \ccc{Vertex_handle} pointing to the level above.} +\ccGlue +\ccMethod{Vertex_handle down() const;} +{Returns the \ccc{Vertex_handle} pointing to the level below.} + +\ccHeading{Setting} +\ccThree{void}{Facetxxxxxxxxxxxxxxxxxxxxxxx}{} + +\ccMethod{void set_up(Vertex_handle v);} +{Sets the \ccc{Vertex_handle} pointing to the level above to \ccc{v}.} +\ccGlue +\ccMethod{void set_down(Vertex_handle v);} +{Sets the \ccc{Vertex_handle} pointing to the level below to \ccc{v}.} + +\ccHasModels + +\ccc{CGAL::Triangulation_hierarchy_vertex_base_3} + +%% \ccExample +%% \ccIncludeExampleCode{Triangulation3/Triangulation_vb_prog.cpp} + +\end{ccDeprecated} + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationTraits_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationTraits_3.tex new file mode 100644 index 00000000000..1f61a21c88d --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationTraits_3.tex @@ -0,0 +1,113 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_Traits_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationTraitsRev}{$Id$} +\RCSdefDate{\RCSTriangulationTraitsDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{TriangulationTraits_3} + +\ccDefinition +The concept \ccRefName\ is the first template parameter of the class +\ccc{Triangulation_3}. It defines the geometric objects (points, segments, +triangles and tetrahedra) forming the triangulation together with a few +geometric predicates and constructions on these objects : lexicographical +comparison, orientation in case of coplanar points and orientation in space. + +\ccTypes +\ccTwo{TriangulationTraits_3::Tetrahedron_3xx}{} + +\ccNestedType{Point_3} +{The point type. It must be \ccc{DefaultConstructible}, +\ccc{CopyConstructible} and \ccc{Assignable}.} +\ccGlue +\ccNestedType{Segment_3} {The segment type.} +\ccGlue +\ccNestedType{Tetrahedron_3} {The tetrahedron type.} +\ccGlue +\ccNestedType{Triangle_3} {The triangle type.} + +\ccTwo{TriangulationTraits_3}{} + +\ccNestedType{Construct_segment_3} +{A constructor object that must provide the function operator\\ +\ccc{Segment_3 operator()(Point_3 p, Point_3 q)},\\ +which constructs a segment from two points.} +\ccGlue +\ccNestedType{Construct_triangle_3} +{A constructor object that must provide the function operator\\ +\ccc{Triangle_3 operator()(Point_3 p, Point_3 q, Point_3 r )},\\ +which constructs a triangle from three points.} +\ccGlue +\ccNestedType{Construct_tetrahedron_3} +{A constructor object that must provide the function operator\\ +\ccc{Tetrahedron_3 operator()(Point_3 p, Point_3 q, Point_3 r, Point_3 s)},\\ +which constructs a tetrahedron from four points.} + +\ccNestedType{Compare_xyz_3} +{A predicate object that must provide the function operator\\ +\ccc{Comparison_result operator()(Point p, Point q)},\\ +which returns \ccc{EQUAL} if the two points are equal. Otherwise it must +return a consistent order for any two points chosen in a same line.} +\ccGlue +\ccNestedType{Coplanar_orientation_3} +{A predicate object that must provide the function operator\\ +\ccc{Orientation operator()(Point p, Point q, Point r)},\\ +which returns \ccc{COLLINEAR} if the points are collinear. Otherwise it must +return a consistent orientation for any three points chosen in a same plane. +} +\ccGlue +\ccNestedType{Orientation_3} +{A predicate object that must provide the function operator\\ +\ccc{Orientation operator()(Point p, Point q, Point r, Point s)},\\ +which returns POSITIVE, if \ccc{s} lies on the positive side of the oriented +plane \ccc{h} defined by \ccc{p}, \ccc{q}, and \ccc{r}, returns NEGATIVE if +\ccc{s} lies on the negative side of \ccc{h}, and returns COPLANAR if \ccc{s} +lies on \ccc{h}.} + +\ccCreation +\ccCreationVariable{traits} +\ccThree{Triangulation_traits_3xxx();}{Triangulation_traits_3 & tr}{} +\ccThreeToTwo + +\ccConstructor{Triangulation_traits_3();}{Default constructor.} +\ccGlue +\ccConstructor{Triangulation_traits_3(const Triangulation_traits_3 & tr);} +{Copy constructor.} + +\ccOperations + +The following functions give access to the predicate and construction objects: + +\ccThree{coplanar_side_of_bounded_circle_3xxx}{gt.xxxxxxxxx(Point p0, Point p1)x}{} + +\ccMethod{Construct_tetrahedron_3 construct_tetrahedron_3_object();}{} +\ccGlue +\ccMethod{Construct_triangle_3 construct_triangle_3_object();}{} +\ccGlue +\ccMethod{Construct_segment_3 construct_segment_3_object();}{} + +\ccMethod{Compare_xyz_3 compare_xyz_3_object();}{} +\ccGlue +\ccMethod{Coplanar_orientation_3 coplanar_orientation_3_object();}{} +\ccGlue +\ccMethod{Orientation_3 orientation_3_object();}{} + + +\ccHasModels + +\ccc{CGAL::Exact_predicates_inexact_constructions_kernel} (recommended)\\ +\ccc{CGAL::Exact_predicates_exact_constructions_kernel}\\ +\ccc{CGAL::Filtered_kernel}\\ +\ccc{CGAL::Cartesian}\\ +\ccc{CGAL::Simple_cartesian}\\ +\ccc{CGAL::Homogeneous}\\ +\ccc{CGAL::Simple_homogeneous} + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationVertexBase_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationVertexBase_3.tex new file mode 100644 index 00000000000..125134f2728 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/TriangulationVertexBase_3.tex @@ -0,0 +1,85 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: TriangulationVertexBase_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationvbRev}{$Id$} +\RCSdefDate{\RCSTriangulationvbDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{TriangulationVertexBase_3} + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[concept]{} %% add further index entries + +\ccDefinition + +The vertex base used by the geometric triangulation must store a point. +So we list here the additional requirements compared to a vertex base usable +for the triangulation data structure. + +\ccRefines{\ccc{TriangulationDSVertexBase_3}} + +\ccTypes +\ccNestedType{Point} +{Must be the same as the point type \ccc{TriangulationTraits_3::Point_3} +defined by the geometric traits class of the triangulation.} + +\ccCreation +\ccCreationVariable{v} %% choose variable name + +\ccThree{Triangulation}{Facetxxxxxxxxxxxxxxxxxxxxxxxxx}{} + +\ccConstructor{TriangulationVertexBase_3(const Point & p);} +{Constructs a vertex whose geometric embedding is point \ccc{p}.} +\ccGlue +\ccConstructor{TriangulationVertexBase_3(const Point & p, Cell_handle c);} +{Constructs a vertex embedding the point \ccc{p} and pointing to cell \ccc{c}.} + +\ccAccessFunctions +\ccThree{Triangulation}{Facetxxxxxxxxxxxxxxxxxxxxx}{} + +\ccMethod{Point point() const;} +{Returns the point.} + +\ccHeading{Setting} + +\ccMethod{void set_point(Point p);} +{Sets the point.} + +\ccHeading{I/O} + +\ccFunction{istream& operator>> +(istream& is, TriangulationVertexBase_3 & v);} +{Inputs the non-combinatorial information given by the vertex: +the point and other possible information.} +%\ccPrecond{The point and the other information have a corresponding +%operator \ccc{>>}. \textit{This precondition is optional for the +%triangulation data structure alone.}}} + +\ccFunction{ostream& operator<< (ostream& os, + const TriangulationVertexBase_3 & v);} +{Outputs the non-combinatorial information given by the vertex: the +point and other possible information.} +%\ccPrecond{The point and the other information have a corresponding +%operator \ccc{<<}. \textit{This precondition is optional for the +%triangulation data structure alone.}}} + +\ccHasModels + +\ccc{CGAL::Triangulation_vertex_base_3}\\ +\ccc{CGAL::Triangulation_vertex_base_with_info_3} + +\ccSeeAlso + +\ccc{TriangulationCellBase_3} + +%% \ccExample + +%% \ccIncludeExampleCode{Triangulation3/Triangulation_vb_prog.cpp} + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_3.tex new file mode 100644 index 00000000000..3a8cf725478 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_3.tex @@ -0,0 +1,1052 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_3.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationRev}{$Id$} +\RCSdefDate{\RCSTriangulationDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_3} + +\ccDefinition + +The class \ccc{Triangulation_3} represents a 3-dimensional tetrahedralization +of points. + +\ccInclude{CGAL/Triangulation_3.h} + +\ccParameters + +The first template argument must be a model of the +\ccc{TriangulationTraits_3} concept. + +The second template argument must be a model of the +\ccc{TriangulationDataStructure_3} concept. +It has the default value \ccc{Triangulation_data_structure_3< +Triangulation_vertex_base_3,Triangulation_cell_base_3 >}. + +\ccInheritsFrom{\ccc{Triangulation_utils_3}} + +\ccTypes +The class \ccc{Triangulation_3} defines the following types: +\ccThree{typedef TriangulationTraits_3::Tetrahedron Tetraxxx;} +{Tetrahedronxxxxx}{} +\ccThreeToTwo + +\ccTypedef{typedef TriangulationDataStructure_3 Triangulation_data_structure;}{} +\ccGlue +\ccTypedef{typedef TriangulationTraits_3 Geom_traits;}{} + +\ccTypedef{typedef TriangulationTraits_3::Point_3 Point;}{} +\ccGlue +\ccTypedef{typedef TriangulationTraits_3::Segment_3 Segment;}{} +\ccGlue +\ccTypedef{typedef TriangulationTraits_3::Triangle_3 Triangle;}{} +\ccGlue +\ccTypedef{typedef TriangulationTraits_3::Tetrahedron_3 Tetrahedron;}{} + +Only vertices ($0$-faces) and cells ($3$-faces) are stored. Edges +($1$-faces) and facets ($2$-faces) are not explicitly represented and +thus there are no corresponding classes (see +Section~\ref{Triangulation3-sec-intro}). + +\ccTypedef{typedef TriangulationDataStructure_3::Vertex Vertex;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Cell Cell;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Facet Facet;}{} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Edge Edge;}{} + +The vertices and faces of the triangulations are accessed through +\ccc{handles}, \ccc{iterators} and \ccc{circulators}. +A handle is a model of the \ccc{Handle} concept, and supports the two +dereference operators \ccc{operator*} and \ccc{operator->}. +A circulator is a model of the concept \ccc{Circulator}. +Iterators and circulators are bidirectional and non-mutable. +The edges and facets of the triangulation can also be visited through +iterators and circulators which are bidirectional and non-mutable. + +Iterators and circulators are convertible to the corresponding handles, thus +the user can pass them directly as arguments to the functions. + +\ccTypedef{typedef TriangulationDataStructure_3::Vertex_handle Vertex_handle;} +{handle to a vertex} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Cell_handle Cell_handle;} +{handle to a cell} + +\ccTypedef{typedef Triangulation_simplex_3 Simplex;} +{Reference to a simplex (vertex, edge, facet or cell) of the triangulation} + +\ccTypedef{typedef TriangulationDataStructure_3::size_type size_type;} +{Size type (an unsigned integral type)} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::difference_type difference_type;} +{Difference type (a signed integral type)} + +\ccThree{typedef TriangulationTraits_3::Tetrahedron Tetraxxxx;} +{Tetrahedronxxxxxxx}{} +\ccThreeToTwo + +\ccTypedef{typedef TriangulationDataStructure_3::Cell_iterator All_cells_iterator;} +{iterator over cells} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Facet_iterator All_facets_iterator;} +{iterator over facets} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Edge_iterator All_edges_iterator;} +{iterator over edges} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Vertex_iterator All_vertices_iterator;} +{iterator over vertices} + +\ccThree{typedef TriangulationTraits_3::Tetrahedron ;} +{Tetrahedron}{} +\ccThreeToTwo + +\ccNestedType{Finite_cells_iterator}{iterator over finite cells} +\ccGlue +\ccNestedType{Finite_facets_iterator}{iterator over finite facets} +\ccGlue +\ccNestedType{Finite_edges_iterator}{iterator over finite edges} +\ccGlue +\ccNestedType{Finite_vertices_iterator}{iterator over finite vertices} +\ccGlue +\ccNestedType{Point_iterator}{iterator over the points corresponding to the +finite vertices of the triangulation.} + +\ccThree{typedef TriangulationTraits_3::Tetrahedron Tetrahedro;}{T}{} +\ccThreeToTwo + +\ccTypedef{typedef TriangulationDataStructure_3::Cell_circulator Cell_circulator;} +{circulator over all cells incident to a given edge} +\ccGlue +\ccTypedef{typedef TriangulationDataStructure_3::Facet_circulator Facet_circulator;} +{circulator over all facets incident to a given edge} + +The triangulation class also defines the following enum type to specify +which case occurs when locating a point in the triangulation. + +\ccEnum{enum Locate_type {VERTEX=0, EDGE, FACET, CELL, OUTSIDE_CONVEX_HULL, +OUTSIDE_AFFINE_HULL};} +{} + + +\ccCreation +\ccCreationVariable{t} %% choose variable name + +\ccThree{Triangulation_3<>}{Facetxxx }{} +\ccThreeToTwo + +\ccConstructor{Triangulation_3 +(const TriangulationTraits_3 & traits = TriangulationTraits_3());} +{Introduces a triangulation \ccVar\ having only one vertex which is the +infinite vertex.} + +\ccConstructor{Triangulation_3 (const Triangulation_3 & tr);} +{Copy constructor. All vertices and faces are duplicated.} + +\ccConstructor{template < class InputIterator> + Triangulation_3 (InputIterator first, InputIterator last, + const TriangulationTraits_3 & traits = TriangulationTraits_3() );} +{Equivalent to constructing an empty triangulation with the optional +traits class argument and calling \ccc{insert(first,last)}.} + +\ccHeading{Assignment} + +\ccMethod{Triangulation_3 & operator=(const Triangulation_3 & tr);} +{The triangulation \ccc{tr} is duplicated, and modifying the copy after the +duplication does not modify the original. The previous triangulation held +by \ccVar\ is deleted.} + +\ccMethod{void swap(Triangulation_3 & tr);} +{The triangulations \ccc{tr} and \ccVar\ are swapped. +\ccVar.\ccc{swap(tr)} should be preferred to \ccVar\ = \ccc{tr} or to +\ccc{t(tr)} if \ccc{tr} is deleted after that. Indeed, there is no +copy of cells and vertices, thus this method runs in constant time.} + +\ccMethod{void clear();} +{Deletes all finite vertices and all cells of \ccVar.} + +\ccFunction{template < class GT, class Tds1, class Tds2 > + bool operator==(const Triangulation_3 & t1, + const Triangulation_3 & t2);} +{Equality operator. Returns true iff there exist a bijection between the +vertices of \ccc{t1} and those of \ccc{t2} and a bijection between the cells of +\ccc{t1} and those of \ccc{t2}, which preserve the geometry of the +triangulation, that is, the points of each corresponding pair of vertices are +equal, and the tetrahedra corresponding to each pair of cells are equal (up to +a permutation of their vertices).} +\ccGlue +\ccFunction{template < class GT, class Tds1, class Tds2 > + bool operator!=(const Triangulation_3 & t1, + const Triangulation_3 & t2);} +{The opposite of \ccc{operator==}.} + +\ccAccessFunctions +\ccThree{TriangulationDataStructure_3&}{number_of_finite_edges}{} + +\ccMethod{const TriangulationTraits_3 & geom_traits() const;} +{Returns a const reference to the geometric traits object.} +\ccGlue +\ccMethod{const TriangulationDataStructure_3 & tds() const;} +{Returns a const reference to the triangulation data structure.} + +\begin{ccAdvanced} +\ccHeading{Non const access} +The responsibility of keeping a valid triangulation belongs to the user +when using advanced operations allowing a direct manipulation of the \ccc{tds}. + +\ccMethod{TriangulationDataStructure_3 & tds();} +{Returns a reference to the triangulation data structure.} + +This method is mainly a help for users implementing their own triangulation +algorithms. + +\end{ccAdvanced} + +\ccThree{Triangulationx}{number_of_finite_edges}{} + +\ccMethod{int dimension() const;} +{Returns the dimension of the affine hull.} +\ccGlue +\ccMethod{size_type number_of_vertices() const;} +{Returns the number of finite vertices.} +\ccGlue +\ccMethod{size_type number_of_cells() const;} +{Returns the number of cells or 0 if \ccVar.\ccc{dimension()}$<3$.} + +\ccMethod{Vertex_handle infinite_vertex();} +{Returns the infinite vertex.} +\ccGlue +\ccMethod{Cell_handle infinite_cell() const;} +{Returns a cell incident to the infinite vertex.} + +\ccHeading{Non-constant-time access functions} + +As previously said, the triangulation is a collection of cells that +are either infinite or represent a finite tetrahedra, where an +infinite cell is a +cell incident to the infinite vertex. Similarly we call +an edge (resp. facet) \ccc{infinite} if it is incident to the infinite vertex. + +\ccThree{size_type}{t.number_of_finite_edges()toto}{} +\ccMethod{size_type number_of_facets() const;} +{The number of facets. Returns 0 if \ccVar.\ccc{dimension()}$<2$.} +\ccGlue +\ccMethod{size_type number_of_edges() const;} +{The number of edges. Returns 0 if \ccVar.\ccc{dimension()}$<1$.} + +\ccMethod{size_type number_of_finite_cells() const;} +{The number of finite cells. Returns 0 if \ccVar.\ccc{dimension()}$<3$.} +\ccGlue +\ccMethod{size_type number_of_finite_facets() const;} +{The number of finite facets. Returns 0 if \ccVar.\ccc{dimension()}$<2$.} +\ccGlue +\ccMethod{size_type number_of_finite_edges() const;} +{The number of finite edges. Returns 0 if \ccVar.\ccc{dimension()}$<1$.} + +\ccHeading{Geometric access functions} +\ccThree{Tetrahedron}{t.tetrahedron()}{} + +\ccMethod{Tetrahedron tetrahedron(Cell_handle c) const;} +{Returns the tetrahedron formed by the four vertices of \ccc{c}. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$ and the cell is finite.}} +\ccGlue +\ccMethod{Triangle triangle(Cell_handle c, int i) const;} +{Returns the triangle formed by the three vertices of facet +\ccc{(c,i)}. The triangle is oriented so that its normal points to the +inside of cell \ccc{c}. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and $i \in \{0,1,2,3\}$ +in dimension~3, $i = 3$ in dimension~2, and the facet is finite.}} +\ccGlue +\ccMethod{Triangle triangle(const Facet & f) const;} +{Same as the previous method for facet \ccc{f}. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and the facet is finite.}} +\ccGlue +\ccMethod{Segment segment(const Edge & e) const;} +{Returns the line segment formed by the vertices of \ccc{e}. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 1$ and \ccc{e} is finite.}} +\ccGlue +\ccMethod{Segment segment(Cell_handle c, int i, int j) const;} +{Same as the previous method for edge \ccc{(c,i,j)}. +\ccPrecond{As above and $i\neq j$. Moreover $i,j \in \{0,1,2,3\}$ in +dimension~3, $i,j \in \{0,1,2\}$ in dimension~2, $i,j \in \{0,1\}$ in +dimension~1, and the edge is finite.}} +\ccGlue +\ccMethod{const Point & point(Cell_handle c, int i) const;} +{Returns the point given by vertex \ccc{i} of cell \ccc{c}. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 0$ and $i \in \{0,1,2,3\}$ +in dimension~3, $i \in \{0,1,2\}$ in dimension~2, $i \in \{0,1\}$ in +dimension~1, $i = 0$ in dimension~0, and the vertex is finite.}} +\ccGlue +\ccMethod{const Point & point(Vertex_handle v) const;} +{Same as the previous method for vertex \ccc{v}. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 0$ and the vertex is finite.}} + +\ccHeading{Tests for Finite and Infinite Vertices and Faces} + +\ccMethod{bool is_infinite(Vertex_handle v) const;} +{\ccc{true}, iff vertex \ccc{v} is the infinite vertex.} +\ccGlue +\ccMethod{bool is_infinite(Cell_handle c) const;} +{\ccc{true}, iff \ccc{c} is incident to the infinite vertex. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$.}} +\ccGlue +\ccMethod{bool is_infinite(Cell_handle c, int i) const;} +{\ccc{true}, iff the facet \ccc{i} of cell \ccc{c} is incident to the +infinite vertex. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and $i\in\{0,1,2,3\}$ in +dimension~3, $i=3$ in dimension~2.}} +\ccGlue +\ccMethod{bool is_infinite(const Facet & f) const;} +{\ccc{true} iff facet \ccc{f} is incident to the infinite vertex. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$.}} +\ccGlue +\ccMethod{bool is_infinite(Cell_handle c, int i, int j) const;} +{\ccc{true}, iff the edge \ccc{(i,j)} of cell \ccc{c} is incident to +the infinite vertex. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 1$ and $i\neq j$. Moreover +$i,j \in \{0,1,2,3\}$ in dimension~3, $i,j \in \{0,1,2\}$ in dimension +2, $i,j \in \{0,1\}$ in dimension~1.}} +\ccGlue +\ccMethod{bool is_infinite(const Edge & e) const;} +{\ccc{true} iff edge \ccc{e} is incident to the infinite vertex. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 1$.}} + +\ccHeading{Queries} + +\ccMethod{bool is_vertex(const Point & p, Vertex_handle & v) const;} +{Tests whether \ccc{p} is a vertex of \ccVar\ by locating \ccc{p} in +the triangulation. If \ccc{p} is found, the associated vertex \ccc{v} +is given.} +\ccGlue +\ccMethod{bool is_vertex(Vertex_handle v) const;} +{Tests whether \ccc{v} is a vertex of \ccVar.} + +\ccMethod{bool is_edge(Vertex_handle u, Vertex_handle v, + Cell_handle & c, int & i, int & j) const;} +{Tests whether \ccc{(u,v)} is an edge of \ccVar. If the edge is found, +it gives a cell \ccc{c} having this edge and the indices \ccc{i} +and \ccc{j} of the vertices \ccc{u} and \ccc{v} in \ccc{c}, in this order. +\ccPrecond{\ccc{u} and \ccc{v} are vertices of \ccVar.}} + +\ccMethod{bool is_facet(Vertex_handle u, Vertex_handle v, Vertex_handle w, + Cell_handle & c, int & i, int & j, int & k) const;} +{Tests whether \ccc{(u,v,w)} is a facet of \ccVar. If the facet is found, +it computes a cell \ccc{c} having this facet and the indices \ccc{i}, +\ccc{j} and \ccc{k} of the vertices \ccc{u}, \ccc{v} and \ccc{w} in \ccc{c}, +in this order. +\ccPrecond{\ccc{u}, \ccc{v} and \ccc{w} are vertices of \ccVar.}} + +\ccMethod{bool is_cell(Cell_handle c) const;} +{Tests whether \ccc{c} is a cell of \ccVar.} +\ccGlue +\ccMethod{bool is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle x, + Cell_handle & c, + int & i, int & j, int & k, int & l) const;} +{Tests whether \ccc{(u,v,w,x)} is a cell of \ccVar. +If the cell \ccc{c} is found, the method +computes the indices \ccc{i}, \ccc{j}, \ccc{k} and \ccc{l} of the +vertices \ccc{u}, \ccc{v}, \ccc{w} and \ccc{x} in \ccc{c}, in this +order. +\ccPrecond{\ccc{u}, \ccc{v}, \ccc{w} and \ccc{x} are vertices of \ccVar.}} +\ccGlue +\ccMethod{bool is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle x, + Cell_handle & c) const;} +{Tests whether \ccc{(u,v,w,x)} is a cell of \ccVar\ and computes +this cell \ccc{c}. +\ccPrecond{\ccc{u}, \ccc{v}, \ccc{w} and \ccc{x} are vertices of \ccVar.}} + +There is a method \ccc{has_vertex} in the cell class. The analogous +methods for facets are defined here. + +\ccMethod{bool has_vertex(const Facet & f, Vertex_handle v, int & j) const;} +{If \ccc{v} is a vertex of \ccc{f}, then \ccc{j} is the index of +\ccc{v} in the cell \ccc{f.first}, and the method returns \ccc{true}. +\ccPrecond{\ccVar.dimension()=3}} +\ccGlue +\ccMethod{bool has_vertex(Cell_handle c, int i, + Vertex_handle v, int & j) const;} +{Same for facet \ccc{(c,i)}. Computes the index \ccc{j} of \ccc{v} in +\ccc{c}.} +\ccGlue +\ccMethod{bool has_vertex(const Facet & f, Vertex_handle v) const;} +{} +\ccGlue +\ccMethod{bool has_vertex(Cell_handle c, int i, Vertex_handle v) const;} +{Same as the first two methods, but these two methods do not return the +index of the vertex.} + +The following three methods test whether two facets have the same +vertices. + +\ccMethod{bool are_equal(Cell_handle c, int i, Cell_handle n, int j) const;} +{} +\ccGlue +\ccMethod{bool are_equal(const Facet & f, const Facet & g) const;} +{} +\ccGlue +\ccMethod{bool are_equal(const Facet & f, Cell_handle n, int j) const;} +{For these three methods: \ccPrecond{\ccVar.dimension()=3}.} + + +\ccHeading{Point location} +\ccThree{Vertex_handle}{t.locate()toto}{} + +The class \ccClassTemplateName\ provides two functions to locate +a given point with respect to a triangulation. It provides +also functions to test if a given point is inside a finite face +or not. Note that the class \ccc{Delaunay_triangulation_3} also +provides a \ccc{nearest_vertex()} function. + +\ccMethod{Cell_handle + locate(const Point & query, Cell_handle start = Cell_handle()) const;} +{ +%\ccPrecond{\ccVar.\ccc{dimension()} $= 3$ (otherwise there is no +%cell yet).}\\ +If the point \ccc{query} lies inside the convex hull of the points, the cell +that contains the query in its interior is returned. If \ccc{query} lies on a +facet, an edge or on a vertex, one of the cells having \ccc{query} on +its boundary is returned.\\ +If the point \ccc{query} lies outside the convex hull of the points, +an infinite cell with vertices $\{ p, q, r, \infty\}$ is returned such that +the tetrahedron $( p, q, r, query )$ is positively oriented +(the rest of the triangulation lies on the other side of facet +$( p, q, r )$). \\ +Note that locate works even in degenerate dimensions: in dimension 2 +(resp. 1, 0) the \ccc{Cell_handle} returned is the one that represents +the facet (resp. edge, vertex) containing the query point. \\ +The optional argument \ccc{start} is used as a starting place for the search. +} + +\ccMethod{Cell_handle + locate(const Point & query, Vertex_handle hint) const;} +{ Same as above but uses \ccc{hint} as the starting place for the search. } + +\ccMethod{Cell_handle + locate(const Point & query, Locate_type & lt, + int & li, int & lj, Cell_handle start = Cell_handle() ) const;} +{If \ccc{query} lies inside the affine hull of the points, the $k$-face +(finite or infinite) that contains \ccc{query} in its interior is +returned, by means of the cell returned together with \ccc{lt}, which +is set to the locate type of the query (\ccc{VERTEX, EDGE, FACET, +CELL}, or \ccc{OUTSIDE_CONVEX_HULL} if the cell is infinite and \ccc{query} +lies strictly in it) and two indices \ccc{li} and \ccc{lj} that +specify the $k$-face of the cell containing \ccc{query}.\\ +If the $k$-face is a cell, \ccc{li} and \ccc{lj} have no +meaning; if it is a facet (resp. vertex), \ccc{li} gives the index of +the facet (resp. vertex) and \ccc{lj} has no meaning; if it is and +edge, \ccc{li} and \ccc{lj} give the indices of its vertices.\\ +%If the point \ccc{query} lies outside the convex hull of the points, but +%in their affine hull, then \ccc{lt} is set to \ccc{OUTSIDE_CONVEX_HULL}, +%and a $k$-face separating the triangulation from \ccc{query} is +%specified by the cell containing \ccc{query}, which is returned, and +%indices as previously.\\ +If the point \ccc{query} lies outside the affine hull of the points, +which can happen in case of degenerate dimensions, \ccc{lt} is set to +\ccc{OUTSIDE_AFFINE_HULL}, and the cell returned has no meaning. +As a particular case, if there is no finite vertex yet in the +triangulation, \ccc{lt} is set to \ccc{OUTSIDE_AFFINE_HULL} and +\textit{locate} returns the default constructed handle. \\ +The optional argument \ccc{start} is used as a starting place for the search. +} + +\ccMethod{Cell_handle + locate(const Point & query, Locate_type & lt, + int & li, int & lj, Vertex_handle hint) const;} +{ Same as above but uses \ccc{hint} as the starting place for the search. } + +\ccMethod{Bounded_side + side_of_cell(const Point & p, + Cell_handle c, + Locate_type & lt, int & li, int & lj) const;} +{Returns a value indicating on which side of the oriented boundary +of \ccc{c} the point \ccc{p} lies. More precisely, it returns:\\ +- \ccc{ON_BOUNDED_SIDE} if \ccc{p} is inside the cell. For an infinite +cell this means that \ccc{p} lies strictly in the half space limited by +its finite facet and not containing any other point of the triangulation. \\ +- \ccc{ON_BOUNDARY} if p on the boundary of the cell. For an infinite +cell this means that \ccc{p} lies on the \textit{finite} facet. Then +\ccc{lt} together with \ccc{li} and \ccc{lj} give the precise location +on the boundary. (See the descriptions of the \textit{locate} methods.)\\ +- \ccc{ON_UNBOUNDED_SIDE} if \ccc{p} lies outside the cell. For an +infinite cell this means that \ccc{p} does not satisfy either of the +two previous conditions. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$}} + +\ccMethod{Bounded_side + side_of_facet(const Point & p, + const Facet & f, + Locate_type & lt, int & li, int & lj) const;} +{Returns a value indicating on which side of the oriented boundary +of \ccc{f} the point \ccc{p} lies:\\ +- \ccc{ON_BOUNDED_SIDE} if \ccc{p} is inside the facet. For an +infinite facet this means that \ccc{p} lies strictly in the half plane +limited by its finite edge and not containing any other point of the +triangulation . \\ +- \ccc{ON_BOUNDARY} if \ccc{p} is on the boundary of the facet. +For an infinite facet this means that \ccc{p} lies on the finite +edge. \ccc{lt}, \ccc{li} and \ccc{lj} give the precise location of +\ccc{p} on the boundary of the facet. \ccc{li} and \ccc{lj} refer to +indices in the degenerate cell \ccc{c} representing \ccc{f}.\\ +- \ccc{ON_UNBOUNDED_SIDE} if \ccc{p} lies outside the facet. For +an infinite facet this means that \ccc{p} does not satisfy either of +the two previous conditions. \\ +\ccPrecond{\ccVar.\ccc{dimension()} $=2$ and \ccc{p} lies in the +plane containing the triangulation. \ccc{f.second} $=3$ (in dimension~2 +there is only one facet per cell).}} +\ccGlue +\ccMethod{Bounded_side + side_of_facet(const Point & p, + Cell_handle c, + Locate_type & lt, int & li, int & lj) const;} +{Same as the previous method for the facet \ccc{(c,3)}.} + +\ccMethod{Bounded_side + side_of_edge(const Point & p, + const Edge & e, + Locate_type & lt, int & li) const;} +{Returns a value indicating on which side of the oriented boundary +of \ccc{e} the point \ccc{p} lies:\\ +- \ccc{ON_BOUNDED_SIDE} if \ccc{p} is inside the edge. For an +infinite edge this means that \ccc{p} lies in the half line defined by +the vertex and not containing any other point of the triangulation.\\ +- \ccc{ON_BOUNDARY} if \ccc{p} equals one of the vertices, +\ccc{li} give the index of the vertex in the cell storing \ccc{e}\\ +- \ccc{ON_UNBOUNDED_SIDE} if \ccc{p} lies outside the edge. For +an infinite edge this means that \ccc{p} lies on the other half line, +which contains the other points of the triangulation. +\ccPrecond{\ccVar.\ccc{dimension()} $=1$ and \ccc{p} is collinear +with the points of the triangulation. \ccc{e.second} $=0$ and +\ccc{e.third} $=1$ (in dimension~1 there is only one edge per cell).}} +\ccGlue +\ccMethod{Bounded_side + side_of_edge(const Point & p, + Cell_handle c, + Locate_type & lt, int & li) const;} +{Same as the previous method for edge $(c,0,1)$.} + +\ccHeading{Flips} + +Two kinds of flips exist for a three-dimensional triangulation. They +are reciprocal. To be flipped, an edge must be incident to three +tetrahedra. During the flip, these three tetrahedra disappear and two +tetrahedra appear. Figure~\ref{Triangulation3-fig-flips}(left) shows the +edge that is flipped as bold dashed, and one of its three incident +facets is shaded. On the right, the facet shared by the two new +tetrahedra is shaded. + +Flips are possible only under the following conditions:\\ +- the edge or facet to be flipped is not on the boundary of the convex +hull of the triangulation \\ +- the five points involved are in convex position. + +\begin{figure} +\begin{ccTexOnly} +\begin{center} +\includegraphics{Triangulation_3_ref/flips} +\end{center} +\end{ccTexOnly} +\caption{Flips. +\label{Triangulation3-fig-flips}} +\begin{ccHtmlOnly} +
+Flips +
+\end{ccHtmlOnly} +\end{figure} + +The following methods guarantee the validity of the resulting 3D +triangulation. + +\textit{Flips for a 2d triangulation are not implemented yet} + +\ccMethod{bool flip(Edge e);}{} +\ccGlue +\ccMethod{bool flip(Cell_handle c, int i, int j);} +{Before flipping, these methods check that edge \ccc{e=(c,i,j)} is +flippable (which is quite expensive). They return \ccc{false} or +\ccc{true} according to this test.} + +\ccMethod{void flip_flippable(Edge e);}{} +\ccGlue +\ccMethod{void flip_flippable(Cell_handle c, int i, int j);} +{Should be preferred to the previous methods when the edge is +known to be flippable. +\ccPrecond{The edge is flippable.}} + +\ccMethod{bool flip(Facet f);}{} +\ccGlue +\ccMethod{bool flip(Cell_handle c, int i);} +{Before flipping, these methods check that facet \ccc{f=(c,i)} is +flippable (which is quite expensive). They return \ccc{false} or +\ccc{true} according to this test.} + +\ccMethod{void flip_flippable(Facet f);}{} +\ccGlue +\ccMethod{void flip_flippable(Cell_handle c, int i);} +{Should be preferred to the previous methods when the facet is +known to be flippable. +\ccPrecond{The facet is flippable.}} + +\ccHeading{Insertions} + +The following operations are guaranteed to lead to a valid triangulation +when they are applied on a valid triangulation. + +\ccMethod{Vertex_handle insert(const Point & p, + Cell_handle start = Cell_handle() );} +{Inserts point \ccc{p} in the triangulation and returns the corresponding + vertex.\\ +If point \ccc{p} coincides with an already existing vertex, this +vertex is returned and the triangulation remains unchanged.\\ +If point \ccc{p} lies in the convex hull of the points, it is added +naturally: if it lies inside a cell, the cell is split into four +cells, if it lies on a facet, the two incident cells are split into +three cells, if it lies on an edge, all the cells incident to this +edge are split into two cells.\\ +If point \ccc{p} is strictly outside the convex hull but in the affine +hull, \ccc{p} is linked to all visible points on the convex hull to +form the new triangulation. See +Figure~\ref{Triangulation3-fig-insert_outside_convex_hull}.\\ +If point \ccc{p} is outside the affine hull of the points, \ccc{p} is +linked to all the points, and the dimension of the triangulation is +incremented. All the points now belong to the boundary of the convex +hull, so, the infinite vertex is linked to all the points to +triangulate the new infinite face. See +Figure~\ref{Triangulation3-fig-insert_outside_affine_hull}. +The optional argument \ccc{start} is used as a starting place for the search.} + +\ccMethod{Vertex_handle insert(const Point & p, Vertex_handle hint);} +{ Same as above but uses \ccc{hint} as the starting place for the search. } + +\ccMethod{Vertex_handle insert(const Point & p, Locate_type lt, + Cell_handle loc, int li, int lj);} +{Inserts point \ccc{p} in the triangulation and returns the corresponding + vertex. Similar to the above \ccc{insert()} function, but takes as additional + parameter the return values of a previous location query. See description of + \textit{locate()} above.} + +\ccMethod{template < class InputIterator > + std::ptrdiff_t + insert(InputIterator first, InputIterator last);} +{Inserts the points in the range $\left[\right.$\ccc{first}, +\ccc{last}$\left.\right)$. Returns the number of inserted points. +Note that this function is not guaranteed to insert the points +following the order of \ccc{InputIterator}. +\ccPrecond{The \ccc{value_type} of \ccc{first} and \ccc{last} is +\ccc{Point}.}} + +The previous methods are sufficient to build a whole triangulation. We +also provide some other methods that can be used instead of +\ccc{insert(p)} when the place where the new point \ccc{p} must be inserted +is already known. They are also guaranteed to lead to a valid +triangulation when they are applied on a valid triangulation. + +\ccMethod{Vertex_handle insert_in_cell(const Point & p, Cell_handle c);} +{Inserts point \ccc{p} in cell \ccc{c}. Cell \ccc{c} is split into 4 +tetrahedra. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$ and \ccc{p} lies strictly +inside cell \ccc{c}.}} + +\ccMethod{Vertex_handle insert_in_facet(const Point & p, const Facet & f);} +{Inserts point \ccc{p} in facet \ccc{f}. In dimension~3, the 2 +neighboring cells are split into 3 tetrahedra; in dimension~2, the facet +is split into 3 triangles. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$ and \ccc{p} lies strictly +inside face \ccc{f}.}} +\ccGlue +\ccMethod{Vertex_handle insert_in_facet(const Point & p, + Cell_handle c, int i);} +{As above, insertion in facet \ccc{(c,i)}. +\ccPrecond{As above and $i \in \{0,1,2,3\}$ in dimension~3, $i = 3$ in +dimension~2.}} + +\ccMethod{Vertex_handle insert_in_edge(const Point & p, const Edge & e);} +{Inserts \ccc{p} in edge \ccc{e}. In dimension~3, +all the cells having this edge are split into 2 tetrahedra; in +dimension~2, the 2 neighboring facets are split into 2 triangles; in +dimension~1, the edge is split into 2 edges. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 1$ and \ccc{p} lies on edge +\ccc{e}.}} +\ccGlue +\ccMethod{Vertex_handle insert_in_edge(Point p, Cell_handle c, int i, int j);} +{As above, inserts \ccc{p} in edge $(\ccc{i}, \ccc{j})$ of \ccc{c}. +\ccPrecond{As above and $i\neq j$. Moreover $i,j \in \{0,1,2,3\}$ in +dimension~3, $i,j \in \{0,1,2\}$ in dimension~2, $i,j \in \{0,1\}$ in +dimension~1.}} + +\ccMethod{Vertex_handle insert_outside_convex_hull(const Point & p, + Cell_handle c);} +% int li, int lj=0);} +{%The cell \ccc{c}, together with \ccc{li} and possibly \ccc{lj}, give a +%separator (facet, edge or vertex, depending on the dimension) for +%\ccc{p} from the triangulation (see the description of method +%\ccc{locate()} for more details on the way the separator is represented).\\ +The cell \ccc{c} must be an infinite cell containing \ccc{p}.\\ +Links \ccc{p} to all points in the triangulation that are visible from +\ccc{p}. Updates consequently the infinite faces. See +Figure~\ref{Triangulation3-fig-insert_outside_convex_hull}. +\ccPrecond{\ccVar.\ccc{dimension()} $>0$, \ccc{c}, and the $k$-face +represented by \ccc{c} is infinite and contains \ccVar.}} + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{Triangulation_3/insert_outside_convex_hull} +\end{center} +\end{ccTexOnly} +\caption{\protect\ccc{insert_outside_convex_hull} (2-dimensional case). +\label{Triangulation3-fig-insert_outside_convex_hull}} +\begin{ccHtmlOnly} +
+ +
+\end{ccHtmlOnly} +\end{figure} + +\ccMethod{Vertex_handle insert_outside_affine_hull(const Point & p);} +{\ccc{p} is linked to all the points, and the infinite vertex is linked +to all the points (including \ccc{p}) to triangulate the new infinite +face, so that all the points now belong to the boundary of the convex +hull. See Figure~\ref{Triangulation3-fig-insert_outside_affine_hull}.\\ +This method can be used to insert the first point in an empty +triangulation. +\ccPrecond{\ccVar.\ccc{dimension()} $<3$ and \ccc{p} lies outside the +affine hull of the points.}} + +\begin{figure}[htbp] +\begin{ccTexOnly} +\begin{center} +\includegraphics{Triangulation_3/insert_outside_affine_hull} +\end{center} +\end{ccTexOnly} +\caption{\protect\ccc{insert_outside_affine_hull} (2-dimensional case). +\label{Triangulation3-fig-insert_outside_affine_hull}} +\begin{ccHtmlOnly} +
+ +
+\end{ccHtmlOnly} +\end{figure} + +\ccMethod{template + Vertex_handle insert_in_hole(Point p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i);} +{Creates a new vertex by starring a hole. It takes an iterator range +[\ccc{cell_begin}; \ccc{cell_end}[ of \ccc{Cell_handle}s which specifies +a hole: a set of connected cells (resp. facets in dimension 2) which is +star-shaped wrt \ccc{p}. +(\ccc{begin}, \ccc{i}) is a facet (resp. an edge) on the boundary of the hole, +that is, \ccc{begin} belongs to the set of cells (resp. facets) previously +described, and \ccc{begin->neighbor(i)} does not. Then this function deletes +all the cells (resp. facets) describing the hole, creates a new vertex +\ccc{v}, and for each facet (resp. edge) on the boundary of the hole, creates +a new cell (resp. facet) with \ccc{v} as vertex. Then \ccc{v->set_point(p)} +is called and \ccc{v} is returned.\\ +This operation is equivalent to calling +\ccStyle{tds().insert_in_hole(cell_begin, cell_end, begin, i); +v->set_point(p)}. +\ccPrecond{\ccVar.\ccc{dimension()} $\geq 2$, the set of cells (resp. facets in +dimension 2) is connected, its boundary is connected, and \ccc{p} lies inside +the hole, which is star-shaped wrt \ccc{p}}.} + +\ccMethod{template + Vertex_handle insert_in_hole(Point p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv);} +{ Same as above, except that \ccc{newv} will be used as the new vertex, which + must have been allocated previously with e.g. \ccc{create_vertex}.} + +\ccHeading{Traversal of the Triangulation} + +The triangulation class provides several iterators and circulators +that allow one to traverse it (completely or partially). + +\ccHeading{Cell, Face, Edge and Vertex Iterators} +\ccThree{Finite_vertices_iterator}{t.finite_vertices_begin()x}{} + +The following iterators allow the user to visit cells, +facets, edges and vertices of the +triangulation. These iterators are non-mutable, bidirectional and +their value types are respectively \ccc{Cell}, \ccc{Facet}, \ccc{Edge} +and \ccc{Vertex}. They are all invalidated by any change in the +triangulation. + +\ccMethod{Finite_vertices_iterator finite_vertices_begin() const;} +{Starts at an arbitrary finite vertex. Then \ccc{++} and \ccc{--} will +iterate over finite vertices. Returns \ccc{finite_vertices_end()} when +\ccVar.\ccc{number_of_vertices()} $=0$.} +\ccGlue +\ccMethod{Finite_vertices_iterator finite_vertices_end() const;} +{Past-the-end iterator} +\ccGlue +\ccMethod{Finite_edges_iterator finite_edges_begin() const;} +{Starts at an arbitrary finite edge. Then \ccc{++} and \ccc{--} will +iterate over finite edges. Returns \ccc{finite_edges_end()} when +\ccVar.\ccc{dimension()} $<1$.} +\ccGlue +\ccMethod{Finite_edges_iterator finite_edges_end() const;} +{Past-the-end iterator} +\ccGlue +\ccMethod{Finite_facets_iterator finite_facets_begin() const;} +{Starts at an arbitrary finite facet. Then \ccc{++} and \ccc{--} will +iterate over finite facets. Returns \ccc{finite_facets_end()} when +\ccVar.\ccc{dimension()} $<2$.} +\ccGlue +\ccMethod{Finite_facets_iterator finite_facets_end() const;} +{Past-the-end iterator} +\ccGlue +\ccMethod{Finite_cells_iterator finite_cells_begin() const;} +{Starts at an arbitrary finite cell. Then \ccc{++} and \ccc{--} will +iterate over finite cells. Returns \ccc{finite_cells_end()} when +\ccVar.\ccc{dimension()} $<3$.} +\ccGlue +\ccMethod{Finite_cells_iterator finite_cells_end() const;} +{Past-the-end iterator} + +\ccMethod{All_vertices_iterator all_vertices_begin() const;} +{Starts at an arbitrary vertex. Iterates over all vertices (even the infinite +one). Returns \ccc{vertices_end()} when +\ccVar.\ccc{number_of_vertices()} $=0$.} +\ccGlue +\ccMethod{All_vertices_iterator all_vertices_end() const;} +{Past-the-end iterator} +\ccGlue +\ccMethod{All_edges_iterator all_edges_begin() const;} +{Starts at an arbitrary edge. Iterates over all edges (even infinite +ones). Returns \ccc{edges_end()} when \ccVar.\ccc{dimension()} $<1$.} +\ccGlue +\ccMethod{All_edges_iterator all_edges_end() const;} +{Past-the-end iterator} +\ccGlue +\ccMethod{All_facets_iterator all_facets_begin() const;} +{Starts at an arbitrary facet. Iterates over all facets (even infinite +ones). Returns \ccc{facets_end()} when +\ccVar.\ccc{dimension()} $<2$.} +\ccGlue +\ccMethod{All_facets_iterator all_facets_end() const;} +{Past-the-end iterator} +\ccGlue +\ccMethod{All_cells_iterator all_cells_begin() const;} +{Starts at an arbitrary cell. Iterates over all cells (even infinite +ones). Returns \ccc{cells_end()} when +\ccVar.\ccc{dimension()} $<3$.} +\ccGlue +\ccMethod{All_cells_iterator all_cells_end() const;} +{Past-the-end iterator} + +\ccMethod{Point_iterator points_begin() const;} +{Iterates over the points of the triangulation.} +\ccGlue +\ccMethod{Point_iterator points_end() const;} +{Past-the-end iterator} + +\ccHeading{Cell and Facet Circulators} +\ccThree{Facet_circulator}{t.incident_facets(Edge e)x}{} + +The following circulators respectively visit all cells or all facets +incident to a given edge. They are non-mutable and bidirectional. They +are invalidated by any modification of one of the cells traversed. + +\ccMethod{Cell_circulator incident_cells(Edge e) const;} +{Starts at an arbitrary cell incident to \ccc{e}. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$.}} +\ccGlue +\ccMethod{Cell_circulator incident_cells(Cell_handle c, int i, int j) const;} +{As above for edge \ccc{(i,j)} of \ccc{c}.} +\ccGlue +\ccMethod{Cell_circulator incident_cells(Edge e, Cell_handle start) const;} +{Starts at cell \ccc{start}. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$ and \ccc{start} is incident to +\ccc{e}.}} +\ccGlue +\ccMethod{Cell_circulator incident_cells(Cell_handle c, int i, int j, +Cell_handle start) const;} +{As above for edge \ccc{(i,j)} of \ccc{c}.} + +The following circulators on facets are defined only in dimension~3, +though facets are defined also in dimension~2: there are only two +facets sharing an edge in dimension~2. + +\ccMethod{Facet_circulator incident_facets(Edge e) const;} +{Starts at an arbitrary facet incident to \ccc{e}. +\ccPrecond{\ccVar.\ccc{dimension()}~$=3$}} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Cell_handle c, int i, int j) const;} +{As above for edge \ccc{(i,j)} of \ccc{c}.} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Edge e, Facet start) const;} +{Starts at facet \ccc{start}. +\ccPrecond{\ccc{start} is incident to \ccc{e}.}} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Edge e, Cell_handle start, int f) +const;} +{Starts at facet of index \ccc{f} in \ccc{start}.} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Cell_handle c, int i, int j, +Facet start) const;} +{As above for edge \ccc{(i,j)} of \ccc{c}.} +\ccGlue +\ccMethod{Facet_circulator incident_facets(Cell_handle c, int i, int j, +Cell_handle start, int f) const;} +{As above for edge \ccc{(i,j)} of \ccc{c} and facet \ccc{(start,f)}.} + + +\ccHeading{Traversal of the incident cells, facets and edges, and the adjacent +vertices of a given vertex} +\ccThree{OutputIterator}{t.incident_cells()}{} + +\ccMethod{template + OutputIterator + incident_cells(Vertex_handle v, OutputIterator cells) const;} +{Copies the \ccc{Cell_handle}s of all cells incident to \ccc{v} to the output +iterator \ccc{cells}. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + finite_incident_cells(Vertex_handle v, OutputIterator cells) const;} +{Copies the \ccc{Cell_handle}s of all finite cells incident to \ccc{v} to the output +iterator \ccc{cells}. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $=3$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + incident_facets(Vertex_handle v, OutputIterator facets) const;} +{Copies all \ccc{Facet}s incident to \ccc{v} to the output iterator +\ccc{facets}. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $>1$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + finite_incident_facets(Vertex_handle v, OutputIterator facets) const;} +{Copies all finite \ccc{Facet}s incident to \ccc{v} to the output iterator +\ccc{facets}. +Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $>1$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + incident_edges(Vertex_handle v, OutputIterator edges) const;} +{Copies all \ccc{Edge}s incident to \ccc{v} to the +output iterator \ccc{edges}. Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $>0$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + finite_incident_edges(Vertex_handle v, OutputIterator edges) const;} +{Copies all finite \ccc{Edge}s incident to \ccc{v} to the +output iterator \ccc{edges}. Returns the resulting output iterator. +\ccPrecond{\ccVar.\ccc{dimension()} $>0$, \ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + adjacent_vertices(Vertex_handle v, OutputIterator vertices) const;} +{Copies the \ccc{Vertex_handle}s of all vertices adjacent to \ccc{v} to the +output iterator \ccc{vertices}. If \ccVar.\ccc{dimension()} $<0$, then do +nothing. Returns the resulting output iterator. +\ccPrecond{\ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{template + OutputIterator + finite_adjacent_vertices(Vertex_handle v, OutputIterator vertices) const;} +{Copies the \ccc{Vertex_handle}s of all finite vertices adjacent to \ccc{v} to the +output iterator \ccc{vertices}. If \ccVar.\ccc{dimension()} $<0$, then do +nothing. Returns the resulting output iterator. +\ccPrecond{\ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccMethod{size_type degree(Vertex_handle v) const;} +{Returns the degree of a vertex, that is, the number of incident vertices. +The infinite vertex is counted. +\ccPrecond{\ccc{v} $\neq$ \ccc{Vertex_handle()}, \ccVar.\ccc{is_vertex(v)}.}} + +\ccHeading{Traversal between adjacent cells} +\ccThree{Vertex_handle}{mirror_vertex(Cell_handle c, int i)x}{} + +\ccMethod{int mirror_index(Cell_handle c, int i) const;} +{Returns the index of \ccc{c} in its $i^{th}$ neighbor. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{Vertex_handle mirror_vertex(Cell_handle c, int i) const;} +{Returns the vertex of the $i^{th}$ neighbor of \ccc{c} that is opposite to +\ccc{c}. +\ccPrecond{$i \in \{0, 1, 2, 3\}$.}} +\ccGlue +\ccMethod{Facet mirror_facet(Facet f) const;} +{Returns the same facet seen from the other adjacent cell.} + +\begin{ccDebug} +\ccHeading{Checking} +The responsibility of keeping a valid triangulation belongs to the user +when using advanced operations allowing a direct manipulation of cells +and vertices. We provide the user with the following methods to help +debugging. + +\ccMethod{bool + is_valid(bool verbose = false) const;} +{Checks the combinatorial validity of the triangulation. Checks also the +validity of its geometric embedding (see +Section~\ref{Triangulation3-sec-intro}).\\ When \ccc{verbose} is set to true, +messages describing the first invalidity encountered are printed.} + +\ccMethod{bool + is_valid(Cell_handle c, bool verbose = false) const;} +{Checks the combinatorial validity of the cell by calling the +\ccc{is_valid} method of the \ccc{TriangulationDataStructure_3} cell class. Also checks the +geometric validity of \ccc{c}, if \ccc{c} is finite. (See +Section~\pageref{Triangulation3-sec-intro}.)\\ +When \ccc{verbose} is set to \ccc{true}, messages are printed to give +a precise indication of the kind of invalidity encountered.} +\end{ccDebug} + +\ccHeading{I/O} + +\cgal\ provides an interface to Geomview for a 3D-triangulation, +see Chapter~\ref{ChapterGeomview} on \ccc{Geomview_stream}. +\ccInclude{CGAL/IO/Triangulation_geomview_ostream_3.h} + +\ccFunction{istream& operator>> (istream& is, Triangulation_3 &t);} +{Reads the underlying combinatorial triangulation from \ccc{is} by +calling the corresponding input operator of the triangulation data +structure class (note that the infinite vertex is numbered 0), and the +non-combinatorial information by calling the corresponding input +operators of the vertex and the cell classes (such as point +coordinates), which are provided by overloading the stream operators +of the vertex and cell types. Assigns the resulting triangulation to +\ccc{t}.} + +\ccFunction{ostream& operator<< (ostream& os, const Triangulation_3 &t);} +{Writes the triangulation \ccc{t} into \ccc{os}.} + +The information in the \ccc{iostream} is: the dimension, the number of +finite vertices, the non-combinatorial information about vertices +(point, etc; note that the infinite vertex is numbered 0), the number +of cells, the indices of the vertices of each cell, plus the +non-combinatorial information about each cell, then the indices of the +neighbors of each cell, where the index corresponds to the preceding +list of cells. When dimension $<$ 3, the same information is stored +for faces of maximal dimension instead of cells. + +\ccSeeAlso + +\ccc{TriangulationDataStructure_3::Vertex}\\ +\ccc{TriangulationDataStructure_3::Cell} + +%\ccExample +%%\ccIncludeExampleCode{Triangulation3/example1.cpp} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_3.tex new file mode 100644 index 00000000000..f4f6ff6a5dd --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_3.tex @@ -0,0 +1,53 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_cell_base_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationcellbaseRev}{$Id$} +\RCSdefDate{\RCSTriangulationcellbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_cell_base_3} + +\ccDefinition + +The class \ccc{Triangulation_cell_base_3} is a model of the concept +\ccc{TriangulationCellBase_3}, the base cell of a 3D-triangulation. + +This class can be used directly or can serve as a base to derive other classes +with some additional attributes (a color for example) tuned for a specific +application. + +\ccInclude{CGAL/Triangulation_cell_base_3.h} + +\ccParameters + +The first template argument is the geometric traits class +\ccc{TriangulationTraits_3}. It is actually not used by this class. + +The second template argument is a combinatorial cell base class from which +\ccc{Triangulation_cell_base_3} derives. +It has the default value \ccc{Triangulation_ds_cell_base_3<>}. + +Note that this model does not store the circumcenter, but computes it +every time the circumcenter function is called. See +\ccc{CGAL::Triangulation_cell_base_with_circumcenter_3} for a way to cache the +circumcenter computation. + + +\ccIsModel \ccc{TriangulationCellBase_3} + +\ccInheritsFrom \ccc{TriangulationDSCellBase_3} + +\ccSeeAlso + +\ccc{CGAL::Triangulation_ds_cell_base_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_info_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_circumcenter_3}\\ +\ccc{CGAL::Triangulation_vertex_base_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_with_circumcenter_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_with_circumcenter_3.tex new file mode 100644 index 00000000000..6b5af88a28f --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_with_circumcenter_3.tex @@ -0,0 +1,61 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_cell_base_with_circumcenter_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Sylvain Pion +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationcellbaseRev}{$Id$} +\RCSdefDate{\RCSTriangulationcellbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_cell_base_with_circumcenter_3} + +\ccDefinition + +The class \ccc{Triangulation_cell_base_with_circumcenter_3} is a model of the +concept \ccc{TriangulationCellBase_3}, the base cell of a 3D-triangulation. +It provides an easy way to cache the computation of the circumcenter of +tetrahedra. +Note that input/output operators discard this additional information. + +All functions modifying the vertices of the cell, invalidate the cached +circumcenter. + +\ccInclude{CGAL/Triangulation_cell_base_with_circumcenter_3.h} + +\ccParameters + +The first template argument is the geometric traits class +\ccc{DelaunayTriangulationTraits_3}. + +The second template argument is a cell base class from which +\ccc{Triangulation_cell_base_with_circumcenter_3} derives. +It has the default value \ccc{Triangulation_cell_base_3}. + +\ccIsModel \ccc{TriangulationCellBase_3} + +\ccInheritsFrom \ccc{TriangulationCellBase_3} + +%\ccTypes +%\ccTypedef{typedef Info Info;}{} + +\ccCreationVariable{v} + +\ccAccessFunctions +\ccThree{const Info&}{Facetxxxxxxxx}{} +\ccTagFullDeclarations + +\ccMethod{const DelaunayTriangulationTraits_3::Point_3& circumcenter( + const DelaunayTriangulationTraits_3> = DelaunayTriangulationTraits_3()) const;} +{Computes the circumcenter of the tetrahedron, or retrieve it if already +computed.} + +\ccSeeAlso + +\ccc{CGAL::Triangulation_cell_base_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_info_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_with_info_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_with_info_3.tex new file mode 100644 index 00000000000..d5dfd5d196a --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_cell_base_with_info_3.tex @@ -0,0 +1,62 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_cell_base_with_info_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationcellbaseRev}{$Id$} +\RCSdefDate{\RCSTriangulationcellbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_cell_base_with_info_3} + +\ccDefinition + +The class \ccc{Triangulation_cell_base_with_info_3} is a model of the concept +\ccc{TriangulationCellBase_3}, the base cell of a 3D-triangulation. +It provides an easy way to add some user defined information in cells. +Note that input/output operators discard this additional information. + +\ccInclude{CGAL/Triangulation_cell_base_with_info_3.h} + +\ccParameters + +The first template argument is the information the user would like to add +to a cell. It has to be \ccc{DefaultConstructible} and \ccc{Assignable}. + +The second template argument is the geometric traits class +\ccc{TriangulationTraits_3}. It is actually not used by this class. + +The third template argument is a cell base class from which +\ccc{Triangulation_cell_base_with_info_3} derives. It has the default value +\ccc{Triangulation_cell_base_3}. + +\ccIsModel \ccc{TriangulationCellBase_3} + +\ccInheritsFrom \ccc{TriangulationCellBase_3} + +\ccTypes +\ccTypedef{typedef Info Info;}{} + +\ccCreationVariable{v} + +\ccAccessFunctions +\ccThree{const Info&}{Facetxxxxxxxx}{} +\ccTagFullDeclarations + +\ccMethod{const Info& info() const;} +{Returns a const reference to the object of type \ccc{Info} stored in the cell.} +\ccGlue +\ccMethod{Info & info();} +{Returns a reference to the object of type \ccc{Info} stored in the cell.} + +\ccSeeAlso + +\ccc{CGAL::Triangulation_cell_base_3}\\ +\ccc{CGAL::Triangulation_cell_base_with_circumcenter_3} +\ccc{CGAL::Triangulation_vertex_base_with_info_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_hierarchy_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_hierarchy_3.tex new file mode 100644 index 00000000000..77696a5c952 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_hierarchy_3.tex @@ -0,0 +1,85 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_hierarchy_3.tex +% +------------------------------------------------------------------------+ +% | +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationhierarchyRev}{$Id$} +\RCSdefDate{\RCSTriangulationhierarchyDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_hierarchy_3} + +\begin{ccDeprecated} + +{\em Note} : this class is deprecated since \cgal\ 3.6. Its functionality has +been replaced by the use of the \ccc{Fast_location} tag as the +\ccc{LocationPolicy} template parameter in \ccc{Delaunay_triangulation_3}. + +\ccDefinition + +The class \ccc{Triangulation_hierarchy_3} implements a triangulation augmented +with a data structure which allows fast point location queries. As proved +in~\cite{cgal:d-dh-02}, this structure has an optimal behavior when it is built +for Delaunay triangulations. It can however be used for other triangulations. + +\ccInclude{CGAL/Triangulation_hierarchy_3.h} + +\ccParameters + +It is templated by a parameter which must be instantiated by one of the \cgal\ +triangulation classes. \textit{In the current implementation, only +\ccc{Delaunay_triangulation_3} is supported for \ccc{Tr}.} + +\ccc{Tr::Vertex} has to be a model of the concept +\ccc{TriangulationHierarchyVertexBase_3}.\\ +\ccc{Tr::Geom_traits} has to be a model of the concept +\ccc{DelaunayTriangulationTraits_3}. + +\ccInheritsFrom + +\ccc{Tr} + +\ccRefName\ offers exactly the same functionalities as \ccc{Tr}. +Most of them (point location, insertion, removal\ldots) are overloaded to +improve their efficiency by using the hierarchic structure. + +Note that, since the algorithms that are provided are randomized, the +running time of constructing a triangulation with a hierarchy may be +improved when shuffling the data points. + +However, the I/O operations are not overloaded. So, writing a +hierarchy into a file will lose the hierarchic structure and reading +it from the file will result in an ordinary triangulation whose +efficiency will be the same as \ccc{Tr}. + +\ccImplementation +The data structure is a hierarchy +of triangulations. The triangulation at the lowest level is +the original triangulation where operations and point location are to +be performed. +Then at each succeeding level, the data structure +stores a triangulation of a small random sample of the vertices +of the triangulation at the preceding level. Point location +is done through a top-down nearest neighbor query. +The nearest neighbor query is first +performed naively in the top level triangulation. +Then, at each following level, the nearest neighbor at that level +is found through a linear walk performed from +the nearest neighbor found at the preceding level. +Because the number of vertices in each triangulation is only a small +fraction of the number of vertices of the preceding triangulation +the data structure remains small and achieves fast point location +queries on real +data. + +\ccSeeAlso +\ccc{CGAL::Triangulation_hierarchy_vertex_base_3}\\ +\ccc{CGAL::Delaunay_triangulation_3} + +\end{ccDeprecated} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_hierarchy_vertex_base_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_hierarchy_vertex_base_3.tex new file mode 100644 index 00000000000..7d5f45ca89e --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_hierarchy_vertex_base_3.tex @@ -0,0 +1,54 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_hierarchy_vertex_base_3.tex +% +------------------------------------------------------------------------+ +% | +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationhierarchyvertexbaseRev}{$Id$} +\RCSdefDate{\RCSTriangulationhierarchyvertexbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_hierarchy_vertex_base_3} + +\begin{ccDeprecated} + +{\em Note} : this class is deprecated since \cgal\ 3.6. Its functionality is now +transparently added when using the \ccc{Fast_location} tag as the +\ccc{LocationPolicy} template parameter in \ccc{Delaunay_triangulation_3}, +instead of \ccc{Triangulation_hierarchy_3}. + +\ccDefinition + +This class is designed to be used as the vertex base class for +\ccc{Triangulation_hierarchy_3}. + +It inherits from its parameter \ccc{TriangulationVertexBase_3}, and adds the +requirements in order to match the concept +\ccc{TriangulationHierarchyVertexBase_3}, it does so by storing two +\ccc{Vertex_handle}s. This design allows to use either a vertex base class +provided by \cgal, or a user customized vertex base with additional +functionalities. + +\ccInclude{CGAL/Triangulation_hierarchy_vertex_base_3.h} + +\ccParameters + +It is parameterized by a model of the concept \ccc{TriangulationVertexBase_3}. + +\ccIsModel \ccc{TriangulationHierarchyVertexBase_3} + +\ccInheritsFrom \ccc{TriangulationVertexBase_3} + +\ccCreationVariable{v} + +\ccSeeAlso +\ccc{CGAL::Triangulation_hierarchy_3}\\ +\ccc{CGAL::Triangulation_vertex_base_3}\\ +\ccc{CGAL::Triangulation_vertex_base_with_info_3} + +\end{ccDeprecated} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_locate_type_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_locate_type_3.tex new file mode 100644 index 00000000000..f13000ce808 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_locate_type_3.tex @@ -0,0 +1,30 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_locate_type_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationlocatetypeRev}{$Id$} +\RCSdefDate{\RCSTriangulationlocatetypeDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + +\ccModifierCrossRefOff +\begin{ccRefEnum}[Triangulation_3::]{Locate_type} + +\ccDefinition + +The enum \ccRefName\ is defined by \ccc{Triangulation_3} to specify +which case occurs when locating a point in the triangulation. + +\ccEnum{enum Locate_type {VERTEX=0, EDGE, FACET, CELL, OUTSIDE_CONVEX_HULL, +OUTSIDE_AFFINE_HULL};} +{} + +\ccSeeAlso + +\ccc{CGAL::Triangulation_3} + +\end{ccRefEnum} +\ccModifierCrossRefOn diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_simplex_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_simplex_3.tex new file mode 100644 index 00000000000..fc46bc610a1 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_simplex_3.tex @@ -0,0 +1,126 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_simplex_3.tex +% +------------------------------------------------------------------------+ +% | 27.09.2005 Nico Kruithof +% | Package: Triangulation_3 +% | +\RCSdef{\RCSTriangulationsimplexRev}{$Id$} +\RCSdefDate{\RCSTriangulationsimplexDate}{$Date$} +% +------------------------------------------------------------------------+ + +\ccRefPageBegin + +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_simplex_3} +\label{refTriangulationSimplex} + +\ccDefinition The class \ccRefName\ stores a simplex of any dimension +defined by the \ccc{Triangulation_3} class. It also defines the +operator less such that simplices can be stored in a \ccc{map} or a +\ccc{set} of simplices. The simplex is invalidated by any change in +the triangulation. + +\ccInclude{CGAL/Triangulation_simplex_3.h} + +\ccParameters +% +It is parameterized by the triangulation it derives the simplices +from. + +\ccTypes +\ccThree{typedef Triangulation_simplex_3}{Triangulated}{} +\ccThreeToTwo + +\ccTypedef{typedef Triangulation_simplex_3 Simplex;}{ + The simplex class itself.} + +\ccTypedef{typedef Triangulation_3::Vertex_handle Vertex_handle;}{} +\ccGlue +\ccTypedef{typedef Triangulation_3::Edge Edge;}{} +\ccGlue +\ccTypedef{typedef Triangulation_3::Facet Facet;}{} +\ccGlue +\ccTypedef{typedef Triangulation_3::Cell_handle Cell_handle;}{} + +\ccTypedef{typedef Triangulation_3::Cell_circulator Cell_circulator;}{} +\ccGlue +\ccTypedef{typedef Triangulation_3::Facet_circulator Facet_circulator;}{} + +\ccTypedef{typedef Triangulation_3::Edge_iterator Edge_iterator;}{} +\ccGlue +\ccTypedef{typedef Triangulation_3::Facet_iterator Facet_iterator;}{} + +\ccTypedef{typedef Triangulation_3::Finite_vertices_iterator Finite_vertices_iterator;}{} +\ccGlue +\ccTypedef{typedef Triangulation_3::Finite_edges_iterator Finite_edges_iterator;}{} +\ccGlue +\ccTypedef{typedef Triangulation_3::Finite_facets_iterator Finite_facets_iterator;}{} +\ccGlue +\ccTypedef{typedef Triangulation_3::Finite_cells_iterator Finite_cells_iterator;}{} + + +\ccCreation +\ccCreationVariable{simplex} %% choose variable name +\ccThree{Triangulation_simplex_3}{simplex}{} +\ccThreeToTwo + +\ccConstructor{Triangulation_simplex_3();}{Initializes the simplex to + an invalid simplex.} + +\ccConstructor{Triangulation_simplex_3(Vertex_handle vh);}{} +\ccGlue +\ccConstructor{Triangulation_simplex_3(Edge e);}{} +\ccGlue +\ccConstructor{Triangulation_simplex_3(Facet f);}{} +\ccGlue +\ccConstructor{Triangulation_simplex_3(Cell_handle ch);}{} + +\ccConstructor{Triangulation_simplex_3(Cell_circulator ccir);}{} +\ccGlue +\ccConstructor{Triangulation_simplex_3(Facet_circulator fcir);}{} + +\ccConstructor{Triangulation_simplex_3(Edge_iterator eit);}{} +\ccGlue +\ccConstructor{Triangulation_simplex_3(Facet_iterator fit);}{} + +\ccOperations +\ccThree{Vertex_handle}{Vertex_handle(simplex)xx}{} +\ccThreeToTwo + +\ccMethod{int dimension () const;}{returns the dimension of the + simplex.} +% +\ccMethod{operator Vertex_handle () const;}{Returns the \ccc{Vertex_handle} + stored in the simplex. \ccPrecond{dimension() == 0}} +\ccGlue +\ccMethod{operator Edge () const;}{Returns the \ccc{Edge} + stored in the simplex. \ccPrecond{dimension() == 1}} +\ccGlue +\ccMethod{operator Facet () const;}{Returns the \ccc{Facet} + stored in the simplex. \ccPrecond{dimension() == 2}} +\ccGlue +\ccMethod{operator Cell_handle () const;}{Returns the \ccc{Cell_handle} + stored in the simplex. \ccPrecond{dimension() == 3}} + +\ccMethod{Cell_handle incident_cell () const;}{Returns a cell incident + to the simplex.} + + +\ccMethod{bool operator==(const + Triangulation_simplex_3 &s1);}{Test whether two + simplices are equal.} +% +\ccGlue +% +\ccMethod{bool operator< (const + Triangulation_simplex_3 &s1);}{Defines a ordering + on the simplices. This ordering depends on the memory layout and is + independent of the geometry. Therefore, the ordering is not intrinsic} + +\ccSeeAlso +\ccRefIdfierPage{CGAL::Triangulation_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_vertex_base_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_vertex_base_3.tex new file mode 100644 index 00000000000..c7d8ba29f0d --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_vertex_base_3.tex @@ -0,0 +1,58 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_vertex_base_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationvertexbaseRev}{$Id$} +\RCSdefDate{\RCSTriangulationvertexbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_vertex_base_3} + +\ccDefinition + +The class \ccc{Triangulation_vertex_base_3} is a model of the concept +\ccc{TriangulationVertexBase_3}, the base vertex of a 3D-triangulation. +This class stores a point. + +This class can be used directly or can serve as a base to derive other classes +with some additional attributes (a color for example) tuned for a specific +application. + +\ccInclude{CGAL/Triangulation_vertex_base_3.h} + +\ccParameters + +The first template argument is the geometric traits class +\ccc{TriangulationTraits_3} which provides the point type, \ccc{Point_3}. +Users of the geometric triangulations (Section~\ref{TDS3-sec-design} and +Chapter~\ref{chapter-Triangulation3}) are strongly advised to use the same +geometric traits class \ccc{TriangulationTraits_3} as the one used for +\ccc{Triangulation_3}. This way, the point type defined by the base vertex is +the same as the point type defined by the geometric traits class. + +The second template argument is a combinatorial vertex base class from which +\ccc{Triangulation_vertex_base_3} derives. +It has the default value \ccc{Triangulation_ds_vertex_base_3<>}. + +\ccIsModel \ccc{TriangulationVertexBase_3} + +\ccInheritsFrom \ccc{TriangulationDSVertexBase_3} + +\ccTypes + +\ccThree{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}{} +\ccThreeToTwo +\ccTypedef{typedef TriangulationTraits_3::Point_3 Point;}{} + +\ccSeeAlso + +\ccc{CGAL::Triangulation_cell_base_3}\\ +\ccc{CGAL::Triangulation_ds_vertex_base_3}\\ +\ccc{CGAL::Triangulation_vertex_base_with_info_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_vertex_base_with_info_3.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_vertex_base_with_info_3.tex new file mode 100644 index 00000000000..bfa2e99e52e --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/Triangulation_vertex_base_with_info_3.tex @@ -0,0 +1,61 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation_vertex_base_with_info_3.tex +% +------------------------------------------------------------------------+ +% | 29.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationvertexbaseRev}{$Id$} +\RCSdefDate{\RCSTriangulationvertexbaseDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Triangulation_vertex_base_with_info_3} + +\ccDefinition + +The class \ccc{Triangulation_vertex_base_with_info_3} is a model of the concept +\ccc{TriangulationVertexBase_3}, the base vertex of a 3D-triangulation. +It provides an easy way to add some user defined information in vertices. +Note that input/output operators discard this additional information. + +\ccInclude{CGAL/Triangulation_vertex_base_with_info_3.h} + +\ccParameters + +The first template argument is the information the user would like to add +to a vertex. It has to be \ccc{DefaultConstructible} and \ccc{Assignable}. + +The second template argument is the geometric traits class +\ccc{TriangulationTraits_3} which provides the \ccc{Point_3}. + +The third template argument is a vertex base class from which +\ccc{Triangulation_vertex_base_with_info_3} derives. It has the default +value \ccc{Triangulation_vertex_base_3}. + +\ccIsModel \ccc{TriangulationVertexBase_3} + +\ccInheritsFrom \ccc{TriangulationVertexBase_3} + +\ccTypes +\ccTypedef{typedef Info Info;}{} + +\ccCreationVariable{v} + +\ccAccessFunctions +\ccThree{const Info&}{Facetxxxxxxxxxx}{} +\ccTagFullDeclarations + +\ccMethod{const Info& info() const;} +{Returns a const reference to the object of type \ccc{Info} stored in the +vertex.} +\ccGlue +\ccMethod{Info& info();} +{Returns a reference to the object of type \ccc{Info} stored in the vertex.} +\ccSeeAlso + +\ccc{CGAL::Triangulation_cell_base_with_info_3}\\ +\ccc{CGAL::Triangulation_vertex_base_3} + +\end{ccRefClass} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/WeightedPoint.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/WeightedPoint.tex new file mode 100644 index 00000000000..91aad12eed4 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/WeightedPoint.tex @@ -0,0 +1,53 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Weight_pt.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSWeightedpointRev}{$Id$} +\RCSdefDate{\RCSWeightedpointDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefConcept}{WeightedPoint} + +%% \ccHtmlCrossLink{} %% add further rules for cross referencing links +%% \ccHtmlIndexC[concept]{} %% add further index entries + +\ccDefinition + +The concept \ccRefName\ is needed by +\ccc{Regular_triangulation_euclidean_traits_3}. +It must fulfill the following requirements: + +\ccTypes +\ccThree{typedef Point::RT}{RTxxxx}{} +\ccNestedType{Point}{The point type} +\ccGlue +\ccNestedType{Weight}{The weight type} +\ccGlue +\ccTypedef{typedef Point::RT RT;}{The ring type} + +\ccCreation +\ccCreationVariable{wp} + +\ccConstructor{WeightedPoint(const Point &p=Point(), const Weight &w += Weight(0))}{} + +\ccAccessFunctions +\ccFunction{Point point() const;}{} +\ccGlue +\ccFunction{Weight weight() const;}{} + +\ccHasModels + +\ccc{Weighted_point}. + +\ccSeeAlso + +\ccc{CGAL::Regular_triangulation_euclidean_traits_3}\\ +\ccc{CGAL::Regular_triangulation_3}. + +\end{ccRefConcept} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/flips.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/flips.gif new file mode 100644 index 00000000000..60156fcaddd Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/flips.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/flips.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/flips.pdf new file mode 100644 index 00000000000..870912cc86d Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/flips.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_affine_hull.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_affine_hull.gif new file mode 100644 index 00000000000..6ee04d717cf Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_affine_hull.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_affine_hull.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_affine_hull.pdf new file mode 100644 index 00000000000..58ce71b391c Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_affine_hull.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_convex_hull.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_convex_hull.gif new file mode 100644 index 00000000000..3e21752d3ff Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_convex_hull.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_convex_hull.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_convex_hull.pdf new file mode 100644 index 00000000000..df40343b31e Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/insert_outside_convex_hull.pdf differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/intro.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/intro.tex new file mode 100644 index 00000000000..da1c3c668a6 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/intro.tex @@ -0,0 +1,96 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Triangulation/intro.tex +% +------------------------------------------------------------------------+ +% | 27.3.2000 Monique Teillaud +% | Package: Triangulation3 +% | +\RCSdef{\RCSTriangulationcellRev}{$Id$} +\RCSdefDate{\RCSTriangulationcellDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + +%\clearpage +%\section{Reference pages for 3D-Triangulations} + +\ccRefChapter{3D Triangulations} +\ccChapterAuthor{Sylvain Pion \and Monique Teillaud} + +A three-dimensional triangulation is a three-dimensional simplicial +complex, pure connected and without singularities \cite{by-ag-98}. Its +cells ($3$-faces) are such that two cells either do not intersect or +share a common facet ($2$-face), edge ($1$-face) or vertex ($0$-face). + +The basic 3D-triangulation class of \cgal\ is primarily designed to +represent the triangulations of a set of points $A$ in $\R^3$. It can +be viewed as a partition of the convex hull of {$A$} into tetrahedra +whose vertices are the points of {$A$}. Together with the unbounded +cell having the convex hull boundary as its frontier, the triangulation +forms a partition of $\R^3$. + +In order to deal +only with tetrahedra, which is convenient for many applications, the +unbounded cell can be subdivided into tetrahedra by considering that +each convex hull facet is incident to an \ccc{infinite cell} having as +fourth vertex an auxiliary vertex called the \ccc{infinite vertex}. In +that way, each facet is incident to exactly two cells and special cases +at the boundary of the convex hull are simple to deal with. + + +A triangulation is a collection of vertices and cells that are linked +together through incidence and adjacency relations. Each cell gives +access to its four incident vertices and to its four adjacent +cells. Each vertex gives access to one of its incident cells. + +The four vertices of a cell are indexed with 0, 1, 2 and 3 in positive +orientation, the positive orientation being defined by the orientation +of the underlying Euclidean space $\R^3$. The neighbors of a cell are also +indexed with 0, 1, 2, 3 in such a way that the neighbor indexed by $i$ +is opposite to the vertex with the same index. See +Figure~\ref{Triangulation3-fig-orient}. + + +\section{Classified Reference Pages} + +\subsection*{Concepts} + +\ccRefConceptPage{TriangulationTraits_3}\\ +\ccRefConceptPage{DelaunayTriangulationTraits_3}\\ +\ccRefConceptPage{RegularTriangulationTraits_3}\\ + +\ccRefConceptPage{TriangulationCellBase_3}\\ +\ccRefConceptPage{TriangulationVertexBase_3}\\ +\ccRefConceptPage{TriangulationHierarchyVertexBase_3}\\ + +\ccRefConceptPage{RegularTriangulationCellBase_3}\\ + +\ccRefConceptPage{TriangulationDataStructure_3}\\ +\ccRefConceptPage{WeightedPoint}\\ + +\subsection*{Classes} + +\subsubsection*{Main Classes} + +\ccRefIdfierPage{CGAL::Triangulation_3}\\ +\ccRefIdfierPage{CGAL::Delaunay_triangulation_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_hierarchy_3}\\ +\ccRefIdfierPage{CGAL::Regular_triangulation_3} + +\ccRefIdfierPage{CGAL::Triangulation_cell_base_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_cell_base_with_info_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_cell_base_with_circumcenter_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_vertex_base_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_vertex_base_with_info_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_hierarchy_vertex_base_3}\\ +\ccRefIdfierPage{CGAL::Regular_triangulation_cell_base_3}\\ +\ccRefIdfierPage{CGAL::Triangulation_simplex_3} + +\subsubsection*{Traits Classes} + +\ccRefIdfierPage{CGAL::Regular_triangulation_euclidean_traits_3} + + +\subsection*{Enums} + +\ccRefIdfierPage{CGAL::Triangulation_3::Locate_type} + diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/main.tex b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/main.tex new file mode 100644 index 00000000000..95572e42ce1 --- /dev/null +++ b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/main.tex @@ -0,0 +1,40 @@ +% +------------------------------------------------------------------------+ +% | CBP Reference Manual: main.tex +% +------------------------------------------------------------------------+ +% | Automatically generated driver file for the reference manual chapter +% | of this package. Do not edit manually, you may loose your changes. +% +------------------------------------------------------------------------+ + +\input{Triangulation_3_ref/intro.tex} + +\input{Triangulation_3_ref/Triangulation_3.tex} +\input{Triangulation_3_ref/Delaunay_triangulation_3.tex} +\input{Triangulation_3_ref/Triangulation_hierarchy_3.tex} +\input{Triangulation_3_ref/Regular_triangulation_3.tex} + +\input{Triangulation_3_ref/TriangulationTraits_3.tex} +\input{Triangulation_3_ref/DelaunayTriangulationTraits_3.tex} +\input{Triangulation_3_ref/RegularTriangulationTraits_3.tex} + +\input{Triangulation_3_ref/Regular_triangulation_euclidean_traits_3.tex} + +\input{Triangulation_3_ref/TriangulationCellBase_3.tex} +\input{Triangulation_3_ref/TriangulationVertexBase_3.tex} +\input{Triangulation_3_ref/Triangulation_simplex_3.tex} +\input{Triangulation_3_ref/TriangulationHierarchyVertexBase_3.tex} + +\input{Triangulation_3_ref/RegularCellBase_3.tex} + +\input{Triangulation_3_ref/Triangulation_cell_base_3.tex} +\input{Triangulation_3_ref/Triangulation_cell_base_with_info_3.tex} +\input{Triangulation_3_ref/Triangulation_cell_base_with_circumcenter_3.tex} +\input{Triangulation_3_ref/Triangulation_vertex_base_3.tex} +\input{Triangulation_3_ref/Triangulation_vertex_base_with_info_3.tex} +\input{Triangulation_3_ref/Triangulation_hierarchy_vertex_base_3.tex} + +\input{Triangulation_3_ref/Regular_triangulation_cell_base_3.tex} + +\input{Triangulation_3_ref/Triangulation_locate_type_3.tex} +\input{Triangulation_3_ref/WeightedPoint.tex} + +\input{Triangulation_3_ref/Regular_triangulation_filtered_traits_3.tex} diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/sidedim2.gif b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/sidedim2.gif new file mode 100644 index 00000000000..d0e019929fa Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/sidedim2.gif differ diff --git a/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/sidedim2.pdf b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/sidedim2.pdf new file mode 100644 index 00000000000..7af4e59330d Binary files /dev/null and b/Triangulation_3_copy_tds/doc_tex/Triangulation_3_ref/sidedim2.pdf differ diff --git a/Triangulation_3_copy_tds/dont_submit b/Triangulation_3_copy_tds/dont_submit new file mode 100644 index 00000000000..f59972245bd --- /dev/null +++ b/Triangulation_3_copy_tds/dont_submit @@ -0,0 +1,2 @@ +tds3_small.pdf +benchmark diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/README b/Triangulation_3_copy_tds/examples/Triangulation_3/README new file mode 100644 index 00000000000..d67b701d3d5 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/README @@ -0,0 +1,52 @@ +------- simple_triangulation_3 ----------------------------------------------- + +This example shows the incremental construction of a 3D triangulation, +the location of a point, and how to manipulate elementary operations +on indices in a cell. It uses the default parameters proposed by +CGAL for the Triangulation_3 class. + + +------- color ------------------------------------------------ + +This example shows how the user can plug his own vertex base in a +triangulation. + +------- adding_handles_3 --------------------------------------- + +This example shows how the user can plug his own vertex base +in a triangulation, when he needs to add handles in it. + + +------- fast_location_3 -------------------------------------------- + +This example shows the use of the Fast_location policy to speed up +point location queries in a Delaunay triangulation. + +------- tds -------------------------------------------------- + +Shows how to construct a 3D triangulation data structure by +inserting vertices. + + +------- find_conflicts_3 --------------------------------------- + +Illustrates how the insertion process of points in a Delaunay +triangulation can be decomposed in order to give access to the +cells in conflict (those which would be destroyed by the insertion +of a point) prior to deciding to do the actual insertion or not. + + +------- linking_2d_and_3d ------------------------------------ + +Illustrates how to setup a 2D and a 3D triangulation data structure +whose vertices respectively store vertex handles of the other one. + + +------- regular_3 ---------------------------------------------- + +Illustrates the use of Regular_triangulation_3. + + +------- simplex ---------------------------------------------- + +Illustrates the use of Triangulation_3::Simplex. diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/adding_handles_3.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/adding_handles_3.cpp new file mode 100644 index 00000000000..91592697d08 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/adding_handles_3.cpp @@ -0,0 +1,61 @@ +#include +#include +#include + +template < class GT, class Vb = CGAL::Triangulation_vertex_base_3 > +class My_vertex_base + : public Vb +{ +public: + typedef typename Vb::Vertex_handle Vertex_handle; + typedef typename Vb::Cell_handle Cell_handle; + typedef typename Vb::Point Point; + + template < class TDS2 > + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef My_vertex_base Other; + }; + + My_vertex_base() {} + + My_vertex_base(const Point& p) + : Vb(p) {} + + My_vertex_base(const Point& p, Cell_handle c) + : Vb(p, c) {} + + Vertex_handle vh; + Cell_handle ch; +}; + + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef CGAL::Triangulation_data_structure_3 > Tds; +typedef CGAL::Delaunay_triangulation_3 Delaunay; + +typedef Delaunay::Vertex_handle Vertex_handle; +typedef Delaunay::Point Point; + +int main() +{ + Delaunay T; + + Vertex_handle v0 = T.insert(Point(0,0,0)); + Vertex_handle v1 = T.insert(Point(1,0,0)); + Vertex_handle v2 = T.insert(Point(0,1,0)); + Vertex_handle v3 = T.insert(Point(0,0,1)); + Vertex_handle v4 = T.insert(Point(2,2,2)); + Vertex_handle v5 = T.insert(Point(-1,0,1)); + + // Now we can link the vertices as we like. + v0->vh = v1; + v1->vh = v2; + v2->vh = v3; + v3->vh = v4; + v4->vh = v5; + v5->vh = v0; + + return 0; +} diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/color.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/color.cpp new file mode 100644 index 00000000000..7bb190843b5 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/color.cpp @@ -0,0 +1,32 @@ +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef CGAL::Triangulation_vertex_base_with_info_3 Vb; +typedef CGAL::Triangulation_data_structure_3 Tds; +typedef CGAL::Delaunay_triangulation_3 Delaunay; + +typedef Delaunay::Point Point; + +int main() +{ + Delaunay T; + + T.insert(Point(0,0,0)); + T.insert(Point(1,0,0)); + T.insert(Point(0,1,0)); + T.insert(Point(0,0,1)); + T.insert(Point(2,2,2)); + T.insert(Point(-1,0,1)); + + // Set the color of finite vertices of degree 6 to red. + Delaunay::Finite_vertices_iterator vit; + for (vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) + if (T.degree(vit) == 6) + vit->info() = CGAL::RED; + + return 0; +} diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/fast_location_3.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/fast_location_3.cpp new file mode 100644 index 00000000000..1d2ce0ccc77 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/fast_location_3.cpp @@ -0,0 +1,35 @@ +#include +#include +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Delaunay_triangulation_3 Delaunay; +typedef Delaunay::Point Point; + +int main() +{ + // generating points on a grid. + std::vector P; + + for (int z=0 ; z<20 ; z++) + for (int y=0 ; y<20 ; y++) + for (int x=0 ; x<20 ; x++) + P.push_back(Point(x,y,z)); + + // building their Delaunay triangulation. + Delaunay T(P.begin(), P.end()); + + assert( T.number_of_vertices() == 8000 ); + + // performing nearest vertex queries to a series of random points, + // which is a case where the Fast_location policy is beneficial. + for (int i=0; i<10000; ++i) + T.nearest_vertex(Point(CGAL::default_random.get_double(0, 20), + CGAL::default_random.get_double(0, 20), + CGAL::default_random.get_double(0, 20))); + + return 0; +} diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/find_conflicts_3.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/find_conflicts_3.cpp new file mode 100644 index 00000000000..60211a47bb3 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/find_conflicts_3.cpp @@ -0,0 +1,58 @@ +#include +#include +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef CGAL::Delaunay_triangulation_3 Delaunay; +typedef Delaunay::Point Point; +typedef Delaunay::Cell_handle Cell_handle; +typedef Delaunay::Facet Facet; + +int main() +{ + Delaunay T; + CGAL::Random_points_in_sphere_3 rnd; + + // First, make sure the triangulation is 3D. + T.insert(Point(0,0,0)); + T.insert(Point(1,0,0)); + T.insert(Point(0,1,0)); + T.insert(Point(0,0,1)); + + assert(T.dimension() == 3); + + // Inserts 100 random points if and only if their insertion + // in the Delaunay tetrahedralization conflicts with + // an even number of cells. + for (int i = 0; i != 100; ++i) { + Point p = *rnd++; + + // Locate the point + Delaunay::Locate_type lt; + int li, lj; + Cell_handle c = T.locate(p, lt, li, lj); + if (lt == Delaunay::VERTEX) + continue; // Point already exists + + // Get the cells that conflict with p in a vector V, + // and a facet on the boundary of this hole in f. + std::vector V; + Facet f; + + T.find_conflicts(p, c, + CGAL::Oneset_iterator(f), // Get one boundary facet + std::back_inserter(V)); // Conflict cells in V + + if ((V.size() & 1) == 0) // Even number of conflict cells ? + T.insert_in_hole(p, V.begin(), V.end(), f.first, f.second); + } + + std::cout << "Final triangulation has " << T.number_of_vertices() + << " vertices." << std::endl; + + return 0; +} diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/linking_2d_and_3d.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/linking_2d_and_3d.cpp new file mode 100644 index 00000000000..f4e6b63a015 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/linking_2d_and_3d.cpp @@ -0,0 +1,82 @@ +#include +#include +#include + +// declare the 2D vertex base type, parametrized by some 3D TDS. +template < typename T3, typename Vb = CGAL::Triangulation_ds_vertex_base_2<> > +class My_vertex_2; + +// declare the 3D vertex base type, parametrized by some 2D TDS. +template < typename T2, typename Vb = CGAL::Triangulation_ds_vertex_base_3<> > +class My_vertex_3; + +// Then, we have to break the dependency cycle. + +// we need to refer to a dummy 3D TDS. +typedef CGAL::Triangulation_ds_vertex_base_3<>::Triangulation_data_structure + Dummy_tds_3; +// the 2D TDS, initially plugging a dummy 3D TDS in the vertex type +// (to break the dependency cycle). +typedef CGAL::Triangulation_data_structure_2 > TDS_2; +// the 3D TDS, here we can plug the 2D TDS directly. +typedef CGAL::Triangulation_data_structure_3 > TDS_3; + + +template < typename T3, typename Vb > +class My_vertex_2 + : public Vb +{ +public: + typedef typename Vb::Face_handle Face_handle; + + template + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + // we also have to break the cycle here by hardcoding TDS_3 instead of T3. + typedef My_vertex_2 Other; + }; + + My_vertex_2() {} + + My_vertex_2(Face_handle f) : Vb(f) {} + + // we store a vertex handle of the 3D TDS. + typename T3::Vertex_handle v3; +}; + +template < typename T2, typename Vb > +class My_vertex_3 + : public Vb +{ +public: + typedef typename Vb::Cell_handle Cell_handle; + + template + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef My_vertex_3 Other; + }; + + My_vertex_3() {} + + My_vertex_3(Cell_handle c) : Vb(c) {} + + // we store a vertex handle of the 2D TDS. + typename T2::Vertex_handle v2; +}; + + +int main() { + TDS_2 t2; + TDS_3 t3; + + TDS_2::Vertex_handle v2 = t2.insert_dim_up(); + TDS_3::Vertex_handle v3 = t3.insert_increase_dimension(); + + v2->v3 = v3; + v3->v2 = v2; + + assert(t2.is_valid()); + assert(t3.is_valid()); + return 0; +} diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/regular_3.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/regular_3.cpp new file mode 100644 index 00000000000..e75adb2a380 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/regular_3.cpp @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef CGAL::Regular_triangulation_euclidean_traits_3 Traits; + +typedef Traits::RT Weight; +typedef Traits::Bare_point Point; +typedef Traits::Weighted_point Weighted_point; + +typedef CGAL::Regular_triangulation_3 Rt; + +typedef Rt::Vertex_iterator Vertex_iterator; +typedef Rt::Vertex_handle Vertex_handle; + +int main() +{ + // generate points on a 3D grid + std::vector P; + + int number_of_points = 0; + + for (int z=0 ; z<5 ; z++) + for (int y=0 ; y<5 ; y++) + for (int x=0 ; x<5 ; x++) { + Point p(x, y, z); + Weight w = (x+y-z*y*x)*2.0; // let's say this is the weight. + P.push_back(Weighted_point(p, w)); + ++number_of_points; + } + + Rt T; + + // insert all points in a row (this is faster than one insert() at a time). + T.insert (P.begin(), P.end()); + + assert( T.is_valid() ); + assert( T.dimension() == 3 ); + + std::cout << "Number of vertices : " << T.number_of_vertices() << std::endl; + + // removal of all vertices + int count = 0; + while (T.number_of_vertices() > 0) { + T.remove (T.finite_vertices_begin()); + ++count; + } + + assert( count == number_of_points ); + + return 0; +} diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/simple_triangulation_3.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/simple_triangulation_3.cpp new file mode 100644 index 00000000000..d997669ee72 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/simple_triangulation_3.cpp @@ -0,0 +1,72 @@ +#include +#include + +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef CGAL::Triangulation_3 Triangulation; + +typedef Triangulation::Cell_handle Cell_handle; +typedef Triangulation::Vertex_handle Vertex_handle; +typedef Triangulation::Locate_type Locate_type; +typedef Triangulation::Point Point; + +int main() +{ + // construction from a list of points : + std::list L; + L.push_front(Point(0,0,0)); + L.push_front(Point(1,0,0)); + L.push_front(Point(0,1,0)); + + Triangulation T(L.begin(), L.end()); + + Triangulation::size_type n = T.number_of_vertices(); + + // insertion from a vector : + std::vector V(3); + V[0] = Point(0,0,1); + V[1] = Point(1,1,1); + V[2] = Point(2,2,2); + + n = n + T.insert(V.begin(), V.end()); + + assert( n == 6 ); // 6 points have been inserted + assert( T.is_valid() ); // checking validity of T + + Locate_type lt; + int li, lj; + Point p(0,0,0); + Cell_handle c = T.locate(p, lt, li, lj); + // p is the vertex of c of index li : + assert( lt == Triangulation::VERTEX ); + assert( c->vertex(li)->point() == p ); + + Vertex_handle v = c->vertex( (li+1)&3 ); + // v is another vertex of c + Cell_handle nc = c->neighbor(li); + // nc = neighbor of c opposite to the vertex associated with p + // nc must have vertex v : + int nli; + assert( nc->has_vertex( v, nli ) ); + // nli is the index of v in nc + + std::ofstream oFileT("output",std::ios::out); + // writing file output; + oFileT << T; + + Triangulation T1; + std::ifstream iFileT("output",std::ios::in); + // reading file output; + iFileT >> T1; + assert( T1.is_valid() ); + assert( T1.number_of_vertices() == T.number_of_vertices() ); + assert( T1.number_of_cells() == T.number_of_cells() ); + + return 0; +} diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/simplex.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/simplex.cpp new file mode 100644 index 00000000000..eed05980d79 --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/simplex.cpp @@ -0,0 +1,53 @@ +#include +#include + +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + +typedef CGAL::Triangulation_3 Triangulation; + +typedef Triangulation::Finite_vertices_iterator Finite_vertices_iterator; +typedef Triangulation::Finite_edges_iterator Finite_edges_iterator; +typedef Triangulation::Finite_facets_iterator Finite_facets_iterator; +typedef Triangulation::Finite_cells_iterator Finite_cells_iterator; +typedef Triangulation::Simplex Simplex; +typedef Triangulation::Locate_type Locate_type; +typedef Triangulation::Point Point; + +int main() +{ + // construction from a list of points : + std::list L; + L.push_front(Point(0,0,0)); + L.push_front(Point(1,0,0)); + L.push_front(Point(0,1,0)); + L.push_front(Point(0,1,1)); + + Triangulation T(L.begin(), L.end()); + + std::set simplices; + + Finite_vertices_iterator vit = T.finite_vertices_begin(); + simplices.insert(Simplex(vit)); + + Finite_cells_iterator cit = T.finite_cells_begin(); + simplices.insert(Simplex(cit)); + + Finite_edges_iterator eit = T.finite_edges_begin(); + simplices.insert(Simplex(*eit)); + + Finite_facets_iterator fit = T.finite_facets_begin(); + simplices.insert(Simplex(*fit)); + + + for (std::set::iterator it = simplices.begin(); + it != simplices.end(); it++) { + std::cout << it->dimension() << std::endl; + } + + return 0; +} diff --git a/Triangulation_3_copy_tds/examples/Triangulation_3/tds.cpp b/Triangulation_3_copy_tds/examples/Triangulation_3/tds.cpp new file mode 100644 index 00000000000..2f3365ebe0d --- /dev/null +++ b/Triangulation_3_copy_tds/examples/Triangulation_3/tds.cpp @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include + +typedef CGAL::Triangulation_data_structure_3<> Tds; + +typedef Tds::size_type size_type; +typedef Tds::Cell_handle Cell_handle; +typedef Tds::Vertex_handle Vertex_handle; + +int main() +{ + Tds T; + + assert( T.number_of_vertices() == 0 ); + assert( T.dimension() == -2 ); + assert( T.is_valid() ); + + std::vector PV(7); + + PV[0] = T.insert_increase_dimension(); + assert( T.number_of_vertices() == 1 ); + assert( T.dimension() == -1 ); + assert( T.is_valid() ); + + // each of the following insertions of vertices increases the dimension + for ( int i=1; i<5; i++ ) { + PV[i] = T.insert_increase_dimension(PV[0]); + assert( T.number_of_vertices() == (size_type) i+1 ); + assert( T.dimension() == i-1 ); + assert( T.is_valid() ); + } + assert( T.number_of_cells() == 5 ); + + // we now have a simplex in dimension 4 + + // cell incident to PV[0] + Cell_handle c = PV[0]->cell(); + int ind; + bool check = c->has_vertex( PV[0], ind ); + assert( check ); + // PV[0] is the vertex of index ind in c + + // insertion of a new vertex in the facet opposite to PV[0] + PV[5] = T.insert_in_facet(c, ind); + + assert( T.number_of_vertices() == 6 ); + assert( T.dimension() == 3 ); + assert( T.is_valid() ); + + // insertion of a new vertex in c + PV[6] = T.insert_in_cell(c); + + assert( T.number_of_vertices() == 7 ); + assert( T.dimension() == 3 ); + assert( T.is_valid() ); + + std::ofstream oFileT("output_tds",std::ios::out); + // writing file output_tds; + oFileT << T; + + return 0; +} diff --git a/Triangulation_3_copy_tds/include/CGAL/Delaunay_triangulation_3.h b/Triangulation_3_copy_tds/include/CGAL/Delaunay_triangulation_3.h new file mode 100644 index 00000000000..0e52632eb40 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Delaunay_triangulation_3.h @@ -0,0 +1,1585 @@ +// Copyright (c) 1999-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Monique Teillaud +// Sylvain Pion +// Andreas Fabri + +#ifndef CGAL_DELAUNAY_TRIANGULATION_3_H +#define CGAL_DELAUNAY_TRIANGULATION_3_H + +#include + +#include +#include + +#include +#include +#include + +#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO +#include + +#include +#include +#include +#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO + +#ifdef CGAL_DELAUNAY_3_OLD_REMOVE +# error "The old remove() code has been removed. Please report any issue you may have with the current one." +#endif + +namespace CGAL { + +template < class Gt, + class Tds_ = Default, + class Location_policy = Default > +class Delaunay_triangulation_3; + + +template < class Gt, class Tds_ > +class Delaunay_triangulation_3 + : public Triangulation_3 +{ + typedef Delaunay_triangulation_3 Self; + typedef Triangulation_3 Tr_Base; + +public: + + typedef typename Tr_Base::Triangulation_data_structure + Triangulation_data_structure; + typedef Gt Geom_traits; + typedef Compact_location Location_policy; + + typedef typename Gt::Point_3 Point; + typedef typename Gt::Segment_3 Segment; + typedef typename Gt::Triangle_3 Triangle; + typedef typename Gt::Tetrahedron_3 Tetrahedron; + + // types for dual: + typedef typename Gt::Line_3 Line; + typedef typename Gt::Ray_3 Ray; + //typedef typename Gt::Plane_3 Plane; + typedef typename Gt::Object_3 Object; + + typedef typename Tr_Base::Cell_handle Cell_handle; + typedef typename Tr_Base::Vertex_handle Vertex_handle; + + typedef typename Tr_Base::Cell Cell; + typedef typename Tr_Base::Vertex Vertex; + typedef typename Tr_Base::Facet Facet; + typedef typename Tr_Base::Edge Edge; + + typedef typename Tr_Base::Cell_circulator Cell_circulator; + typedef typename Tr_Base::Facet_circulator Facet_circulator; + typedef typename Tr_Base::Cell_iterator Cell_iterator; + typedef typename Tr_Base::Facet_iterator Facet_iterator; + typedef typename Tr_Base::Edge_iterator Edge_iterator; + typedef typename Tr_Base::Vertex_iterator Vertex_iterator; + + typedef typename Tr_Base::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Tr_Base::Finite_cells_iterator Finite_cells_iterator; + typedef typename Tr_Base::Finite_facets_iterator Finite_facets_iterator; + typedef typename Tr_Base::Finite_edges_iterator Finite_edges_iterator; + + typedef typename Tr_Base::All_cells_iterator All_cells_iterator; + + typedef typename Tr_Base::size_type size_type; + typedef typename Tr_Base::Locate_type Locate_type; + + +#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2 + using Tr_Base::cw; + using Tr_Base::ccw; + using Tr_Base::geom_traits; + using Tr_Base::number_of_vertices; + using Tr_Base::dimension; + using Tr_Base::finite_facets_begin; + using Tr_Base::finite_facets_end; + using Tr_Base::finite_vertices_begin; + using Tr_Base::finite_vertices_end; + using Tr_Base::finite_cells_begin; + using Tr_Base::finite_cells_end; + using Tr_Base::finite_edges_begin; + using Tr_Base::finite_edges_end; + using Tr_Base::tds; + using Tr_Base::infinite_vertex; + using Tr_Base::next_around_edge; + using Tr_Base::vertex_triple_index; + using Tr_Base::mirror_vertex; + using Tr_Base::coplanar; + using Tr_Base::coplanar_orientation; + using Tr_Base::orientation; + using Tr_Base::adjacent_vertices; + using Tr_Base::construct_segment; + using Tr_Base::incident_facets; + using Tr_Base::insert_in_conflict; + using Tr_Base::is_infinite; + using Tr_Base::is_valid_finite; + using Tr_Base::locate; + using Tr_Base::side_of_edge; + using Tr_Base::side_of_segment; + using Tr_Base::find_conflicts; +#endif + +protected: + + Oriented_side + side_of_oriented_sphere(const Point &p0, const Point &p1, const Point &p2, + const Point &p3, const Point &t, bool perturb = false) const; + + Bounded_side + coplanar_side_of_bounded_circle(const Point &p, const Point &q, + const Point &r, const Point &s, bool perturb = false) const; + + // for dual: + Point + construct_circumcenter(const Point &p, const Point &q, const Point &r) const + { + return geom_traits().construct_circumcenter_3_object()(p, q, r); + } + + Line + construct_equidistant_line(const Point &p1, const Point &p2, + const Point &p3) const + { + return geom_traits().construct_equidistant_line_3_object()(p1, p2, p3); + } + + Ray + construct_ray(const Point &p, const Line &l) const + { + return geom_traits().construct_ray_3_object()(p, l); + } + + Object + construct_object(const Point &p) const + { + return geom_traits().construct_object_3_object()(p); + } + + Object + construct_object(const Segment &s) const + { + return geom_traits().construct_object_3_object()(s); + } + + Object + construct_object(const Ray &r) const + { + return geom_traits().construct_object_3_object()(r); + } + + bool + less_distance(const Point &p, const Point &q, const Point &r) const + { + return geom_traits().compare_distance_3_object()(p, q, r) == SMALLER; + } + +public: + + Delaunay_triangulation_3(const Gt& gt = Gt()) + : Tr_Base(gt) + {} + + // copy constructor duplicates vertices and cells + Delaunay_triangulation_3(const Delaunay_triangulation_3 & tr) + : Tr_Base(tr) + { + CGAL_triangulation_postcondition( is_valid() ); + } + + template < typename InputIterator > + Delaunay_triangulation_3(InputIterator first, InputIterator last, + const Gt& gt = Gt()) + : Tr_Base(gt) + { + insert(first, last); + } + +#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, InputIterator last, + typename boost::enable_if< + boost::is_base_of< + Point, + typename std::iterator_traits::value_type + > + >::type* = NULL + ) +#else + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, InputIterator last) +#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO + { + size_type n = number_of_vertices(); + std::vector points (first, last); + spatial_sort (points.begin(), points.end(), geom_traits()); + + Vertex_handle hint; + for (typename std::vector::const_iterator p = points.begin(), end = points.end(); + p != end; ++p) + hint = insert(*p, hint); + + return number_of_vertices() - n; + } + + +#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO +private: + template + const Point& top_get_first(const std::pair& pair) const { return pair.first; } + template + const Info& top_get_second(const std::pair& pair) const { return pair.second; } + template + const Point& top_get_first(const boost::tuple& tuple) const { return boost::get<0>(tuple); } + template + const Info& top_get_second(const boost::tuple& tuple) const { return boost::get<1>(tuple); } + + template + std::ptrdiff_t insert_with_info(InputIterator first,InputIterator last) + { + size_type n = number_of_vertices(); + std::vector indices; + std::vector points; + std::vector infos; + std::size_t index=0; + for (InputIterator it=first;it!=last;++it){ + Tuple_or_pair value=*it; + points.push_back( top_get_first(value) ); + infos.push_back ( top_get_second(value) ); + indices.push_back(index++); + } + + typedef internal::Vector_property_map Point_pmap; + typedef internal::Spatial_sort_traits_with_property_map_3 Search_traits; + + spatial_sort(indices.begin(),indices.end(),Search_traits(Point_pmap(points),geom_traits())); + + Vertex_handle hint; + for (typename std::vector::const_iterator + it = indices.begin(), end = indices.end(); + it != end; ++it){ + hint = insert(points[*it], hint); + if (hint!=Vertex_handle()) hint->info()=infos[*it]; + } + + return number_of_vertices() - n; + } + +public: + + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, + InputIterator last, + typename boost::enable_if< + boost::is_same< + typename std::iterator_traits::value_type, + std::pair::type> + > >::type* =NULL + ) + { + return insert_with_info< std::pair::type> >(first,last); + } + + template + std::ptrdiff_t + insert( boost::zip_iterator< boost::tuple > first, + boost::zip_iterator< boost::tuple > last, + typename boost::enable_if< + boost::mpl::and_< + boost::is_same< typename std::iterator_traits::value_type, Point >, + boost::is_same< typename std::iterator_traits::value_type, typename internal::Info_check::type > + > + >::type* =NULL + ) + { + return insert_with_info< boost::tuple::type> >(first,last); + } +#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO + + Vertex_handle insert(const Point & p, Vertex_handle hint) + { + return insert(p, hint == Vertex_handle() ? this->infinite_cell() : hint->cell()); + } + + Vertex_handle insert(const Point & p, Cell_handle start = Cell_handle()); + + Vertex_handle insert(const Point & p, Locate_type lt, + Cell_handle c, int li, int); + +public: // internal methods + + template + Vertex_handle insert_and_give_new_cells(const Point &p, + OutputItCells fit, + Cell_handle start = Cell_handle() ); + + template + Vertex_handle insert_and_give_new_cells(const Point& p, + OutputItCells fit, + Vertex_handle hint); + + template + Vertex_handle insert_and_give_new_cells(const Point& p, + Locate_type lt, + Cell_handle c, int li, int lj, + OutputItCells fit); + +public: + +#ifndef CGAL_NO_DEPRECATED_CODE + CGAL_DEPRECATED Vertex_handle move_point(Vertex_handle v, const Point & p); +#endif + + template + Triple + find_conflicts(const Point &p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit, + OutputIteratorInternalFacets ifit) const + { + CGAL_triangulation_precondition(dimension() >= 2); + + std::vector cells; + cells.reserve(32); + std::vector facets; + facets.reserve(64); + + if (dimension() == 2) { + Conflict_tester_2 tester(p, this); + ifit = Tr_Base::find_conflicts + (c, tester, + make_triple(std::back_inserter(facets), + std::back_inserter(cells), + ifit)).third; + } + else { + Conflict_tester_3 tester(p, this); + ifit = Tr_Base::find_conflicts + (c, tester, + make_triple(std::back_inserter(facets), + std::back_inserter(cells), + ifit)).third; + } + + // Reset the conflict flag on the boundary. + for(typename std::vector::iterator fit=facets.begin(); + fit != facets.end(); ++fit) { + fit->first->neighbor(fit->second)->tds_data().clear(); + *bfit++ = *fit; + } + + // Reset the conflict flag in the conflict cells. + for(typename std::vector::iterator ccit=cells.begin(); + ccit != cells.end(); ++ccit) { + (*ccit)->tds_data().clear(); + *cit++ = *ccit; + } + return make_triple(bfit, cit, ifit); + } + + template + std::pair + find_conflicts(const Point &p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit) const + { + Triple t = find_conflicts(p, c, bfit, cit, + Emptyset_iterator()); + return std::make_pair(t.first, t.second); + } + +#ifndef CGAL_NO_DEPRECATED_CODE + // Returns the vertices on the boundary of the conflict hole. + template + OutputIterator + vertices_in_conflict(const Point&p, Cell_handle c, OutputIterator res) const + { + return vertices_on_conflict_zone_boundary(p, c, res); + } +#endif // CGAL_NO_DEPRECATED_CODE + + // Returns the vertices on the boundary of the conflict hole. + template + OutputIterator + vertices_on_conflict_zone_boundary(const Point&p, Cell_handle c, + OutputIterator res) const + { + CGAL_triangulation_precondition(dimension() >= 2); + + // Get the facets on the boundary of the hole. + std::vector facets; + find_conflicts(p, c, std::back_inserter(facets), + Emptyset_iterator(), Emptyset_iterator()); + + // Then extract uniquely the vertices. + std::set vertices; + if (dimension() == 3) { + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.insert(i->first->vertex((i->second+1)&3)); + vertices.insert(i->first->vertex((i->second+2)&3)); + vertices.insert(i->first->vertex((i->second+3)&3)); + } + } else { + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.insert(i->first->vertex(cw(i->second))); + vertices.insert(i->first->vertex(ccw(i->second))); + } + } + + return std::copy(vertices.begin(), vertices.end(), res); + } + + // REMOVE + void remove(Vertex_handle v); + + // return new cells (internal) + template + void remove_and_give_new_cells(Vertex_handle v, + OutputItCells fit); + + template < typename InputIterator > + size_type remove(InputIterator first, InputIterator beyond) + { + CGAL_triangulation_precondition(!this->does_repeat_in_range(first, beyond)); + size_type n = number_of_vertices(); + while (first != beyond) { + remove(*first); + ++first; + } + return n - number_of_vertices(); + } + + template < typename InputIterator > + size_type remove_cluster(InputIterator first, InputIterator beyond) + { + Self tmp; + Vertex_remover remover (tmp); + return Tr_Base::remove(first, beyond, remover); + } + + // MOVE + Vertex_handle move_if_no_collision(Vertex_handle v, const Point &p); + + Vertex_handle move(Vertex_handle v, const Point &p); + + // return new cells (internal) + template + Vertex_handle move_if_no_collision_and_give_new_cells(Vertex_handle v, + const Point &p, + OutputItCells fit); + +private: + + Bounded_side + side_of_sphere(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + const Point &p, bool perturb) const; +public: + + // Queries + Bounded_side + side_of_sphere(Cell_handle c, const Point & p, + bool perturb = false) const + { + return side_of_sphere(c->vertex(0), c->vertex(1), + c->vertex(2), c->vertex(3), p, perturb); + } + + Bounded_side + side_of_circle( const Facet & f, const Point & p, bool perturb = false) const + { + return side_of_circle(f.first, f.second, p, perturb); + } + + Bounded_side + side_of_circle( Cell_handle c, int i, const Point & p, + bool perturb = false) const; + + Vertex_handle + nearest_vertex_in_cell(const Point& p, Cell_handle c) const; + + Vertex_handle + nearest_vertex(const Point& p, Cell_handle c = Cell_handle()) const; + + bool is_Gabriel(Cell_handle c, int i) const; + bool is_Gabriel(Cell_handle c, int i, int j) const; + bool is_Gabriel(const Facet& f)const ; + bool is_Gabriel(const Edge& e) const; + + bool is_delaunay_after_displacement(Vertex_handle v, + const Point &p) const; + +// Dual functions + Point dual(Cell_handle c) const; + + Object dual(const Facet & f) const + { return dual( f.first, f.second ); } + + Object dual(Cell_handle c, int i) const; + + Line dual_support(Cell_handle c, int i) const; + + bool is_valid(bool verbose = false, int level = 0) const; + + bool is_valid(Cell_handle c, bool verbose = false, int level = 0) const; + + template < class Stream> + Stream& draw_dual(Stream & os) + { + for (Finite_facets_iterator fit = finite_facets_begin(), + end = finite_facets_end(); + fit != end; ++fit) { + Object o = dual(*fit); + if (const Segment *s = object_cast(&o)) os << *s; + else if (const Ray *r = object_cast(&o)) os << *r; + else if (const Point *p = object_cast(&o)) os << *p; + } + return os; + } + +protected: + + Vertex_handle + nearest_vertex(const Point &p, Vertex_handle v, Vertex_handle w) const + { + // In case of equality, v is returned. + CGAL_triangulation_precondition(v != w); + + if (is_infinite(v)) + return w; + if (is_infinite(w)) + return v; + return less_distance(p, w->point(), v->point()) ? w : v; + } + + class Conflict_tester_3 + { + const Point &p; + const Self *t; + + public: + + Conflict_tester_3(const Point &pt, const Self *tr) + : p(pt), t(tr) {} + + bool operator()(const Cell_handle c) const + { + return t->side_of_sphere(c, p, true) == ON_BOUNDED_SIDE; + } + Oriented_side compare_weight(const Point &, const Point &) const + { + return ZERO; + } + bool test_initial_cell(Cell_handle) const + { + return true; + } + }; + + class Conflict_tester_2 + { + const Point &p; + const Self *t; + + public: + + Conflict_tester_2(const Point &pt, const Self *tr) + : p(pt), t(tr) {} + + bool operator()(const Cell_handle c) const + { + return t->side_of_circle(c, 3, p, true) == ON_BOUNDED_SIDE; + } + Oriented_side compare_weight(const Point &, const Point &) const + { + return ZERO; + } + bool test_initial_cell(Cell_handle) const + { + return true; + } + }; + class Hidden_point_visitor + { + public: + + Hidden_point_visitor() {} + + template + void process_cells_in_conflict(InputIterator, InputIterator) const {} + void reinsert_vertices(Vertex_handle ) {} + Vertex_handle replace_vertex(Cell_handle c, int index, + const Point &) { + return c->vertex(index); + } + void hide_point(Cell_handle, const Point &) {} + }; + + class Perturbation_order { + const Self *t; + + public: + Perturbation_order(const Self *tr) + : t(tr) {} + + bool operator()(const Point *p, const Point *q) const { + return t->compare_xyz(*p, *q) == SMALLER; + } + }; + + template < class DelaunayTriangulation_3 > + class Vertex_remover; + + template < class DelaunayTriangulation_3 > + class Vertex_inserter; + + friend class Perturbation_order; + friend class Conflict_tester_3; + friend class Conflict_tester_2; + + Hidden_point_visitor hidden_point_visitor; +}; + +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +insert(const Point & p, Cell_handle start) +{ + Locate_type lt; + int li, lj; + Cell_handle c = locate(p, lt, li, lj, start); + return insert(p, lt, c, li, lj); +} + +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +insert(const Point & p, Locate_type lt, Cell_handle c, int li, int lj) +{ + switch (dimension()) { + case 3: + { + Conflict_tester_3 tester(p, this); + Vertex_handle v = insert_in_conflict(p, lt, c, li, lj, + tester, hidden_point_visitor); + return v; + }// dim 3 + case 2: + { + Conflict_tester_2 tester(p, this); + return insert_in_conflict(p, lt, c, li, lj, + tester, hidden_point_visitor); + }//dim 2 + default : + // dimension <= 1 + // Do not use the generic insert. + return Tr_Base::insert(p, c); + } +} + +template < class Gt, class Tds > +template +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +insert_and_give_new_cells(const Point &p, + OutputItCells fit, + Cell_handle start) +{ + Vertex_handle v = insert(p, start); + int dimension = this->dimension(); + if(dimension == 3) this->incident_cells(v, fit); + else if(dimension == 2) + { + Cell_handle c = v->cell(), end = c; + do { + *fit++ = c; + int i = c->index(v); + c = c->neighbor((i+1)%3); + } while(c != end); + } + else if(dimension == 1) + { + Cell_handle c = v->cell(); + *fit++ = c; + *fit++ = c->neighbor((~(c->index(v)))&1); + } + else *fit++ = v->cell(); // dimension = 0 + return v; +} + +template < class Gt, class Tds > +template +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +insert_and_give_new_cells(const Point& p, + OutputItCells fit, + Vertex_handle hint) +{ + Vertex_handle v = insert(p, hint); + int dimension = this->dimension(); + if(dimension == 3) this->incident_cells(v, fit); + else if(dimension == 2) + { + Cell_handle c = v->cell(), end = c; + do { + *fit++ = c; + int i = c->index(v); + c = c->neighbor((i+1)%3); + } while(c != end); + } + else if(dimension == 1) + { + Cell_handle c = v->cell(); + *fit++ = c; + *fit++ = c->neighbor((~(c->index(v)))&1); + } + else *fit++ = v->cell(); // dimension = 0 + return v; +} + +template < class Gt, class Tds > +template +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +insert_and_give_new_cells(const Point& p, + Locate_type lt, + Cell_handle c, int li, int lj, + OutputItCells fit) +{ + Vertex_handle v = insert(p, lt, c, li, lj); + int dimension = this->dimension(); + if(dimension == 3) this->incident_cells(v, fit); + else if(dimension == 2) + { + Cell_handle c = v->cell(), end = c; + do { + *fit++ = c; + int i = c->index(v); + c = c->neighbor((i+1)%3); + } while(c != end); + } + else if(dimension == 1) + { + Cell_handle c = v->cell(); + *fit++ = c; + *fit++ = c->neighbor((~(c->index(v)))&1); + } + else *fit++ = v->cell(); // dimension = 0 + return v; +} + +#ifndef CGAL_NO_DEPRECATED_CODE +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +move_point(Vertex_handle v, const Point & p) +{ + CGAL_triangulation_precondition(! is_infinite(v)); + CGAL_triangulation_expensive_precondition(is_vertex(v)); + + // Dummy implementation for a start. + + // Remember an incident vertex to restart + // the point location after the removal. + Cell_handle c = v->cell(); + Vertex_handle old_neighbor = c->vertex(c->index(v) == 0 ? 1 : 0); + CGAL_triangulation_assertion(old_neighbor != v); + + remove(v); + + if (dimension() <= 0) + return insert(p); + return insert(p, old_neighbor->cell()); +} +#endif + +template +template +class Delaunay_triangulation_3::Vertex_remover { + typedef DelaunayTriangulation_3 Delaunay; +public: + typedef Nullptr_t Hidden_points_iterator; + + Vertex_remover(Delaunay &tmp_) : tmp(tmp_) {} + + Delaunay &tmp; + + void add_hidden_points(Cell_handle) {} + Hidden_points_iterator hidden_points_begin() { return NULL; } + Hidden_points_iterator hidden_points_end() { return NULL; } + + Bounded_side side_of_bounded_circle(const Point &p, const Point &q, + const Point &r, const Point &s, bool perturb = false) const { + return tmp.coplanar_side_of_bounded_circle(p,q,r,s,perturb); + } +}; + +template +template +class Delaunay_triangulation_3::Vertex_inserter { + typedef DelaunayTriangulation_3 Delaunay; +public: + typedef Nullptr_t Hidden_points_iterator; + + Vertex_inserter(Delaunay &tmp_) : tmp(tmp_) {} + + Delaunay &tmp; + + void add_hidden_points(Cell_handle) {} + Hidden_points_iterator hidden_points_begin() { return NULL; } + Hidden_points_iterator hidden_points_end() { return NULL; } + + Vertex_handle insert(const Point& p, + Locate_type lt, Cell_handle c, int li, int lj) { + return tmp.insert(p, lt, c, li, lj); + } + + Vertex_handle insert(const Point& p, Cell_handle c) { + return tmp.insert(p, c); + } + + Vertex_handle insert(const Point& p) { + return tmp.insert(p); + } +}; + +template < class Gt, class Tds > +void +Delaunay_triangulation_3:: +remove(Vertex_handle v) +{ + Self tmp; + Vertex_remover remover (tmp); + Tr_Base::remove(v,remover); + + CGAL_triangulation_expensive_postcondition(is_valid()); +} + +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +move_if_no_collision(Vertex_handle v, const Point &p) +{ + Self tmp; + Vertex_remover remover (tmp); + Vertex_inserter inserter (*this); + Vertex_handle res = Tr_Base::move_if_no_collision(v,p,remover,inserter); + + CGAL_triangulation_expensive_postcondition(is_valid()); + return res; +} + +template +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +move(Vertex_handle v, const Point &p) { + CGAL_triangulation_precondition(!is_infinite(v)); + if(v->point() == p) return v; + Self tmp; + Vertex_remover remover (tmp); + Vertex_inserter inserter (*this); + return Tr_Base::move(v,p,remover,inserter); +} + +template < class Gt, class Tds > +template +void +Delaunay_triangulation_3:: +remove_and_give_new_cells(Vertex_handle v, OutputItCells fit) +{ + Self tmp; + Vertex_remover remover (tmp); + Tr_Base::remove_and_give_new_cells(v,remover,fit); + + CGAL_triangulation_expensive_postcondition(is_valid()); +} + +template < class Gt, class Tds > +template +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point &p, + OutputItCells fit) +{ + Self tmp; + Vertex_remover remover (tmp); + Vertex_inserter inserter (*this); + Vertex_handle res = + Tr_Base::move_if_no_collision_and_give_new_cells(v,p, + remover,inserter,fit); + + CGAL_triangulation_expensive_postcondition(is_valid()); + return res; +} + +template < class Gt, class Tds > +Oriented_side +Delaunay_triangulation_3:: +side_of_oriented_sphere(const Point &p0, const Point &p1, const Point &p2, + const Point &p3, const Point &p, bool perturb) const +{ + CGAL_triangulation_precondition( orientation(p0, p1, p2, p3) == POSITIVE ); + + Oriented_side os = + geom_traits().side_of_oriented_sphere_3_object()(p0, p1, p2, p3, p); + + if (os != ON_ORIENTED_BOUNDARY || !perturb) + return os; + + // We are now in a degenerate case => we do a symbolic perturbation. + + // We sort the points lexicographically. + const Point * points[5] = {&p0, &p1, &p2, &p3, &p}; + std::sort(points, points+5, Perturbation_order(this) ); + + // We successively look whether the leading monomial, then 2nd monomial + // of the determinant has non null coefficient. + // 2 iterations are enough (cf paper) + for (int i=4; i>2; --i) { + if (points[i] == &p) + return ON_NEGATIVE_SIDE; // since p0 p1 p2 p3 are non coplanar + // and positively oriented + Orientation o; + if (points[i] == &p3 && (o = orientation(p0,p1,p2,p)) != COPLANAR ) + return o; + if (points[i] == &p2 && (o = orientation(p0,p1,p,p3)) != COPLANAR ) + return o; + if (points[i] == &p1 && (o = orientation(p0,p,p2,p3)) != COPLANAR ) + return o; + if (points[i] == &p0 && (o = orientation(p,p1,p2,p3)) != COPLANAR ) + return o; + } + + CGAL_triangulation_assertion(false); + return ON_NEGATIVE_SIDE; +} + +template < class Gt, class Tds > +Bounded_side +Delaunay_triangulation_3:: +coplanar_side_of_bounded_circle(const Point &p0, const Point &p1, + const Point &p2, const Point &p, bool perturb) const +{ + // In dim==2, we should even be able to assert orient == POSITIVE. + CGAL_triangulation_precondition( coplanar_orientation(p0, p1, p2) + != COLLINEAR ); + + Bounded_side bs = + geom_traits().coplanar_side_of_bounded_circle_3_object()(p0, p1, p2, p); + + if (bs != ON_BOUNDARY || !perturb) + return bs; + + // We are now in a degenerate case => we do a symbolic perturbation. + + // We sort the points lexicographically. + const Point * points[4] = {&p0, &p1, &p2, &p}; + std::sort(points, points+4, Perturbation_order(this) ); + + Orientation local = coplanar_orientation(p0, p1, p2); + + // we successively look whether the leading monomial, then 2nd monimial, + // then 3rd monomial, of the determinant which has non null coefficient + // [syl] : TODO : Probably it can be stopped earlier like the 3D version + for (int i=3; i>0; --i) { + if (points[i] == &p) + return Bounded_side(NEGATIVE); // since p0 p1 p2 are non collinear + // but not necessarily positively oriented + Orientation o; + if (points[i] == &p2 + && (o = coplanar_orientation(p0,p1,p)) != COLLINEAR ) + // [syl] : TODO : I'm not sure of the signs here (nor the rest :) + return Bounded_side(o*local); + if (points[i] == &p1 + && (o = coplanar_orientation(p0,p,p2)) != COLLINEAR ) + return Bounded_side(o*local); + if (points[i] == &p0 + && (o = coplanar_orientation(p,p1,p2)) != COLLINEAR ) + return Bounded_side(o*local); + } + + // case when the first non null coefficient is the coefficient of + // the 4th monomial + // moreover, the tests (points[] == &p) were false up to here, so the + // monomial corresponding to p is the only monomial with non-zero + // coefficient, it is equal to coplanar_orient(p0,p1,p2) == positive + // so, no further test is required + return Bounded_side(-local); //ON_UNBOUNDED_SIDE; +} + +template < class Gt, class Tds > +Bounded_side +Delaunay_triangulation_3:: +side_of_sphere(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + const Point &p, bool perturb) const +{ + CGAL_triangulation_precondition( dimension() == 3 ); + + if (is_infinite(v0)) { + Orientation o = orientation(v2->point(), v1->point(), v3->point(), p); + if (o != COPLANAR) + return Bounded_side(o); + return coplanar_side_of_bounded_circle(v2->point(), v1->point(), v3->point(), p, perturb); + } + + if (is_infinite(v1)) { + Orientation o = orientation(v2->point(), v3->point(), v0->point(), p); + if (o != COPLANAR) + return Bounded_side(o); + return coplanar_side_of_bounded_circle(v2->point(), v3->point(), v0->point(), p, perturb); + } + + if (is_infinite(v2)) { + Orientation o = orientation(v1->point(), v0->point(), v3->point(), p); + if (o != COPLANAR) + return Bounded_side(o); + return coplanar_side_of_bounded_circle(v1->point(), v0->point(), v3->point(), p, perturb); + } + + if (is_infinite(v3)) { + Orientation o = orientation(v0->point(), v1->point(), v2->point(), p); + if (o != COPLANAR) + return Bounded_side(o); + return coplanar_side_of_bounded_circle(v0->point(), v1->point(), v2->point(), p, perturb); + } + + return (Bounded_side) side_of_oriented_sphere(v0->point(), v1->point(), v2->point(), v3->point(), p, perturb); +} + +template < class Gt, class Tds > +Bounded_side +Delaunay_triangulation_3:: +side_of_circle(Cell_handle c, int i, + const Point & p, bool perturb) const + // precondition : dimension >=2 + // in dimension 3, - for a finite facet + // returns ON_BOUNDARY if the point lies on the circle, + // ON_UNBOUNDED_SIDE when exterior, ON_BOUNDED_SIDE + // interior + // for an infinite facet, considers the plane defined by the + // adjacent finite facet of the same cell, and does the same as in + // dimension 2 in this plane + // in dimension 2, for an infinite facet + // in this case, returns ON_BOUNDARY if the point lies on the + // finite edge (endpoints included) + // ON_BOUNDED_SIDE for a point in the open half-plane + // ON_UNBOUNDED_SIDE elsewhere +{ + CGAL_triangulation_precondition( dimension() >= 2 ); + int i3 = 5; + + if ( dimension() == 2 ) { + CGAL_triangulation_precondition( i == 3 ); + // the triangulation is supposed to be valid, ie the facet + // with vertices 0 1 2 in this order is positively oriented + if ( ! c->has_vertex( infinite_vertex(), i3 ) ) + return coplanar_side_of_bounded_circle( c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + p, perturb); + // else infinite facet + // v1, v2 finite vertices of the facet such that v1,v2,infinite + // is positively oriented + Vertex_handle v1 = c->vertex( ccw(i3) ), + v2 = c->vertex( cw(i3) ); + CGAL_triangulation_assertion(coplanar_orientation(v1->point(), v2->point(), + mirror_vertex(c, i3)->point()) == NEGATIVE); + Orientation o = coplanar_orientation(v1->point(), v2->point(), p); + if ( o != COLLINEAR ) + return Bounded_side( o ); + // because p is in f iff + // it does not lie on the same side of v1v2 as vn + int i_e; + Locate_type lt; + // case when p collinear with v1v2 + return side_of_segment( p, + v1->point(), v2->point(), + lt, i_e ); + } + + // else dimension == 3 + CGAL_triangulation_precondition( i >= 0 && i < 4 ); + if ( ( ! c->has_vertex(infinite_vertex(),i3) ) || ( i3 != i ) ) { + // finite facet + // initialization of i0 i1 i2, vertices of the facet positively + // oriented (if the triangulation is valid) + int i0 = (i>0) ? 0 : 1; + int i1 = (i>1) ? 1 : 2; + int i2 = (i>2) ? 2 : 3; + CGAL_triangulation_precondition( coplanar( c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), + p ) ); + return coplanar_side_of_bounded_circle( c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), + p, perturb); + } + + //else infinite facet + // v1, v2 finite vertices of the facet such that v1,v2,infinite + // is positively oriented + Vertex_handle v1 = c->vertex( next_around_edge(i3,i) ), + v2 = c->vertex( next_around_edge(i,i3) ); + Orientation o = (Orientation) + (coplanar_orientation( v1->point(), v2->point(), + c->vertex(i)->point()) * + coplanar_orientation( v1->point(), v2->point(), p )); + // then the code is duplicated from 2d case + if ( o != COLLINEAR ) + return Bounded_side( -o ); + // because p is in f iff + // it is not on the same side of v1v2 as c->vertex(i) + int i_e; + Locate_type lt; + // case when p collinear with v1v2 + return side_of_segment( p, + v1->point(), v2->point(), + lt, i_e ); +} + +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +nearest_vertex_in_cell(const Point& p, Cell_handle c) const +// Returns the finite vertex of the cell c which is the closest to p. +{ + CGAL_triangulation_precondition(dimension() >= 0); + + Vertex_handle nearest = nearest_vertex(p, c->vertex(0), c->vertex(1)); + if (dimension() >= 2) { + nearest = nearest_vertex(p, nearest, c->vertex(2)); + if (dimension() == 3) + nearest = nearest_vertex(p, nearest, c->vertex(3)); + } + return nearest; +} + +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Vertex_handle +Delaunay_triangulation_3:: +nearest_vertex(const Point& p, Cell_handle start) const +{ + if (number_of_vertices() == 0) + return Vertex_handle(); + + // Use a brute-force algorithm if dimension < 3. + if (dimension() < 3) { + Finite_vertices_iterator vit = finite_vertices_begin(); + Vertex_handle res = vit; + ++vit; + for (Finite_vertices_iterator end = finite_vertices_end(); vit != end; ++vit) + res = nearest_vertex(p, res, vit); + return res; + } + + Locate_type lt; + int li, lj; + Cell_handle c = locate(p, lt, li, lj, start); + if (lt == Tr_Base::VERTEX) + return c->vertex(li); + + // - start with the closest vertex from the located cell. + // - repeatedly take the nearest of its incident vertices if any + // - if not, we're done. + Vertex_handle nearest = nearest_vertex_in_cell(p, c); + std::vector vs; + vs.reserve(32); + while (true) { + Vertex_handle tmp = nearest; + adjacent_vertices(nearest, std::back_inserter(vs)); + for (typename std::vector::const_iterator + vsit = vs.begin(); vsit != vs.end(); ++vsit) + tmp = nearest_vertex(p, tmp, *vsit); + if (tmp == nearest) + break; + vs.clear(); + nearest = tmp; + } + + return nearest; +} + +// This is not a fast version. +// The optimized version needs an int for book-keeping in +// tds() so as to avoiding the need to clear +// the tds marker in each cell (which is an unsigned char) +// Also the visitor in TDS could be more clever. +// The Delaunay triangulation which filters displacements +// will do these optimizations. +template +bool +Delaunay_triangulation_3:: +is_delaunay_after_displacement(Vertex_handle v, const Point &p) const +{ + CGAL_triangulation_precondition(!this->is_infinite(v)); + CGAL_triangulation_precondition(this->dimension() == 2); + CGAL_triangulation_precondition(!this->test_dim_down(v)); + if(v->point() == p) return true; + Point ant = v->point(); + v->set_point(p); + + std::size_t size; + + // are incident cells well-oriented + std::vector cells; + cells.reserve(64); + this->incident_cells(v, std::back_inserter(cells)); + size = cells.size(); + for(std::size_t i=0; iis_infinite(c)) continue; + if(this->orientation(c->vertex(0)->point(), c->vertex(1)->point(), + c->vertex(2)->point(), c->vertex(3)->point()) + != POSITIVE) + { + v->set_point(ant); + return false; + } + } + + // are incident bi-cells Delaunay? + std::vector facets; + facets.reserve(128); + this->incident_facets(v, std::back_inserter(facets)); + size = facets.size(); + for(std::size_t i=0; ineighbor(j); + int mj = this->mirror_index(c, j); + Vertex_handle h1 = c->vertex(j); + if(this->is_infinite(h1)) { + if(this->side_of_sphere(c, cj->vertex(mj)->point(), true) + != ON_UNBOUNDED_SIDE) { + v->set_point(ant); + return false; + } + } else { + if(this->side_of_sphere(cj, h1->point(), true) != ON_UNBOUNDED_SIDE) { + v->set_point(ant); + return false; + } + } + } + + v->set_point(ant); + return true; +} + +template < class Gt, class Tds > +bool +Delaunay_triangulation_3:: +is_Gabriel(const Facet& f) const +{ + return is_Gabriel(f.first, f.second); +} + +template < class Gt, class Tds > +bool +Delaunay_triangulation_3:: +is_Gabriel(Cell_handle c, int i) const +{ + CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i)); + typename Geom_traits::Side_of_bounded_sphere_3 + side_of_bounded_sphere = + geom_traits().side_of_bounded_sphere_3_object(); + + if ((!is_infinite(c->vertex(i))) && + side_of_bounded_sphere ( + c->vertex(vertex_triple_index(i,0))->point(), + c->vertex(vertex_triple_index(i,1))->point(), + c->vertex(vertex_triple_index(i,2))->point(), + c->vertex(i)->point()) == ON_BOUNDED_SIDE ) return false; + Cell_handle neighbor = c->neighbor(i); + int in = neighbor->index(c); + + if ((!is_infinite(neighbor->vertex(in))) && + side_of_bounded_sphere( + c->vertex(vertex_triple_index(i,0))->point(), + c->vertex(vertex_triple_index(i,1))->point(), + c->vertex(vertex_triple_index(i,2))->point(), + neighbor->vertex(in)->point()) == ON_BOUNDED_SIDE ) return false; + + return true; +} + +template < class Gt, class Tds > +bool +Delaunay_triangulation_3:: +is_Gabriel(const Edge& e) const +{ + return is_Gabriel(e.first, e.second, e.third); +} + +template < class Gt, class Tds > +bool +Delaunay_triangulation_3:: +is_Gabriel(Cell_handle c, int i, int j) const +{ + CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i,j)); + typename Geom_traits::Side_of_bounded_sphere_3 + side_of_bounded_sphere = + geom_traits().side_of_bounded_sphere_3_object(); + + Facet_circulator fcirc = incident_facets(c,i,j), + fdone(fcirc); + Vertex_handle v1 = c->vertex(i); + Vertex_handle v2 = c->vertex(j); + do { + // test whether the vertex of cc opposite to *fcirc + // is inside the sphere defined by the edge e = (s, i,j) + Cell_handle cc = (*fcirc).first; + int ii = (*fcirc).second; + if (!is_infinite(cc->vertex(ii)) && + side_of_bounded_sphere( v1->point(), + v2->point(), + cc->vertex(ii)->point()) + == ON_BOUNDED_SIDE ) return false; + } while(++fcirc != fdone); + return true; +} + +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Point +Delaunay_triangulation_3:: +dual(Cell_handle c) const +{ + CGAL_triangulation_precondition(dimension()==3); + CGAL_triangulation_precondition( ! is_infinite(c) ); + return c->circumcenter(geom_traits()); +} + + +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Object +Delaunay_triangulation_3:: +dual(Cell_handle c, int i) const +{ + CGAL_triangulation_precondition(dimension()>=2); + CGAL_triangulation_precondition( ! is_infinite(c,i) ); + + if ( dimension() == 2 ) { + CGAL_triangulation_precondition( i == 3 ); + return construct_object( construct_circumcenter(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point()) ); + } + + // dimension() == 3 + Cell_handle n = c->neighbor(i); + if ( ! is_infinite(c) && ! is_infinite(n) ) + return construct_object(construct_segment( dual(c), dual(n) )); + + // either n or c is infinite + int in; + if ( is_infinite(c) ) + in = n->index(c); + else { + n = c; + in = i; + } + // n now denotes a finite cell, either c or c->neighbor(i) + int ind[3] = {(in+1)&3,(in+2)&3,(in+3)&3}; + if ( (in&1) == 1 ) + std::swap(ind[0], ind[1]); + // in=0: 1 2 3 + // in=1: 3 2 0 + // in=2: 3 0 1 + // in=3: 1 0 2 + const Point& p = n->vertex(ind[0])->point(); + const Point& q = n->vertex(ind[1])->point(); + const Point& r = n->vertex(ind[2])->point(); + + Line l = construct_equidistant_line( p, q, r ); + return construct_object(construct_ray( dual(n), l)); +} + + + +template < class Gt, class Tds > +typename Delaunay_triangulation_3::Line +Delaunay_triangulation_3:: +dual_support(Cell_handle c, int i) const +{ + CGAL_triangulation_precondition(dimension()>=2); + CGAL_triangulation_precondition( ! is_infinite(c,i) ); + + if ( dimension() == 2 ) { + CGAL_triangulation_precondition( i == 3 ); + return construct_equidistant_line( c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point() ); + } + + return construct_equidistant_line( c->vertex((i+1)&3)->point(), + c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point() ); +} + + +template < class Gt, class Tds > +bool +Delaunay_triangulation_3:: +is_valid(bool verbose, int level) const +{ + if ( ! tds().is_valid(verbose,level) ) { + if (verbose) + std::cerr << "invalid data structure" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + if ( infinite_vertex() == Vertex_handle() ) { + if (verbose) + std::cerr << "no infinite vertex" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + switch ( dimension() ) { + case 3: + { + for(Finite_cells_iterator it = finite_cells_begin(), end = finite_cells_end(); it != end; ++it) { + is_valid_finite(it); + for(int i=0; i<4; i++ ) { + if ( !is_infinite + (it->neighbor(i)->vertex(it->neighbor(i)->index(it))) ) { + if ( side_of_sphere + (it, + it->neighbor(i)->vertex(it->neighbor(i)->index(it))->point()) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty sphere " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } + break; + } + case 2: + { + for(Finite_facets_iterator it = finite_facets_begin(), end = finite_facets_end(); it != end; ++it) { + is_valid_finite((*it).first); + for(int i=0; i<3; i++ ) { + if( !is_infinite + ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) + ->index((*it).first))) ) { + if ( side_of_circle ( (*it).first, 3, + (*it).first->neighbor(i)-> + vertex( (((*it).first)->neighbor(i)) + ->index((*it).first) )->point() ) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty circle " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } + break; + } + case 1: + { + for(Finite_edges_iterator it = finite_edges_begin(), end = finite_edges_end(); it != end; ++it) + is_valid_finite((*it).first); + break; + } + } + if (verbose) + std::cerr << "Delaunay valid triangulation" << std::endl; + return true; +} + +template < class Gt, class Tds > +bool +Delaunay_triangulation_3:: +is_valid(Cell_handle c, bool verbose, int level) const +{ + if ( ! Tr_Base::is_valid(c,verbose,level) ) { + if (verbose) { + std::cerr << "combinatorically invalid cell" ; + for (int i=0; i <= dimension(); i++ ) + std::cerr << c->vertex(i)->point() << ", " ; + std::cerr << std::endl; + } + CGAL_triangulation_assertion(false); + return false; + } + switch ( dimension() ) { + case 3: + { + if ( ! is_infinite(c) ) { + is_valid_finite(c,verbose,level); + for (int i=0; i<4; i++ ) { + if (side_of_sphere(c, c->vertex((c->neighbor(i))->index(c))->point()) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty sphere " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + break; + } + case 2: + { + if ( ! is_infinite(c,3) ) { + for (int i=0; i<2; i++ ) { + if (side_of_circle(c, 3, c->vertex(c->neighbor(i)->index(c))->point()) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty circle " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + break; + } + } + if (verbose) + std::cerr << "Delaunay valid cell" << std::endl; + return true; +} + +} //namespace CGAL + +#include + +#endif // CGAL_DELAUNAY_TRIANGULATION_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/IO/Triangulation_geomview_ostream_3.h b/Triangulation_3_copy_tds/include/CGAL/IO/Triangulation_geomview_ostream_3.h new file mode 100644 index 00000000000..4b4eb25f484 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/IO/Triangulation_geomview_ostream_3.h @@ -0,0 +1,97 @@ +// Copyright (c) 2000 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_IO_TRIANGULATION_GEOMVIEW_OSTREAM_3_H +#define CGAL_IO_TRIANGULATION_GEOMVIEW_OSTREAM_3_H + +#include +#include + +// TODO : +// - Check the correctness when dimension < 3. +// - Use the stream color instead of built-in constant/random. +// - If interfaces were more similar, we could think of sharing 2d and 3d ? + +namespace CGAL { + +// This one is to show the edges of a 3D triangulation. +template < class GT, class TDS > +void +show_triangulation_edges(Geomview_stream &gv, const Triangulation_3 &T) +{ + // Header. + gv.set_ascii_mode(); + gv << "(geometry " << gv.get_new_id("triangulationedge") + << " {appearance {}{ SKEL \n" + << T.number_of_vertices() << T.number_of_finite_edges() << "\n"; + + // Finite vertices coordinates. + std::map::Vertex_handle, int> V; + int inum = 0; + for( typename Triangulation_3::Finite_vertices_iterator + vit = T.finite_vertices_begin(); vit != T.finite_vertices_end(); ++vit) { + V[vit] = inum++; + gv << vit->point() << "\n"; + } + + // Finite edges indices. + for( typename Triangulation_3::Finite_edges_iterator + eit = T.finite_edges_begin(); eit != T.finite_edges_end(); ++eit) { + gv << 2 + << V[(*eit).first->vertex((*eit).second)] + << V[(*eit).first->vertex((*eit).third)] + << "\n"; // without color. + // << 4 << drand48() << drand48() << drand48() << 1.0; // random color. + } +} + +template < class GT, class TDS > +Geomview_stream& +operator<<( Geomview_stream &gv, const Triangulation_3 &T) +{ + if (gv.get_wired()) { + // We draw the edges. + bool ascii_bak = gv.get_ascii_mode(); + bool raw_bak = gv.set_raw(true); + + show_triangulation_edges(gv, T); + + // Footer. + gv << "}})"; + + gv.set_raw(raw_bak); + gv.set_ascii_mode(ascii_bak); + } + else { + // We draw the facets. + std::vector triangles; + + for (typename Triangulation_3::Finite_facets_iterator + fit = T.finite_facets_begin(); fit != T.finite_facets_end(); + ++fit) + triangles.push_back(T.triangle(*fit)); + + gv.draw_triangles(triangles.begin(), triangles.end()); + } + return gv; +} + +} //namespace CGAL + +#endif // CGAL_IO_TRIANGULATION_GEOMVIEW_OSTREAM_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_3.h b/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_3.h new file mode 100644 index 00000000000..f63120f6cae --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_3.h @@ -0,0 +1,1693 @@ +// Copyright (c) 1999-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Monique Teillaud +// Sylvain Pion +// Christophe Delage + +#ifndef CGAL_REGULAR_TRIANGULATION_3_H +#define CGAL_REGULAR_TRIANGULATION_3_H + +#include + +#include + +#include +#include +#include + +#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO +#include + +#include +#include +#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4355) // complaint about using 'this' to +#endif // initialize a member + +namespace CGAL { + +template < class Gt, class Tds_ = Default > +class Regular_triangulation_3 + : public Triangulation_3, + Regular_triangulation_cell_base_3 > >::type> +{ + typedef Regular_triangulation_3 Self; + + typedef typename Default::Get, + Regular_triangulation_cell_base_3 > >::type Tds; + + typedef Triangulation_3 Tr_Base; + +public: + + typedef Tds Triangulation_data_structure; + typedef Gt Geom_traits; + + typedef typename Tr_Base::Vertex_handle Vertex_handle; + typedef typename Tr_Base::Cell_handle Cell_handle; + typedef typename Tr_Base::Vertex Vertex; + typedef typename Tr_Base::Cell Cell; + typedef typename Tr_Base::Facet Facet; + typedef typename Tr_Base::Edge Edge; + + typedef typename Tr_Base::size_type size_type; + typedef typename Tr_Base::Locate_type Locate_type; + typedef typename Tr_Base::Cell_iterator Cell_iterator; + typedef typename Tr_Base::Facet_iterator Facet_iterator; + typedef typename Tr_Base::Edge_iterator Edge_iterator; + typedef typename Tr_Base::Facet_circulator Facet_circulator; + + typedef typename Tr_Base::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Tr_Base::Finite_cells_iterator Finite_cells_iterator; + typedef typename Tr_Base::Finite_facets_iterator Finite_facets_iterator; + typedef typename Tr_Base::Finite_edges_iterator Finite_edges_iterator; + typedef typename Tr_Base::All_cells_iterator All_cells_iterator; + + typedef typename Gt::Weighted_point_3 Weighted_point; + typedef typename Gt::Bare_point Bare_point; + typedef typename Gt::Segment_3 Segment; + typedef typename Gt::Triangle_3 Triangle; + typedef typename Gt::Tetrahedron_3 Tetrahedron; + + // types for dual: + typedef typename Gt::Line_3 Line; + typedef typename Gt::Ray_3 Ray; + typedef typename Gt::Plane_3 Plane; + typedef typename Gt::Object_3 Object; + + //Tag to distinguish Delaunay from Regular triangulations + typedef Tag_true Weighted_tag; + + using Tr_Base::cw; + using Tr_Base::ccw; +#ifndef CGAL_CFG_USING_BASE_MEMBER_BUG_2 + using Tr_Base::geom_traits; +#endif + using Tr_Base::number_of_vertices; + using Tr_Base::dimension; + using Tr_Base::finite_facets_begin; + using Tr_Base::finite_facets_end; + using Tr_Base::finite_vertices_begin; + using Tr_Base::finite_vertices_end; + using Tr_Base::finite_cells_begin; + using Tr_Base::finite_cells_end; + using Tr_Base::finite_edges_begin; + using Tr_Base::finite_edges_end; + using Tr_Base::tds; + using Tr_Base::infinite_vertex; + using Tr_Base::next_around_edge; + using Tr_Base::vertex_triple_index; + using Tr_Base::mirror_vertex; + using Tr_Base::mirror_index; + using Tr_Base::orientation; + using Tr_Base::coplanar_orientation; + using Tr_Base::adjacent_vertices; + using Tr_Base::construct_segment; + using Tr_Base::incident_facets; + using Tr_Base::insert_in_conflict; + using Tr_Base::is_infinite; + using Tr_Base::is_valid_finite; + using Tr_Base::locate; + using Tr_Base::side_of_segment; + using Tr_Base::side_of_edge; + using Tr_Base::find_conflicts; + using Tr_Base::is_valid; + + Regular_triangulation_3(const Gt & gt = Gt()) + : Tr_Base(gt), hidden_point_visitor(this) + {} + + Regular_triangulation_3(const Regular_triangulation_3 & rt) + : Tr_Base(rt), hidden_point_visitor(this) + { + CGAL_triangulation_postcondition( is_valid() ); + } + + //insertion + template < typename InputIterator > + Regular_triangulation_3(InputIterator first, InputIterator last, + const Gt & gt = Gt()) + : Tr_Base(gt), hidden_point_visitor(this) + { + insert(first, last); + } + +#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, InputIterator last, + typename boost::enable_if< + boost::mpl::or_< + boost::is_same< + typename std::iterator_traits::value_type, + Weighted_point + >, + boost::is_same< + typename std::iterator_traits::value_type, + Bare_point + > + > + >::type* = NULL + ) +#else + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, InputIterator last) +#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO + { + size_type n = number_of_vertices(); + + std::vector points(first, last); + spatial_sort (points.begin(), points.end(), geom_traits()); + + Cell_handle hint; + for (typename std::vector::const_iterator p = points.begin(), + end = points.end(); p != end; ++p) + { + Locate_type lt; + Cell_handle c; + int li, lj; + c = locate (*p, lt, li, lj, hint); + + Vertex_handle v = insert (*p, lt, c, li, lj); + + hint = v == Vertex_handle() ? c : v->cell(); + } + return number_of_vertices() - n; + } + + +#ifndef CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO +private: + template + const Weighted_point& top_get_first(const std::pair& pair) const { return pair.first; } + template + const Info& top_get_second(const std::pair& pair) const { return pair.second; } + template + const Weighted_point& top_get_first(const boost::tuple& tuple) const { return boost::get<0>(tuple); } + template + const Info& top_get_second(const boost::tuple& tuple) const { return boost::get<1>(tuple); } + + template + std::ptrdiff_t insert_with_info(InputIterator first,InputIterator last) + { + int n = number_of_vertices(); + std::vector indices; + std::vector points; + std::vector infos; + std::size_t index=0; + for (InputIterator it=first;it!=last;++it){ + Tuple_or_pair pair = *it; + points.push_back( top_get_first(pair) ); + infos.push_back ( top_get_second(pair) ); + indices.push_back(index++); + } + + typedef internal::Vector_property_map Point_pmap; + typedef internal::Spatial_sort_traits_with_property_map_3 Search_traits; + + spatial_sort(indices.begin(),indices.end(),Search_traits(Point_pmap(points),geom_traits())); + + Cell_handle hint; + for (typename std::vector::const_iterator + it = indices.begin(), end = indices.end(); + it != end; ++it) + { + Locate_type lt; + Cell_handle c; + int li, lj; + c = locate (points[*it], lt, li, lj, hint); + + Vertex_handle v = insert (points[*it], lt, c, li, lj); + if (v!=Vertex_handle()){ + v->info()=infos[*it]; + hint=v->cell(); + } + else + hint=c; + } + + return number_of_vertices() - n; + } + +public: + + template < class InputIterator > + std::ptrdiff_t + insert( InputIterator first, + InputIterator last, + typename boost::enable_if< + boost::mpl::or_< + boost::is_same< + typename std::iterator_traits::value_type, + std::pair::type> + >, + boost::is_same< + typename std::iterator_traits::value_type, + std::pair::type> + > + > + >::type* = NULL + ) + {return insert_with_info< std::pair::type> >(first,last);} + + template + std::ptrdiff_t + insert( boost::zip_iterator< boost::tuple > first, + boost::zip_iterator< boost::tuple > last, + typename boost::enable_if< + boost::mpl::and_< + boost::mpl::or_< + typename boost::is_same< typename std::iterator_traits::value_type, Weighted_point >, + typename boost::is_same< typename std::iterator_traits::value_type, Bare_point > + >, + typename boost::is_same< typename std::iterator_traits::value_type, typename internal::Info_check::type > + > + >::type* =NULL + ) + {return insert_with_info< boost::tuple::type> >(first,last);} +#endif //CGAL_TRIANGULATION_3_DONT_INSERT_RANGE_OF_POINTS_WITH_INFO + + + Vertex_handle insert(const Weighted_point & p, Vertex_handle hint) + { + return insert(p, hint == Vertex_handle() ? this->infinite_cell() : hint->cell()); + } + + Vertex_handle insert(const Weighted_point & p, + Cell_handle start = Cell_handle()); + + Vertex_handle insert(const Weighted_point & p, Locate_type lt, + Cell_handle c, int li, int); + + template + Vertex_handle + insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i); + + template + Vertex_handle + insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv); + + template + Triple + find_conflicts(const Weighted_point &p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit, + OutputIteratorInternalFacets ifit) const + { + CGAL_triangulation_precondition(dimension() >= 2); + + std::vector cells; + cells.reserve(32); + std::vector facets; + facets.reserve(64); + + if (dimension() == 2) { + Conflict_tester_2 tester(p, this); + if (! tester (c)) return make_triple (bfit, cit, ifit); + ifit = Tr_Base::find_conflicts + (c, tester, + make_triple(std::back_inserter(facets), + std::back_inserter(cells), + ifit)).third; + } + else { + Conflict_tester_3 tester(p, this); + if (! tester (c)) return make_triple (bfit, cit, ifit); + ifit = Tr_Base::find_conflicts + (c, tester, + make_triple(std::back_inserter(facets), + std::back_inserter(cells), + ifit)).third; + } + + // Reset the conflict flag on the boundary. + for(typename std::vector::iterator fit=facets.begin(); + fit != facets.end(); ++fit) { + fit->first->neighbor(fit->second)->tds_data().clear(); + *bfit++ = *fit; + } + + // Reset the conflict flag in the conflict cells. + for(typename std::vector::iterator ccit=cells.begin(); + ccit != cells.end(); ++ccit) { + (*ccit)->tds_data().clear(); + *cit++ = *ccit; + } + return make_triple(bfit, cit, ifit); + } + + template + std::pair + find_conflicts(const Weighted_point &p, Cell_handle c, + OutputIteratorBoundaryFacets bfit, + OutputIteratorCells cit) const + { + Triple t = find_conflicts(p, c, bfit, cit, + Emptyset_iterator()); + return std::make_pair(t.first, t.second); + } + + // Returns the vertices on the interior of the conflict hole. + template + OutputIterator + vertices_inside_conflict_zone(const Weighted_point&p, Cell_handle c, + OutputIterator res) const + { + CGAL_triangulation_precondition(dimension() >= 2); + + // Get the facets on the boundary of the hole, and the cells of the hole + std::vector cells; + std::vector facets; + find_conflicts(p, c, std::back_inserter(facets), + std::back_inserter(cells), Emptyset_iterator()); + + // Put all vertices on the hole in 'vertices' + const int d = dimension(); + std::set vertices; + for (typename std::vector::const_iterator + it = cells.begin(), + end = cells.end(); it != end; ++it) + { + for(int i = 0; i <= d; ++i) { + vertices.insert((*it)->vertex(i)); + } + } + // Then extract the vertices of the boundary and remove them from + // 'vertices' + if (dimension() == 3) { + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.erase(i->first->vertex((i->second+1)&3)); + vertices.erase(i->first->vertex((i->second+2)&3)); + vertices.erase(i->first->vertex((i->second+3)&3)); + } + } else { + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.erase(i->first->vertex(cw(i->second))); + vertices.erase(i->first->vertex(ccw(i->second))); + } + } + + return std::copy(vertices.begin(), vertices.end(), res); + } + +#ifndef CGAL_NO_DEPRECATED_CODE + // Returns the vertices on the boundary of the conflict hole. + template + OutputIterator + vertices_in_conflict(const Weighted_point&p, Cell_handle c, OutputIterator res) const + { + return vertices_on_conflict_zone_boundary(p, c, res); + } +#endif // CGAL_NO_DEPRECATED_CODE + + // Returns the vertices on the boundary of the conflict hole. + template + OutputIterator + vertices_on_conflict_zone_boundary(const Weighted_point&p, Cell_handle c, + OutputIterator res) const + { + CGAL_triangulation_precondition(dimension() >= 2); + + // Get the facets on the boundary of the hole. + std::vector facets; + find_conflicts(p, c, std::back_inserter(facets), + Emptyset_iterator(), Emptyset_iterator()); + + // Then extract uniquely the vertices. + std::set vertices; + if (dimension() == 3) { + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.insert(i->first->vertex((i->second+1)&3)); + vertices.insert(i->first->vertex((i->second+2)&3)); + vertices.insert(i->first->vertex((i->second+3)&3)); + } + } else { + for (typename std::vector::const_iterator i = facets.begin(); + i != facets.end(); ++i) { + vertices.insert(i->first->vertex(cw(i->second))); + vertices.insert(i->first->vertex(ccw(i->second))); + } + } + + return std::copy(vertices.begin(), vertices.end(), res); + } + + void remove (Vertex_handle v); + + template < typename InputIterator > + size_type remove(InputIterator first, InputIterator beyond) + { + CGAL_triangulation_precondition(!this->does_repeat_in_range(first, beyond)); + size_type n = number_of_vertices(); + while (first != beyond) { + remove (*first); + ++first; + } + return n - number_of_vertices(); + } + + // DISPLACEMENT + Vertex_handle move_point(Vertex_handle v, const Weighted_point & p); + + // Displacement works only for Regular triangulation + // without hidden points at any time + Vertex_handle move_if_no_collision(Vertex_handle v, const Weighted_point & p); + Vertex_handle move(Vertex_handle v, const Weighted_point & p); + + // REMOVE CLUSTER - works only when Regular has no hidden point at all + // "regular as Delaunay" + template < typename InputIterator > + size_type remove_cluster(InputIterator first, InputIterator beyond) + { + Self tmp; + Vertex_remover remover (tmp); + return Tr_Base::remove(first, beyond, remover); + } + +protected: + + Oriented_side + side_of_oriented_power_sphere(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p3, + const Weighted_point &p, + bool perturb = false) const; + + Oriented_side + side_of_oriented_power_circle(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p, + bool perturb = false) const; + + Bounded_side + side_of_bounded_power_circle(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p, + bool perturb = false) const; + + Bounded_side + side_of_bounded_power_segment(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p, + bool perturb = false) const; + + +public: + + // Queries + Bounded_side + side_of_power_sphere(Cell_handle c, const Weighted_point &p, + bool perturb = false) const; + + Bounded_side + side_of_power_circle(const Facet & f, const Weighted_point & p, + bool /* perturb */ = false) const + { + return side_of_power_circle(f.first, f.second, p); + } + + Bounded_side + side_of_power_circle(Cell_handle c, int i, const Weighted_point &p, + bool perturb = false) const; + + Bounded_side + side_of_power_segment(Cell_handle c, const Weighted_point &p, + bool perturb = false) const; + + Vertex_handle + nearest_power_vertex_in_cell(const Bare_point& p, + Cell_handle c) const; + + Vertex_handle + nearest_power_vertex(const Bare_point& p, Cell_handle c = + Cell_handle()) const; + + bool is_Gabriel(Cell_handle c, int i) const; + bool is_Gabriel(Cell_handle c, int i, int j) const; + bool is_Gabriel(const Facet& f)const ; + bool is_Gabriel(const Edge& e) const; + bool is_Gabriel(Vertex_handle v) const; + + + // Dual functions + Bare_point dual(Cell_handle c) const; + + Object dual(const Facet & f) const + { return dual( f.first, f.second ); } + + Object dual(Cell_handle c, int i) const; + + template < class Stream> + Stream& draw_dual(Stream & os) + { + for (Finite_facets_iterator fit = finite_facets_begin(), + end = finite_facets_end(); + fit != end; ++fit) { + Object o = dual(*fit); + if (const Segment *s = object_cast(&o)) os << *s; + else if (const Ray *r = object_cast(&o)) os << *r; + else if (const Bare_point *p = object_cast(&o)) os << *p; + } + return os; + } + + bool is_valid(bool verbose = false, int level = 0) const; + +protected: + bool + less_power_distance(const Bare_point &p, + const Weighted_point &q, + const Weighted_point &r) const + { + return + geom_traits().compare_power_distance_3_object()(p, q, r) == SMALLER; + } + + Bare_point + construct_weighted_circumcenter(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r, + const Weighted_point &s) const + { + return geom_traits().construct_weighted_circumcenter_3_object()(p,q,r,s); + } + + Bare_point + construct_weighted_circumcenter(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r) const + { + return geom_traits().construct_weighted_circumcenter_3_object()(p,q,r); + } + + Line + construct_perpendicular_line(const Plane &pl, const Bare_point &p) const + { + return geom_traits().construct_perpendicular_line_3_object()(pl, p); + } + + Plane + construct_plane(const Bare_point &p, const Bare_point &q, const Bare_point &r) const + { + return geom_traits().construct_plane_3_object()(p, q, r); + } + + Ray + construct_ray(const Bare_point &p, const Line &l) const + { + return geom_traits().construct_ray_3_object()(p, l); + } + + Object + construct_object(const Bare_point &p) const + { + return geom_traits().construct_object_3_object()(p); + } + + Object + construct_object(const Segment &s) const + { + return geom_traits().construct_object_3_object()(s); + } + + Object + construct_object(const Ray &r) const + { + return geom_traits().construct_object_3_object()(r); + } + + Vertex_handle + nearest_power_vertex(const Bare_point &p, + Vertex_handle v, + Vertex_handle w) const + { + // In case of equality, v is returned. + CGAL_triangulation_precondition(v != w); + if (is_infinite(v)) return w; + if (is_infinite(w)) return v; + return less_power_distance(p, w->point(), v->point()) ? w : v; + } + + Oriented_side + power_test(const Weighted_point &p, const Weighted_point &q) const + { + CGAL_triangulation_precondition(this->equal(p, q)); + return geom_traits().power_test_3_object()(p, q); + } + + Oriented_side + power_test(const Weighted_point &p, const Weighted_point &q, + const Weighted_point &r) const + { + CGAL_triangulation_precondition(this->collinear(p, q, r)); + return geom_traits().power_test_3_object()(p, q, r); + } + + Oriented_side + power_test(const Weighted_point &p, const Weighted_point &q, + const Weighted_point &r, const Weighted_point &s) const + { + CGAL_triangulation_precondition(this->coplanar(p, q, r, s)); + return geom_traits().power_test_3_object()(p, q, r, s); + } + + Oriented_side + power_test(const Weighted_point &p, const Weighted_point &q, + const Weighted_point &r, const Weighted_point &s, + const Weighted_point &t) const + { + return geom_traits().power_test_3_object()(p, q, r, s, t); + } + + bool in_conflict_3(const Weighted_point &p, const Cell_handle c) const + { + return side_of_power_sphere(c, p, true) == ON_BOUNDED_SIDE; + } + + bool in_conflict_2(const Weighted_point &p, const Cell_handle c, int i) const + { + return side_of_power_circle(c, i, p, true) == ON_BOUNDED_SIDE; + } + + bool in_conflict_1(const Weighted_point &p, const Cell_handle c) const + { + return side_of_power_segment(c, p, true) == ON_BOUNDED_SIDE; + } + + bool in_conflict_0(const Weighted_point &p, const Cell_handle c) const + { + return power_test(c->vertex(0)->point(), p) == ON_POSITIVE_SIDE; + } + + bool in_conflict(const Weighted_point &p, const Cell_handle c) const + { + switch (dimension()) { + case 0: return in_conflict_0(p, c); + case 1: return in_conflict_1(p, c); + case 2: return in_conflict_2(p, c, 3); + case 3: return in_conflict_3(p, c); + } + return true; + } + + class Conflict_tester_3 + { + const Weighted_point &p; + const Self *t; + + public: + + Conflict_tester_3(const Weighted_point &pt, const Self *tr) + : p(pt), t(tr) {} + + bool operator()(const Cell_handle c) const { + return t->in_conflict_3(p, c); + } + + bool test_initial_cell(const Cell_handle c) const { + return operator()(c); + } + Oriented_side compare_weight(const Weighted_point &wp1, + const Weighted_point &wp2) const + { + return t->power_test (wp1, wp2); + } + }; + + class Conflict_tester_2 + { + const Weighted_point &p; + const Self *t; + public: + + Conflict_tester_2(const Weighted_point &pt, const Self *tr) + : p(pt), t(tr) {} + + bool operator()(const Cell_handle c) const + { + return t->in_conflict_2(p, c, 3); + } + bool test_initial_cell(const Cell_handle c) const { + return operator()(c); + } + Oriented_side compare_weight(const Weighted_point &wp1, + const Weighted_point &wp2) const + { + return t->power_test (wp1, wp2); + } + }; + + class Conflict_tester_1 + { + const Weighted_point &p; + const Self *t; + + public: + + Conflict_tester_1(const Weighted_point &pt, const Self *tr) + : p(pt), t(tr) {} + + bool operator()(const Cell_handle c) const + { + return t->in_conflict_1(p, c); + } + bool test_initial_cell(const Cell_handle c) const { + return operator()(c); + } + Oriented_side compare_weight(const Weighted_point &wp1, + const Weighted_point &wp2) const + { + return t->power_test (wp1, wp2); + } + }; + + class Conflict_tester_0 + { + const Weighted_point &p; + const Self *t; + + public: + + Conflict_tester_0(const Weighted_point &pt, const Self *tr) + : p(pt), t(tr) {} + + bool operator()(const Cell_handle c) const + { + return t->in_conflict_0(p, c); + } + bool test_initial_cell(const Cell_handle c) const { + return operator()(c); + } + int compare_weight(const Weighted_point &wp1, + const Weighted_point &wp2) const + { + return t->power_test (wp1, wp2); + } + }; + + class Hidden_point_visitor + { + Self *t; + mutable std::vector vertices; + mutable std::vector hidden_points; + + public: + + Hidden_point_visitor(Self *tr) : t(tr) {} + + template + void process_cells_in_conflict(InputIterator start, InputIterator end) const + { + int dim = t->dimension(); + while (start != end) { + std::copy((*start)->hidden_points_begin(), + (*start)->hidden_points_end(), + std::back_inserter(hidden_points)); + + for (int i=0; i<=dim; i++) { + Vertex_handle v = (*start)->vertex(i); + if (v->cell() != Cell_handle()) { + vertices.push_back(v); + v->set_cell(Cell_handle()); + } + } + start ++; + } + } + void reinsert_vertices(Vertex_handle v) { + Cell_handle hc = v->cell(); + for (typename std::vector::iterator + vi = vertices.begin(); vi != vertices.end(); ++vi) { + if ((*vi)->cell() != Cell_handle()) continue; + hc = t->locate ((*vi)->point(), hc); + hide_point(hc, (*vi)->point()); + t->tds().delete_vertex(*vi); + } + vertices.clear(); + for (typename std::vector::iterator + hp = hidden_points.begin(); hp != hidden_points.end(); ++hp) { + hc = t->locate (*hp, hc); + hide_point (hc, *hp); + } + hidden_points.clear(); + } + Vertex_handle replace_vertex(Cell_handle c, int index, + const Weighted_point &p) { + Vertex_handle v = c->vertex(index); + hide_point(c, v->point()); + v->set_point(p); + return v; + } + void hide_point(Cell_handle c, const Weighted_point &p) { + c->hide_point(p); + } + }; + + template < class RegularTriangulation_3 > + class Vertex_remover; + + template < class RegularTriangulation_3 > + class Vertex_inserter; + + Hidden_point_visitor hidden_point_visitor; +}; + + +template < class Gt, class Tds > +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +nearest_power_vertex_in_cell(const Bare_point& p, + Cell_handle c) const +// Returns the finite vertex of the cell c with smaller +// power distance to p. +{ + CGAL_triangulation_precondition(dimension() >= 1); + Vertex_handle nearest = nearest_power_vertex(p, + c->vertex(0), + c->vertex(1)); + if (dimension() >= 2) { + nearest = nearest_power_vertex(p, nearest, c->vertex(2)); + if (dimension() == 3) + nearest = nearest_power_vertex(p, nearest, c->vertex(3)); + } + return nearest; +} + + +template < class Gt, class Tds > +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +nearest_power_vertex(const Bare_point& p, Cell_handle start) const +{ + if (number_of_vertices() == 0) + return Vertex_handle(); + + // Use a brute-force algorithm if dimension < 3. + if (dimension() < 3) { + Finite_vertices_iterator vit = finite_vertices_begin(); + Vertex_handle res = vit; + ++vit; + for (Finite_vertices_iterator end = finite_vertices_end(); vit != end; ++vit) + res = nearest_power_vertex(p, res, vit); + return res; + } + + Locate_type lt; + int li, lj; + // I put the cast here temporarily + // until we solve the traits class pb of regular triangulation + Cell_handle c = locate(static_cast(p), lt, li, lj, start); + + // - start with the closest vertex from the located cell. + // - repeatedly take the nearest of its incident vertices if any + // - if not, we're done. + Vertex_handle nearest = nearest_power_vertex_in_cell(p, c); + std::vector vs; + vs.reserve(32); + while (true) { + Vertex_handle tmp = nearest; + adjacent_vertices(nearest, std::back_inserter(vs)); + for (typename std::vector::const_iterator + vsit = vs.begin(); vsit != vs.end(); ++vsit) + tmp = nearest_power_vertex(p, tmp, *vsit); + if (tmp == nearest) + break; + vs.clear(); + nearest = tmp; + } + return nearest; +} + +template < class Gt, class Tds > +typename Regular_triangulation_3::Bare_point +Regular_triangulation_3:: +dual(Cell_handle c) const +{ + CGAL_triangulation_precondition(dimension()==3); + CGAL_triangulation_precondition( ! is_infinite(c) ); + return construct_weighted_circumcenter( c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point() ); +} + +template < class Gt, class Tds > +typename Regular_triangulation_3::Object +Regular_triangulation_3:: +dual(Cell_handle c, int i) const +{ + CGAL_triangulation_precondition(dimension()>=2); + CGAL_triangulation_precondition( ! is_infinite(c,i) ); + + if ( dimension() == 2 ) { + CGAL_triangulation_precondition( i == 3 ); + return construct_object( + construct_weighted_circumcenter(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point()) ); + } + + // dimension() == 3 + Cell_handle n = c->neighbor(i); + if ( ! is_infinite(c) && ! is_infinite(n) ) + return construct_object(construct_segment( dual(c), dual(n) )); + + // either n or c is infinite + int in; + if ( is_infinite(c) ) + in = n->index(c); + else { + n = c; + in = i; + } + // n now denotes a finite cell, either c or c->neighbor(i) + int ind[3] = {(in+1)&3,(in+2)&3,(in+3)&3}; + if ( (in&1) == 1 ) + std::swap(ind[0], ind[1]); + const Weighted_point& p = n->vertex(ind[0])->point(); + const Weighted_point& q = n->vertex(ind[1])->point(); + const Weighted_point& r = n->vertex(ind[2])->point(); + + Line l = + construct_perpendicular_line( construct_plane(p,q,r), + construct_weighted_circumcenter(p,q,r) ); + return construct_object(construct_ray( dual(n), l)); +} + + +template < class Gt, class Tds > +Oriented_side +Regular_triangulation_3:: +side_of_oriented_power_sphere(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p3, + const Weighted_point &p, bool perturb) const +{ + CGAL_triangulation_precondition( orientation(p0, p1, p2, p3) == POSITIVE ); + + using namespace boost; + + Oriented_side os = power_test(p0, p1, p2, p3, p); + + if (os != ON_ORIENTED_BOUNDARY || !perturb) + return os; + + // We are now in a degenerate case => we do a symbolic perturbation. + + // We sort the points lexicographically. + const Weighted_point * points[5] = {&p0, &p1, &p2, &p3, &p}; + std::sort(points, points + 5, + boost::bind(geom_traits().compare_xyz_3_object(), + boost::bind(Dereference(), _1), + boost::bind(Dereference(), _2)) == SMALLER); + + // We successively look whether the leading monomial, then 2nd monomial + // of the determinant has non null coefficient. + for (int i=4; i>1; --i) { + if (points[i] == &p) + return ON_NEGATIVE_SIDE; // since p0 p1 p2 p3 are non coplanar + // and positively oriented + Orientation o; + if (points[i] == &p3 && (o = orientation(p0,p1,p2,p)) != COPLANAR ) + return o; + if (points[i] == &p2 && (o = orientation(p0,p1,p,p3)) != COPLANAR ) + return o; + if (points[i] == &p1 && (o = orientation(p0,p,p2,p3)) != COPLANAR ) + return o; + if (points[i] == &p0 && (o = orientation(p,p1,p2,p3)) != COPLANAR ) + return o; + } + + CGAL_triangulation_assertion(false); + return ON_NEGATIVE_SIDE; +} + + +template < class Gt, class Tds > +Bounded_side +Regular_triangulation_3:: +side_of_power_sphere(Cell_handle c, const Weighted_point &p, + bool perturb) const +{ + CGAL_triangulation_precondition( dimension() == 3 ); + int i3; + if ( ! c->has_vertex( infinite_vertex(), i3 ) ) { + return Bounded_side( side_of_oriented_power_sphere(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point(), + p, perturb) ); + } + // else infinite cell : + int i0,i1,i2; + if ( (i3%2) == 1 ) { + i0 = (i3+1)&3; + i1 = (i3+2)&3; + i2 = (i3+3)&3; + } + else { + i0 = (i3+2)&3; + i1 = (i3+1)&3; + i2 = (i3+3)&3; + } + + // general case + Orientation o = orientation(c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), p); + if (o != ZERO) + return Bounded_side(o); + + // else p coplanar with i0,i1,i2 + return side_of_bounded_power_circle(c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), + p, perturb); +} + + +template < class Gt, class Tds > +Bounded_side +Regular_triangulation_3:: +side_of_bounded_power_circle(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p, bool perturb) const +{ + CGAL_triangulation_precondition(coplanar_orientation(p0, p1, p2) != 0); + if (coplanar_orientation(p0, p1, p2) == POSITIVE) + return Bounded_side (side_of_oriented_power_circle(p0, p1, p2, p, perturb)); + // Wrong because the low level power test already does a coplanar orientation + // test. + // return Bounded_side (- side_of_oriented_power_circle (p0, p2, p1, p, + // perturb)); + return Bounded_side (side_of_oriented_power_circle(p0, p2, p1, p, perturb)); +} + + +template < class Gt, class Tds > +Oriented_side +Regular_triangulation_3:: +side_of_oriented_power_circle(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p, bool perturb) const +{ + CGAL_triangulation_precondition( coplanar_orientation(p0, p1, p2) == POSITIVE ); + + using namespace boost; + + Oriented_side os = power_test(p0, p1, p2, p); + + if (os != ON_ORIENTED_BOUNDARY || !perturb) + return os; + + // We are now in a degenerate case => we do a symbolic perturbation. + + // We sort the points lexicographically. + const Weighted_point * points[4] = {&p0, &p1, &p2, &p}; + std::sort(points, points + 4, + boost::bind(geom_traits().compare_xyz_3_object(), + boost::bind(Dereference(), _1), + boost::bind(Dereference(), _2)) == SMALLER); + + // We successively look whether the leading monomial, then 2nd monomial + // of the determinant has non null coefficient. + // 2 iterations are enough (cf paper) + for (int i=3; i>1; --i) { + if (points[i] == &p) + return ON_NEGATIVE_SIDE; // since p0 p1 p2 are non collinear + // and positively oriented + Orientation o; + if (points[i] == &p2 && (o = coplanar_orientation(p0,p1,p)) != COPLANAR ) + return o; + if (points[i] == &p1 && (o = coplanar_orientation(p0,p,p2)) != COPLANAR ) + return o; + if (points[i] == &p0 && (o = coplanar_orientation(p,p1,p2)) != COPLANAR ) + return o; + } + + CGAL_triangulation_assertion(false); + return ON_NEGATIVE_SIDE; +} + + +template < class Gt, class Tds > +Bounded_side +Regular_triangulation_3:: +side_of_power_circle(Cell_handle c, int i, const Weighted_point &p, + bool perturb) const +{ + CGAL_triangulation_precondition( dimension() >= 2 ); + int i3 = 5; + if ( dimension() == 2 ) { + CGAL_triangulation_precondition( i == 3 ); + // the triangulation is supposed to be valid, ie the facet + // with vertices 0 1 2 in this order is positively oriented + if ( ! c->has_vertex( infinite_vertex(), i3 ) ) + return Bounded_side( side_of_oriented_power_circle(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + p, perturb) ); + // else infinite facet + // v1, v2 finite vertices of the facet such that v1,v2,infinite + // is positively oriented + Vertex_handle v1 = c->vertex( ccw(i3) ), + v2 = c->vertex( cw(i3) ); + CGAL_triangulation_assertion(coplanar_orientation(v1->point(), v2->point(), + mirror_vertex(c, i3)->point()) == NEGATIVE); + Orientation o = coplanar_orientation(v1->point(), v2->point(), p); + if ( o != ZERO ) + return Bounded_side( o ); + // case when p collinear with v1v2 + return side_of_bounded_power_segment(v1->point(), + v2->point(), + p, perturb); + }// dim 2 + + // else dimension == 3 + CGAL_triangulation_precondition( (i >= 0) && (i < 4) ); + if ( ( ! c->has_vertex(infinite_vertex(),i3) ) || ( i3 != i ) ) { + // finite facet + // initialization of i0 i1 i2, vertices of the facet positively + // oriented (if the triangulation is valid) + int i0 = (i>0) ? 0 : 1; + int i1 = (i>1) ? 1 : 2; + int i2 = (i>2) ? 2 : 3; + CGAL_triangulation_precondition(this->coplanar(c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), p)); + return side_of_bounded_power_circle(c->vertex(i0)->point(), + c->vertex(i1)->point(), + c->vertex(i2)->point(), + p, perturb); + } + //else infinite facet + // v1, v2 finite vertices of the facet such that v1,v2,infinite + // is positively oriented + Vertex_handle v1 = c->vertex( next_around_edge(i3,i) ), + v2 = c->vertex( next_around_edge(i,i3) ); + Orientation o = (Orientation) + (coplanar_orientation( v1->point(), v2->point(), + c->vertex(i)->point()) * + coplanar_orientation( v1->point(), v2->point(), p)); + // then the code is duplicated from 2d case + if ( o != ZERO ) + return Bounded_side( -o ); + // because p is in f iff + // it is not on the same side of v1v2 as c->vertex(i) + // case when p collinear with v1v2 : + return side_of_bounded_power_segment(v1->point(), + v2->point(), + p, perturb); +} + +template < class Gt, class Tds > +Bounded_side +Regular_triangulation_3:: +side_of_bounded_power_segment(const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p, bool perturb) const +{ + Oriented_side os = power_test(p0, p1, p); + + if (os != ON_ORIENTED_BOUNDARY || !perturb) + return Bounded_side(os); + + // We are now in a degenerate case => we do a symbolic perturbation. + + switch (this->collinear_position(p0, p, p1)) { + case Tr_Base::BEFORE: case Tr_Base::AFTER: + return ON_UNBOUNDED_SIDE; + case Tr_Base::MIDDLE: + return ON_BOUNDED_SIDE; + default: + ; + } + + CGAL_triangulation_assertion(false); + return ON_UNBOUNDED_SIDE; +} + +template < class Gt, class Tds > +Bounded_side +Regular_triangulation_3:: +side_of_power_segment(Cell_handle c, const Weighted_point &p, + bool perturb) const +{ + CGAL_triangulation_precondition( dimension() == 1 ); + if ( ! is_infinite(c,0,1) ) + return side_of_bounded_power_segment(c->vertex(0)->point(), + c->vertex(1)->point(), + p, perturb); + Locate_type lt; int i; + Bounded_side soe = side_of_edge( p, c, lt, i ); + if (soe != ON_BOUNDARY) + return soe; + // Either we compare weights, or we use the finite neighboring edge + Cell_handle finite_neighbor = c->neighbor(c->index(infinite_vertex())); + CGAL_triangulation_assertion(!is_infinite(finite_neighbor,0,1)); + return side_of_bounded_power_segment(finite_neighbor->vertex(0)->point(), + finite_neighbor->vertex(1)->point(), + p, perturb); +} + +template < class Gt, class Tds > +bool +Regular_triangulation_3:: +is_Gabriel(const Facet& f) const +{ + return is_Gabriel(f.first, f.second); +} + +template < class Gt, class Tds > +bool +Regular_triangulation_3:: +is_Gabriel(Cell_handle c, int i) const +{ + CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i)); + typename Geom_traits::Side_of_bounded_orthogonal_sphere_3 + side_of_bounded_orthogonal_sphere = + geom_traits().side_of_bounded_orthogonal_sphere_3_object(); + + if ((!is_infinite(c->vertex(i))) && + side_of_bounded_orthogonal_sphere( + c->vertex(vertex_triple_index(i,0))->point(), + c->vertex(vertex_triple_index(i,1))->point(), + c->vertex(vertex_triple_index(i,2))->point(), + c->vertex(i)->point()) == ON_BOUNDED_SIDE ) return false; + + Cell_handle neighbor = c->neighbor(i); + int in = neighbor->index(c); + + if ((!is_infinite(neighbor->vertex(in))) && + side_of_bounded_orthogonal_sphere( + c->vertex(vertex_triple_index(i,0))->point(), + c->vertex(vertex_triple_index(i,1))->point(), + c->vertex(vertex_triple_index(i,2))->point(), + neighbor->vertex(in)->point()) == ON_BOUNDED_SIDE ) return false; + + return true; +} + + +template < class Gt, class Tds > +bool +Regular_triangulation_3:: +is_Gabriel(const Edge& e) const +{ + return is_Gabriel(e.first, e.second, e.third); +} + +template < class Gt, class Tds > +bool +Regular_triangulation_3:: +is_Gabriel(Cell_handle c, int i, int j) const +{ + CGAL_triangulation_precondition(dimension() == 3 && !is_infinite(c,i,j)); + typename Geom_traits::Side_of_bounded_orthogonal_sphere_3 + side_of_bounded_orthogonal_sphere = + geom_traits().side_of_bounded_orthogonal_sphere_3_object(); + + Facet_circulator fcirc = incident_facets(c,i,j), + fdone(fcirc); + Vertex_handle v1 = c->vertex(i); + Vertex_handle v2 = c->vertex(j); + do { + // test whether the vertex of cc opposite to *fcirc + // is inside the sphere defined by the edge e = (s, i,j) + Cell_handle cc = (*fcirc).first; + int ii = (*fcirc).second; + if (!is_infinite(cc->vertex(ii)) && + side_of_bounded_orthogonal_sphere( v1->point(), + v2->point(), + cc->vertex(ii)->point()) + == ON_BOUNDED_SIDE ) return false; + } while(++fcirc != fdone); + return true; +} + +template < class Gt, class Tds > +bool +Regular_triangulation_3:: +is_Gabriel(Vertex_handle v) const +{ + return nearest_power_vertex( v->point().point(), v->cell()) == v; +} + +template < class Gt, class Tds > +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +insert(const Weighted_point & p, Cell_handle start) +{ + Locate_type lt; + int li, lj; + Cell_handle c = locate(p, lt, li, lj, start); + return insert(p, lt, c, li, lj); +} + +template < class Gt, class Tds > +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +insert(const Weighted_point & p, Locate_type lt, Cell_handle c, int li, int lj) +{ + switch (dimension()) { + case 3: + { + Conflict_tester_3 tester (p, this); + return insert_in_conflict(p, lt,c,li,lj, tester, hidden_point_visitor); + } + case 2: + { + Conflict_tester_2 tester (p, this); + return insert_in_conflict(p, lt,c,li,lj, tester, hidden_point_visitor); + } + case 1: + { + Conflict_tester_1 tester (p, this); + return insert_in_conflict(p, lt,c,li,lj, tester, hidden_point_visitor); + } + } + + Conflict_tester_0 tester (p, this); + return insert_in_conflict(p, lt,c,li,lj, tester, hidden_point_visitor); +} + + +template < class Gt, class Tds > +template +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i) +{ + CGAL_triangulation_precondition(cell_begin != cell_end); + + hidden_point_visitor.process_cells_in_conflict(cell_begin,cell_end); + + Vertex_handle v = + Tr_Base::insert_in_hole(p, cell_begin, cell_end, begin, i); + + // Store the hidden points in their new cells and hide vertices that + // have to be hidden + hidden_point_visitor.reinsert_vertices(v); + return v; +} + + +template < class Gt, class Tds > +template +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +insert_in_hole(const Weighted_point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv) +{ + CGAL_triangulation_precondition(cell_begin != cell_end); + + hidden_point_visitor.process_cells_in_conflict(cell_begin,cell_end); + + Vertex_handle v = + Tr_Base::insert_in_hole(p, cell_begin, cell_end, begin, i, newv); + + // Store the hidden points in their new cells and hide vertices that + // have to be hidden + hidden_point_visitor.reinsert_vertices(v); + return v; +} + +template +template +class Regular_triangulation_3::Vertex_remover { + typedef RegularTriangulation_3 Regular; + typedef typename Gt::Point_3 Point; +public: + typedef typename std::vector::iterator + Hidden_points_iterator; + + Vertex_remover(Regular &tmp_) : tmp(tmp_) {} + + Regular &tmp; + + void add_hidden_points(Cell_handle ch) { + std::copy (ch->hidden_points_begin(), ch->hidden_points_end(), + std::back_inserter(hidden)); + } + + Hidden_points_iterator hidden_points_begin() { + return hidden.begin(); + } + Hidden_points_iterator hidden_points_end() { + return hidden.end(); + } + + Bounded_side side_of_bounded_circle(const Point &p, const Point &q, + const Point &r, const Point &s, bool perturb = false) const { + return tmp.side_of_bounded_power_circle(p,q,r,s,perturb); + } + +private: + // The removal of v may un-hide some points, + // Space functions output them. + std::vector hidden; +}; + +// The displacement method works only +// on regular triangulation without hidden points at any time +// the vertex inserter is used only +// for the purpose of displacements +template +template +class Regular_triangulation_3::Vertex_inserter { + typedef RegularTriangulation_3 Regular; +public: + typedef Nullptr_t Hidden_points_iterator; + + Vertex_inserter(Regular &tmp_) : tmp(tmp_) {} + + Regular &tmp; + + void add_hidden_points(Cell_handle) {} + Hidden_points_iterator hidden_points_begin() { return NULL; } + Hidden_points_iterator hidden_points_end() { return NULL; } + + Vertex_handle insert(const Weighted_point& p, + Locate_type lt, Cell_handle c, int li, int lj) { + return tmp.insert(p, lt, c, li, lj); + } + + Vertex_handle insert(const Weighted_point& p, Cell_handle c) { + return tmp.insert(p, c); + } + + Vertex_handle insert(const Weighted_point& p) { + return tmp.insert(p); + } +}; + +template < class Gt, class Tds > +void +Regular_triangulation_3:: +remove(Vertex_handle v) +{ + Cell_handle c; + if (dimension() > 0) + c = v->cell()->neighbor(v->cell()->index(v)); + + Self tmp; + Vertex_remover remover(tmp); + Tr_Base::remove(v,remover); + + // Re-insert the points that v was hiding. + for (typename Vertex_remover::Hidden_points_iterator + hi = remover.hidden_points_begin(); + hi != remover.hidden_points_end(); ++hi) { + Vertex_handle hv = insert (*hi, c); + if (hv != Vertex_handle()) c = hv->cell(); + } + CGAL_triangulation_expensive_postcondition (is_valid()); +} + +// Again, verbatim copy from Delaunay. +template < class Gt, class Tds > +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +move_point(Vertex_handle v, const Weighted_point & p) +{ + CGAL_triangulation_precondition(! is_infinite(v)); + CGAL_triangulation_expensive_precondition(is_vertex(v)); + + // Dummy implementation for a start. + + // Remember an incident vertex to restart + // the point location after the removal. + Cell_handle c = v->cell(); + Vertex_handle old_neighbor = c->vertex(c->index(v) == 0 ? 1 : 0); + CGAL_triangulation_assertion(old_neighbor != v); + + remove(v); + + if (dimension() <= 0) + return insert(p); + return insert(p, old_neighbor->cell()); +} + +// Displacement works only for Regular triangulation +// without hidden points at any time +template < class Gt, class Tds > +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +move_if_no_collision(Vertex_handle v, const Weighted_point &p) +{ + Self tmp; + Vertex_remover remover (tmp); + Vertex_inserter inserter (*this); + Vertex_handle res = Tr_Base::move_if_no_collision(v,p,remover,inserter); + + CGAL_triangulation_expensive_postcondition(is_valid()); + return res; +} + +template +typename Regular_triangulation_3::Vertex_handle +Regular_triangulation_3:: +move(Vertex_handle v, const Weighted_point &p) { + CGAL_triangulation_precondition(!is_infinite(v)); + if(v->point() == p) return v; + Self tmp; + Vertex_remover remover (tmp); + Vertex_inserter inserter (*this); + return Tr_Base::move(v,p,remover,inserter); +} + +template < class Gt, class Tds > +bool +Regular_triangulation_3:: +is_valid(bool verbose, int level) const +{ + if ( ! Tr_Base::is_valid(verbose,level) ) { + if (verbose) + std::cerr << "invalid base triangulation" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + switch ( dimension() ) { + case 3: + { + for(Finite_cells_iterator it = finite_cells_begin(), end = finite_cells_end(); it != end; ++it) { + is_valid_finite(it, verbose, level); + for(int i=0; i<4; i++) { + if ( !is_infinite + (it->neighbor(i)->vertex(it->neighbor(i)->index(it))) ) { + if ( side_of_power_sphere + (it, + it->neighbor(i)->vertex(it->neighbor(i)->index(it))->point()) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty sphere " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } + break; + } + case 2: + { + for(Finite_facets_iterator it = finite_facets_begin(), end = finite_facets_end(); it!= end; ++it) { + is_valid_finite((*it).first, verbose, level); + for(int i=0; i<3; i++) { + if( !is_infinite + ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) + ->index((*it).first))) ) { + if ( side_of_power_circle + ( (*it).first, 3, + (*it).first->neighbor(i)-> + vertex( (((*it).first)->neighbor(i)) + ->index((*it).first) )->point() ) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty circle " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } + break; + } + case 1: + { + for(Finite_edges_iterator it = finite_edges_begin(), end = finite_edges_end(); it != end; ++it) { + is_valid_finite((*it).first, verbose, level); + for(int i=0; i<2; i++) { + if( !is_infinite + ((*it).first->neighbor(i)->vertex( (((*it).first)->neighbor(i)) + ->index((*it).first))) ) { + if ( side_of_power_segment + ( (*it).first, + (*it).first->neighbor(i)-> + vertex( (((*it).first)->neighbor(i)) + ->index((*it).first) )->point() ) + == ON_BOUNDED_SIDE ) { + if (verbose) + std::cerr << "non-empty edge " << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } + break; + } + } + if (verbose) + std::cerr << "valid Regular triangulation" << std::endl; + return true; +} + +} //namespace CGAL + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // CGAL_REGULAR_TRIANGULATION_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_cell_base_3.h b/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_cell_base_3.h new file mode 100644 index 00000000000..fe6759275e2 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_cell_base_3.h @@ -0,0 +1,88 @@ +// Copyright (c) 2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Christophe Delage + +// cell of a triangulation of any dimension <=3 +// with hidden points (for the regular triangulation) + +#ifndef CGAL_REGULAR_TRIANGULATION_CELL_BASE_3_H +#define CGAL_REGULAR_TRIANGULATION_CELL_BASE_3_H + +#include +#include + +namespace CGAL { + +template < typename GT, + typename Cb = Triangulation_cell_base_3, + typename C = std::list > +class Regular_triangulation_cell_base_3 + : public Cb +{ +public: + static const bool DO_HIDE_POINT = true; + typedef typename Cb::Vertex_handle Vertex_handle; + typedef typename Cb::Cell_handle Cell_handle; + + typedef GT Geom_traits; + typedef typename Geom_traits::Weighted_point_3 Point; + + typedef C Point_container; + typedef typename Point_container::iterator Point_iterator; + typedef typename Point_container::const_iterator Point_const_iterator; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Cb::template Rebind_TDS::Other Cb2; + typedef Regular_triangulation_cell_base_3 Other; + }; + + Regular_triangulation_cell_base_3() + : Cb() {} + + Regular_triangulation_cell_base_3(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2, + Vertex_handle v3) + : Cb(v0, v1, v2, v3) {} + + Regular_triangulation_cell_base_3(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2, + Vertex_handle v3, + Cell_handle n0, + Cell_handle n1, + Cell_handle n2, + Cell_handle n3) + : Cb(v0, v1, v2, v3, n0, n1, n2, n3) {} + + Point_iterator hidden_points_begin() { return _hidden.begin(); } + Point_iterator hidden_points_end() { return _hidden.end(); } + + Point_const_iterator hidden_points_begin() const { return _hidden.begin(); } + Point_const_iterator hidden_points_end() const { return _hidden.end(); } + + void hide_point (const Point &p) { _hidden.push_back(p); } + // void unhide_point (Point_iterator i) { _hidden.delete(i); } + +private: + Point_container _hidden; +}; + +} //namespace CGAL + +#endif // CGAL_REGULAR_TRIANGULATION_CELL_BASE_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_euclidean_traits_3.h b/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_euclidean_traits_3.h new file mode 100644 index 00000000000..0c31dd52680 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_euclidean_traits_3.h @@ -0,0 +1,774 @@ +// Copyright (c) 1999,2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Sylvain Pion +// Monique Teillaud +// Mariette Yvinec + +#ifndef CGAL_REGULAR_TRIANGULATION_EUCLIDEAN_TRAITS_3_H +#define CGAL_REGULAR_TRIANGULATION_EUCLIDEAN_TRAITS_3_H + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +namespace CGAL { + +// returns minus the sign of the determinant of the lifted points +// associated with p,q,r,s,t [P,Q,R,S,T] +// where the P colum is [ p, p^2-wp,1] +template < typename K > +class Power_test_3 +{ +public: + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::Oriented_side Oriented_side; + + typedef Oriented_side result_type; + + Oriented_side operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s, + const Weighted_point_3 & t) const + { + return power_test_3(p,q,r,s,t); + } + + Oriented_side operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s) const + { + return power_test_3(p,q,r,s); + } + + Oriented_side operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r) const + { + return power_test_3(p,q,r); + } + + Oriented_side operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q) const + { + return power_test_3(p,q); + } +}; + + +template < typename K > +class Compare_power_distance_3 +{ +public: + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::Bare_point Point_3; + typedef typename K::Comparison_result Comparison_result; + + typedef Comparison_result result_type; + + Comparison_result operator() ( const Point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r) const + { + return compare_power_distance_3(p,q,r); + } +}; + + +// operator () +// return the sign of the power test of last weighted point +// with respect to the smallest sphere orthogonal to the others +template< typename K > +class In_smallest_orthogonal_sphere_3 +{ +public: + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::Sign Sign; + + typedef Sign result_type; + + Sign operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s, + const Weighted_point_3 & t) const + { + K traits; + typename K::Orientation_3 orientation = traits.orientation_3_object(); + typename K::Orientation o = orientation(p,q,r,s); + typename K::Oriented_side os = power_test_3(p,q,r,s,t); + CGAL_triangulation_assertion( o != COPLANAR); + // the minus sign below is due to the fact that power_test_3 + // return in fact minus the 5x5 determinant of lifted (p,q,r,s.t) + return - o * os; + } + + Sign operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s) const + { + return in_smallest_orthogonal_sphereC3( + p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + r.x(), r.y(), r.z(), r.weight(), + s.x(), s.y(), s.z(), s.weight()); + } + + Sign operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r) const + { + return in_smallest_orthogonal_sphereC3( + p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + r.x(), r.y(), r.z(), r.weight()); + } + + Sign operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q) const + { + return CGAL_NTS sign( CGAL_NTS square(p.x()-q.x()) + + CGAL_NTS square(p.y()-q.y()) + + CGAL_NTS square(p.z()-q.z()) + + p.weight() - q.weight()); + } + +}; + +template < typename K > +class Side_of_bounded_orthogonal_sphere_3 +{ +public : + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::In_smallest_orthogonal_sphere_3 In_sphere; + typedef typename K::Bounded_side Bounded_side; + + typedef Bounded_side result_type; + + Bounded_side operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s, + const Weighted_point_3 & t) const + { + return enum_cast( - In_sphere()(p,q,r,s,t)); + } + + Bounded_side operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s) const + { + return enum_cast( - In_sphere()(p,q,r,s) ); + } + + Bounded_side operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r) const + { + return enum_cast( - In_sphere()(p,q,r) ); + } + +}; + + +// operator() returns true if the affine hull of the dual +// to the given weighted points +// intersect the simplex formed by the bare points +template < typename K > +class Does_simplex_intersect_weighted_dual_support_3 +{ +public: + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::Bounded_side Bounded_side; + + typedef Bounded_side result_type; + + Bounded_side operator()(const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s) const + { + return does_simplex_intersect_weighted_dual_supportC3( + p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + r.x(), r.y(), r.z(), r.weight(), + s.x(), s.y(), s.z(), s.weight()); + } + + Bounded_side operator()(const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r) const + { + return does_simplex_intersect_weighted_dual_supportC3( + p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + r.x(), r.y(), r.z(), r.weight()); + } + + Bounded_side operator()(const Weighted_point_3 & p, + const Weighted_point_3 & q) const + { + return does_simplex_intersect_weighted_dual_supportC3( + p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight()); + } +}; + +template < typename K > +class Construct_weighted_circumcenter_3 +{ +public: + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::Bare_point Bare_point; + typedef typename K::FT FT; + + typedef Bare_point result_type; + + Bare_point operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s) const + { + FT x, y, z; + weighted_circumcenterC3(p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + r.x(), r.y(), r.z(), r.weight(), + s.x(), s.y(), s.z(), s.weight(), + x,y,z); + return Bare_point(x,y,z); + } + + Bare_point operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r) const + { + FT x, y, z; + weighted_circumcenterC3(p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + r.x(), r.y(), r.z(), r.weight(), + x,y,z); + return Bare_point(x,y,z); + } + + Bare_point operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q) const + { + FT x, y, z; + weighted_circumcenterC3(p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + x,y,z); + return Bare_point(x,y,z); + } +}; + + +template < typename K > +class Compute_power_product_3 +{ +public: + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::FT FT; + + typedef FT result_type; + + FT operator() (const Weighted_point_3 & p, + const Weighted_point_3 & q) const + { + return power_productC3(p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight()); + } +}; + + +template < typename K > +class Compute_squared_radius_smallest_orthogonal_sphere_3 +{ +public: + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::FT FT; + + typedef FT result_type; + + FT operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s) const + { + return squared_radius_orthogonal_sphereC3( + p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + r.x(), r.y(), r.z(), r.weight(), + s.x(), s.y(), s.z(), s.weight()); + } + + FT operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r) const + { + return squared_radius_smallest_orthogonal_sphereC3( + p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight(), + r.x(), r.y(), r.z(), r.weight()); + } + + FT operator() (const Weighted_point_3 & p, + const Weighted_point_3 & q) const + { + return squared_radius_smallest_orthogonal_sphereC3( + p.x(), p.y(), p.z(), p.weight(), + q.x(), q.y(), q.z(), q.weight()); + } + + FT operator() (const Weighted_point_3 & p) const + { + return -p.weight(); + } + +}; + + +// Compute the square radius of the circle centered in t +// and orthogonal to the circle orthogonal to p,q,r,s +template< typename K> +class Compute_critical_squared_radius_3 +{ + public: + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::FT FT; + + typedef FT result_type; + + result_type operator() (const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s, + const Weighted_point_3 & t) const + { + return critical_squared_radiusC3 (p.x(),p.y(),p.z(),FT(p.weight()), + q.x(),q.y(),q.z(),FT(q.weight()), + r.x(),r.y(),r.z(),FT(r.weight()), + s.x(),s.y(),s.z(),FT(s.weight()), + t.x(),t.y(),t.z(),FT(t.weight())); + } +}; + + + +template +class Compare_weighted_squared_radius_3 +{ + + typedef typename K::Weighted_point_3 Weighted_point_3; + typedef typename K::Comparison_result Comparison_result; + typedef typename K::FT FT; + +public: + typedef Comparison_result result_type; + + + result_type operator() ( + const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s, + const FT& w) const + { + return compare( + squared_radius_orthogonal_sphereC3( + p.x(),p.y(),p.z(),p.weight(), + q.x(),q.y(),q.z(),q.weight(), + r.x(),r.y(),r.z(),r.weight(), + s.x(),s.y(),s.z(),s.weight() ), + w); + } + + result_type operator() ( + const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const FT& w) const + { + return compare( + squared_radius_smallest_orthogonal_sphereC3( + p.x(),p.y(),p.z(),p.weight(), + q.x(),q.y(),q.z(),q.weight(), + r.x(),r.y(),r.z(),r.weight() ), + w); + } + + result_type operator() ( + const Weighted_point_3 & p, + const Weighted_point_3 & q, + const FT& w) const + { + return compare( + squared_radius_smallest_orthogonal_sphereC3( + p.x(),p.y(),p.z(),p.weight(), + q.x(),q.y(),q.z(),q.weight() ), + w); + } + + result_type operator() ( + const Weighted_point_3 & p, + const FT& w) const + { + return compare(-p.weight(),w); + } +}; + + + + +template < class K, class Weight = typename K::RT > +class Regular_triangulation_euclidean_traits_base_3 + : public K +{ +public: + typedef K Kernel; + typedef typename K::FT FT; + typedef typename K::Point_3 Bare_point; + typedef CGAL::Weighted_point Weighted_point; + typedef Weighted_point Weighted_point_3; + typedef Weighted_point Point_3; + //typedef typename K::Point_3 Point_3; + + typedef Regular_triangulation_euclidean_traits_base_3 Self; + + // The next typedef is there for backward compatibility + // Some users take their point type from the traits class. + // Before this type was Point + typedef Point_3 Point; + + typedef CGAL::Power_test_3 Power_test_3; + typedef CGAL::Compare_power_distance_3 Compare_power_distance_3; + typedef CGAL::In_smallest_orthogonal_sphere_3 + In_smallest_orthogonal_sphere_3; + typedef CGAL::Side_of_bounded_orthogonal_sphere_3 + Side_of_bounded_orthogonal_sphere_3; + typedef CGAL::Does_simplex_intersect_weighted_dual_support_3 + Does_simplex_intersect_dual_support_3; + typedef CGAL::Construct_weighted_circumcenter_3 + Construct_weighted_circumcenter_3; + typedef CGAL::Compute_squared_radius_smallest_orthogonal_sphere_3 + Compute_squared_radius_smallest_orthogonal_sphere_3; + typedef CGAL::Compute_power_product_3 Compute_power_product_3; + typedef CGAL::Compute_critical_squared_radius_3 + Compute_critical_squared_radius_3; + typedef CGAL::Compare_weighted_squared_radius_3 + Compare_weighted_squared_radius_3; + + enum { Has_filtered_predicates = false }; + + Power_test_3 power_test_3_object() const + { return Power_test_3(); } + + Compare_power_distance_3 compare_power_distance_3_object() const + { return Compare_power_distance_3(); } + + In_smallest_orthogonal_sphere_3 + in_smallest_orthogonal_sphere_3_object() const + { return In_smallest_orthogonal_sphere_3(); } + + Side_of_bounded_orthogonal_sphere_3 + side_of_bounded_orthogonal_sphere_3_object() const + { return Side_of_bounded_orthogonal_sphere_3(); } + + Does_simplex_intersect_dual_support_3 + does_simplex_intersect_dual_support_3_object() const + { return Does_simplex_intersect_dual_support_3(); } + + Construct_weighted_circumcenter_3 + construct_weighted_circumcenter_3_object() const + { return Construct_weighted_circumcenter_3(); } + + Compute_power_product_3 + compute_power_product_3_object() const + { return Compute_power_product_3(); } + + Compute_squared_radius_smallest_orthogonal_sphere_3 + compute_squared_radius_smallest_orthogonal_sphere_3_object() const + { return Compute_squared_radius_smallest_orthogonal_sphere_3(); } + + Compute_critical_squared_radius_3 + compute_critical_squared_radius_3_object() const + {return Compute_critical_squared_radius_3(); } + + Compare_weighted_squared_radius_3 + compare_weighted_squared_radius_3_object() const + {return Compare_weighted_squared_radius_3(); } +}; + +// We need to introduce a "traits_base_3" class in order to get the +// specialization for Exact_predicates_inexact_constructions_kernel to work, +// otherwise there is a cycle in the derivation. +template < typename K, class Weight = typename K::RT, bool UseFilteredPredicates = K::Has_filtered_predicates> +class Regular_triangulation_euclidean_traits_3 + : public Regular_triangulation_euclidean_traits_base_3 +{}; + +// Cartesian versions. +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r, + const Weighted_point &s, + const Weighted_point &t, + Cartesian_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return power_testC3(p.x(), p.y(), p.z(), FT(p.weight()), + q.x(), q.y(), q.z(), FT(q.weight()), + r.x(), r.y(), r.z(), FT(r.weight()), + s.x(), s.y(), s.z(), FT(s.weight()), + t.x(), t.y(), t.z(), FT(t.weight())); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r, + const Weighted_point &t, + Cartesian_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return power_testC3(p.x(), p.y(), p.z(), FT(p.weight()), + q.x(), q.y(), q.z(), FT(q.weight()), + r.x(), r.y(), r.z(), FT(r.weight()), + t.x(), t.y(), t.z(), FT(t.weight())); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &t, + Cartesian_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return power_testC3(p.x(), p.y(), p.z(), FT(p.weight()), + q.x(), q.y(), q.z(), FT(q.weight()), + t.x(), t.y(), t.z(), FT(t.weight())); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + Cartesian_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return power_testC3(FT(p.weight()), + FT(q.weight())); +} + + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Comparison_result +compare_power_distance_3 (const Point &p, + const Weighted_point &q, + const Weighted_point &r, + Cartesian_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return compare_power_distanceC3(p.x(), p.y(), p.z(), + q.x(), q.y(), q.z(), FT(q.weight()), + r.x(), r.y(), r.z(), FT(r.weight())); +} + + + +// Homogeneous versions. +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r, + const Weighted_point &s, + const Weighted_point &t, + Homogeneous_tag) +{ + typedef typename Kernel_traits::Kernel::RT RT; + return power_testH3(p.hx(), p.hy(), p.hz(), p.hw(), RT(p.weight()), + q.hx(), q.hy(), q.hz(), q.hw(), RT(q.weight()), + r.hx(), r.hy(), r.hz(), r.hw(), RT(r.weight()), + s.hx(), s.hy(), s.hz(), s.hw(), RT(s.weight()), + t.hx(), t.hy(), t.hz(), t.hw(), RT(t.weight())); +} + +// The followings call the cartesian version over FT, because an homogeneous +// special version would be boring to write. + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r, + const Weighted_point &t, + Homogeneous_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return power_testC3(p.x(), p.y(), p.z(), FT(p.weight()), + q.x(), q.y(), q.z(), FT(q.weight()), + r.x(), r.y(), r.z(), FT(r.weight()), + t.x(), t.y(), t.z(), FT(t.weight())); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &t, + Homogeneous_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return power_testC3(p.x(), p.y(), p.z(), FT(p.weight()), + q.x(), q.y(), q.z(), FT(q.weight()), + t.x(), t.y(), t.z(), FT(t.weight())); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + Homogeneous_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return power_testC3(FT(p.weight()), + FT(q.weight())); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Comparison_result +compare_power_distance_3 (const Point &p, + const Weighted_point &q, + const Weighted_point &t, + Homogeneous_tag) +{ + typedef typename Kernel_traits::Kernel::FT FT; + return compare_power_distanceC3(p.x(), p.y(), p.z(), FT(p.weight()), + q.x(), q.y(), q.z(), FT(q.weight()), + t.x(), t.y(), t.z(), FT(t.weight())); +} + +// Kludges for M$. + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r, + const Weighted_point &s, + const Weighted_point &t) +{ + typedef typename Kernel_traits::Kernel::Rep_tag Tag; + return power_test_3(p,q,r,s,t, Tag()); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &r, + const Weighted_point &t) +{ + typedef typename Kernel_traits::Kernel::Rep_tag Tag; + return power_test_3(p,q,r,t, Tag()); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q, + const Weighted_point &t) +{ + typedef typename Kernel_traits::Kernel::Rep_tag Tag; + return power_test_3(p,q,t, Tag()); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Oriented_side +power_test_3(const Weighted_point &p, + const Weighted_point &q) +{ + typedef typename Kernel_traits::Kernel::Rep_tag Tag; + return power_test_3(p,q, Tag()); +} + +template < class Point, class Weight > +inline +typename Kernel_traits::Kernel::Comparison_result +compare_power_distance_3 (const Point &p, + const Weighted_point &q, + const Weighted_point &r) +{ + typedef typename Kernel_traits::Kernel::Rep_tag Tag; + return compare_power_distance_3(p,q,r, Tag()); +} + +} //namespace CGAL + +// Partial specialization for Filtered_kernel. + +#include +#include + +namespace CGAL { + +namespace internal{ + // This declaration is needed to break the cyclic dependency. + template < typename K,bool b > + class Regular_triangulation_filtered_traits_3; +} //namespace internal + +template < typename K, class Weight> +class Regular_triangulation_euclidean_traits_3 + : public internal::Regular_triangulation_filtered_traits_3 +{ +public: + typedef K Kernel; +}; + + +} //namespace CGAL + +#endif // CGAL_REGULAR_TRIANGULATION_EUCLIDEAN_TRAITS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_filtered_traits_3.h b/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_filtered_traits_3.h new file mode 100644 index 00000000000..17163831751 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Regular_triangulation_filtered_traits_3.h @@ -0,0 +1,42 @@ +// Copyright (c) 2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_REGULAR_TRIANGULATION_FILTERED_TRAITS_3_H +#define CGAL_REGULAR_TRIANGULATION_FILTERED_TRAITS_3_H + +#ifndef CGAL_NO_DEPRECATED_CODE + +#include + + +namespace CGAL{ + + +// The argument is supposed to be a Filtered_kernel like kernel. +template < typename K> +class Regular_triangulation_filtered_traits_3 + : public Regular_triangulation_euclidean_traits_3 +{}; + + + +} //namespace CGAL::internal + +#endif //CGAL_NO_DEPRECATED_CODE + +#endif // CGAL_REGULAR_TRIANGULATION_FILTERED_TRAITS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_3.h new file mode 100644 index 00000000000..9a7f67521f6 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_3.h @@ -0,0 +1,5590 @@ +// Copyright (c) 1999-2003 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud +// Sylvain Pion + +#ifndef CGAL_TRIANGULATION_3_H +#define CGAL_TRIANGULATION_3_H + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifndef CGAL_NO_STRUCTURAL_FILTERING +#include +#include +#endif // no CGAL_NO_STRUCTURAL_FILTERING + +namespace CGAL { + +template < class GT, class Tds = Default > class Triangulation_3; + +template < class GT, class Tds > std::istream& operator>> +(std::istream& is, Triangulation_3 &tr); + +#ifndef CGAL_NO_STRUCTURAL_FILTERING +namespace internal { +// structural filtering is performed only for EPIC +struct Structural_filtering_3_tag {}; +struct No_structural_filtering_3_tag {}; + +template +struct Structural_filtering_selector_3 { + typedef No_structural_filtering_3_tag Tag; +}; + +template <> +struct Structural_filtering_selector_3 { + typedef Structural_filtering_3_tag Tag; +}; +} +#endif // no CGAL_NO_STRUCTURAL_FILTERING + +template < class GT, class Tds_ > +class Triangulation_3 + : public Triangulation_utils_3 +{ + friend std::istream& operator>> <> + (std::istream& is, Triangulation_3 &tr); + + typedef Triangulation_3 Self; + + typedef typename Default::Get, + Triangulation_cell_base_3 > >::type Tds; + +public: + + typedef Tds Triangulation_data_structure; + typedef GT Geom_traits; + + typedef typename GT::Point_3 Point; + typedef typename GT::Segment_3 Segment; + typedef typename GT::Triangle_3 Triangle; + typedef typename GT::Tetrahedron_3 Tetrahedron; + + typedef typename Tds::Vertex Vertex; + typedef typename Tds::Cell Cell; + typedef typename Tds::Facet Facet; + typedef typename Tds::Edge Edge; + + typedef typename Tds::size_type size_type; + typedef typename Tds::difference_type difference_type; + + typedef typename Tds::Vertex_handle Vertex_handle; + typedef typename Tds::Cell_handle Cell_handle; + + typedef typename Tds::Cell_circulator Cell_circulator; + typedef typename Tds::Facet_circulator Facet_circulator; + + // Not documented, see TDS. + typedef typename Tds::Face_circulator Face_circulator; + + typedef typename Tds::Cell_iterator Cell_iterator; + typedef typename Tds::Facet_iterator Facet_iterator; + typedef typename Tds::Edge_iterator Edge_iterator; + typedef typename Tds::Vertex_iterator Vertex_iterator; + + typedef Cell_iterator All_cells_iterator; + typedef Facet_iterator All_facets_iterator; + typedef Edge_iterator All_edges_iterator; + typedef Vertex_iterator All_vertices_iterator; + + typedef typename Tds::Simplex Simplex; +private: + // This class is used to generate the Finite_*_iterators. + class Infinite_tester + { + const Self *t; + + public: + + Infinite_tester() {} + + Infinite_tester(const Self *tr) + : t(tr) {} + + bool operator()(const Vertex_iterator & v) const + { + return t->is_infinite(v); + } + + bool operator()(const Cell_iterator & c) const + { + return t->is_infinite(c); + } + + bool operator()(const Edge_iterator & e) const + { + return t->is_infinite(*e); + } + + bool operator()(const Facet_iterator & f) const + { + return t->is_infinite(*f); + } + }; + +public: + + // We derive in order to add a conversion to handle. + class Finite_cells_iterator + : public Filter_iterator { + typedef Filter_iterator Base; + typedef Finite_cells_iterator Self; + public: + + Finite_cells_iterator() : Base() {} + Finite_cells_iterator(const Base &b) : Base(b) {} + + Self & operator++() { Base::operator++(); return *this; } + Self & operator--() { Base::operator--(); return *this; } + Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } + Self operator--(int) { Self tmp(*this); --(*this); return tmp; } + + operator Cell_handle() const { return Base::base(); } + }; + + // We derive in order to add a conversion to handle. + class Finite_vertices_iterator + : public Filter_iterator { + typedef Filter_iterator Base; + typedef Finite_vertices_iterator Self; + public: + + Finite_vertices_iterator() : Base() {} + Finite_vertices_iterator(const Base &b) : Base(b) {} + + Self & operator++() { Base::operator++(); return *this; } + Self & operator--() { Base::operator--(); return *this; } + Self operator++(int) { Self tmp(*this); ++(*this); return tmp; } + Self operator--(int) { Self tmp(*this); --(*this); return tmp; } + + operator Vertex_handle() const { return Base::base(); } + }; + + typedef Filter_iterator + Finite_edges_iterator; + typedef Filter_iterator + Finite_facets_iterator; + +private: + // Auxiliary iterators for convenience + // do not use default template argument to please VC++ + typedef Project_point Proj_point; +public: + typedef Iterator_project Point_iterator; + + typedef Point value_type; // to have a back_inserter + typedef const value_type& const_reference; + + //Tag to distinguish triangulations with weighted_points + typedef Tag_false Weighted_tag; + + + + enum Locate_type { + VERTEX=0, + EDGE, //1 + FACET, //2 + CELL, //3 + OUTSIDE_CONVEX_HULL, //4 + OUTSIDE_AFFINE_HULL };//5 + +protected: + Tds _tds; + GT _gt; + Vertex_handle infinite; //infinite vertex + + Comparison_result + compare_xyz(const Point &p, const Point &q) const + { + return geom_traits().compare_xyz_3_object()(p, q); + } + + bool + equal(const Point &p, const Point &q) const + { + return compare_xyz(p, q) == EQUAL; + } + + Orientation + orientation(const Point &p, const Point &q, + const Point &r, const Point &s) const + { + return geom_traits().orientation_3_object()(p, q, r, s); + } + + bool + coplanar(const Point &p, const Point &q, + const Point &r, const Point &s) const + { + return orientation(p, q, r, s) == COPLANAR; + } + + Orientation + coplanar_orientation(const Point &p, const Point &q, const Point &r) const + { + return geom_traits().coplanar_orientation_3_object()(p, q, r); + } + + bool + collinear(const Point &p, const Point &q, const Point &r) const + { + return coplanar_orientation(p, q, r) == COLLINEAR; + } + + Segment + construct_segment(const Point &p, const Point &q) const + { + return geom_traits().construct_segment_3_object()(p, q); + } + + Triangle + construct_triangle(const Point &p, const Point &q, const Point &r) const + { + return geom_traits().construct_triangle_3_object()(p, q, r); + } + + Tetrahedron + construct_tetrahedron(const Point &p, const Point &q, + const Point &r, const Point &s) const + { + return geom_traits().construct_tetrahedron_3_object()(p, q, r, s); + } + + enum COLLINEAR_POSITION {BEFORE, SOURCE, MIDDLE, TARGET, AFTER}; + + COLLINEAR_POSITION + collinear_position(const Point &s, const Point &p, const Point &t) const + // (s,t) defines a line, p is on that line. + // Depending on the position of p wrt s and t, returns : + // --------------- s ---------------- t -------------- + // BEFORE SOURCE MIDDLE TARGET AFTER + { + CGAL_triangulation_precondition(!equal(s, t)); + CGAL_triangulation_precondition(collinear(s, p, t)); + + Comparison_result ps = compare_xyz(p, s); + if (ps == EQUAL) + return SOURCE; + Comparison_result st = compare_xyz(s, t); + if (ps == st) + return BEFORE; + Comparison_result pt = compare_xyz(p, t); + if (pt == EQUAL) + return TARGET; + if (pt == st) + return MIDDLE; + return AFTER; + } + + void init_tds() + { + infinite = _tds.insert_increase_dimension(); + } + +public: + + // CONSTRUCTORS + Triangulation_3(const GT & gt = GT()) + : _tds(), _gt(gt) + { + init_tds(); + } + + // copy constructor duplicates vertices and cells + Triangulation_3(const Triangulation_3 & tr) + : _gt(tr._gt) + { + infinite = _tds.copy_tds(tr._tds, tr.infinite); + CGAL_triangulation_expensive_postcondition(*this == tr); + } + + template < typename InputIterator > + Triangulation_3(InputIterator first, InputIterator last, + const GT & gt = GT()) + : _gt(gt) + { + init_tds(); + insert(first, last); + } + + void clear() + { + _tds.clear(); + init_tds(); + } + + Triangulation_3 & operator=(Triangulation_3 tr) + { + // The triangulation passed as argument has been copied, + // because the parameter tr is passed by value. Then the following + // swap consumes the *copy*. The original triangulation is left + // untouched. + swap(tr); + return *this; + } + + // HELPING FUNCTIONS + + void swap(Triangulation_3 &tr) + { + std::swap(tr._gt, _gt); + std::swap(tr.infinite, infinite); + _tds.swap(tr._tds); + } + + //ACCESS FUNCTIONS + const GT & geom_traits() const + { return _gt;} + + const Tds & tds() const + { return _tds;} + + Tds & tds() + { return _tds;} + + int dimension() const + { return _tds.dimension();} + + size_type number_of_finite_cells() const; + + size_type number_of_cells() const; + + size_type number_of_finite_facets() const; + + size_type number_of_facets() const; + + size_type number_of_finite_edges() const; + + size_type number_of_edges() const; + + size_type number_of_vertices() const // number of finite vertices + {return _tds.number_of_vertices()-1;} + + Vertex_handle infinite_vertex() const + { return infinite; } + + Cell_handle infinite_cell() const + { + CGAL_triangulation_assertion(infinite_vertex()->cell()-> + has_vertex(infinite_vertex())); + return infinite_vertex()->cell(); + } + + // GEOMETRIC ACCESS FUNCTIONS + + Tetrahedron tetrahedron(const Cell_handle c) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + CGAL_triangulation_precondition( ! is_infinite(c) ); + return construct_tetrahedron(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point()); + } + + Triangle triangle(const Cell_handle c, int i) const; + + Triangle triangle(const Facet & f) const + { return triangle(f.first, f.second); } + + Segment segment(const Cell_handle c, int i, int j) const; + + Segment segment(const Edge & e) const + { return segment(e.first,e.second,e.third); } + + const Point & point(Cell_handle c, int i) const { + CGAL_triangulation_precondition( dimension() >= 0 ); + CGAL_triangulation_precondition( i >= 0 && i <= dimension() ); + CGAL_triangulation_precondition( ! is_infinite(c->vertex(i)) ); + return c->vertex(i)->point(); + } + + const Point & point(Vertex_handle v) const { + CGAL_triangulation_precondition( dimension() >= 0 ); + CGAL_triangulation_precondition( ! is_infinite(v) ); + return v->point(); + } + + // TEST IF INFINITE FEATURES + bool is_infinite(const Vertex_handle v) const + { return v == infinite_vertex(); } + + bool is_infinite(const Cell_handle c) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return c->has_vertex(infinite_vertex()); + } + + bool is_infinite(const Cell_handle c, int i) const; + + bool is_infinite(const Facet & f) const + { return is_infinite(f.first,f.second); } + + bool is_infinite(const Cell_handle c, int i, int j) const; + + bool is_infinite(const Edge & e) const + { return is_infinite(e.first,e.second,e.third); } + + + //QUERIES + + bool is_vertex(const Point & p, Vertex_handle & v) const; + + bool is_vertex(Vertex_handle v) const; + bool is_edge(Vertex_handle u, Vertex_handle v, + Cell_handle & c, int & i, int & j) const; + bool is_facet(Vertex_handle u, Vertex_handle v, Vertex_handle w, + Cell_handle & c, int & i, int & j, int & k) const; + bool is_cell(Cell_handle c) const; + bool is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const; + bool is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle t, + Cell_handle & c) const; + + bool has_vertex(const Facet & f, Vertex_handle v, int & j) const; + bool has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const; + bool has_vertex(const Facet & f, Vertex_handle v) const; + bool has_vertex(Cell_handle c, int i, Vertex_handle v) const; + + bool are_equal(Cell_handle c, int i, Cell_handle n, int j) const; + bool are_equal(const Facet & f, const Facet & g) const; + bool are_equal(const Facet & f, Cell_handle n, int j) const; + +#ifdef CGAL_NO_STRUCTURAL_FILTERING + Cell_handle + locate(const Point & p, + Locate_type & lt, int & li, int & lj, + Cell_handle start = Cell_handle()) const; +#else // no CGAL_NO_STRUCTURAL_FILTERING +# ifndef CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS +# define CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS 2500 +# endif // no CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS + + +protected: + Cell_handle + inexact_locate(const Point& p, + Cell_handle start, + int max_num_cells = CGAL_T3_STRUCTURAL_FILTERING_MAX_VISITED_CELLS) const; + + Cell_handle + exact_locate(const Point& p, + Locate_type& lt, + int& li, int & lj, + Cell_handle start) const; + + Cell_handle + generic_locate(const Point& p, + Locate_type& lt, + int& li, int & lj, + Cell_handle start, + internal::Structural_filtering_3_tag) const { + return exact_locate(p, lt, li, lj, inexact_locate(p, start)); + } + + Cell_handle + generic_locate(const Point& p, + Locate_type& lt, + int& li, int & lj, + Cell_handle start, + internal::No_structural_filtering_3_tag) const { + return exact_locate(p, lt, li, lj, start); + } + + Orientation + inexact_orientation(const Point &p, const Point &q, + const Point &r, const Point &s) const + { + const double px = to_double(p.x()); + const double py = to_double(p.y()); + const double pz = to_double(p.z()); + const double qx = to_double(q.x()); + const double qy = to_double(q.y()); + const double qz = to_double(q.z()); + const double rx = to_double(r.x()); + const double ry = to_double(r.y()); + const double rz = to_double(r.z()); + const double sx = to_double(s.x()); + const double sy = to_double(s.y()); + const double sz = to_double(s.z()); + + const double pqx = qx - px; + const double pqy = qy - py; + const double pqz = qz - pz; + const double prx = rx - px; + const double pry = ry - py; + const double prz = rz - pz; + const double psx = sx - px; + const double psy = sy - py; + const double psz = sz - pz; + + const double det = determinant(pqx, pqy, pqz, + prx, pry, prz, + psx, psy, psz); + if (det > 0) return POSITIVE; + if (det < 0) return NEGATIVE; + return ZERO; + } + +public: + + Cell_handle + locate(const Point & p, + Locate_type & lt, int & li, int & lj, + Cell_handle start = Cell_handle()) const + { + typedef Triangulation_structural_filtering_traits TSFT; + typedef typename internal::Structural_filtering_selector_3< + TSFT::Use_structural_filtering_tag::value >::Tag Should_filter_tag; + + return generic_locate(p, lt, li, lj, start, Should_filter_tag()); + } +#endif // no CGAL_NO_STRUCTURAL_FILTERING + + Cell_handle + locate(const Point & p, Cell_handle start = Cell_handle()) const + { + Locate_type lt; + int li, lj; + return locate( p, lt, li, lj, start); + } + + Cell_handle + locate(const Point & p, + Locate_type & lt, int & li, int & lj, Vertex_handle hint) const + { + return locate(p, lt, li, lj, hint == Vertex_handle() ? infinite_cell() : hint->cell()); + } + + Cell_handle + locate(const Point & p, Vertex_handle hint) const + { + return locate(p, hint == Vertex_handle() ? infinite_cell() : hint->cell()); + } + + // PREDICATES ON POINTS ``TEMPLATED'' by the geom traits + + Bounded_side + side_of_tetrahedron(const Point & p, + const Point & p0, + const Point & p1, + const Point & p2, + const Point & p3, + Locate_type & lt, int & i, int & j ) const; + Bounded_side + side_of_cell(const Point & p, + Cell_handle c, + Locate_type & lt, int & i, int & j) const; + Bounded_side + side_of_triangle(const Point & p, + const Point & p0, const Point & p1, const Point & p2, + Locate_type & lt, int & i, int & j ) const; + Bounded_side + side_of_facet(const Point & p, + Cell_handle c, + Locate_type & lt, int & li, int & lj) const; + Bounded_side + side_of_facet(const Point & p, + const Facet & f, + Locate_type & lt, int & li, int & lj) const + { + CGAL_triangulation_precondition( f.second == 3 ); + return side_of_facet(p, f.first, lt, li, lj); + } + Bounded_side + side_of_segment(const Point & p, + const Point & p0, const Point & p1, + Locate_type & lt, int & i ) const; + Bounded_side + side_of_edge(const Point & p, + Cell_handle c, + Locate_type & lt, int & li) const; + Bounded_side + side_of_edge(const Point & p, + const Edge & e, + Locate_type & lt, int & li) const + { + CGAL_triangulation_precondition( e.second == 0 ); + CGAL_triangulation_precondition( e.third == 1 ); + return side_of_edge(p, e.first, lt, li); + } + + // Functions forwarded from TDS. + int mirror_index(Cell_handle c, int i) const + { return _tds.mirror_index(c, i); } + + Vertex_handle mirror_vertex(Cell_handle c, int i) const + { return _tds.mirror_vertex(c, i); } + + Facet mirror_facet(Facet f) const + { return _tds.mirror_facet(f);} + + // MODIFIERS + bool flip(const Facet &f) + // returns false if the facet is not flippable + // true other wise and + // flips facet i of cell c + // c will be replaced by one of the new cells + { + return flip( f.first, f.second); + } + bool flip(Cell_handle c, int i); + void flip_flippable(const Facet &f) + { + flip_flippable( f.first, f.second); + } + void flip_flippable(Cell_handle c, int i); + bool flip(const Edge &e) + // returns false if the edge is not flippable + // true otherwise and + // flips edge i,j of cell c + // c will be deleted + { + return flip( e.first, e.second, e.third ); + } + bool flip(Cell_handle c, int i, int j); + void flip_flippable(const Edge &e) + { + flip_flippable( e.first, e.second, e.third ); + } + void flip_flippable(Cell_handle c, int i, int j); + + //INSERTION + + Vertex_handle insert(const Point & p, Vertex_handle hint) + { + return insert(p, hint == Vertex_handle() ? infinite_cell() : hint->cell()); + } + Vertex_handle insert(const Point & p, Cell_handle start = Cell_handle()); + Vertex_handle insert(const Point & p, Locate_type lt, Cell_handle c, + int li, int lj); + +//protected: // internal methods + + template + Vertex_handle insert_and_give_new_cells(const Point &p, + OutputItCells fit, + Cell_handle start = Cell_handle() ); + + template + Vertex_handle insert_and_give_new_cells(const Point& p, + OutputItCells fit, + Vertex_handle hint); + + template + Vertex_handle insert_and_give_new_cells(const Point& p, + Locate_type lt, + Cell_handle c, int li, int lj, + OutputItCells fit); + + template < class Conflict_tester, class Hidden_points_visitor > + inline Vertex_handle insert_in_conflict(const Point & p, + Locate_type lt, + Cell_handle c, int li, int lj, + const Conflict_tester &tester, + Hidden_points_visitor &hider); + + template < class InputIterator > + std::ptrdiff_t insert(InputIterator first, InputIterator last) + { + size_type n = number_of_vertices(); + + std::vector points (first, last); + spatial_sort (points.begin(), points.end(), geom_traits()); + + Vertex_handle hint; + for (typename std::vector::const_iterator p = points.begin(), end = points.end(); + p != end; ++p) + hint = insert(*p, hint); + + return number_of_vertices() - n; + } + + Vertex_handle + insert_in_cell(const Point & p, Cell_handle c); + + Vertex_handle + insert_in_facet(const Point & p, Cell_handle c, int i); + + Vertex_handle + insert_in_facet(const Point & p, const Facet & f) + { + return insert_in_facet(p, f.first, f.second); + } + + Vertex_handle + insert_in_edge(const Point & p, Cell_handle c, int i, int j); + + Vertex_handle + insert_in_edge(const Point & p, const Edge & e) + { + return insert_in_edge(p, e.first, e.second, e.third); + } + + Vertex_handle + insert_outside_convex_hull(const Point & p, Cell_handle c); + + Vertex_handle + insert_outside_affine_hull(const Point & p); + + template + Vertex_handle + insert_in_hole(const Point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i) + { + // Some geometric preconditions should be tested... + Vertex_handle v = _tds.insert_in_hole(cell_begin, cell_end, begin, i); + v->set_point(p); + return v; + } + + template + Vertex_handle + insert_in_hole(const Point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv) + { + // Some geometric preconditions should be tested... + newv->set_point(p); + return _tds.insert_in_hole(cell_begin, cell_end, begin, i, newv); + } + + // Internal function, cells should already be marked. + template + Vertex_handle + _insert_in_hole(const Point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i) + { + // Some geometric preconditions should be tested... + Vertex_handle v = _tds._insert_in_hole(cell_begin, cell_end, begin, i); + v->set_point(p); + return v; + } + + // Internal function, cells should already be marked. + template + Vertex_handle + _insert_in_hole(const Point & p, CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, Vertex_handle newv) + { + // Some geometric preconditions should be tested... + newv->set_point(p); + return _tds._insert_in_hole(cell_begin, cell_end, begin, i, newv); + } + +protected: + + template < class InputIterator > + bool does_repeat_in_range(InputIterator first, InputIterator beyond) const; + + template < class InputIterator > + bool infinite_vertex_in_range(InputIterator first, InputIterator beyond) const; + + // - c is the current cell, which must be in conflict. + // - tester is the function object that tests if a cell is in conflict. + template < + class Conflict_test, + class OutputIteratorBoundaryFacets, + class OutputIteratorCells, + class OutputIteratorInternalFacets> + Triple + find_conflicts(Cell_handle d, const Conflict_test &tester, + Triple it) const + { + CGAL_triangulation_precondition( dimension()>=2 ); + CGAL_triangulation_precondition( tester(d) ); + + std::stack cell_stack; + cell_stack.push(d); + d->tds_data().mark_in_conflict(); + *it.second++ = d; + + do { + Cell_handle c = cell_stack.top(); + cell_stack.pop(); + + for (int i=0; ineighbor(i); + if (test->tds_data().is_in_conflict()) { + if (c < test) + *it.third++ = Facet(c, i); // Internal facet. + continue; // test was already in conflict. + } + if (test->tds_data().is_clear()) { + if (tester(test)) { + if (c < test) + *it.third++ = Facet(c, i); // Internal facet. + + cell_stack.push(test); + test->tds_data().mark_in_conflict(); + *it.second++ = test; + continue; + } + test->tds_data().mark_on_boundary(); + } + *it.first++ = Facet(c, i); + } + } while (!cell_stack.empty()); + return it; + } + + // This one takes a function object to recursively determine the cells in + // conflict, then calls _tds._insert_in_hole(). + template < class Conflict_test > + Vertex_handle + insert_conflict(Cell_handle c, const Conflict_test &tester) + { + CGAL_triangulation_precondition( dimension() >= 2 ); + CGAL_triangulation_precondition( c != Cell_handle() ); + CGAL_triangulation_precondition( tester(c) ); + + std::vector cells; + cells.reserve(32); + + Facet facet; + + // Find the cells in conflict + switch (dimension()) { + case 3: + find_conflicts(c, tester, make_triple(Oneset_iterator(facet), + std::back_inserter(cells), + Emptyset_iterator())); + break; + case 2: + find_conflicts(c, tester, make_triple(Oneset_iterator(facet), + std::back_inserter(cells), + Emptyset_iterator())); + } + // Create the new cells and delete the old. + return _tds._insert_in_hole(cells.begin(), cells.end(), + facet.first, facet.second); + } + +private: + // Here are the conflit tester function objects passed to + // insert_conflict_[23]() by insert_outside_convex_hull(). + class Conflict_tester_outside_convex_hull_3 + { + const Point &p; + const Self *t; + + public: + + Conflict_tester_outside_convex_hull_3(const Point &pt, const Self *tr) + : p(pt), t(tr) {} + + bool operator()(const Cell_handle c) const + { + Locate_type loc; + int i, j; + return t->side_of_cell( p, c, loc, i, j ) == ON_BOUNDED_SIDE; + } + }; + + class Conflict_tester_outside_convex_hull_2 + { + const Point &p; + const Self *t; + + public: + + Conflict_tester_outside_convex_hull_2(const Point &pt, const Self *tr) + : p(pt), t(tr) {} + + bool operator()(const Cell_handle c) const + { + Locate_type loc; + int i, j; + return t->side_of_facet( p, c, loc, i, j ) == ON_BOUNDED_SIDE; + } + }; + +protected: + + // no point being private, we might need to test + // whether a displacement decreases dimension on + // others inherited triangulations + bool test_dim_down(Vertex_handle v) const; + + // REMOVAL + template < class VertexRemover > + void remove(Vertex_handle v, VertexRemover &remover); + + template < class VertexRemover, class OutputItCells > + void remove_and_give_new_cells(Vertex_handle v, VertexRemover &remover, + OutputItCells fit); + + // This function removes a batch of points at once. + // If points are grouped in cluster, the performance is increased + // compared to removing one by one. + // For now, this function is only guaranteed for Delaunay triangulations (or Regular as Delaunay). + // By doing these kind of remove followed by inserting the cluster, + // we achieve fast relocations for a batch of points (in a Delaunay triangulation). + template < class InputIterator, class VertexRemover > + size_type remove(InputIterator first, InputIterator beyond, + VertexRemover &remover); + enum REMOVE_VERTEX_STATE {CLEAR, TO_REMOVE, PROCESSED, EXTREMITY}; + + // MOVE + template < class VertexRemover, class VertexInserter > + Vertex_handle move_if_no_collision(Vertex_handle v, const Point &p, + VertexRemover &remover, + VertexInserter &inserter); + + template < class VertexRemover, class VertexInserter > + Vertex_handle move(Vertex_handle v, const Point &p, + VertexRemover &remover, VertexInserter &inserter); + + // move and give new cells + template < class VertexRemover, class VertexInserter, class OutputItCells > + Vertex_handle move_if_no_collision_and_give_new_cells( + Vertex_handle v, const Point &p, VertexRemover &remover, + VertexInserter &inserter, OutputItCells fit); + + // This is a function better suited for tds + // but because it is not required in the model of tds + // at this time, it should be implemented here. + void flip_2D(Cell_handle f, int i) + { + CGAL_triangulation_precondition( dimension()==2); + Cell_handle n = f->neighbor(i); + int ni = this->_tds.mirror_index(f,i); //ni = n->index(f); + + int cwi = (i+2)%3; + int ccwi = (i+1)%3; + int cwni = (ni+2)%3; + int ccwni = (ni+1)%3; + + Vertex_handle v_cw = f->vertex(cwi); + Vertex_handle v_ccw = f->vertex(ccwi); + + // bl == bottom left, tr == top right + Cell_handle tr = f->neighbor(ccwi); + int tri = this->_tds.mirror_index(f,ccwi); + Cell_handle bl = n->neighbor(ccwni); + int bli = this->_tds.mirror_index(n,ccwni); + + f->set_vertex(cwi, n->vertex(ni)); + n->set_vertex(cwni, f->vertex(i)); + + // update the neighborhood relations + this->_tds.set_adjacency(f, i, bl, bli); + this->_tds.set_adjacency(f, ccwi, n, ccwni); + this->_tds.set_adjacency(n, ni, tr, tri); + + if(v_cw->cell() == f) { + v_cw->set_cell(n); + } + + if(v_ccw->cell() == n) { + v_ccw->set_cell(f); + } + } + + template < class VertexRemover, class VertexInserter > + void restore_edges_after_decrease_dimension(Vertex_handle v, + VertexRemover &remover, VertexInserter &inserter) + { + + Cell_handle fkstart = v->cell(); + Cell_handle start = fkstart->neighbor(fkstart->index(v)); + + std::list hole; + make_hole_2D(v, hole, remover); + fill_hole_2D(hole, remover); + // make hole here will work if the link of v is a valid triangulation + // the aim here is Delaunay triangulations + // to make it more general one could have an internal function here + // to remove v without touching its handle + + // This insert must be from Delaunay (or the particular trian.) + // not the basic Triangulation_3. + // Here we correct the recent triangulation (with decreased dimension) formed + // in particular here a 2D (from 3D to 2D displacement) + Vertex_handle inserted = inserter.insert(v->point(), start); + + // fixing pointer + Cell_handle fc = inserted->cell(), done(fc); + std::vector faces_pt; + faces_pt.reserve(16); + do { + faces_pt.push_back(fc); + fc = fc->neighbor((fc->index(inserted) + 1)%3); + } while(fc != done); + std::size_t ss = faces_pt.size(); + for(std::size_t k=0; kindex(inserted); + f->set_vertex(i, v); + } + v->set_cell(inserted->cell()); + + tds().delete_vertex(inserted); + } + +private: + typedef Facet Edge_2D; + typedef Triple Vertex_triple; + + Vertex_triple make_vertex_triple(const Facet& f) const; + void make_canonical(Vertex_triple& t) const; + + template < class VertexRemover > + VertexRemover& make_hole_2D(Vertex_handle v, std::list & hole, + VertexRemover &remover); + template < class VertexRemover > + VertexRemover& make_hole_2D(Vertex_handle v, std::list & hole, + VertexRemover &remover, + std::set &cells_set); + + template < class VertexRemover > + void fill_hole_2D(std::list & hole, VertexRemover &remover); + + void make_hole_3D( Vertex_handle v, std::map& outer_map, + std::vector & hole); + + template < class VertexRemover > + VertexRemover& remove_dim_down(Vertex_handle v, VertexRemover &remover); + template < class VertexRemover > + VertexRemover& remove_1D(Vertex_handle v, VertexRemover &remover); + template < class VertexRemover > + VertexRemover& remove_2D(Vertex_handle v, VertexRemover &remover); + template < class VertexRemover > + VertexRemover& remove_3D(Vertex_handle v, VertexRemover &remover); + + template < class VertexRemover, class OutputItCells > + VertexRemover& remove_dim_down(Vertex_handle v, VertexRemover &remover, + OutputItCells fit); + + template < class VertexRemover, class OutputItCells > + VertexRemover& remove_1D(Vertex_handle v, VertexRemover &remover, + OutputItCells fit); + + template < class VertexRemover, class OutputItCells > + VertexRemover& remove_2D(Vertex_handle v, VertexRemover &remover, + OutputItCells fit); + + template < class VertexRemover, class OutputItCells > + VertexRemover& remove_3D(Vertex_handle v, VertexRemover &remover, + OutputItCells fit); + + template < class VertexRemover, class OutputItCells > + void fill_hole_2D(std::list & hole, VertexRemover &remover, + OutputItCells fit); + + // They access "Self", so need to be friend. + friend class Conflict_tester_outside_convex_hull_3; + friend class Conflict_tester_outside_convex_hull_2; + friend class Infinite_tester; + friend class Finite_vertices_iterator; + friend class Finite_cells_iterator; + + // remove cluster + template < class InputIterator > + void _mark_vertices_to_remove(InputIterator first, InputIterator beyond, + std::map &vstates) const + { + while (first != beyond) vstates[*first++] = TO_REMOVE; + } + + bool _test_dim_down_cluster( + std::map &vstates) const + // tests whether removing the cluster of vertices + // marked as "to remove", decreases the dimension of the triangulation + { + CGAL_triangulation_precondition( dimension() == 3 ); + int k=0; + Vertex_handle v[4]; + for (Finite_vertices_iterator fit = finite_vertices_begin(); + fit != finite_vertices_end(); ++fit ) { + if(vstates[fit] == TO_REMOVE) continue; + v[k++] = fit; + if(k == 4) + { + if (!coplanar(v[0]->point(), v[1]->point(), + v[2]->point(), v[3]->point())) return false; + k--; + } + } + return k < 4; + } + + template < class InputIterator, class VertexRemover > + bool + _remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover &remover, + std::map &vstates); + + void _make_big_hole_3D(Vertex_handle v, + std::map& outer_map, + std::vector & hole, + std::vector & vertices, + std::map &vstates); + +public: + + //TRAVERSING : ITERATORS AND CIRCULATORS + Finite_cells_iterator finite_cells_begin() const + { + if ( dimension() < 3 ) + return finite_cells_end(); + return CGAL::filter_iterator(cells_end(), Infinite_tester(this), + cells_begin()); + } + Finite_cells_iterator finite_cells_end() const + { + return CGAL::filter_iterator(cells_end(), Infinite_tester(this)); + } + + Cell_iterator cells_begin() const + { + return _tds.cells_begin(); + } + Cell_iterator cells_end() const + { + return _tds.cells_end(); + } + + All_cells_iterator all_cells_begin() const + { + return _tds.cells_begin(); + } + All_cells_iterator all_cells_end() const + { + return _tds.cells_end(); + } + + Finite_vertices_iterator finite_vertices_begin() const + { + if ( number_of_vertices() <= 0 ) + return finite_vertices_end(); + return CGAL::filter_iterator(vertices_end(), Infinite_tester(this), + vertices_begin()); + } + Finite_vertices_iterator finite_vertices_end() const + { + return CGAL::filter_iterator(vertices_end(), Infinite_tester(this)); + } + + Vertex_iterator vertices_begin() const + { + return _tds.vertices_begin(); + } + Vertex_iterator vertices_end() const + { + return _tds.vertices_end(); + } + + All_vertices_iterator all_vertices_begin() const + { + return _tds.vertices_begin(); + } + All_vertices_iterator all_vertices_end() const + { + return _tds.vertices_end(); + } + + Finite_edges_iterator finite_edges_begin() const + { + if ( dimension() < 1 ) + return finite_edges_end(); + return CGAL::filter_iterator(edges_end(), Infinite_tester(this), + edges_begin()); + } + Finite_edges_iterator finite_edges_end() const + { + return CGAL::filter_iterator(edges_end(), Infinite_tester(this)); + } + + Edge_iterator edges_begin() const + { + return _tds.edges_begin(); + } + Edge_iterator edges_end() const + { + return _tds.edges_end(); + } + + All_edges_iterator all_edges_begin() const + { + return _tds.edges_begin(); + } + All_edges_iterator all_edges_end() const + { + return _tds.edges_end(); + } + + Finite_facets_iterator finite_facets_begin() const + { + if ( dimension() < 2 ) + return finite_facets_end(); + return CGAL::filter_iterator(facets_end(), Infinite_tester(this), + facets_begin()); + } + Finite_facets_iterator finite_facets_end() const + { + return CGAL::filter_iterator(facets_end(), Infinite_tester(this)); + } + + Facet_iterator facets_begin() const + { + return _tds.facets_begin(); + } + Facet_iterator facets_end() const + { + return _tds.facets_end(); + } + + All_facets_iterator all_facets_begin() const + { + return _tds.facets_begin(); + } + All_facets_iterator all_facets_end() const + { + return _tds.facets_end(); + } + + Point_iterator points_begin() const + { + return Point_iterator(finite_vertices_begin()); + } + Point_iterator points_end() const + { + return Point_iterator(finite_vertices_end()); + } + + // cells around an edge + Cell_circulator incident_cells(const Edge & e) const + { + return _tds.incident_cells(e); + } + Cell_circulator incident_cells(Cell_handle c, int i, int j) const + { + return _tds.incident_cells(c, i, j); + } + Cell_circulator incident_cells(const Edge & e, Cell_handle start) const + { + return _tds.incident_cells(e, start); + } + Cell_circulator incident_cells(Cell_handle c, int i, int j, + Cell_handle start) const + { + return _tds.incident_cells(c, i, j, start); + } + + // facets around an edge + Facet_circulator incident_facets(const Edge & e) const + { + return _tds.incident_facets(e); + } + Facet_circulator incident_facets(Cell_handle c, int i, int j) const + { + return _tds.incident_facets(c, i, j); + } + Facet_circulator incident_facets(const Edge & e, const Facet & start) const + { + return _tds.incident_facets(e, start); + } + Facet_circulator incident_facets(Cell_handle c, int i, int j, + const Facet & start) const + { + return _tds.incident_facets(c, i, j, start); + } + Facet_circulator incident_facets(const Edge & e, + Cell_handle start, int f) const + { + return _tds.incident_facets(e, start, f); + } + Facet_circulator incident_facets(Cell_handle c, int i, int j, + Cell_handle start, int f) const + { + return _tds.incident_facets(c, i, j, start, f); + } + + // around a vertex + class Finite_filter { + const Self* t; + public: + Finite_filter(const Self* _t): t(_t) {} + template + bool operator() (const T& e) const { + return t->is_infinite(e); + } + }; + + class Finite_filter_2D { + const Self* t; + public: + Finite_filter_2D(const Self* _t): t(_t) {} + + template + bool operator() (const T& e) const { + return t->is_infinite(e); + } + + bool operator() (const Cell_handle c) { + return t->is_infinite(c, 3); + } + }; + + template + OutputIterator + incident_cells(Vertex_handle v, OutputIterator cells) const + { + return _tds.incident_cells(v, cells); + } + + template + OutputIterator + finite_incident_cells(Vertex_handle v, OutputIterator cells) const + { + if(dimension() == 2) + return _tds.incident_cells(v, cells, Finite_filter_2D(this)); + return _tds.incident_cells(v, cells, Finite_filter(this)); + } + + template + OutputIterator + incident_facets(Vertex_handle v, OutputIterator facets) const + { + return _tds.incident_facets(v, facets); + } + + template + OutputIterator + finite_incident_facets(Vertex_handle v, OutputIterator facets) const + { + return _tds.incident_facets(v, facets, Finite_filter(this)); + } + + // old name (up to CGAL 3.4) + // kept for backwards compatibility but not documented + template + OutputIterator + incident_vertices(Vertex_handle v, OutputIterator vertices) const + { + return _tds.adjacent_vertices(v, vertices); + } + + // correct name + template + OutputIterator + adjacent_vertices(Vertex_handle v, OutputIterator vertices) const + { + return _tds.adjacent_vertices(v, vertices); + } + + // old name (up to CGAL 3.4) + // kept for backwards compatibility but not documented + template + OutputIterator + finite_incident_vertices(Vertex_handle v, OutputIterator vertices) const + { + return _tds.adjacent_vertices(v, vertices, Finite_filter(this)); + } + + // correct name + template + OutputIterator + finite_adjacent_vertices(Vertex_handle v, OutputIterator vertices) const + { + return _tds.adjacent_vertices(v, vertices, Finite_filter(this)); + } + + template + OutputIterator + incident_edges(Vertex_handle v, OutputIterator edges) const + { + return _tds.incident_edges(v, edges); + } + + template + OutputIterator + finite_incident_edges(Vertex_handle v, OutputIterator edges) const + { + return _tds.incident_edges(v, edges, Finite_filter(this)); + } + + size_type degree(Vertex_handle v) const + { + return _tds.degree(v); + } + + + + // CHECKING + bool is_valid(bool verbose = false, int level = 0) const; + + bool is_valid(Cell_handle c, bool verbose = false, int level = 0) const; + + bool is_valid_finite(Cell_handle c, bool verbose = false, int level=0) const; +}; + +template < class GT, class Tds > +std::istream & +operator>> (std::istream& is, Triangulation_3 &tr) + // reads + // the dimension + // the number of finite vertices + // the non combinatorial information on vertices (point, etc) + // the number of cells + // the cells by the indices of their vertices in the preceding list + // of vertices, plus the non combinatorial information on each cell + // the neighbors of each cell by their index in the preceding list of cells + // when dimension < 3 : the same with faces of maximal dimension +{ + typedef Triangulation_3 Triangulation; + typedef typename Triangulation::Vertex_handle Vertex_handle; + typedef typename Triangulation::Cell_handle Cell_handle; + + tr._tds.clear(); // infinite vertex deleted + tr.infinite = tr._tds.create_vertex(); + + std::size_t n; + int d; + if(is_ascii(is)) + is >> d >> n; + else { + read(is, d); + read(is, n); + } + if(!is) return is; + tr._tds.set_dimension(d); + + std::map< std::size_t, Vertex_handle > V; + V[0] = tr.infinite_vertex(); + // the infinite vertex is numbered 0 + + for (std::size_t i=1; i <= n; i++) { + V[i] = tr._tds.create_vertex(); + if(!(is >> *V[i])) return is; + } + + std::map< std::size_t, Cell_handle > C; + + std::size_t m; + tr._tds.read_cells(is, V, m, C); + + for (std::size_t j=0 ; j < m; j++) + if(!(is >> *(C[j]))) return is; + + CGAL_triangulation_assertion( tr.is_valid(false) ); + return is; +} + +template < class GT, class Tds > +std::ostream & +operator<< (std::ostream& os, const Triangulation_3 &tr) + // writes : + // the dimension + // the number of finite vertices + // the non combinatorial information on vertices (point, etc) + // the number of cells + // the cells by the indices of their vertices in the preceding list + // of vertices, plus the non combinatorial information on each cell + // the neighbors of each cell by their index in the preceding list of cells + // when dimension < 3 : the same with faces of maximal dimension +{ + typedef Triangulation_3 Triangulation; + typedef typename Triangulation::size_type size_type; + typedef typename Triangulation::Vertex_handle Vertex_handle; + typedef typename Triangulation::Vertex_iterator Vertex_iterator; + typedef typename Triangulation::Cell_iterator Cell_iterator; + typedef typename Triangulation::Edge_iterator Edge_iterator; + typedef typename Triangulation::Facet_iterator Facet_iterator; + + // outputs dimension and number of vertices + size_type n = tr.number_of_vertices(); + if (is_ascii(os)) + os << tr.dimension() << std::endl << n << std::endl; + else + { + write(os, tr.dimension()); + write(os, n); + } + + if (n == 0) + return os; + + std::vector TV(n+1); + size_type i = 0; + + // write the vertices + + for (Vertex_iterator it = tr.vertices_begin(), end = tr.vertices_end(); + it != end; ++it) + TV[i++] = it; + + CGAL_triangulation_assertion( i == n+1 ); + CGAL_triangulation_assertion( tr.is_infinite(TV[0]) ); + + std::map V; + + V[tr.infinite_vertex()] = 0; + for (i=1; i <= n; i++) { + os << *TV[i]; + V[TV[i]] = i; + if (is_ascii(os)) + os << std::endl; + } + + // asks the tds for the combinatorial information + tr.tds().print_cells(os, V); + + + // write the non combinatorial information on the cells + // using the << operator of Cell + // works because the iterator of the tds traverses the cells in the + // same order as the iterator of the triangulation + switch ( tr.dimension() ) { + case 3: + { + for(Cell_iterator it = tr.cells_begin(), end = tr.cells_end(); it != end; ++it) { + os << *it; // other information + if(is_ascii(os)) + os << std::endl; + } + break; + } + case 2: + { + for(Facet_iterator it = tr.facets_begin(), end = tr.facets_end(); it != end; ++it) { + os << *((*it).first); // other information + if(is_ascii(os)) + os << std::endl; + } + break; + } + case 1: + { + for(Edge_iterator it = tr.edges_begin(), end = tr.edges_end(); it != end; ++it) { + os << *((*it).first); // other information + if(is_ascii(os)) + os << std::endl; + } + break; + } + } + + + return os ; +} + +template < class GT, class Tds > +typename Triangulation_3::size_type +Triangulation_3:: +number_of_finite_cells() const +{ + if ( dimension() < 3 ) return 0; + return std::distance(finite_cells_begin(), finite_cells_end()); +} + +template < class GT, class Tds > +typename Triangulation_3::size_type +Triangulation_3:: +number_of_cells() const +{ + return _tds.number_of_cells(); +} + +template < class GT, class Tds > +typename Triangulation_3::size_type +Triangulation_3:: +number_of_finite_facets() const +{ + if ( dimension() < 2 ) return 0; + return std::distance(finite_facets_begin(), finite_facets_end()); +} + +template < class GT, class Tds > +typename Triangulation_3::size_type +Triangulation_3:: +number_of_facets() const +{ + return _tds.number_of_facets(); +} + +template < class GT, class Tds > +typename Triangulation_3::size_type +Triangulation_3:: +number_of_finite_edges() const +{ + if ( dimension() < 1 ) return 0; + return std::distance(finite_edges_begin(), finite_edges_end()); +} + +template < class GT, class Tds > +typename Triangulation_3::size_type +Triangulation_3:: +number_of_edges() const +{ + return _tds.number_of_edges(); +} + +template < class GT, class Tds > +typename Triangulation_3::Triangle +Triangulation_3:: +triangle(const Cell_handle c, int i) const +{ + CGAL_triangulation_precondition( dimension() == 2 || dimension() == 3 ); + CGAL_triangulation_precondition( (dimension() == 2 && i == 3) + || (dimension() == 3 && i >= 0 && i <= 3) ); + CGAL_triangulation_precondition( ! is_infinite(Facet(c, i)) ); + if ( (i&1)==0 ) + return construct_triangle(c->vertex( (i+2)&3 )->point(), + c->vertex( (i+1)&3 )->point(), + c->vertex( (i+3)&3 )->point()); + return construct_triangle(c->vertex( (i+1)&3 )->point(), + c->vertex( (i+2)&3 )->point(), + c->vertex( (i+3)&3 )->point()); +} + +template < class GT, class Tds > +typename Triangulation_3::Segment +Triangulation_3:: +segment(const Cell_handle c, int i, int j) const +{ + CGAL_triangulation_precondition( i != j ); + CGAL_triangulation_precondition( dimension() >= 1 && dimension() <= 3 ); + CGAL_triangulation_precondition( i >= 0 && i <= dimension() + && j >= 0 && j <= dimension() ); + CGAL_triangulation_precondition( ! is_infinite(Edge(c, i, j)) ); + return construct_segment( c->vertex(i)->point(), c->vertex(j)->point() ); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +is_infinite(const Cell_handle c, int i) const +{ + CGAL_triangulation_precondition( dimension() == 2 || dimension() == 3 ); + CGAL_triangulation_precondition( (dimension() == 2 && i == 3) + || (dimension() == 3 && i >= 0 && i <= 3) ); + return is_infinite(c->vertex(i<=0 ? 1 : 0)) || + is_infinite(c->vertex(i<=1 ? 2 : 1)) || + is_infinite(c->vertex(i<=2 ? 3 : 2)); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +is_infinite(const Cell_handle c, int i, int j) const +{ + CGAL_triangulation_precondition( i != j ); + CGAL_triangulation_precondition( dimension() >= 1 && dimension() <= 3 ); + CGAL_triangulation_precondition( + i >= 0 && i <= dimension() && j >= 0 && j <= dimension() ); + return is_infinite( c->vertex(i) ) || is_infinite( c->vertex(j) ); +} + +template < class GT, class Tds > +bool +Triangulation_3:: +is_vertex(const Point & p, Vertex_handle & v) const +{ + Locate_type lt; + int li, lj; + Cell_handle c = locate( p, lt, li, lj ); + if ( lt != VERTEX ) + return false; + v = c->vertex(li); + return true; +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +is_vertex(Vertex_handle v) const +{ + return _tds.is_vertex(v); +} + +template < class GT, class Tds > +bool +Triangulation_3:: +is_edge(Vertex_handle u, Vertex_handle v, + Cell_handle & c, int & i, int & j) const +{ + return _tds.is_edge(u, v, c, i, j); +} + +template < class GT, class Tds > +bool +Triangulation_3:: +is_facet(Vertex_handle u, Vertex_handle v, Vertex_handle w, + Cell_handle & c, int & i, int & j, int & k) const +{ + return _tds.is_facet(u, v, w, c, i, j, k); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +is_cell(Cell_handle c) const +{ + return _tds.is_cell(c); +} + +template < class GT, class Tds > +bool +Triangulation_3:: +is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const +{ + return _tds.is_cell(u, v, w, t, c, i, j, k, l); +} + +template < class GT, class Tds > +bool +Triangulation_3:: +is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle t, + Cell_handle & c) const +{ + int i,j,k,l; + return _tds.is_cell(u, v, w, t, c, i, j, k, l); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +has_vertex(const Facet & f, Vertex_handle v, int & j) const +{ + return _tds.has_vertex(f.first, f.second, v, j); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const +{ + return _tds.has_vertex(c, i, v, j); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +has_vertex(const Facet & f, Vertex_handle v) const +{ + return _tds.has_vertex(f.first, f.second, v); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +has_vertex(Cell_handle c, int i, Vertex_handle v) const +{ + return _tds.has_vertex(c, i, v); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +are_equal(Cell_handle c, int i, Cell_handle n, int j) const +{ + return _tds.are_equal(c, i, n, j); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +are_equal(const Facet & f, const Facet & g) const +{ + return _tds.are_equal(f.first, f.second, g.first, g.second); +} + +template < class GT, class Tds > +inline +bool +Triangulation_3:: +are_equal(const Facet & f, Cell_handle n, int j) const +{ + return _tds.are_equal(f.first, f.second, n, j); +} + +template < class GT, class Tds > +typename Triangulation_3::Cell_handle +Triangulation_3:: +#ifdef CGAL_NO_STRUCTURAL_FILTERING +locate(const Point & p, Locate_type & lt, int & li, int & lj, + Cell_handle start ) const +#else +exact_locate(const Point & p, Locate_type & lt, int & li, int & lj, + Cell_handle start ) const +#endif + // returns the (finite or infinite) cell p lies in + // starts at cell "start" + // if lt == OUTSIDE_CONVEX_HULL, li is the + // index of a facet separating p from the rest of the triangulation + // in dimension 2 : + // returns a facet (Cell_handle,li) if lt == FACET + // returns an edge (Cell_handle,li,lj) if lt == EDGE + // returns a vertex (Cell_handle,li) if lt == VERTEX + // if lt == OUTSIDE_CONVEX_HULL, li, lj give the edge of c + // separating p from the rest of the triangulation + // lt = OUTSIDE_AFFINE_HULL if p is not coplanar with the triangulation +{ + CGAL_triangulation_expensive_assertion(start == Cell_handle() || tds().is_simplex(start) ); + + if ( dimension() >= 1 ) { + // Make sure we continue from here with a finite cell. + if ( start == Cell_handle() ) + start = infinite_cell(); + + int ind_inf; + if ( start->has_vertex(infinite, ind_inf) ) + start = start->neighbor(ind_inf); + } + + boost::rand48 rng; + + switch (dimension()) { + case 3: + { + CGAL_triangulation_precondition( start != Cell_handle() ); + CGAL_triangulation_precondition( ! start->has_vertex(infinite) ); + + // We implement the remembering visibility/stochastic walk. + + // Remembers the previous cell to avoid useless orientation tests. + Cell_handle previous = Cell_handle(); + Cell_handle c = start; + + // Stores the results of the 4 orientation tests. It will be used + // at the end to decide if p lies on a face/edge/vertex/interior. + Orientation o[4]; + + boost::uniform_smallint<> four(0, 3); + boost::variate_generator > die4(rng, four); + + // Now treat the cell c. + try_next_cell: + + // We know that the 4 vertices of c are positively oriented. + // So, in order to test if p is seen outside from one of c's facets, + // we just replace the corresponding point by p in the orientation + // test. We do this using the array below. + const Point* pts[4] = { &(c->vertex(0)->point()), + &(c->vertex(1)->point()), + &(c->vertex(2)->point()), + &(c->vertex(3)->point()) }; + + // For the remembering stochastic walk, + // we need to start trying with a random index : + int i = die4(); + // For the remembering visibility walk (Delaunay and Regular only), we don't : + // int i = 0; + + for (int j=0; j != 4; ++j, i = (i+1)&3) { + Cell_handle next = c->neighbor(i); + if (previous == next) { + o[i] = POSITIVE; + continue; + } + // We temporarily put p at i's place in pts. + const Point* backup = pts[i]; + pts[i] = &p; + o[i] = orientation(*pts[0], *pts[1], *pts[2], *pts[3]); + if ( o[i] != NEGATIVE ) { + pts[i] = backup; + continue; + } + if ( next->has_vertex(infinite, li) ) { + // We are outside the convex hull. + lt = OUTSIDE_CONVEX_HULL; + return next; + } + previous = c; + c = next; + goto try_next_cell; + } + + // now p is in c or on its boundary + int sum = ( o[0] == COPLANAR ) + + ( o[1] == COPLANAR ) + + ( o[2] == COPLANAR ) + + ( o[3] == COPLANAR ); + switch (sum) { + case 0: + { + lt = CELL; + break; + } + case 1: + { + lt = FACET; + li = ( o[0] == COPLANAR ) ? 0 : + ( o[1] == COPLANAR ) ? 1 : + ( o[2] == COPLANAR ) ? 2 : 3; + break; + } + case 2: + { + lt = EDGE; + li = ( o[0] != COPLANAR ) ? 0 : + ( o[1] != COPLANAR ) ? 1 : 2; + lj = ( o[li+1] != COPLANAR ) ? li+1 : + ( o[li+2] != COPLANAR ) ? li+2 : li+3; + CGAL_triangulation_assertion(collinear( p, + c->vertex( li )->point(), + c->vertex( lj )->point())); + break; + } + case 3: + { + lt = VERTEX; + li = ( o[0] != COPLANAR ) ? 0 : + ( o[1] != COPLANAR ) ? 1 : + ( o[2] != COPLANAR ) ? 2 : 3; + break; + } + } + return c; + } + case 2: + { + CGAL_triangulation_precondition( start != Cell_handle() ); + CGAL_triangulation_precondition( ! start->has_vertex(infinite) ); + Cell_handle c = start; + + boost::uniform_smallint<> three(0, 2); + boost::variate_generator > die3(rng, three); + + //first tests whether p is coplanar with the current triangulation + if ( orientation( c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + p ) != DEGENERATE ) { + lt = OUTSIDE_AFFINE_HULL; + li = 3; // only one facet in dimension 2 + return c; + } + // if p is coplanar, location in the triangulation + // only the facet numbered 3 exists in each cell + while (1) { + int inf; + if ( c->has_vertex(infinite,inf) ) { + // c must contain p in its interior + lt = OUTSIDE_CONVEX_HULL; + li = cw(inf); + lj = ccw(inf); + return c; + } + + // else c is finite + // we test its edges in a random order until we find a + // neighbor to go further + int i = die3(); + const Point & p0 = c->vertex( i )->point(); + const Point & p1 = c->vertex( ccw(i) )->point(); + const Point & p2 = c->vertex( cw(i) )->point(); + Orientation o[3]; + CGAL_triangulation_assertion(coplanar_orientation(p0,p1,p2)==POSITIVE); + o[0] = coplanar_orientation(p0,p1,p); + if ( o[0] == NEGATIVE ) { + c = c->neighbor( cw(i) ); + continue; + } + o[1] = coplanar_orientation(p1,p2,p); + if ( o[1] == NEGATIVE ) { + c = c->neighbor( i ); + continue; + } + o[2] = coplanar_orientation(p2,p0,p); + if ( o[2] == NEGATIVE ) { + c = c->neighbor( ccw(i) ); + continue; + } + + // now p is in c or on its boundary + int sum = ( o[0] == COLLINEAR ) + + ( o[1] == COLLINEAR ) + + ( o[2] == COLLINEAR ); + switch (sum) { + case 0: + { + lt = FACET; + li = 3; // useless ? + break; + } + case 1: + { + lt = EDGE; + li = ( o[0] == COLLINEAR ) ? i : + ( o[1] == COLLINEAR ) ? ccw(i) : + cw(i); + lj = ccw(li); + break; + } + case 2: + { + lt = VERTEX; + li = ( o[0] != COLLINEAR ) ? cw(i) : + ( o[1] != COLLINEAR ) ? i : + ccw(i); + break; + } + } + return c; + } + } + case 1: + { + CGAL_triangulation_precondition( start != Cell_handle() ); + CGAL_triangulation_precondition( ! start->has_vertex(infinite) ); + Cell_handle c = start; + + //first tests whether p is collinear with the current triangulation + if ( ! collinear( p, + c->vertex(0)->point(), + c->vertex(1)->point()) ) { + lt = OUTSIDE_AFFINE_HULL; + return c; + } + // if p is collinear, location : + while (1) { + if ( c->has_vertex(infinite) ) { + // c must contain p in its interior + lt = OUTSIDE_CONVEX_HULL; + return c; + } + + // else c is finite + // we test on which direction to continue the traversal + switch (collinear_position(c->vertex(0)->point(), + p, + c->vertex(1)->point()) ) { + case AFTER: + c = c->neighbor(0); + continue; + case BEFORE: + c = c->neighbor(1); + continue; + case MIDDLE: + lt = EDGE; + li = 0; + lj = 1; + return c; + case SOURCE: + lt = VERTEX; + li = 0; + return c; + case TARGET: + lt = VERTEX; + li = 1; + return c; + } + } + } + case 0: + { + Finite_vertices_iterator vit = finite_vertices_begin(); + if ( ! equal( p, vit->point() ) ) { + lt = OUTSIDE_AFFINE_HULL; + } + else { + lt = VERTEX; + li = 0; + } + return vit->cell(); + } + case -1: + { + lt = OUTSIDE_AFFINE_HULL; + return Cell_handle(); + } + default: + { + CGAL_triangulation_assertion(false); + return Cell_handle(); + } + } +} + +#ifndef CGAL_NO_STRUCTURAL_FILTERING +template +inline +typename Triangulation_3::Cell_handle +Triangulation_3:: +inexact_locate(const Point & t, Cell_handle start, int n_of_turns) const +{ + CGAL_triangulation_expensive_assertion(start == Cell_handle() || tds().is_simplex(start) ); + + if(dimension() < 3) return start; + + // Make sure we continue from here with a finite cell. + if ( start == Cell_handle() ) + start = infinite_cell(); + + int ind_inf; + if( start->has_vertex(infinite, ind_inf) ) + start = start->neighbor(ind_inf); + + CGAL_triangulation_precondition( start != Cell_handle() ); + CGAL_triangulation_precondition( ! start->has_vertex(infinite) ); + + // We implement the remembering visibility walk. + // in this phase, no need to be stochastic + + // Remembers the previous cell to avoid useless orientation tests. + Cell_handle previous = Cell_handle(); + Cell_handle c = start; + + // Now treat the cell c. + try_next_cell: + + n_of_turns--; + + // We know that the 4 vertices of c are positively oriented. + // So, in order to test if p is seen outside from one of c's facets, + // we just replace the corresponding point by p in the orientation + // test. We do this using the array below. + const Point* pts[4] = { &(c->vertex(0)->point()), + &(c->vertex(1)->point()), + &(c->vertex(2)->point()), + &(c->vertex(3)->point()) }; + + // (non-stochastic) visibility walk + for (int i=0; i != 4; ++i) { + Cell_handle next = c->neighbor(i); + if (previous == next) continue; + + // We temporarily put p at i's place in pts. + const Point* backup = pts[i]; + pts[i] = &t; + if( inexact_orientation(*pts[0], *pts[1], *pts[2], *pts[3]) != NEGATIVE) { + pts[i] = backup; + continue; + } + if(next->has_vertex(infinite)) { + // We are outside the convex hull. + return next; + } + previous = c; + c = next; + if(n_of_turns) goto try_next_cell; + } + + return c; +} +#endif // no CGAL_NO_STRUCTURAL_FILTERING + +template < class GT, class Tds > +Bounded_side +Triangulation_3:: +side_of_tetrahedron(const Point & p, + const Point & p0, + const Point & p1, + const Point & p2, + const Point & p3, + Locate_type & lt, int & i, int & j ) const + // p0,p1,p2,p3 supposed to be non coplanar + // tetrahedron p0,p1,p2,p3 is supposed to be well oriented + // returns : + // ON_BOUNDED_SIDE if p lies strictly inside the tetrahedron + // ON_BOUNDARY if p lies on one of the facets + // ON_UNBOUNDED_SIDE if p lies strictly outside the tetrahedron +{ + CGAL_triangulation_precondition + ( orientation(p0,p1,p2,p3) == POSITIVE ); + + Orientation o0,o1,o2,o3; + if ( ((o0 = orientation(p,p1,p2,p3)) == NEGATIVE) || + ((o1 = orientation(p0,p,p2,p3)) == NEGATIVE) || + ((o2 = orientation(p0,p1,p,p3)) == NEGATIVE) || + ((o3 = orientation(p0,p1,p2,p)) == NEGATIVE) ) { + lt = OUTSIDE_CONVEX_HULL; + return ON_UNBOUNDED_SIDE; + } + + // now all the oi's are >=0 + // sum gives the number of facets p lies on + int sum = ( (o0 == ZERO) ? 1 : 0 ) + + ( (o1 == ZERO) ? 1 : 0 ) + + ( (o2 == ZERO) ? 1 : 0 ) + + ( (o3 == ZERO) ? 1 : 0 ); + + switch (sum) { + case 0: + { + lt = CELL; + return ON_BOUNDED_SIDE; + } + case 1: + { + lt = FACET; + // i = index such that p lies on facet(i) + i = ( o0 == ZERO ) ? 0 : + ( o1 == ZERO ) ? 1 : + ( o2 == ZERO ) ? 2 : + 3; + return ON_BOUNDARY; + } + case 2: + { + lt = EDGE; + // i = smallest index such that p does not lie on facet(i) + // i must be < 3 since p lies on 2 facets + i = ( o0 == POSITIVE ) ? 0 : + ( o1 == POSITIVE ) ? 1 : + 2; + // j = larger index such that p not on facet(j) + // j must be > 0 since p lies on 2 facets + j = ( o3 == POSITIVE ) ? 3 : + ( o2 == POSITIVE ) ? 2 : + 1; + return ON_BOUNDARY; + } + case 3: + { + lt = VERTEX; + // i = index such that p does not lie on facet(i) + i = ( o0 == POSITIVE ) ? 0 : + ( o1 == POSITIVE ) ? 1 : + ( o2 == POSITIVE ) ? 2 : + 3; + return ON_BOUNDARY; + } + default: + { + // impossible : cannot be on 4 facets for a real tetrahedron + CGAL_triangulation_assertion(false); + return ON_BOUNDARY; + } + } +} + +template < class GT, class Tds > +Bounded_side +Triangulation_3:: +side_of_cell(const Point & p, + Cell_handle c, + Locate_type & lt, int & i, int & j) const + // returns + // ON_BOUNDED_SIDE if p inside the cell + // (for an infinite cell this means that p lies strictly in the half space + // limited by its finite facet) + // ON_BOUNDARY if p on the boundary of the cell + // (for an infinite cell this means that p lies on the *finite* facet) + // ON_UNBOUNDED_SIDE if p lies outside the cell + // (for an infinite cell this means that p is not in the preceding + // two cases) + // lt has a meaning only when ON_BOUNDED_SIDE or ON_BOUNDARY +{ + CGAL_triangulation_precondition( dimension() == 3 ); + if ( ! is_infinite(c) ) { + return side_of_tetrahedron(p, + c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point(), + lt, i, j); + } + else { + int inf = c->index(infinite); + Orientation o; + Vertex_handle + v1=c->vertex((inf+1)&3), + v2=c->vertex((inf+2)&3), + v3=c->vertex((inf+3)&3); + if ( (inf&1) == 0 ) + o = orientation(p, v1->point(), v2->point(), v3->point()); + else + o = orientation(v3->point(), p, v1->point(), v2->point()); + + switch (o) { + case POSITIVE: + { + lt = CELL; + return ON_BOUNDED_SIDE; + } + case NEGATIVE: + return ON_UNBOUNDED_SIDE; + case ZERO: + { + // location in the finite facet + int i_f, j_f; + Bounded_side side = + side_of_triangle(p, v1->point(), v2->point(), v3->point(), + lt, i_f, j_f); + // lt need not be modified in most cases : + switch (side) { + case ON_BOUNDED_SIDE: + { + // lt == FACET ok + i = inf; + return ON_BOUNDARY; + } + case ON_BOUNDARY: + { + // lt == VERTEX OR EDGE ok + i = ( i_f == 0 ) ? ((inf+1)&3) : + ( i_f == 1 ) ? ((inf+2)&3) : + ((inf+3)&3); + if ( lt == EDGE ) { + j = (j_f == 0 ) ? ((inf+1)&3) : + ( j_f == 1 ) ? ((inf+2)&3) : + ((inf+3)&3); + } + return ON_BOUNDARY; + } + case ON_UNBOUNDED_SIDE: + { + // p lies on the plane defined by the finite facet + // lt must be initialized + return ON_UNBOUNDED_SIDE; + } + default: + { + CGAL_triangulation_assertion(false); + return ON_BOUNDARY; + } + } // switch side + }// case ZERO + default: + { + CGAL_triangulation_assertion(false); + return ON_BOUNDARY; + } + } // switch o + } // else infinite cell +} // side_of_cell + +template < class GT, class Tds > +Bounded_side +Triangulation_3:: +side_of_triangle(const Point & p, + const Point & p0, + const Point & p1, + const Point & p2, + Locate_type & lt, int & i, int & j ) const + // p0,p1,p2 supposed to define a plane + // p supposed to lie on plane p0,p1,p2 + // triangle p0,p1,p2 defines the orientation of the plane + // returns + // ON_BOUNDED_SIDE if p lies strictly inside the triangle + // ON_BOUNDARY if p lies on one of the edges + // ON_UNBOUNDED_SIDE if p lies strictly outside the triangle +{ + CGAL_triangulation_precondition( coplanar(p,p0,p1,p2) ); + + Orientation o012 = coplanar_orientation(p0,p1,p2); + CGAL_triangulation_precondition( o012 != COLLINEAR ); + + Orientation o0; // edge p0 p1 + Orientation o1; // edge p1 p2 + Orientation o2; // edge p2 p0 + + if ((o0 = coplanar_orientation(p0,p1,p)) == opposite(o012) || + (o1 = coplanar_orientation(p1,p2,p)) == opposite(o012) || + (o2 = coplanar_orientation(p2,p0,p)) == opposite(o012)) { + lt = OUTSIDE_CONVEX_HULL; + return ON_UNBOUNDED_SIDE; + } + + // now all the oi's are >=0 + // sum gives the number of edges p lies on + int sum = ( (o0 == ZERO) ? 1 : 0 ) + + ( (o1 == ZERO) ? 1 : 0 ) + + ( (o2 == ZERO) ? 1 : 0 ); + + switch (sum) { + case 0: + { + lt = FACET; + return ON_BOUNDED_SIDE; + } + case 1: + { + lt = EDGE; + i = ( o0 == ZERO ) ? 0 : + ( o1 == ZERO ) ? 1 : + 2; + if ( i == 2 ) + j=0; + else + j = i+1; + return ON_BOUNDARY; + } + case 2: + { + lt = VERTEX; + i = ( o0 == o012 ) ? 2 : + ( o1 == o012 ) ? 0 : + 1; + return ON_BOUNDARY; + } + default: + { + // cannot happen + CGAL_triangulation_assertion(false); + return ON_BOUNDARY; + } + } +} + +template < class GT, class Tds > +Bounded_side +Triangulation_3:: +side_of_facet(const Point & p, + Cell_handle c, + Locate_type & lt, int & li, int & lj) const + // supposes dimension 2 otherwise does not work for infinite facets + // returns : + // ON_BOUNDED_SIDE if p inside the facet + // (for an infinite facet this means that p lies strictly in the half plane + // limited by its finite edge) + // ON_BOUNDARY if p on the boundary of the facet + // (for an infinite facet this means that p lies on the *finite* edge) + // ON_UNBOUNDED_SIDE if p lies outside the facet + // (for an infinite facet this means that p is not in the + // preceding two cases) + // lt has a meaning only when ON_BOUNDED_SIDE or ON_BOUNDARY + // when they mean anything, li and lj refer to indices in the cell c + // giving the facet (c,i) +{ + CGAL_triangulation_precondition( dimension() == 2 ); + if ( ! is_infinite(c,3) ) { + // The following precondition is useless because it is written + // in side_of_facet + // CGAL_triangulation_precondition( coplanar (p, + // c->vertex(0)->point, + // c->vertex(1)->point, + // c->vertex(2)->point) ); + int i_t, j_t; + Bounded_side side = side_of_triangle(p, + c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + lt, i_t, j_t); + // We protect the following code by this test to avoid valgrind messages. + if (side == ON_BOUNDARY) { + // indices in the original cell : + li = ( i_t == 0 ) ? 0 : + ( i_t == 1 ) ? 1 : 2; + lj = ( j_t == 0 ) ? 0 : + ( j_t == 1 ) ? 1 : 2; + } + return side; + } + // else infinite facet + int inf = c->index(infinite); + // The following precondition is useless because it is written + // in side_of_facet + // CGAL_triangulation_precondition( coplanar (p, + // c->neighbor(inf)->vertex(0)->point(), + // c->neighbor(inf)->vertex(1)->point(), + // c->neighbor(inf)->vertex(2)->point())); + int i2 = next_around_edge(inf,3); + int i1 = 3-inf-i2; + Vertex_handle v1 = c->vertex(i1), + v2 = c->vertex(i2); + + CGAL_triangulation_assertion(coplanar_orientation(v1->point(), v2->point(), + mirror_vertex(c, inf)->point()) == POSITIVE); + + switch (coplanar_orientation(v1->point(), v2->point(), p)) { + case POSITIVE: + // p lies on the same side of v1v2 as vn, so not in f + return ON_UNBOUNDED_SIDE; + case NEGATIVE: + // p lies in f + lt = FACET; + li = 3; + return ON_BOUNDED_SIDE; + default: // case ZERO: + // p collinear with v1v2 + int i_e; + switch (side_of_segment(p, v1->point(), v2->point(), lt, i_e)) { + // computation of the indices in the original cell + case ON_BOUNDED_SIDE: + // lt == EDGE ok + li = i1; + lj = i2; + return ON_BOUNDARY; + case ON_BOUNDARY: + // lt == VERTEX ok + li = ( i_e == 0 ) ? i1 : i2; + return ON_BOUNDARY; + default: // case ON_UNBOUNDED_SIDE: + // p lies on the line defined by the finite edge + return ON_UNBOUNDED_SIDE; + } + } +} + +template < class GT, class Tds > +Bounded_side +Triangulation_3:: +side_of_segment(const Point & p, + const Point & p0, + const Point & p1, + Locate_type & lt, int & i ) const + // p0, p1 supposed to be different + // p supposed to be collinear to p0, p1 + // returns : + // ON_BOUNDED_SIDE if p lies strictly inside the edge + // ON_BOUNDARY if p equals p0 or p1 + // ON_UNBOUNDED_SIDE if p lies strictly outside the edge +{ + CGAL_triangulation_precondition( ! equal(p0, p1) ); + CGAL_triangulation_precondition( collinear(p, p0, p1) ); + + switch (collinear_position(p0, p, p1)) { + case MIDDLE: + lt = EDGE; + return ON_BOUNDED_SIDE; + case SOURCE: + lt = VERTEX; + i = 0; + return ON_BOUNDARY; + case TARGET: + lt = VERTEX; + i = 1; + return ON_BOUNDARY; + default: // case BEFORE: case AFTER: + lt = OUTSIDE_CONVEX_HULL; + return ON_UNBOUNDED_SIDE; + } +} + +template < class GT, class Tds > +Bounded_side +Triangulation_3:: +side_of_edge(const Point & p, + Cell_handle c, + Locate_type & lt, int & li) const + // supposes dimension 1 otherwise does not work for infinite edges + // returns : + // ON_BOUNDED_SIDE if p inside the edge + // (for an infinite edge this means that p lies in the half line + // defined by the vertex) + // ON_BOUNDARY if p equals one of the vertices + // ON_UNBOUNDED_SIDE if p lies outside the edge + // (for an infinite edge this means that p lies on the other half line) + // lt has a meaning when ON_BOUNDED_SIDE and ON_BOUNDARY + // li refer to indices in the cell c +{ + CGAL_triangulation_precondition( dimension() == 1 ); + if ( ! is_infinite(c,0,1) ) + return side_of_segment(p, c->vertex(0)->point(), c->vertex(1)->point(), + lt, li); + // else infinite edge + int inf = c->index(infinite); + switch (collinear_position(c->vertex(1-inf)->point(), p, + mirror_vertex(c, inf)->point())) { + case SOURCE: + lt = VERTEX; + li = 1-inf; + return ON_BOUNDARY; + case BEFORE: + lt = EDGE; + return ON_BOUNDED_SIDE; + default: // case MIDDLE: case AFTER: case TARGET: + return ON_UNBOUNDED_SIDE; + } +} + +template < class GT, class Tds > +bool +Triangulation_3:: +flip( Cell_handle c, int i ) +{ + CGAL_triangulation_precondition( (dimension() == 3) && (0<=i) && (i<4) + && (number_of_vertices() >= 5) ); + + Cell_handle n = c->neighbor(i); + int in = n->index(c); + if ( is_infinite( c ) || is_infinite( n ) ) return false; + + if ( i%2 == 1 ) { + if ( orientation( c->vertex((i+1)&3)->point(), + c->vertex((i+2)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; + if ( orientation( c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; + if ( orientation( c->vertex((i+3)&3)->point(), + c->vertex((i+1)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; + } + else { + if ( orientation( c->vertex((i+2)&3)->point(), + c->vertex((i+1)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; + if ( orientation( c->vertex((i+3)&3)->point(), + c->vertex((i+2)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; + if ( orientation( c->vertex((i+1)&3)->point(), + c->vertex((i+3)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + != POSITIVE ) return false; + } + + _tds.flip_flippable(c, i); + return true; +} + +template < class GT, class Tds > +void +Triangulation_3:: +flip_flippable( Cell_handle c, int i ) +{ + CGAL_triangulation_precondition( (dimension() == 3) && (0<=i) && (i<4) + && (number_of_vertices() >= 5) ); + CGAL_triangulation_precondition_code( Cell_handle n = c->neighbor(i); ); + CGAL_triangulation_precondition_code( int in = n->index(c); ); + CGAL_triangulation_precondition( ( ! is_infinite( c ) ) && + ( ! is_infinite( n ) ) ); + + if ( i%2 == 1 ) { + CGAL_triangulation_precondition( orientation( c->vertex((i+1)&3)->point(), + c->vertex((i+2)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); + CGAL_triangulation_precondition( orientation( c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); + CGAL_triangulation_precondition( orientation( c->vertex((i+3)&3)->point(), + c->vertex((i+1)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); + } + else { + CGAL_triangulation_precondition( orientation( c->vertex((i+2)&3)->point(), + c->vertex((i+1)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); + CGAL_triangulation_precondition( orientation( c->vertex((i+3)&3)->point(), + c->vertex((i+2)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); + CGAL_triangulation_precondition( orientation( c->vertex((i+1)&3)->point(), + c->vertex((i+3)&3)->point(), + n->vertex(in)->point(), + c->vertex(i)->point() ) + == POSITIVE ); + } + + _tds.flip_flippable(c, i); +} + +template < class GT, class Tds > +bool +Triangulation_3:: +flip( Cell_handle c, int i, int j ) + // flips edge i,j of cell c +{ + CGAL_triangulation_precondition( (dimension() == 3) + && (0<=i) && (i<4) + && (0<=j) && (j<4) + && ( i != j ) + && (number_of_vertices() >= 5) ); + + // checks that degree 3 and not on the convex hull + int degree = 0; + Cell_circulator ccir = incident_cells(c,i,j); + Cell_circulator cdone = ccir; + do { + if ( is_infinite(ccir) ) return false; + ++degree; + ++ccir; + } while ( ccir != cdone ); + + if ( degree != 3 ) return false; + + // checks that future tetrahedra are well oriented + Cell_handle n = c->neighbor( next_around_edge(i,j) ); + int in = n->index( c->vertex(i) ); + int jn = n->index( c->vertex(j) ); + if ( orientation( c->vertex(next_around_edge(i,j))->point(), + c->vertex(next_around_edge(j,i))->point(), + n->vertex(next_around_edge(jn,in))->point(), + c->vertex(j)->point() ) + != POSITIVE ) return false; + if ( orientation( c->vertex(i)->point(), + c->vertex(next_around_edge(j,i))->point(), + n->vertex(next_around_edge(jn,in))->point(), + c->vertex(next_around_edge(i,j))->point() ) + != POSITIVE ) return false; + + _tds.flip_flippable(c, i, j); + return true; +} + +template < class GT, class Tds > +void +Triangulation_3:: +flip_flippable( Cell_handle c, int i, int j ) + // flips edge i,j of cell c +{ +#if !defined CGAL_TRIANGULATION_NO_PRECONDITIONS && \ + !defined CGAL_NO_PRECONDITIONS && !defined NDEBUG + CGAL_triangulation_precondition( (dimension() == 3) + && (0<=i) && (i<4) + && (0<=j) && (j<4) + && ( i != j ) + && (number_of_vertices() >= 5) ); + int degree = 0; + Cell_circulator ccir = incident_cells(c,i,j); + Cell_circulator cdone = ccir; + do { + CGAL_triangulation_precondition( ! is_infinite(ccir) ); + ++degree; + ++ccir; + } while ( ccir != cdone ); + CGAL_triangulation_precondition( degree == 3 ); + + Cell_handle n = c->neighbor( next_around_edge(i, j) ); + int in = n->index( c->vertex(i) ); + int jn = n->index( c->vertex(j) ); + CGAL_triangulation_precondition + ( orientation( c->vertex(next_around_edge(i,j))->point(), + c->vertex(next_around_edge(j,i))->point(), + n->vertex(next_around_edge(jn,in))->point(), + c->vertex(j)->point() ) == POSITIVE ); + CGAL_triangulation_precondition + ( orientation( c->vertex(i)->point(), + c->vertex(next_around_edge(j,i))->point(), + n->vertex(next_around_edge(jn,in))->point(), + c->vertex(next_around_edge(i,j))->point() ) == POSITIVE ); +#endif + _tds.flip_flippable(c, i, j); +} + +template < class GT, class Tds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +insert(const Point & p, Cell_handle start) +{ + Locate_type lt; + int li, lj; + Cell_handle c = locate( p, lt, li, lj, start); + return insert(p, lt, c, li, lj); +} + +template < class GT, class Tds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +insert(const Point & p, Locate_type lt, Cell_handle c, int li, int lj) +{ + switch (lt) { + case VERTEX: + return c->vertex(li); + case EDGE: + return insert_in_edge(p, c, li, lj); + case FACET: + return insert_in_facet(p, c, li); + case CELL: + return insert_in_cell(p, c); + case OUTSIDE_CONVEX_HULL: + return insert_outside_convex_hull(p, c); + case OUTSIDE_AFFINE_HULL: + default: + return insert_outside_affine_hull(p); + } +} + + + +template < class GT, class Tds > +template < class Conflict_tester, class Hidden_points_visitor > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +insert_in_conflict(const Point & p, + Locate_type lt, Cell_handle c, int li, int /*lj*/, + const Conflict_tester &tester, + Hidden_points_visitor &hider) +{ + switch (dimension()) { + case 3: + { + if ((lt == VERTEX) && + (tester.compare_weight(c->vertex(li)->point(), p)==0) ) { + return c->vertex(li); + } + // If the new point is not in conflict with its cell, it is hidden. + if (!tester.test_initial_cell(c)) { + hider.hide_point(c,p); + return Vertex_handle(); + } + + // Ok, we really insert the point now. + // First, find the conflict region. + std::vector cells; + Facet facet; + + cells.reserve(32); + find_conflicts + (c, tester, make_triple(Oneset_iterator(facet), + std::back_inserter(cells), + Emptyset_iterator())); + + // Remember the points that are hidden by the conflicting cells, + // as they will be deleted during the insertion. + hider.process_cells_in_conflict(cells.begin(), cells.end()); + + Vertex_handle v = _insert_in_hole(p, cells.begin(), cells.end(), + facet.first, facet.second); + + // Store the hidden points in their new cells. + hider.reinsert_vertices(v); + return v; + } + case 2: + { + // This check is added compared to the 3D case + if (lt == OUTSIDE_AFFINE_HULL) + return insert_outside_affine_hull (p); + + if ((lt == VERTEX) && + (tester.compare_weight(c->vertex(li)->point(), p)==0) ) { + return c->vertex(li); + } + // If the new point is not in conflict with its cell, it is hidden. + if (!tester.test_initial_cell(c)) { + hider.hide_point(c,p); + return Vertex_handle(); + } + + // Ok, we really insert the point now. + // First, find the conflict region. + std::vector cells; + Facet facet; + + cells.reserve(32); + find_conflicts + (c, tester, make_triple(Oneset_iterator(facet), + std::back_inserter(cells), + Emptyset_iterator())); + + // Remember the points that are hidden by the conflicting cells, + // as they will be deleted during the insertion. + hider.process_cells_in_conflict(cells.begin(), cells.end()); + + Vertex_handle v = _insert_in_hole(p, cells.begin(), cells.end(), + facet.first, facet.second); + + // Store the hidden points in their new cells. + hider.reinsert_vertices(v); + return v; + } + default: + { + // dimension() <= 1 + if (lt == OUTSIDE_AFFINE_HULL) + return insert_outside_affine_hull (p); + + if (lt == VERTEX && + tester.compare_weight(c->vertex(li)->point(), p) == 0) { + return c->vertex(li); + } + + // If the new point is not in conflict with its cell, it is hidden. + if (! tester.test_initial_cell(c)) { + hider.hide_point(c,p); + return Vertex_handle(); + } + + if (dimension() == 0) { + return hider.replace_vertex(c, li, p); + } + + + // dimension() == 1; + + // Ok, we really insert the point now. + // First, find the conflict region. + std::vector cells; + Facet facet; + Cell_handle bound[2]; + // corresponding index: bound[j]->neighbor(1-j) is in conflict. + + // We get all cells in conflict, + // and remember the 2 external boundaries. + cells.push_back(c); + + for (int j = 0; j<2; ++j) { + Cell_handle n = c->neighbor(j); + while ( tester(n) ) { + cells.push_back(n); + n = n->neighbor(j); + } + bound[j] = n; + } + + // Insertion. + hider.process_cells_in_conflict(cells.begin(), cells.end()); + + tds().delete_cells(cells.begin(), cells.end()); + + // We preserve the order (like the orientation in 2D-3D). + Vertex_handle v = tds().create_vertex(); + Cell_handle c0 = tds().create_face(v, bound[0]->vertex(0), Vertex_handle()); + Cell_handle c1 = tds().create_face(bound[1]->vertex(1), v, Vertex_handle()); + tds().set_adjacency(c0, 1, c1, 0); + tds().set_adjacency(bound[0], 1, c0, 0); + tds().set_adjacency(c1, 1, bound[1], 0); + bound[0]->vertex(0)->set_cell(bound[0]); + bound[1]->vertex(1)->set_cell(bound[1]); + v->set_cell(c0); + v->set_point (p); + + hider.reinsert_vertices(v); + + return v; + } + } +} + +template < class GT, class Tds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +insert_in_cell(const Point & p, Cell_handle c) +{ + CGAL_triangulation_precondition( dimension() == 3 ); + CGAL_triangulation_precondition_code + ( Locate_type lt; + int i; int j; ); + CGAL_triangulation_precondition + ( side_of_tetrahedron( p, + c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point(), + lt,i,j ) == ON_BOUNDED_SIDE ); + + Vertex_handle v = _tds.insert_in_cell(c); + v->set_point(p); + return v; +} + +template < class GT, class Tds > +inline +typename Triangulation_3::Vertex_handle +Triangulation_3:: +insert_in_facet(const Point & p, Cell_handle c, int i) +{ + CGAL_triangulation_precondition( dimension() == 2 || dimension() == 3); + CGAL_triangulation_precondition( (dimension() == 2 && i == 3) + || (dimension() == 3 && i >= 0 && i <= 3) ); + CGAL_triangulation_exactness_precondition_code + ( Locate_type lt; + int li; int lj; ); + CGAL_triangulation_exactness_precondition + ( coplanar( p, c->vertex((i+1)&3)->point(), + c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point() ) + && + side_of_triangle( p, + c->vertex((i+1)&3)->point(), + c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point(), + lt, li, lj) == ON_BOUNDED_SIDE ); + + Vertex_handle v = _tds.insert_in_facet(c, i); + v->set_point(p); + return v; +} + +template < class GT, class Tds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +insert_in_edge(const Point & p, Cell_handle c, int i, int j) +{ + CGAL_triangulation_precondition( i != j ); + CGAL_triangulation_precondition( dimension() >= 1 && dimension() <= 3 ); + CGAL_triangulation_precondition( i >= 0 && i <= dimension() + && j >= 0 && j <= dimension() ); + CGAL_triangulation_exactness_precondition_code( Locate_type lt; int li; ); + switch ( dimension() ) { + case 3: + case 2: + { + CGAL_triangulation_precondition( ! is_infinite(c, i, j) ); + CGAL_triangulation_exactness_precondition( + collinear( c->vertex(i)->point(), + p, + c->vertex(j)->point() ) + && side_of_segment( p, + c->vertex(i)->point(), + c->vertex(j)->point(), + lt, li ) == ON_BOUNDED_SIDE ); + break; + } + case 1: + { + CGAL_triangulation_exactness_precondition( side_of_edge(p, c, lt, li) + == ON_BOUNDED_SIDE ); + break; + } + } + + Vertex_handle v = _tds.insert_in_edge(c, i, j); + v->set_point(p); + return v; +} + +template < class GT, class Tds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +insert_outside_convex_hull(const Point & p, Cell_handle c) + // c is an infinite cell containing p + // p is strictly outside the convex hull + // dimension 0 not allowed, use outside-affine-hull +{ + CGAL_triangulation_precondition( dimension() > 0 ); + CGAL_triangulation_precondition( c->has_vertex(infinite) ); + // the precondition that p is in c is tested in each of the + // insertion methods called from this method + switch ( dimension() ) { + case 1: + { + // // p lies in the infinite edge neighboring c + // // on the other side of li + // return insert_in_edge(p,c->neighbor(1-li),0,1); + return insert_in_edge(p,c,0,1); + } + case 2: + { + Conflict_tester_outside_convex_hull_2 tester(p, this); + Vertex_handle v = insert_conflict(c, tester); + v->set_point(p); + return v; + } + default: // case 3: + { + Conflict_tester_outside_convex_hull_3 tester(p, this); + Vertex_handle v = insert_conflict(c, tester); + v->set_point(p); + return v; + } + } +} + +template < class GT, class Tds > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +insert_outside_affine_hull(const Point & p) +{ + CGAL_triangulation_precondition( dimension() < 3 ); + bool reorient; + switch ( dimension() ) { + case 1: + { + Cell_handle c = infinite_cell(); + Cell_handle n = c->neighbor(c->index(infinite_vertex())); + Orientation o = coplanar_orientation(n->vertex(0)->point(), + n->vertex(1)->point(), p); + CGAL_triangulation_precondition ( o != COLLINEAR ); + reorient = o == NEGATIVE; + break; + } + case 2: + { + Cell_handle c = infinite_cell(); + Cell_handle n = c->neighbor(c->index(infinite_vertex())); + Orientation o = orientation( n->vertex(0)->point(), + n->vertex(1)->point(), + n->vertex(2)->point(), p ); + CGAL_triangulation_precondition ( o != COPLANAR ); + reorient = o == NEGATIVE; + break; + } + default: + reorient = false; + } + + Vertex_handle v = _tds.insert_increase_dimension(infinite_vertex()); + v->set_point(p); + + if (reorient) + _tds.reorient(); + + return v; +} + +template < class GT, class Tds > +template < class OutputItCells > +typename Triangulation_3::Vertex_handle +Triangulation_3::insert_and_give_new_cells(const Point &p, + OutputItCells fit, + Cell_handle start) +{ + Vertex_handle v = insert(p, start); + int dimension = this->dimension(); + if(dimension == 3) this->incident_cells(v, fit); + else if(dimension == 2) + { + Cell_handle c = v->cell(), end = c; + do { + *fit++ = c; + int i = c->index(v); + c = c->neighbor((i+1)%3); + } while(c != end); + } + else if(dimension == 1) + { + Cell_handle c = v->cell(); + *fit++ = c; + *fit++ = c->neighbor((~(c->index(v)))&1); + } + else *fit++ = v->cell(); // dimension = 0 + return v; +} + +template < class GT, class Tds > +template < class OutputItCells > +typename Triangulation_3::Vertex_handle +Triangulation_3::insert_and_give_new_cells(const Point& p, + OutputItCells fit, + Vertex_handle hint) +{ + Vertex_handle v = insert(p, hint); + int dimension = this->dimension(); + if(dimension == 3) this->incident_cells(v, fit); + else if(dimension == 2) + { + Cell_handle c = v->cell(), end = c; + do { + *fit++ = c; + int i = c->index(v); + c = c->neighbor((i+1)%3); + } while(c != end); + } + else if(dimension == 1) + { + Cell_handle c = v->cell(); + *fit++ = c; + *fit++ = c->neighbor((~(c->index(v)))&1); + } + else *fit++ = v->cell(); // dimension = 0 + return v; +} + +template < class GT, class Tds > +template < class OutputItCells > +typename Triangulation_3::Vertex_handle +Triangulation_3::insert_and_give_new_cells(const Point& p, + Locate_type lt, + Cell_handle c, int li, int lj, + OutputItCells fit) +{ + Vertex_handle v = insert(p, lt, c, li, lj); + int dimension = this->dimension(); + if(dimension == 3) this->incident_cells(v, fit); + else if(dimension == 2) + { + Cell_handle c = v->cell(), end = c; + do { + *fit++ = c; + int i = c->index(v); + c = c->neighbor((i+1)%3); + } while(c != end); + } + else if(dimension == 1) + { + Cell_handle c = v->cell(); + *fit++ = c; + *fit++ = c->neighbor((~(c->index(v)))&1); + } + else *fit++ = v->cell(); // dimension = 0 + return v; +} + +template < class Gt, class Tds > +typename Triangulation_3::Vertex_triple +Triangulation_3:: +make_vertex_triple(const Facet& f) const +{ + Cell_handle ch = f.first; + int i = f.second; + + return Vertex_triple(ch->vertex(vertex_triple_index(i,0)), + ch->vertex(vertex_triple_index(i,1)), + ch->vertex(vertex_triple_index(i,2))); +} + +template < class Gt, class Tds > +void +Triangulation_3:: +make_canonical(Vertex_triple& t) const +{ + int i = (&*(t.first) < &*(t.second))? 0 : 1; + if(i==0) { + i = (&*(t.first) < &*(t.third))? 0 : 2; + } else { + i = (&*(t.second) < &*(t.third))? 1 : 2; + } + Vertex_handle tmp; + switch(i){ + case 0: return; + case 1: + tmp = t.first; + t.first = t.second; + t.second = t.third; + t.third = tmp; + return; + default: + tmp = t.first; + t.first = t.third; + t.third = t.second; + t.second = tmp; + } +} + +template < class GT, class Tds > +bool +Triangulation_3:: +test_dim_down(Vertex_handle v) const + // tests whether removing v decreases the dimension of the triangulation + // true iff + // v is incident to all finite cells/facets + // and all the other vertices are coplanar/collinear in dim3/2. +{ + CGAL_triangulation_precondition(dimension() >= 0); + CGAL_triangulation_precondition(! is_infinite(v) ); + + if (dimension() == 3) { + Finite_cells_iterator cit = finite_cells_begin(); + + int iv; + if ( ! cit->has_vertex(v,iv) ) + return false; + const Point &p1=cit->vertex((iv+1)&3)->point(); + const Point &p2=cit->vertex((iv+2)&3)->point(); + const Point &p3=cit->vertex((iv+3)&3)->point(); + ++cit; + + for (; cit != finite_cells_end(); ++cit ) { + if ( ! cit->has_vertex(v,iv) ) + return false; + for (int i=1; i<4; i++ ) + if ( !coplanar(p1,p2,p3,cit->vertex((iv+i)&3)->point()) ) + return false; + } + } + else if (dimension() == 2) + { + Finite_facets_iterator cit = finite_facets_begin(); + + int iv; + if ( ! cit->first->has_vertex(v,iv) ) + return false; + const Point &p1 = cit->first->vertex(cw(iv))->point(); + const Point &p2 = cit->first->vertex(ccw(iv))->point(); + ++cit; + + for (; cit != finite_facets_end(); ++cit ) { + if ( ! cit->first->has_vertex(v,iv) ) + return false; + if ( !collinear(p1, p2, cit->first->vertex(cw(iv))->point()) || + !collinear(p1, p2, cit->first->vertex(ccw(iv))->point()) ) + return false; + } + } + else // dimension() == 1 or 0 + return number_of_vertices() == (size_type) dimension() + 1; + + return true; +} + +template +template < class VertexRemover > +VertexRemover& +Triangulation_3:: +make_hole_2D(Vertex_handle v, std::list &hole, VertexRemover &remover) +{ + std::vector to_delete; + to_delete.reserve(32); + + Face_circulator fc = tds().incident_faces(v); + Face_circulator done(fc); + + // We prepare for deleting all interior cells. + // We ->set_cell() pointers to cells outside the hole. + // We push the Edges_2D of the boundary (seen from outside) in "hole". + do { + Cell_handle f = fc; + int i = f->index(v); + Cell_handle fn = f->neighbor(i); + int in = fn->index(f); + + f->vertex(cw(i))->set_cell(fn); + fn->set_neighbor(in, Cell_handle()); + + hole.push_back(Edge_2D(fn, in)); + remover.add_hidden_points(f); + to_delete.push_back(f); + + ++fc; + } while (fc != done); + + tds().delete_cells(to_delete.begin(), to_delete.end()); + return remover; +} + +// this one also erases a set of cells +// which is useful to the move method +// outputting newly created cells +template +template < class VertexRemover > +VertexRemover& +Triangulation_3:: +make_hole_2D(Vertex_handle v, std::list &hole, VertexRemover &remover, + std::set &cells_set) +{ + std::vector to_delete; + to_delete.reserve(32); + + Face_circulator fc = tds().incident_faces(v); + Face_circulator done(fc); + + // We prepare for deleting all interior cells. + // We ->set_cell() pointers to cells outside the hole. + // We push the Edges_2D of the boundary (seen from outside) in "hole". + do { + Cell_handle f = fc; + int i = f->index(v); + Cell_handle fn = f->neighbor(i); + int in = fn->index(f); + + f->vertex(cw(i))->set_cell(fn); + fn->set_neighbor(in, Cell_handle()); + + hole.push_back(Edge_2D(fn, in)); + remover.add_hidden_points(f); + to_delete.push_back(f); + + ++fc; + } while (fc != done); + + for(typename std::vector::const_iterator ib = to_delete.begin(), + iend = to_delete.end(); ib != iend; ib++) cells_set.erase(*ib); + + tds().delete_cells(to_delete.begin(), to_delete.end()); + return remover; +} + +template +template < class VertexRemover > +void +Triangulation_3:: +fill_hole_2D(std::list & first_hole, VertexRemover &remover) +{ + typedef std::list Hole; + + std::vector hole_list; + + Cell_handle f, ff, fn; + int i, ii, in; + + hole_list.push_back(first_hole); + + while( ! hole_list.empty()) + { + Hole hole = hole_list.back(); + hole_list.pop_back(); + + // if the hole has only three edges, create the triangle + if (hole.size() == 3) { + typename Hole::iterator hit = hole.begin(); + f = (*hit).first; i = (*hit).second; + ff = (* ++hit).first; ii = (*hit).second; + fn = (* ++hit).first; in = (*hit).second; + tds().create_face(f, i, ff, ii, fn, in); + continue; + } + + // else find an edge with two finite vertices + // on the hole boundary + // and the new triangle adjacent to that edge + // cut the hole and push it back + + // first, ensure that a neighboring face + // whose vertices on the hole boundary are finite + // is the first of the hole + while (1) { + ff = (hole.front()).first; + ii = (hole.front()).second; + if ( is_infinite(ff->vertex(cw(ii))) || + is_infinite(ff->vertex(ccw(ii)))) { + hole.push_back(hole.front()); + hole.pop_front(); + } + else + break; + } + + // take the first neighboring face and pop it; + ff = (hole.front()).first; + ii = (hole.front()).second; + hole.pop_front(); + + Vertex_handle v0 = ff->vertex(cw(ii)); + Vertex_handle v1 = ff->vertex(ccw(ii)); + Vertex_handle v2 = infinite_vertex(); + const Point &p0 = v0->point(); + const Point &p1 = v1->point(); + const Point *p2 = NULL; // Initialize to NULL to avoid warning. + + typename Hole::iterator hdone = hole.end(); + typename Hole::iterator hit = hole.begin(); + typename Hole::iterator cut_after(hit); + + // if tested vertex is c with respect to the vertex opposite + // to NULL neighbor, + // stop at the before last face; + hdone--; + for (; hit != hdone; ++hit) { + fn = hit->first; + in = hit->second; + Vertex_handle vv = fn->vertex(ccw(in)); + if (is_infinite(vv)) { + if (is_infinite(v2)) + cut_after = hit; + } + else { // vv is a finite vertex + const Point &p = vv->point(); + if (coplanar_orientation(p0, p1, p) == COUNTERCLOCKWISE) { + if (is_infinite(v2) || + remover.side_of_bounded_circle(p0, p1, *p2, p, true) + == ON_BOUNDED_SIDE) { + v2 = vv; + p2 = &p; + cut_after = hit; + } + } + } + } + + // create new triangle and update adjacency relations + Cell_handle newf; + + //update the hole and push back in the Hole_List stack + // if v2 belongs to the neighbor following or preceding *f + // the hole remain a single hole + // otherwise it is split in two holes + + fn = (hole.front()).first; + in = (hole.front()).second; + if (fn->has_vertex(v2, i) && i == ccw(in)) { + newf = tds().create_face(ff, ii, fn, in); + hole.pop_front(); + hole.push_front(Edge_2D(newf, 1)); + hole_list.push_back(hole); + } + else{ + fn = (hole.back()).first; + in = (hole.back()).second; + if (fn->has_vertex(v2, i) && i == cw(in)) { + newf = tds().create_face(fn, in, ff, ii); + hole.pop_back(); + hole.push_back(Edge_2D(newf, 1)); + hole_list.push_back(hole); + } + else{ + // split the hole in two holes + newf = tds().create_face(ff, ii, v2); + Hole new_hole; + ++cut_after; + while( hole.begin() != cut_after ) + { + new_hole.push_back(hole.front()); + hole.pop_front(); + } + + hole.push_front(Edge_2D(newf, 1)); + new_hole.push_front(Edge_2D(newf, 0)); + hole_list.push_back(hole); + hole_list.push_back(new_hole); + } + } + } +} + +template +template < class VertexRemover, class OutputItCells > +void +Triangulation_3:: +fill_hole_2D(std::list & first_hole, VertexRemover &remover, + OutputItCells fit) +{ + typedef std::list Hole; + + std::vector hole_list; + + Cell_handle f, ff, fn; + int i, ii, in; + + hole_list.push_back(first_hole); + + while( ! hole_list.empty()) + { + Hole hole = hole_list.back(); + hole_list.pop_back(); + + // if the hole has only three edges, create the triangle + if (hole.size() == 3) { + typename Hole::iterator hit = hole.begin(); + f = (*hit).first; i = (*hit).second; + ff = (* ++hit).first; ii = (*hit).second; + fn = (* ++hit).first; in = (*hit).second; + *fit++ = tds().create_face(f, i, ff, ii, fn, in); + continue; + } + + // else find an edge with two finite vertices + // on the hole boundary + // and the new triangle adjacent to that edge + // cut the hole and push it back + + // first, ensure that a neighboring face + // whose vertices on the hole boundary are finite + // is the first of the hole + while (1) { + ff = (hole.front()).first; + ii = (hole.front()).second; + if ( is_infinite(ff->vertex(cw(ii))) || + is_infinite(ff->vertex(ccw(ii)))) { + hole.push_back(hole.front()); + hole.pop_front(); + } + else + break; + } + + // take the first neighboring face and pop it; + ff = (hole.front()).first; + ii = (hole.front()).second; + hole.pop_front(); + + Vertex_handle v0 = ff->vertex(cw(ii)); + Vertex_handle v1 = ff->vertex(ccw(ii)); + Vertex_handle v2 = infinite_vertex(); + const Point &p0 = v0->point(); + const Point &p1 = v1->point(); + const Point *p2 = NULL; // Initialize to NULL to avoid warning. + + typename Hole::iterator hdone = hole.end(); + typename Hole::iterator hit = hole.begin(); + typename Hole::iterator cut_after(hit); + + // if tested vertex is c with respect to the vertex opposite + // to NULL neighbor, + // stop at the before last face; + hdone--; + for (; hit != hdone; ++hit) { + fn = hit->first; + in = hit->second; + Vertex_handle vv = fn->vertex(ccw(in)); + if (is_infinite(vv)) { + if (is_infinite(v2)) + cut_after = hit; + } + else { // vv is a finite vertex + const Point &p = vv->point(); + if (coplanar_orientation(p0, p1, p) == COUNTERCLOCKWISE) { + if (is_infinite(v2) || + remover.side_of_bounded_circle(p0, p1, *p2, p, true) + == ON_BOUNDED_SIDE) { + v2 = vv; + p2 = &p; + cut_after = hit; + } + } + } + } + + // create new triangle and update adjacency relations + Cell_handle newf; + + //update the hole and push back in the Hole_List stack + // if v2 belongs to the neighbor following or preceding *f + // the hole remain a single hole + // otherwise it is split in two holes + + fn = (hole.front()).first; + in = (hole.front()).second; + if (fn->has_vertex(v2, i) && i == ccw(in)) { + newf = tds().create_face(ff, ii, fn, in); + hole.pop_front(); + hole.push_front(Edge_2D(newf, 1)); + hole_list.push_back(hole); + } else { + fn = (hole.back()).first; + in = (hole.back()).second; + if (fn->has_vertex(v2, i) && i == cw(in)) { + newf = tds().create_face(fn, in, ff, ii); + hole.pop_back(); + hole.push_back(Edge_2D(newf, 1)); + hole_list.push_back(hole); + } else { + // split the hole in two holes + newf = tds().create_face(ff, ii, v2); + Hole new_hole; + ++cut_after; + while( hole.begin() != cut_after ) + { + new_hole.push_back(hole.front()); + hole.pop_front(); + } + hole.push_front(Edge_2D(newf, 1)); + new_hole.push_front(Edge_2D(newf, 0)); + hole_list.push_back(hole); + hole_list.push_back(new_hole); + } + } + + *fit++ = newf; + + } +} + +template < class Gt, class Tds > +void +Triangulation_3:: +make_hole_3D( Vertex_handle v, + std::map& outer_map, + std::vector & hole) +{ + CGAL_triangulation_expensive_precondition( ! test_dim_down(v) ); + + incident_cells(v, std::back_inserter(hole)); + + for (typename std::vector::iterator cit = hole.begin(), + end = hole.end(); cit != end; ++cit) { + int indv = (*cit)->index(v); + Cell_handle opp_cit = (*cit)->neighbor( indv ); + Facet f(opp_cit, opp_cit->index(*cit)); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + outer_map[vt] = f; + for (int i=0; i<4; i++) + if ( i != indv ) + (*cit)->vertex(i)->set_cell(opp_cit); + } +} + +template < class Gt, class Tds > +template < class VertexRemover > +VertexRemover& +Triangulation_3:: +remove_dim_down(Vertex_handle v, VertexRemover &remover) +{ + CGAL_triangulation_precondition (dimension() >= 0); + + // Collect all the hidden points. + for (All_cells_iterator ci = tds().raw_cells_begin(), + end = tds().raw_cells_end(); ci != end; ++ci) + remover.add_hidden_points(ci); + + tds().remove_decrease_dimension(v, infinite_vertex()); + + // Now try to see if we need to re-orient. + if (dimension() == 2) { + Facet f = *finite_facets_begin(); + if (coplanar_orientation(f.first->vertex(0)->point(), + f.first->vertex(1)->point(), + f.first->vertex(2)->point()) == NEGATIVE) + tds().reorient(); + } + + return remover; +} + +template < class Gt, class Tds > +template < class VertexRemover > +VertexRemover& +Triangulation_3:: +remove_1D(Vertex_handle v, VertexRemover &remover) +{ + CGAL_triangulation_precondition (dimension() == 1); + + Cell_handle c1 = v->cell(); + Cell_handle c2 = c1->neighbor(c1->index(v) == 0 ? 1 : 0); + remover.add_hidden_points(c1); + remover.add_hidden_points(c2); + + tds().remove_from_maximal_dimension_simplex (v); + + return remover; +} + +template < class Gt, class Tds > +template < class VertexRemover > +VertexRemover& +Triangulation_3:: +remove_2D(Vertex_handle v, VertexRemover &remover) +{ + CGAL_triangulation_precondition(dimension() == 2); + std::list hole; + make_hole_2D(v, hole, remover); + fill_hole_2D(hole, remover); + tds().delete_vertex(v); + return remover; +} + +template < class Gt, class Tds > +template < class VertexRemover > +VertexRemover& +Triangulation_3:: +remove_3D(Vertex_handle v, VertexRemover &remover) +{ + std::vector hole; + hole.reserve(64); + + // Construct the set of vertex triples on the boundary + // with the facet just behind + typedef std::map Vertex_triple_Facet_map; + Vertex_triple_Facet_map outer_map; + Vertex_triple_Facet_map inner_map; + + make_hole_3D(v, outer_map, hole); + CGAL_assertion(remover.hidden_points_begin() == + remover.hidden_points_end() ); + + // Output the hidden points. + for (typename std::vector::iterator + hi = hole.begin(), hend = hole.end(); hi != hend; ++hi) + remover.add_hidden_points(*hi); + + bool inf = false; + unsigned int i; + // collect all vertices on the boundary + std::vector vertices; + vertices.reserve(64); + + adjacent_vertices(v, std::back_inserter(vertices)); + + // create a Delaunay triangulation of the points on the boundary + // and make a map from the vertices in remover.tmp towards the vertices + // in *this + + Unique_hash_map vmap; + Cell_handle ch = Cell_handle(); + for(i=0; i < vertices.size(); i++){ + if(! is_infinite(vertices[i])){ + Vertex_handle vh = remover.tmp.insert(vertices[i]->point(), ch); + ch = vh->cell(); + vmap[vh] = vertices[i]; + }else { + inf = true; + } + } + + if(remover.tmp.dimension()==2){ + Vertex_handle fake_inf = remover.tmp.insert(v->point()); + vmap[fake_inf] = infinite_vertex(); + } else { + vmap[remover.tmp.infinite_vertex()] = infinite_vertex(); + } + + CGAL_triangulation_assertion(remover.tmp.dimension() == 3); + + // Construct the set of vertex triples of remover.tmp + // We reorient the vertex triple so that it matches those from outer_map + // Also note that we use the vertices of *this, not of remover.tmp + + if(inf){ + for(All_cells_iterator it = remover.tmp.all_cells_begin(), + end = remover.tmp.all_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } else { + for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), + end = remover.tmp.finite_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } + // Grow inside the hole, by extending the surface + while(! outer_map.empty()){ + typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); + while(is_infinite(oit->first.first) || + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ + ++oit; + // otherwise the lookup in the inner_map fails + // because the infinite vertices are different + } + typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + Cell_handle o_ch = o_vt_f_pair.second.first; + unsigned int o_i = o_vt_f_pair.second.second; + + typename Vertex_triple_Facet_map::iterator iit = + inner_map.find(o_vt_f_pair.first); + CGAL_triangulation_assertion(iit != inner_map.end()); + typename Vertex_triple_Facet_map::value_type i_vt_f_pair = *iit; + Cell_handle i_ch = i_vt_f_pair.second.first; + unsigned int i_i = i_vt_f_pair.second.second; + + // create a new cell and glue it to the outer surface + Cell_handle new_ch = tds().create_cell(); + new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + + o_ch->set_neighbor(o_i,new_ch); + new_ch->set_neighbor(i_i, o_ch); + + // for the other faces check, if they can also be glued + for(i = 0; i < 4; i++){ + if(i != i_i){ + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } + } + } + outer_map.erase(oit); + } + tds().delete_vertex(v); + tds().delete_cells(hole.begin(), hole.end()); + + return remover; +} + +template < class Gt, class Tds > +template < class VertexRemover > +void +Triangulation_3:: +remove(Vertex_handle v, VertexRemover &remover) { + CGAL_triangulation_precondition( v != Vertex_handle()); + CGAL_triangulation_precondition( !is_infinite(v)); + CGAL_triangulation_expensive_precondition( tds().is_vertex(v) ); + + if (test_dim_down (v)) { + remove_dim_down (v, remover); + } + else { + switch (dimension()) { + case 1: remove_1D (v, remover); break; + case 2: remove_2D (v, remover); break; + case 3: remove_3D (v, remover); break; + default: + CGAL_triangulation_assertion (false); + } + } +} + +// The remove here uses the remover, but +// no function envolving hidden points +// will be used in this internal version +template < class Gt, class Tds > +template < class VertexRemover, class OutputItCells > +VertexRemover& +Triangulation_3:: +remove_dim_down(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { + remove_dim_down(v, remover); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); + afi++) *fit++ = afi; +} + +template < class Gt, class Tds > +template < class VertexRemover, class OutputItCells > +VertexRemover& +Triangulation_3:: +remove_1D(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { + Point p = v->point(); + remove_1D(v, remover); + *fit++ = locate(p); +} + +template < class Gt, class Tds > +template < class VertexRemover, class OutputItCells > +VertexRemover& +Triangulation_3:: +remove_2D(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { + CGAL_triangulation_precondition(dimension() == 2); + std::list hole; + make_hole_2D(v, hole, remover); + fill_hole_2D(hole, remover, fit); + tds().delete_vertex(v); + return remover; +} + +template < class Gt, class Tds > +template < class VertexRemover, class OutputItCells > +VertexRemover& +Triangulation_3:: +remove_3D(Vertex_handle v, VertexRemover &remover, OutputItCells fit) { + CGAL_triangulation_precondition(dimension() == 3); + + std::vector hole; + hole.reserve(64); + + // Construct the set of vertex triples on the boundary + // with the facet just behind + typedef std::map Vertex_triple_Facet_map; + Vertex_triple_Facet_map outer_map; + Vertex_triple_Facet_map inner_map; + + make_hole_3D(v, outer_map, hole); + + CGAL_assertion(remover.hidden_points_begin() == + remover.hidden_points_end() ); + + // Output the hidden points. + for (typename std::vector::iterator + hi = hole.begin(), hend = hole.end(); hi != hend; ++hi) + remover.add_hidden_points(*hi); + + bool inf = false; + unsigned int i; + // collect all vertices on the boundary + std::vector vertices; + vertices.reserve(64); + + adjacent_vertices(v, std::back_inserter(vertices)); + + // create a Delaunay triangulation of the points on the boundary + // and make a map from the vertices in remover.tmp towards the vertices + // in *this + + Unique_hash_map vmap; + Cell_handle ch = Cell_handle(); + for(i=0; i < vertices.size(); i++){ + if(! is_infinite(vertices[i])){ + Vertex_handle vh = remover.tmp.insert(vertices[i]->point(), ch); + ch = vh->cell(); + vmap[vh] = vertices[i]; + }else { + inf = true; + } + } + + if(remover.tmp.dimension()==2){ + Vertex_handle fake_inf = remover.tmp.insert(v->point()); + vmap[fake_inf] = infinite_vertex(); + } else { + vmap[remover.tmp.infinite_vertex()] = infinite_vertex(); + } + + CGAL_triangulation_assertion(remover.tmp.dimension() == 3); + + // Construct the set of vertex triples of remover.tmp + // We reorient the vertex triple so that it matches those from outer_map + // Also note that we use the vertices of *this, not of remover.tmp + + if(inf){ + for(All_cells_iterator it = remover.tmp.all_cells_begin(), + end = remover.tmp.all_cells_end(); it != end; ++it) + { + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } else { + for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), + end = remover.tmp.finite_cells_end(); it != end; ++it) + { + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } + // Grow inside the hole, by extending the surface + while(! outer_map.empty()){ + typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); + while(is_infinite(oit->first.first) || + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ + ++oit; + // otherwise the lookup in the inner_map fails + // because the infinite vertices are different + } + typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + Cell_handle o_ch = o_vt_f_pair.second.first; + unsigned int o_i = o_vt_f_pair.second.second; + + typename Vertex_triple_Facet_map::iterator iit = + inner_map.find(o_vt_f_pair.first); + CGAL_triangulation_assertion(iit != inner_map.end()); + typename Vertex_triple_Facet_map::value_type i_vt_f_pair = *iit; + Cell_handle i_ch = i_vt_f_pair.second.first; + unsigned int i_i = i_vt_f_pair.second.second; + + // create a new cell and glue it to the outer surface + Cell_handle new_ch = tds().create_cell(); + *fit++ = new_ch; + + new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + + o_ch->set_neighbor(o_i,new_ch); + new_ch->set_neighbor(i_i, o_ch); + + // for the other faces check, if they can also be glued + for(i = 0; i < 4; i++){ + if(i != i_i){ + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } + } + } + outer_map.erase(oit); + } + tds().delete_vertex(v); + tds().delete_cells(hole.begin(), hole.end()); + + return remover; +} + + +template < class Gt, class Tds > +template < class VertexRemover, class OutputItCells > +void +Triangulation_3:: +remove_and_give_new_cells(Vertex_handle v, VertexRemover &remover, + OutputItCells fit) { + CGAL_triangulation_precondition( v != Vertex_handle()); + CGAL_triangulation_precondition( !is_infinite(v)); + CGAL_triangulation_expensive_precondition( tds().is_vertex(v) ); + + if (test_dim_down (v)) { + remove_dim_down (v, remover, fit); + } + else { + switch (dimension()) { + case 1: remove_1D (v, remover, fit); break; + case 2: remove_2D (v, remover, fit); break; + case 3: remove_3D (v, remover, fit); break; + default: + CGAL_triangulation_assertion (false); + } + } +} + +// The VertexInserter is needed so as to +// allow us the usage of the insertion method +// from the particular triangulation +template +template < class VertexRemover, class VertexInserter > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +move_if_no_collision(Vertex_handle v, const Point &p, + VertexRemover &remover, VertexInserter &inserter) { + CGAL_assertion(remover.hidden_points_begin() == + remover.hidden_points_end() ); + CGAL_triangulation_precondition(!is_infinite(v)); + if(v->point() == p) return v; + const int dim = dimension(); + + // If displacements are known to be small + // we might want to optimize by checking + // whether there is a topological change + // or not before. + // In this version this will not be put inside this method + // because it is for general purposes, + // and remaining Delaunay after motion is a bit too restrictive. + // In the filtered version optimized for displacements + // it will be used as an a priori. + // However, a non-fully optimized but good version of + // is_delaunay_after_displacement is provided as an internal method of + // Delaunay_triangulation_3 (see the class for more details). + + Locate_type lt; + int li, lj; + Cell_handle loc = locate(p, lt, li, lj, v->cell()); + + if(lt == VERTEX) return loc->vertex(li); + + if(dim == 0) { + v->set_point(p); + return v; + } + + size_type n_vertices = tds().number_of_vertices(); + + if((lt == OUTSIDE_AFFINE_HULL) && (dim == 1) && (n_vertices == 3)) { + v->set_point(p); + return v; + } + + if((lt == OUTSIDE_AFFINE_HULL) && (dim == 2) && (n_vertices == 4)) { + v->set_point(p); + return v; + } + + if((lt != OUTSIDE_AFFINE_HULL) && (dim == 1)) { + + if(loc->has_vertex(v)) { + v->set_point(p); + } else { + Vertex_handle inserted = insert(p, lt, loc, li, lj); + Cell_handle f = v->cell(); + int i = f->index(v); + if (i==0) {f = f->neighbor(1);} + CGAL_triangulation_assertion(f->index(v) == 1); + Cell_handle g= f->neighbor(0); + f->set_vertex(1, g->vertex(1)); + f->set_neighbor(0,g->neighbor(0)); + g->neighbor(0)->set_neighbor(1,f); + g->vertex(1)->set_cell(f); + tds().delete_cell(g); + Cell_handle f_ins = inserted->cell(); + i = f_ins->index(inserted); + if (i==0) {f_ins = f_ins->neighbor(1);} + CGAL_triangulation_assertion(f_ins->index(inserted) == 1); + Cell_handle g_ins = f_ins->neighbor(0); + f_ins->set_vertex(1, v); + g_ins->set_vertex(0, v); + v->set_point(p); + v->set_cell(inserted->cell()); + tds().delete_vertex(inserted); + } + return v; + } + + bool dim_down = test_dim_down(v); + + if((lt != OUTSIDE_AFFINE_HULL) && dim_down && (dim == 2)) { + // verify if p and two static vertices are collinear in this case + int iinf; + Cell_handle finf = infinite_vertex()->cell(), fdone; + fdone = finf; + do { + iinf = finf->index(infinite_vertex()); + if(!finf->has_vertex(v)) break; + finf = finf->neighbor((iinf+1)%3); + } while(finf != fdone); + iinf = ~iinf; + if(this->collinear(finf->vertex(iinf&1)->point(), + finf->vertex(iinf&2)->point(), + p)) + { + v->set_point(p); + _tds.decrease_dimension(loc, loc->index(v)); + return v; + } + } + + if(((dim == 2) && (lt != OUTSIDE_AFFINE_HULL)) || + ((lt == OUTSIDE_AFFINE_HULL) && (dim == 1))) + { + + // This is insert must be from Delaunay (or the particular trian.) + // not Triangulation_3 ! + Vertex_handle inserted = inserter.insert(p, lt, loc, li, lj); + + std::list hole; + make_hole_2D(v, hole, remover); + fill_hole_2D(hole, remover); + + // fixing pointer + Cell_handle fc = inserted->cell(), done(fc); + std::vector faces_pt; + faces_pt.reserve(16); + do { + faces_pt.push_back(fc); + fc = fc->neighbor((fc->index(inserted) + 1)%3); + } while(fc != done); + std::size_t ss = faces_pt.size(); + for(std::size_t k=0; kindex(inserted); + f->set_vertex(i, v); + } + v->set_point(p); + v->set_cell(inserted->cell()); + + tds().delete_vertex(inserted); + + return v; + } + + if((lt != OUTSIDE_AFFINE_HULL) && dim_down && (dim == 3)) { + // verify if p and two static vertices are collinear in this case + std::vector ics; + incident_cells(infinite_vertex(), std::back_inserter(ics)); + std::size_t size = ics.size(); + Cell_handle finf; + for (std::size_t i=0; ihas_vertex(v)) break; + } + int iinf = finf->index(infinite_vertex()); + if(remover.tmp.coplanar(finf->vertex((iinf+1)&3)->point(), + finf->vertex((iinf+2)&3)->point(), + finf->vertex((iinf+3)&3)->point(), + p)) + { + v->set_point(p); + _tds.decrease_dimension(loc, loc->index(v)); + Facet f = *finite_facets_begin(); + if (coplanar_orientation(f.first->vertex(0)->point(), + f.first->vertex(1)->point(), + f.first->vertex(2)->point()) == NEGATIVE) + tds().reorient(); + restore_edges_after_decrease_dimension(v, remover,inserter); + return v; + } + } + + // This is insert must be from Delaunay (or the particular trian.) + // not Triangulation_3 ! + Vertex_handle inserted = inserter.insert(p, lt, loc, li, lj); + + std::vector hole; + hole.reserve(64); + + // Construct the set of vertex triples on the boundary + // with the facet just behind + typedef std::map Vertex_triple_Facet_map; + Vertex_triple_Facet_map outer_map; + Vertex_triple_Facet_map inner_map; + + make_hole_3D(v, outer_map, hole); + + CGAL_assertion(remover.hidden_points_begin() == + remover.hidden_points_end() ); + + // Output the hidden points. + for (typename std::vector::iterator + hi = hole.begin(), hend = hole.end(); hi != hend; ++hi) + remover.add_hidden_points(*hi); + + bool inf = false; + unsigned int i; + // collect all vertices on the boundary + std::vector vertices; + vertices.reserve(64); + + adjacent_vertices(v, std::back_inserter(vertices)); + + // create a Delaunay triangulation of the points on the boundary + // and make a map from the vertices in remover.tmp towards the vertices + // in *this + + Unique_hash_map vmap; + Cell_handle ch = Cell_handle(); + for(i=0; i < vertices.size(); i++){ + if(! is_infinite(vertices[i])){ + Vertex_handle vh = remover.tmp.insert(vertices[i]->point(), ch); + ch = vh->cell(); + vmap[vh] = vertices[i]; + }else { + inf = true; + } + } + + if(remover.tmp.dimension()==2){ + Vertex_handle fake_inf = remover.tmp.insert(v->point()); + vmap[fake_inf] = infinite_vertex(); + } else { + vmap[remover.tmp.infinite_vertex()] = infinite_vertex(); + } + + CGAL_triangulation_assertion(remover.tmp.dimension() == 3); + + // Construct the set of vertex triples of remover.tmp + // We reorient the vertex triple so that it matches those from outer_map + // Also note that we use the vertices of *this, not of remover.tmp + + if(inf){ + for(All_cells_iterator it = remover.tmp.all_cells_begin(), + end = remover.tmp.all_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } else { + for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), + end = remover.tmp.finite_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } + // Grow inside the hole, by extending the surface + while(! outer_map.empty()){ + typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); + while(is_infinite(oit->first.first) || + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ + ++oit; + // otherwise the lookup in the inner_map fails + // because the infinite vertices are different + } + typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + Cell_handle o_ch = o_vt_f_pair.second.first; + unsigned int o_i = o_vt_f_pair.second.second; + + typename Vertex_triple_Facet_map::iterator iit = + inner_map.find(o_vt_f_pair.first); + CGAL_triangulation_assertion(iit != inner_map.end()); + typename Vertex_triple_Facet_map::value_type i_vt_f_pair = *iit; + Cell_handle i_ch = i_vt_f_pair.second.first; + unsigned int i_i = i_vt_f_pair.second.second; + + // create a new cell and glue it to the outer surface + Cell_handle new_ch = tds().create_cell(); + + new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + + o_ch->set_neighbor(o_i,new_ch); + new_ch->set_neighbor(i_i, o_ch); + + // for the other faces check, if they can also be glued + for(i = 0; i < 4; i++){ + if(i != i_i){ + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } + } + } + outer_map.erase(oit); + } + + // fixing pointer + std::vector cells_pt; + cells_pt.reserve(64); + incident_cells(inserted, std::back_inserter(cells_pt)); + std::size_t size = cells_pt.size(); + for(std::size_t i=0; iset_vertex(c->index(inserted), v); + } + v->set_point(p); + v->set_cell(inserted->cell()); + tds().delete_vertex(inserted); + tds().delete_cells(hole.begin(), hole.end()); + return v; +} + +template +template < class VertexRemover, class VertexInserter > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +move(Vertex_handle v, const Point &p, + VertexRemover &remover, VertexInserter &inserter) { + CGAL_assertion(remover.hidden_points_begin() == + remover.hidden_points_end() ); + CGAL_triangulation_precondition(!is_infinite(v)); + if(v->point() == p) return v; + Vertex_handle w = move_if_no_collision(v,p,remover,inserter); + if(w != v) { + remove(v, remover); + return w; + } + return v; +} + +// The VertexInserter is needed so as to +// allow us the usage of the insertion method +// from the particular triangulation +template +template < class VertexRemover, class VertexInserter, class OutputItCells > +typename Triangulation_3::Vertex_handle +Triangulation_3:: +move_if_no_collision_and_give_new_cells(Vertex_handle v, const Point &p, + VertexRemover &remover, VertexInserter &inserter, OutputItCells fit) { + CGAL_assertion(remover.hidden_points_begin() == + remover.hidden_points_end() ); + CGAL_triangulation_precondition(!is_infinite(v)); + if(v->point() == p) return v; + const int dim = dimension(); + + // If displacements are known to be small + // we might want to optimize by checking + // whether there is a topological change + // or not before. + // In this version this will not be put inside this method + // because it is for general purposes, + // and remaining Delaunay after motion is a bit too restrictive. + // In the filtered version optimized for displacements + // it will be used as an a priori. + // However, a non-fully optimized but good version of + // is_delaunay_after_displacement is provided as an internal method of + // Delaunay_triangulation_3 (see the class for more details). + + Locate_type lt; + int li, lj; + Cell_handle loc = locate(p, lt, li, lj, v->cell()); + + if(lt == VERTEX) return loc->vertex(li); + + if(dim == 0) { + v->set_point(p); + return v; + } + + int n_vertices = tds().number_of_vertices(); + + if((lt == OUTSIDE_AFFINE_HULL) && (dim == 1) && (n_vertices == 3)) { + v->set_point(p); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); + afi++) *fit++ = afi; + return v; + } + + if((lt == OUTSIDE_AFFINE_HULL) && (dim == 2) && (n_vertices == 4)) { + v->set_point(p); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); + afi++) *fit++ = afi; + return v; + } + + if((lt != OUTSIDE_AFFINE_HULL) && (dim == 1)) { + if(loc->has_vertex(v)) { + v->set_point(p); + } else { + Vertex_handle inserted = insert(p, lt, loc, li, lj); + Cell_handle f = v->cell(); + int i = f->index(v); + if (i==0) {f = f->neighbor(1);} + CGAL_triangulation_assertion(f->index(v) == 1); + Cell_handle g= f->neighbor(0); + f->set_vertex(1, g->vertex(1)); + f->set_neighbor(0,g->neighbor(0)); + g->neighbor(0)->set_neighbor(1,f); + g->vertex(1)->set_cell(f); + tds().delete_cell(g); + *fit++ = f; + Cell_handle f_ins = inserted->cell(); + i = f_ins->index(inserted); + if (i==0) {f_ins = f_ins->neighbor(1);} + CGAL_triangulation_assertion(f_ins->index(inserted) == 1); + Cell_handle g_ins = f_ins->neighbor(0); + f_ins->set_vertex(1, v); + g_ins->set_vertex(0, v); + v->set_point(p); + v->set_cell(inserted->cell()); + tds().delete_vertex(inserted); + } + *fit++ = v->cell(); + if(v->cell()->neighbor(0)->has_vertex(v)) + *fit++ = v->cell()->neighbor(0); + if(v->cell()->neighbor(1)->has_vertex(v)) + *fit++ = v->cell()->neighbor(1); + return v; + } + + bool dim_down = test_dim_down(v); + + if((lt != OUTSIDE_AFFINE_HULL) && dim_down && (dim == 2)) { + // verify if p and two static vertices are collinear in this case + int iinf; + Cell_handle finf = infinite_vertex()->cell(), fdone; + fdone = finf; + do { + iinf = finf->index(infinite_vertex()); + if(!finf->has_vertex(v)) break; + finf = finf->neighbor((iinf+1)%3); + } while(finf != fdone); + iinf = ~iinf; + if(this->collinear(finf->vertex(iinf&1)->point(), + finf->vertex(iinf&2)->point(), + p)) + { + v->set_point(p); + _tds.decrease_dimension(loc, loc->index(v)); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); + afi++) *fit++ = afi; + return v; + } + } + + if(((dim == 2) && (lt != OUTSIDE_AFFINE_HULL)) || + ((lt == OUTSIDE_AFFINE_HULL) && (dim == 1))) + { + + std::set cells_set; + // This is insert must be from Delaunay (or the particular trian.) + // not Triangulation_3 ! + Vertex_handle inserted = inserter.insert(p, lt, loc, li, lj); + Cell_handle c = inserted->cell(), end = c; + do { + cells_set.insert(c); + int i = c->index(inserted); + c = c->neighbor((i+1)%3); + } while(c != end); + + std::list hole; + make_hole_2D(v, hole, remover, cells_set); + fill_hole_2D(hole, remover, fit); + + // fixing pointer + Cell_handle fc = inserted->cell(), done(fc); + std::vector faces_pt; + faces_pt.reserve(16); + do { + faces_pt.push_back(fc); + fc = fc->neighbor((fc->index(inserted) + 1)%3); + } while(fc != done); + int ss = faces_pt.size(); + for(int k=0; kindex(inserted); + f->set_vertex(i, v); + } + v->set_point(p); + v->set_cell(inserted->cell()); + + tds().delete_vertex(inserted); + + for(typename std::set::const_iterator ib = cells_set.begin(), + iend = cells_set.end(); ib != iend; ib++) *fit++ = *ib; + + return v; + } + + if((lt != OUTSIDE_AFFINE_HULL) && dim_down && (dim == 3)) { + // verify if p and two static vertices are collinear in this case + std::vector ics; + incident_cells(infinite_vertex(), std::back_inserter(ics)); + int size = ics.size(); + Cell_handle finf; + for (int i=0; ihas_vertex(v)) break; + } + int iinf = finf->index(infinite_vertex()); + if(remover.tmp.coplanar(finf->vertex((iinf+1)&3)->point(), + finf->vertex((iinf+2)&3)->point(), + finf->vertex((iinf+3)&3)->point(), + p)) + { + v->set_point(p); + _tds.decrease_dimension(loc, loc->index(v)); + Facet f = *finite_facets_begin(); + if (coplanar_orientation(f.first->vertex(0)->point(), + f.first->vertex(1)->point(), + f.first->vertex(2)->point()) == NEGATIVE) + tds().reorient(); + restore_edges_after_decrease_dimension(v, remover,inserter); + for(All_cells_iterator afi = tds().raw_cells_begin(); + afi != tds().raw_cells_end(); + afi++) *fit++ = afi; + return v; + } + } + + std::set cells_set; + + // This is insert must be from Delaunay (or the particular trian.) + // not Triangulation_3 ! + Vertex_handle inserted = inserter.insert(p, lt, loc, li, lj); + + std::vector cells_tmp; + cells_tmp.reserve(64); + incident_cells(inserted, std::back_inserter(cells_tmp)); + int size = cells_tmp.size(); + for(int i=0; i hole; + hole.reserve(64); + + // Construct the set of vertex triples on the boundary + // with the facet just behind + typedef std::map Vertex_triple_Facet_map; + Vertex_triple_Facet_map outer_map; + Vertex_triple_Facet_map inner_map; + + make_hole_3D(v, outer_map, hole); + + for(typename std::vector::const_iterator ib = hole.begin(), + iend = hole.end(); ib != iend; ib++) cells_set.erase(*ib); + + CGAL_assertion(remover.hidden_points_begin() == + remover.hidden_points_end() ); + + // Output the hidden points. + for (typename std::vector::iterator + hi = hole.begin(), hend = hole.end(); hi != hend; ++hi) + remover.add_hidden_points(*hi); + + bool inf = false; + unsigned int i; + // collect all vertices on the boundary + std::vector vertices; + vertices.reserve(64); + + adjacent_vertices(v, std::back_inserter(vertices)); + + // create a Delaunay triangulation of the points on the boundary + // and make a map from the vertices in remover.tmp towards the vertices + // in *this + + Unique_hash_map vmap; + Cell_handle ch = Cell_handle(); + for(i=0; i < vertices.size(); i++){ + if(! is_infinite(vertices[i])){ + Vertex_handle vh = remover.tmp.insert(vertices[i]->point(), ch); + ch = vh->cell(); + vmap[vh] = vertices[i]; + }else { + inf = true; + } + } + + if(remover.tmp.dimension()==2){ + Vertex_handle fake_inf = remover.tmp.insert(v->point()); + vmap[fake_inf] = infinite_vertex(); + } else { + vmap[remover.tmp.infinite_vertex()] = infinite_vertex(); + } + + CGAL_triangulation_assertion(remover.tmp.dimension() == 3); + + // Construct the set of vertex triples of remover.tmp + // We reorient the vertex triple so that it matches those from outer_map + // Also note that we use the vertices of *this, not of remover.tmp + + if(inf){ + for(All_cells_iterator it = remover.tmp.all_cells_begin(), + end = remover.tmp.all_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } else { + for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), + end = remover.tmp.finite_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + make_canonical(vt); + inner_map[vt]= f; + } + } + } + // Grow inside the hole, by extending the surface + while(! outer_map.empty()){ + typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); + while(is_infinite(oit->first.first) || + is_infinite(oit->first.second) || + is_infinite(oit->first.third)){ + ++oit; + // otherwise the lookup in the inner_map fails + // because the infinite vertices are different + } + typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + Cell_handle o_ch = o_vt_f_pair.second.first; + unsigned int o_i = o_vt_f_pair.second.second; + + typename Vertex_triple_Facet_map::iterator iit = + inner_map.find(o_vt_f_pair.first); + CGAL_triangulation_assertion(iit != inner_map.end()); + typename Vertex_triple_Facet_map::value_type i_vt_f_pair = *iit; + Cell_handle i_ch = i_vt_f_pair.second.first; + unsigned int i_i = i_vt_f_pair.second.second; + + // create a new cell and glue it to the outer surface + Cell_handle new_ch = tds().create_cell(); + *fit++ = new_ch; + + new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + + o_ch->set_neighbor(o_i,new_ch); + new_ch->set_neighbor(i_i, o_ch); + + // for the other faces check, if they can also be glued + for(i = 0; i < 4; i++){ + if(i != i_i){ + Facet f = std::pair(new_ch,i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } + } + } + outer_map.erase(oit); + } + + // fixing pointer + std::vector cells_pt; + cells_pt.reserve(64); + incident_cells(inserted, std::back_inserter(cells_pt)); + size = cells_pt.size(); + for(int i=0; iset_vertex(c->index(inserted), v); + } + v->set_point(p); + v->set_cell(inserted->cell()); + tds().delete_vertex(inserted); + tds().delete_cells(hole.begin(), hole.end()); + + for(typename std::set::const_iterator ib = cells_set.begin(), + iend = cells_set.end(); ib != iend; ib++) *fit++ = *ib; + return v; +} + +template < class Gt, class Tds > +void +Triangulation_3:: +_make_big_hole_3D( Vertex_handle v, + std::map& outer_map, + std::vector & hole, + std::vector & vertices, + std::map &vstates) +{ + + Cell_handle start = v->cell(); + start->tds_data().mark_processed(); + hole.push_back(start); + std::size_t i=0, n=1; + while(i < n) + { + + Cell_handle c = hole[i++]; + + for(int k=0; k<4; k++) + { + Vertex_handle v0 = c->vertex(k); + + const REMOVE_VERTEX_STATE vst = vstates[v0]; + + if(vst == CLEAR) + { + vstates[v0] = EXTREMITY; + vertices.push_back(v0); + } else if(vst == TO_REMOVE) { + // we mark the vertices, so all the vertices + // from the same cluster will be skipped + // in the remove_cluster_3D function + vstates[v0] = PROCESSED; + } + + int i1 = vertex_triple_index(k, 0); + int i2 = vertex_triple_index(k, 1); + int i3 = vertex_triple_index(k, 2); + + Vertex_handle v1 = c->vertex(i1); + Vertex_handle v2 = c->vertex(i2); + Vertex_handle v3 = c->vertex(i3); + + Cell_handle opp_cit = c->neighbor(k); + int opp_i = tds().mirror_index(c,k); + Vertex_handle vm = opp_cit->vertex(opp_i); + + bool pb1 = false, pb2 = false, pb3 = false, pbm = false; + + const REMOVE_VERTEX_STATE vst1 = vstates[v1]; + pb1 = vst1 == TO_REMOVE || vst1 == PROCESSED; + + if(!pb1) { + const REMOVE_VERTEX_STATE vst2 = vstates[v2]; + pb2 = vst2 == TO_REMOVE || vst2 == PROCESSED; + + if(!pb2) { + const REMOVE_VERTEX_STATE vst3 = vstates[v3]; + pb3 = vst3 == TO_REMOVE || vst3 == PROCESSED; + + if(!pb3) { + const REMOVE_VERTEX_STATE vstm = vstates[vm]; + pbm = vstm == TO_REMOVE || vstm == PROCESSED; + } + + } + + } + + bool bad_opposite_cell = pb1 || pb2 || pb3 || pbm; + + // update the hole if needed + // when the vertex is not to be removed + if(bad_opposite_cell) + { + if(opp_cit->tds_data().is_clear()) + { + hole.push_back(opp_cit); + opp_cit->tds_data().mark_processed(); + n++; + } + continue; + } + + Facet f(opp_cit, opp_i); + Vertex_triple vt = make_vertex_triple(f); + make_canonical(vt); + outer_map[vt] = f; + v1->set_cell(opp_cit); + v2->set_cell(opp_cit); + v3->set_cell(opp_cit); + vm->set_cell(opp_cit); + + } + } + + std::size_t vsize = vertices.size(); + for(std::size_t i=0; i +template < class InputIterator, class VertexRemover > +bool +Triangulation_3:: +_remove_cluster_3D(InputIterator first, InputIterator beyond, VertexRemover &remover, + std::map &vstates) { + InputIterator init = first; + while(first != beyond) + { + Vertex_handle v = *first++; + + if(vstates[v] == PROCESSED) continue; + + // _make_big_hole_3D and we fill the hole for each cluster + vstates[v] = PROCESSED; + + // here, we make the hole for the cluster with v inside + typedef std::map Vertex_triple_Facet_map; + std::vector hole; + std::vector vertices; + hole.reserve(64); + vertices.reserve(32); + Vertex_triple_Facet_map outer_map; + _make_big_hole_3D(v, outer_map, hole, vertices, vstates); + + // the connectivity is totally lost, we need to rebuild + if(!outer_map.size()) + { + std::size_t nh = hole.size(); + for(std::size_t i=0; itds_data().clear(); + return false; + } + + std::size_t vsi = vertices.size(); + + bool inf = false; + std::size_t i; + Unique_hash_map vmap; + Cell_handle ch = Cell_handle(); + + if(vsi > 100) + { + // spatial sort if too many points + std::vector vps; + std::map mp_vps; + for(i=0; iis_infinite(vv)) { + vps.push_back(vv->point()); + mp_vps[vv->point()] = vv; + } else inf = true; + } + spatial_sort(vps.begin(), vps.end()); + + std::size_t svps = vps.size(); + + for(i=0; i < svps; i++){ + Vertex_handle vv = mp_vps[vps[i]]; + Vertex_handle vh = remover.tmp.insert(vv->point(), ch); + ch = vh->cell(); + vmap[vh] = vv; + } + + if(remover.tmp.dimension()==2){ + Vertex_handle fake_inf = remover.tmp.insert(v->point()); + vmap[fake_inf] = this->infinite_vertex(); + } else { + vmap[remover.tmp.infinite_vertex()] = this->infinite_vertex(); + } + } else { + + for(i=0; i < vsi; i++){ + if(!this->is_infinite(vertices[i])){ + Vertex_handle vh = remover.tmp.insert(vertices[i]->point(), ch); + ch = vh->cell(); + vmap[vh] = vertices[i]; + } else { + inf = true; + } + } + + if(remover.tmp.dimension()==2){ + Vertex_handle fake_inf = remover.tmp.insert(v->point()); + vmap[fake_inf] = this->infinite_vertex(); + } else { + vmap[remover.tmp.infinite_vertex()] = this->infinite_vertex(); + } + } + + Vertex_triple_Facet_map inner_map; + + if(inf){ + for(All_cells_iterator it = remover.tmp.all_cells_begin(), + end = remover.tmp.all_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++) { + Facet f = std::pair(it,i); + Vertex_triple vt_aux = this->make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + this->make_canonical(vt); + inner_map[vt]= f; + } + } + } else { + for(Finite_cells_iterator it = remover.tmp.finite_cells_begin(), + end = remover.tmp.finite_cells_end(); it != end; ++it){ + for(i=0; i < 4; i++){ + Facet f = std::pair(it,i); + Vertex_triple vt_aux = this->make_vertex_triple(f); + Vertex_triple vt(vmap[vt_aux.first],vmap[vt_aux.third],vmap[vt_aux.second]); + this->make_canonical(vt); + inner_map[vt]= f; + } + } + } + + // Grow inside the hole, by extending the surface + while(! outer_map.empty()){ + typename Vertex_triple_Facet_map::iterator oit = outer_map.begin(); + + while(this->is_infinite(oit->first.first) || + this->is_infinite(oit->first.second) || + this->is_infinite(oit->first.third)){ + ++oit; + // otherwise the lookup in the inner_map fails + // because the infinite vertices are different + } + typename Vertex_triple_Facet_map::value_type o_vt_f_pair = *oit; + Cell_handle o_ch = o_vt_f_pair.second.first; + unsigned int o_i = o_vt_f_pair.second.second; + + typename Vertex_triple_Facet_map::iterator iit = + inner_map.find(o_vt_f_pair.first); + CGAL_triangulation_assertion(iit != inner_map.end()); + typename Vertex_triple_Facet_map::value_type i_vt_f_pair = *iit; + Cell_handle i_ch = i_vt_f_pair.second.first; + unsigned int i_i = i_vt_f_pair.second.second; + + // create a new cell and glue it to the outer surface + Cell_handle new_ch = tds().create_cell(); + new_ch->set_vertices(vmap[i_ch->vertex(0)], vmap[i_ch->vertex(1)], + vmap[i_ch->vertex(2)], vmap[i_ch->vertex(3)]); + + o_ch->set_neighbor(o_i,new_ch); + new_ch->set_neighbor(i_i, o_ch); + + for(i=0;i<4;i++) new_ch->vertex(i)->set_cell(new_ch); + + // for the other faces check, if they can also be glued + for(i = 0; i < 4; i++){ + if(i != i_i){ + Facet f = std::pair(new_ch,i); + Vertex_triple vt = this->make_vertex_triple(f); + this->make_canonical(vt); + std::swap(vt.second,vt.third); + typename Vertex_triple_Facet_map::iterator oit2 = outer_map.find(vt); + if(oit2 == outer_map.end()){ + std::swap(vt.second,vt.third); + outer_map[vt]= f; + } else { + // glue the faces + typename Vertex_triple_Facet_map::value_type o_vt_f_pair2 = *oit2; + Cell_handle o_ch2 = o_vt_f_pair2.second.first; + int o_i2 = o_vt_f_pair2.second.second; + o_ch2->set_neighbor(o_i2,new_ch); + new_ch->set_neighbor(i, o_ch2); + outer_map.erase(oit2); + } + } + } + + outer_map.erase(oit); + } + + this->tds().delete_cells(hole.begin(), hole.end()); + remover.tmp.clear(); + + } + + this->tds().delete_vertices(init, beyond); + + return true; +} + +template < class Gt, class Tds > +template < class InputIterator > +bool +Triangulation_3:: +does_repeat_in_range(InputIterator first, InputIterator beyond) const { + std::set s; + while (first!=beyond) if (! s.insert(*first++).second ) return true; + return false; +} + +template < class Gt, class Tds > +template < class InputIterator > +bool +Triangulation_3:: +infinite_vertex_in_range(InputIterator first, InputIterator beyond) const { + while(first != beyond) if(is_infinite(*first++)) return true; + return false; +} + +template < class Gt, class Tds > +template < class InputIterator, class VertexRemover > +typename Triangulation_3::size_type +Triangulation_3:: +remove(InputIterator first, InputIterator beyond, VertexRemover &remover) { + CGAL_triangulation_precondition(!does_repeat_in_range(first, beyond)); + CGAL_triangulation_precondition(!infinite_vertex_in_range(first, beyond)); + size_type n = number_of_vertices(); + InputIterator init = first, init2 = first; + if(dimension() == 3 && n > 4) + { + // If we could add states on a vertex base as it is done + // for cells, it would improve the performance. + std::map vstates; + _mark_vertices_to_remove(first, beyond, vstates); + if(!_test_dim_down_cluster(vstates)) + { + if(_remove_cluster_3D(init, beyond, remover, vstates)) + return n - number_of_vertices(); + } + } + + // dimension() < 3 or + // no connectivity of the remaining vertices + // we remove one by one + while (init2 != beyond) { + Vertex_handle v = *init2++; + remover.tmp.clear(); + remove(v, remover); + } + return n - number_of_vertices(); +} + +template < class GT, class Tds > +bool +Triangulation_3:: +is_valid(bool verbose, int level) const +{ + if ( ! _tds.is_valid(verbose,level) ) { + if (verbose) + std::cerr << "invalid data structure" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + if ( infinite_vertex() == Vertex_handle() ) { + if (verbose) + std::cerr << "no infinite vertex" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + switch ( dimension() ) { + case 3: + { + for(Finite_cells_iterator it = finite_cells_begin(), end = finite_cells_end(); + it != end; ++it) + is_valid_finite(it, verbose, level); + break; + } + case 2: + { + for(Finite_facets_iterator it = finite_facets_begin(), end = finite_facets_end(); + it != end; ++it) + is_valid_finite(it->first,verbose,level); + break; + } + case 1: + { + for(Finite_edges_iterator it = finite_edges_begin(), end = finite_edges_end(); + it != end; ++it) + is_valid_finite(it->first,verbose,level); + break; + } + } + if (verbose) + std::cerr << "valid triangulation" << std::endl; + return true; +} + +template < class GT, class Tds > +bool +Triangulation_3:: +is_valid(Cell_handle c, bool verbose, int level) const +{ + if ( ! _tds.is_valid(c,verbose,level) ) { + if (verbose) { + std::cerr << "combinatorially invalid cell"; + for (int i=0; i <= dimension(); i++ ) + std::cerr << c->vertex(i)->point() << ", "; + std::cerr << std::endl; + } + CGAL_triangulation_assertion(false); + return false; + } + if ( ! is_infinite(c) ) + is_valid_finite(c, verbose, level); + if (verbose) + std::cerr << "geometrically valid cell" << std::endl; + return true; +} + + +template < class GT, class Tds > +bool +Triangulation_3:: +is_valid_finite(Cell_handle c, bool verbose, int) const +{ + switch ( dimension() ) { + case 3: + { + if ( orientation(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point()) != POSITIVE ) { + if (verbose) + std::cerr << "badly oriented cell " + << c->vertex(0)->point() << ", " + << c->vertex(1)->point() << ", " + << c->vertex(2)->point() << ", " + << c->vertex(3)->point() << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + break; + } + case 2: + { + if (coplanar_orientation(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point()) != POSITIVE) { + if (verbose) + std::cerr << "badly oriented face " + << c->vertex(0)->point() << ", " + << c->vertex(1)->point() << ", " + << c->vertex(2)->point() << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + break; + } + case 1: + { + const Point & p0 = c->vertex(0)->point(); + const Point & p1 = c->vertex(1)->point(); + + Vertex_handle v = c->neighbor(0)->vertex(c->neighbor(0)->index(c)); + if ( ! is_infinite(v) ) + { + if ( collinear_position(p0, p1, v->point()) != MIDDLE ) { + if (verbose) + std::cerr << "badly oriented edge " + << p0 << ", " << p1 << std::endl + << "with neighbor 0" + << c->neighbor(0)->vertex(1-c->neighbor(0)->index(c)) + ->point() + << ", " << v->point() << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + + v = c->neighbor(1)->vertex(c->neighbor(1)->index(c)); + if ( ! is_infinite(v) ) + { + if ( collinear_position(p1, p0, v->point()) != MIDDLE ) { + if (verbose) + std::cerr << "badly oriented edge " + << p0 << ", " << p1 << std::endl + << "with neighbor 1" + << c->neighbor(1)->vertex(1-c->neighbor(1)->index(c)) + ->point() + << ", " << v->point() << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + break; + } + } + return true; +} + + +namespace internal { + +// Internal function used by operator==. +template < class GT, class Tds1, class Tds2 > +bool +test_next(const Triangulation_3 &t1, + const Triangulation_3 &t2, + typename Triangulation_3::Cell_handle c1, + typename Triangulation_3::Cell_handle c2, + std::map::Cell_handle, + typename Triangulation_3::Cell_handle> &Cmap, + std::map::Vertex_handle, + typename Triangulation_3::Vertex_handle> &Vmap) +{ + // This function tests and registers the 4 neighbors of c1/c2, + // and recursively calls itself over them. + // Returns false if an inequality has been found. + + // Precondition: c1, c2 have been registered as well as their 4 vertices. + CGAL_triangulation_precondition(t1.dimension() >= 2); + CGAL_triangulation_precondition(Cmap[c1] == c2); + CGAL_triangulation_precondition(Vmap.find(c1->vertex(0)) != Vmap.end()); + CGAL_triangulation_precondition(Vmap.find(c1->vertex(1)) != Vmap.end()); + CGAL_triangulation_precondition(Vmap.find(c1->vertex(2)) != Vmap.end()); + CGAL_triangulation_precondition(t1.dimension() == 2 || + Vmap.find(c1->vertex(3)) != Vmap.end()); + + typedef Triangulation_3 Tr1; + typedef Triangulation_3 Tr2; + typedef typename Tr1::Vertex_handle Vertex_handle1; + typedef typename Tr1::Cell_handle Cell_handle1; + typedef typename Tr2::Vertex_handle Vertex_handle2; + typedef typename Tr2::Cell_handle Cell_handle2; + typedef typename std::map::const_iterator Cit; + typedef typename std::map::const_iterator Vit; + + for (int i=0; i <= t1.dimension(); ++i) { + Cell_handle1 n1 = c1->neighbor(i); + Cit cit = Cmap.find(n1); + Vertex_handle1 v1 = c1->vertex(i); + Vertex_handle2 v2 = Vmap[v1]; + Cell_handle2 n2 = c2->neighbor(c2->index(v2)); + if (cit != Cmap.end()) { + // n1 was already registered. + if (cit->second != n2) + return false; + continue; + } + // n1 has not yet been registered. + // We check that the new vertices match geometrically. + // And we register them. + Vertex_handle1 vn1 = n1->vertex(n1->index(c1)); + Vertex_handle2 vn2 = n2->vertex(n2->index(c2)); + Vit vit = Vmap.find(vn1); + if (vit != Vmap.end()) { + // vn1 already registered + if (vit->second != vn2) + return false; + } + else { + if (t2.is_infinite(vn2)) + return false; // vn1 can't be infinite, + // since it would have been registered. + if (t1.geom_traits().compare_xyz_3_object()(vn1->point(), + vn2->point()) != 0) + return false; + // We register vn1/vn2. + Vmap.insert(std::make_pair(vn1, vn2)); + } + + // We register n1/n2. + Cmap.insert(std::make_pair(n1, n2)); + + // We recurse on n1/n2. + if (!test_next(t1, t2, n1, n2, Cmap, Vmap)) + return false; + } + + return true; +} + +} // namespace internal + + +template < class GT, class Tds1, class Tds2 > +bool +operator==(const Triangulation_3 &t1, + const Triangulation_3 &t2) +{ + typedef typename Triangulation_3::Vertex_handle Vertex_handle1; + typedef typename Triangulation_3::Cell_handle Cell_handle1; + typedef typename Triangulation_3::Vertex_handle Vertex_handle2; + typedef typename Triangulation_3::Cell_handle Cell_handle2; + + typedef typename Triangulation_3::Point Point; + typedef typename Triangulation_3::Geom_traits::Equal_3 Equal_3; + typedef typename Triangulation_3::Geom_traits::Compare_xyz_3 Compare_xyz_3; + + Equal_3 equal = t1.geom_traits().equal_3_object(); + Compare_xyz_3 cmp1 = t1.geom_traits().compare_xyz_3_object(); + Compare_xyz_3 cmp2 = t2.geom_traits().compare_xyz_3_object(); + + // Some quick checks. + if (t1.dimension() != t2.dimension() + || t1.number_of_vertices() != t2.number_of_vertices() + || t1.number_of_cells() != t2.number_of_cells()) + return false; + + int dim = t1.dimension(); + // Special case for dimension < 1. + // The triangulation is uniquely defined in these cases. + if (dim < 1) + return true; + + // Special case for dimension == 1. + if (dim == 1) { + // It's enough to test that the points are the same, + // since the triangulation is uniquely defined in this case. + using namespace boost; + std::vector V1 (t1.points_begin(), t1.points_end()); + std::vector V2 (t2.points_begin(), t2.points_end()); + std::sort(V1.begin(), V1.end(), bind(cmp1, _1, _2) == NEGATIVE); + std::sort(V2.begin(), V2.end(), bind(cmp2, _1, _2) == NEGATIVE); + return V1 == V2; + } + + // We will store the mapping between the 2 triangulations vertices and + // cells in 2 maps. + std::map Vmap; + std::map Cmap; + + // Handle the infinite vertex. + Vertex_handle1 v1 = t1.infinite_vertex(); + Vertex_handle2 iv2 = t2.infinite_vertex(); + Vmap.insert(std::make_pair(v1, iv2)); + + // We pick one infinite cell of t1, and try to match it against the + // infinite cells of t2. + Cell_handle1 c = v1->cell(); + Vertex_handle1 v2 = c->vertex((c->index(v1)+1)%(dim+1)); + Vertex_handle1 v3 = c->vertex((c->index(v1)+2)%(dim+1)); + Vertex_handle1 v4 = c->vertex((c->index(v1)+3)%(dim+1)); + const Point &p2 = v2->point(); + const Point &p3 = v3->point(); + const Point &p4 = v4->point(); + + std::vector ics; + t2.incident_cells(iv2, std::back_inserter(ics)); + for (typename std::vector::const_iterator cit = ics.begin(); + cit != ics.end(); ++cit) { + int inf = (*cit)->index(iv2); + + if (equal(p2, (*cit)->vertex((inf+1)%(dim+1))->point())) + Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+1)%(dim+1)))); + else if (equal(p2, (*cit)->vertex((inf+2)%(dim+1))->point())) + Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+2)%(dim+1)))); + else if (dim == 3 && + equal(p2, (*cit)->vertex((inf+3)%(dim+1))->point())) + Vmap.insert(std::make_pair(v2, (*cit)->vertex((inf+3)%(dim+1)))); + else + continue; // None matched v2. + + if (equal(p3, (*cit)->vertex((inf+1)%(dim+1))->point())) + Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+1)%(dim+1)))); + else if (equal(p3, (*cit)->vertex((inf+2)%(dim+1))->point())) + Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+2)%(dim+1)))); + else if (dim == 3 && + equal(p3, (*cit)->vertex((inf+3)%(dim+1))->point())) + Vmap.insert(std::make_pair(v3, (*cit)->vertex((inf+3)%(dim+1)))); + else + continue; // None matched v3. + + if (dim == 3) { + if (equal(p4, (*cit)->vertex((inf+1)%(dim+1))->point())) + Vmap.insert(std::make_pair(v4, + (*cit)->vertex((inf+1)%(dim+1)))); + else if (equal(p4, (*cit)->vertex((inf+2)%(dim+1))->point())) + Vmap.insert(std::make_pair(v4, + (*cit)->vertex((inf+2)%(dim+1)))); + else if (equal(p4, (*cit)->vertex((inf+3)%(dim+1))->point())) + Vmap.insert(std::make_pair(v4, + (*cit)->vertex((inf+3)%(dim+1)))); + else + continue; // None matched v4. + } + + // Found it ! + Cmap.insert(std::make_pair(c, *cit)); + break; + } + + if (Cmap.size() == 0) + return false; + + // We now have one cell, we need to propagate recursively. + return internal::test_next(t1, t2, + Cmap.begin()->first, Cmap.begin()->second, Cmap, Vmap); +} + +template < class GT, class Tds1, class Tds2 > +inline +bool +operator!=(const Triangulation_3 &t1, + const Triangulation_3 &t2) +{ + return ! (t1 == t2); +} + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_3.h new file mode 100644 index 00000000000..ff4dec07903 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_3.h @@ -0,0 +1,103 @@ +// Copyright (c) 1999 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud +// Sylvain Pion + +// cell of a triangulation of any dimension <=3 + +#ifndef CGAL_TRIANGULATION_CELL_BASE_3_H +#define CGAL_TRIANGULATION_CELL_BASE_3_H + +#include +#include +#include + +namespace CGAL { + +template < typename GT, typename Cb = Triangulation_ds_cell_base_3<> > +class Triangulation_cell_base_3 + : public Cb +{ +public: + typedef typename Cb::Vertex_handle Vertex_handle; + typedef typename Cb::Cell_handle Cell_handle; + + typedef GT Geom_traits; + typedef typename Geom_traits::Point_3 Point; + + typedef Point* Point_container; + typedef Point* Point_iterator; + typedef const Point* Point_const_iterator; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Cb::template Rebind_TDS::Other Cb2; + typedef Triangulation_cell_base_3 Other; + }; + + Triangulation_cell_base_3() + : Cb() {} + + Triangulation_cell_base_3(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + : Cb(v0, v1, v2, v3) {} + + Triangulation_cell_base_3(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) + : Cb(v0, v1, v2, v3, n0, n1, n2, n3) {} + + Point_iterator hidden_points_begin() const { return hidden_points_end(); } + Point_iterator hidden_points_end() const { return NULL; } + void hide_point (const Point &) const { } + + typename Geom_traits::Point_3 + circumcenter(const Geom_traits& gt = Geom_traits()) const + { + return gt.construct_circumcenter_3_object()(this->vertex(0)->point(), + this->vertex(1)->point(), + this->vertex(2)->point(), + this->vertex(3)->point()); + } + +}; + +// The following should be useless. +#if 0 +template < class GT, class Cb > +inline +std::istream& +operator>>(std::istream &is, Triangulation_cell_base_3 &c) + // non combinatorial information. Default = nothing +{ + return is >> static_cast(c); +} + +template < class GT, class Cb > +inline +std::ostream& +operator<<(std::ostream &os, const Triangulation_cell_base_3 &c) + // non combinatorial information. Default = nothing +{ + return os << static_cast(c); +} +#endif + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_CELL_BASE_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_with_circumcenter_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_with_circumcenter_3.h new file mode 100644 index 00000000000..a0ef35940e2 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_with_circumcenter_3.h @@ -0,0 +1,131 @@ +// Copyright (c) 1999-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud +// Sylvain Pion + +// cell of a triangulation of any dimension <=3, +// storing its circumcenter lazily. + +#ifndef CGAL_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H +#define CGAL_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H + +#include +#include +#include + +namespace CGAL { + +template < typename GT, typename Cb = Triangulation_ds_cell_base_3<> > +class Triangulation_cell_base_with_circumcenter_3 + : public Cb +{ + typedef typename GT::Point_3 Point_3; + + mutable Point_3 * circumcenter_; + + void invalidate_circumcenter() + { + if (circumcenter_) { + delete circumcenter_; + circumcenter_ = NULL; + } + } + +public: + typedef typename Cb::Vertex_handle Vertex_handle; + typedef typename Cb::Cell_handle Cell_handle; + + typedef GT Geom_traits; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Cb::template Rebind_TDS::Other Cb2; + typedef Triangulation_cell_base_with_circumcenter_3 Other; + }; + + Triangulation_cell_base_with_circumcenter_3() + : Cb(), circumcenter_(NULL) {} + + Triangulation_cell_base_with_circumcenter_3 + (const Triangulation_cell_base_with_circumcenter_3 &c) + : Cb(c), circumcenter_(c.circumcenter_ != NULL ? new Point_3(*(c.circumcenter_)) : NULL) + {} + + Triangulation_cell_base_with_circumcenter_3& + operator=(const Triangulation_cell_base_with_circumcenter_3 &c) + { + Triangulation_cell_base_with_circumcenter_3 tmp=c; + std::swap(tmp, *this); + return *this; + } + + Triangulation_cell_base_with_circumcenter_3( + Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + : Cb(v0, v1, v2, v3), circumcenter_(NULL) {} + + Triangulation_cell_base_with_circumcenter_3( + Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) + : Cb(v0, v1, v2, v3, n0, n1, n2, n3), circumcenter_(NULL) {} + + ~Triangulation_cell_base_with_circumcenter_3() + { + delete circumcenter_; + } + + // We must override the functions that modify the vertices. + // And if the point inside a vertex is modified, we fail, + // but there's not much we can do for this now. + void set_vertex(int i, Vertex_handle v) + { + invalidate_circumcenter(); + Cb::set_vertex(i, v); + } + + void set_vertices() + { + invalidate_circumcenter(); + Cb::set_vertices(); + } + + void set_vertices(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + { + invalidate_circumcenter(); + Cb::set_vertices(v0, v1, v2, v3); + } + + const Point_3 & + circumcenter(const Geom_traits& gt = Geom_traits()) const + { + if (circumcenter_ == NULL) { + circumcenter_ = new Point_3( + gt.construct_circumcenter_3_object()(this->vertex(0)->point(), + this->vertex(1)->point(), + this->vertex(2)->point(), + this->vertex(3)->point())); + } + return *circumcenter_; + } +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_CELL_BASE_WITH_CIRCUMCENTER_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_with_info_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_with_info_3.h new file mode 100644 index 00000000000..68d344f6507 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_cell_base_with_info_3.h @@ -0,0 +1,65 @@ +// Copyright (c) 2003 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +// cell of a triangulation of any dimension <=3 + +#ifndef CGAL_TRIANGULATION_CELL_BASE_WITH_INFO_3_H +#define CGAL_TRIANGULATION_CELL_BASE_WITH_INFO_3_H + +#include + +namespace CGAL { + +template < typename Info_, typename GT, + typename Cb = Triangulation_cell_base_3 > +class Triangulation_cell_base_with_info_3 + : public Cb +{ + Info_ _info; +public: + typedef typename Cb::Vertex_handle Vertex_handle; + typedef typename Cb::Cell_handle Cell_handle; + typedef Info_ Info; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Cb::template Rebind_TDS::Other Cb2; + typedef Triangulation_cell_base_with_info_3 Other; + }; + + Triangulation_cell_base_with_info_3() + : Cb() {} + + Triangulation_cell_base_with_info_3(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + : Cb(v0, v1, v2, v3) {} + + Triangulation_cell_base_with_info_3(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) + : Cb(v0, v1, v2, v3, n0, n1, n2, n3) {} + + const Info& info() const { return _info; } + Info& info() { return _info; } +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_CELL_BASE_WITH_INFO_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_data_structure_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_data_structure_3.h new file mode 100644 index 00000000000..d53a516c771 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_data_structure_3.h @@ -0,0 +1,3472 @@ +// Copyright (c) 1999-2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud +// Sylvain Pion + +// combinatorial triangulation of the boundary of a polytope +// of dimension d in dimension d+1 +// for -1 <= d <= 3 + +#ifndef CGAL_TRIANGULATION_DATA_STRUCTURE_3_H +#define CGAL_TRIANGULATION_DATA_STRUCTURE_3_H + +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include + +#include +#include + +#ifdef CGAL_HAS_THREADS +# include +#endif + + +namespace CGAL { + +// TODO : noms : Vb != Vertex_base : clarifier. + +template < class Vb = Triangulation_ds_vertex_base_3<>, + class Cb = Triangulation_ds_cell_base_3<> > +class Triangulation_data_structure_3 + : public Triangulation_utils_3 +{ + typedef Triangulation_data_structure_3 Tds; + +public: + + // Tools to change the Vertex and Cell types of the TDS. + template < typename Vb2 > + struct Rebind_vertex { + typedef Triangulation_data_structure_3 Other; + }; + + template < typename Cb2 > + struct Rebind_cell { + typedef Triangulation_data_structure_3 Other; + }; + + // Put this TDS inside the Vertex and Cell types. + typedef typename Vb::template Rebind_TDS::Other Vertex; + typedef typename Cb::template Rebind_TDS::Other Cell; + + class Cell_data { + unsigned char conflict_state; + public: + Cell_data() : conflict_state(0) {} + + void clear() { conflict_state = 0; } + void mark_in_conflict() { conflict_state = 1; } + void mark_on_boundary() { conflict_state = 2; } + void mark_processed() { conflict_state = 1; } + + bool is_clear() const { return conflict_state == 0; } + bool is_in_conflict() const { return conflict_state == 1; } + bool is_on_boundary() const { return conflict_state == 2; } + bool processed() const { return conflict_state == 1; } + }; + +private: + + friend class internal::Triangulation_ds_facet_iterator_3; + friend class internal::Triangulation_ds_edge_iterator_3; + + friend class internal::Triangulation_ds_cell_circulator_3; + friend class internal::Triangulation_ds_facet_circulator_3; + +public: + + typedef Compact_container Cell_range; + typedef Compact_container Vertex_range; + + typedef typename Cell_range::size_type size_type; + typedef typename Cell_range::difference_type difference_type; + + typedef typename Cell_range::iterator Cell_iterator; + typedef typename Vertex_range::iterator Vertex_iterator; + + typedef internal::Triangulation_ds_facet_iterator_3 Facet_iterator; + typedef internal::Triangulation_ds_edge_iterator_3 Edge_iterator; + + typedef internal::Triangulation_ds_cell_circulator_3 Cell_circulator; + typedef internal::Triangulation_ds_facet_circulator_3 Facet_circulator; + +//private: // In 2D only : + typedef internal::Triangulation_ds_face_circulator_3 Face_circulator; + + typedef Vertex_iterator Vertex_handle; + typedef Cell_iterator Cell_handle; + + typedef std::pair Facet; + typedef Triple Edge; + + typedef Triangulation_simplex_3 Simplex; +#ifndef CGAL_TDS_USE_OLD_CREATE_STAR_3 + //internally used for create_star_3 (faster than a tuple) + struct iAdjacency_info{ + int v1; + Cell_handle v2; + int v3; + Cell_handle v4; + int v5; + int v6; + iAdjacency_info(){} + iAdjacency_info(int a1,Cell_handle a2,int a3,Cell_handle a4,int a5 ,int a6): + v1(a1),v2(a2),v3(a3),v4(a4),v5(a5),v6(a6) {} + void update_variables(int& a1,Cell_handle& a2,int& a3,Cell_handle& a4,int& a5 ,int& a6) + { + a1=v1; + a2=v2; + a3=v3; + a4=v4; + a5=v5; + a6=v6; + } + }; +#endif + + +public: + Triangulation_data_structure_3() + : _dimension(-2) + {} + + Triangulation_data_structure_3(const Tds & tds) + { + copy_tds(tds); + } + + Tds & operator= (const Tds & tds) + { + if (&tds != this) { + Tds tmp(tds); + swap(tmp); + } + return *this; + } + + size_type number_of_vertices() const { return vertices().size(); } + + int dimension() const {return _dimension;} + + size_type number_of_cells() const + { + if ( dimension() < 3 ) return 0; + return cells().size(); + } + + size_type number_of_facets() const + { + if ( dimension() < 2 ) return 0; + return std::distance(facets_begin(), facets_end()); + } + + size_type number_of_edges() const + { + if ( dimension() < 1 ) return 0; + return std::distance(edges_begin(), edges_end()); + } + + // USEFUL CONSTANT TIME FUNCTIONS + + // SETTING + + void set_dimension(int n) { _dimension = n; } + + Vertex_handle create_vertex(const Vertex &v) + { + return vertices().insert(v); + } + + Vertex_handle create_vertex() + { + return vertices().emplace(); + } + + Vertex_handle create_vertex(Vertex_handle v) + { + return create_vertex(*v); + } + + Cell_handle create_cell(const Cell &c) + { + return cells().insert(c); + } + + Cell_handle create_cell() + { + return cells().emplace(); + } + + Cell_handle create_cell(Cell_handle c) + { + return create_cell(*c); + } + + Cell_handle create_cell(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + { + return cells().emplace(v0, v1, v2, v3); + } + + Cell_handle create_cell(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) + { + return cells().emplace(v0, v1, v2, v3, n0, n1, n2, n3); + } + + Cell_handle create_face() + { + CGAL_triangulation_precondition(dimension()<3); + return create_cell(); + } + + Cell_handle create_face(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2) + { + CGAL_triangulation_precondition(dimension()<3); + return cells().emplace(v0, v1, v2, Vertex_handle()); + } + + // The following functions come from TDS_2. + Cell_handle create_face(Cell_handle f0, int i0, + Cell_handle f1, int i1, + Cell_handle f2, int i2) + { + CGAL_triangulation_precondition(dimension() <= 2); + Cell_handle newf = create_face(f0->vertex(cw(i0)), + f1->vertex(cw(i1)), + f2->vertex(cw(i2))); + set_adjacency(newf, 2, f0, i0); + set_adjacency(newf, 0, f1, i1); + set_adjacency(newf, 1, f2, i2); + return newf; + } + + Cell_handle create_face(Cell_handle f0, int i0, + Cell_handle f1, int i1) + { + CGAL_triangulation_precondition(dimension() <= 2); + Cell_handle newf = create_face(f0->vertex(cw(i0)), + f1->vertex(cw(i1)), + f1->vertex(ccw(i1))); + set_adjacency(newf, 2, f0, i0); + set_adjacency(newf, 0, f1, i1); + return newf; + } + + Cell_handle create_face(Cell_handle f, int i, Vertex_handle v) + { + CGAL_triangulation_precondition(dimension() <= 2); + Cell_handle newf = create_face(f->vertex(cw(i)), + f->vertex(ccw(i)), + v); + set_adjacency(newf, 2, f, i); + return newf; + } + + // not documented + void read_cells(std::istream& is, std::map< std::size_t, Vertex_handle > &V, + std::size_t & m, std::map< std::size_t, Cell_handle > &C ); + // not documented + void print_cells(std::ostream& os, + const std::map &V ) const; + + // ACCESS FUNCTIONS + + void delete_vertex( Vertex_handle v ) + { + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + vertices().erase(v); + } + + void delete_cell( Cell_handle c ) + { + CGAL_triangulation_expensive_precondition( is_simplex(c) ); + cells().erase(c); + } + + template + void delete_vertices(InputIterator begin, InputIterator end) + { + for(; begin != end; ++begin) + delete_vertex(*begin); + } + + template + void delete_cells(InputIterator begin, InputIterator end) + { + for(; begin != end; ++begin) + delete_cell(*begin); + } + + // QUERIES + + bool is_simplex(Cell_handle c) const; // undocumented for now + bool is_vertex(Vertex_handle v) const; + bool is_edge(Cell_handle c, int i, int j) const; + bool is_edge(Vertex_handle u, Vertex_handle v, Cell_handle & c, + int & i, int & j) const; + bool is_edge(Vertex_handle u, Vertex_handle v) const; + bool is_facet(Cell_handle c, int i) const; + bool is_facet(Vertex_handle u, Vertex_handle v, + Vertex_handle w, + Cell_handle & c, int & i, int & j, int & k) const; + bool is_cell(Cell_handle c) const; + bool is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const; + bool is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle t) const; + + bool has_vertex(const Facet & f, Vertex_handle v, int & j) const; + bool has_vertex(Cell_handle c, int i, + Vertex_handle v, int & j) const; + bool has_vertex(const Facet & f, Vertex_handle v) const; + bool has_vertex(Cell_handle c, int i, Vertex_handle v) const; + + bool are_equal(Cell_handle c, int i, + Cell_handle n, int j) const; + bool are_equal(const Facet & f, const Facet & g) const; + bool are_equal(const Facet & f, Cell_handle n, int j) const; + + // MODIFY + + bool flip(Cell_handle c, int i); + bool flip(const Facet &f) + { return flip( f.first, f.second); } + + void flip_flippable(Cell_handle c, int i); + void flip_flippable(const Facet &f) + { flip_flippable( f.first, f.second ); } + + bool flip(Cell_handle c, int i, int j); + bool flip(const Edge &e) + { return flip( e.first, e.second, e.third ); } + + void flip_flippable(Cell_handle c, int i, int j); + void flip_flippable(const Edge &e) + { flip_flippable( e.first, e.second, e.third ); } + +private: + // common to flip and flip_flippable + void flip_really(Cell_handle c, int i, Cell_handle n, int in); + void flip_really(Cell_handle c, int i, int j, + Cell_handle c1, Vertex_handle v1, + int i1, int j1, int next1, + Cell_handle c2, Vertex_handle v2, + int i2, int j2, int next2, + Vertex_handle v3); + + Cell_handle create_star_3(Vertex_handle v, Cell_handle c, + int li, int prev_ind2 = -1); + + Cell_handle create_star_2(Vertex_handle v, + Cell_handle c, int li); + +public: + + // Internal function : assumes the conflict cells are marked. + template + Vertex_handle _insert_in_hole(CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, + Vertex_handle newv) + { + CGAL_triangulation_precondition(begin != Cell_handle()); + // if begin == NULL (default arg), we could compute one by walking in + // CellIt. At the moment, the functionality is not available, you have + // to specify a starting facet. + + Cell_handle cnew; + if (dimension() == 3) + cnew = create_star_3(newv, begin, i); + else + cnew = create_star_2(newv, begin, i); + + newv->set_cell(cnew); + delete_cells(cell_begin, cell_end); + return newv; + } + + // Internal function : assumes the conflict cells are marked. + template + Vertex_handle _insert_in_hole(CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i) + { + return _insert_in_hole(cell_begin, cell_end, begin, i, create_vertex()); + } + + // Mark the cells in conflict, then calls the internal function. + template + Vertex_handle insert_in_hole(CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i, + Vertex_handle newv) + { + for (CellIt cit = cell_begin; cit != cell_end; ++cit) + (*cit)->tds_data().mark_in_conflict(); + + return _insert_in_hole(cell_begin, cell_end, begin, i, newv); + } + + // Mark the cells in conflict, then calls the internal function. + template + Vertex_handle insert_in_hole(CellIt cell_begin, CellIt cell_end, + Cell_handle begin, int i) + { + return insert_in_hole(cell_begin, cell_end, begin, i, create_vertex()); + } + + //INSERTION + + Vertex_handle insert_in_cell(Cell_handle c); + + Vertex_handle insert_in_facet(const Facet & f) + { return insert_in_facet(f.first, f.second); } + + Vertex_handle insert_in_facet(Cell_handle c, int i); + + Vertex_handle insert_in_edge(const Edge & e) + { return insert_in_edge(e.first, e.second, e.third); } + + Vertex_handle insert_in_edge(Cell_handle c, int i, int j); + + Vertex_handle insert_increase_dimension(Vertex_handle star =Vertex_handle()); + + // REMOVAL + +private: + Cell_handle remove_degree_4(Vertex_handle v); + Cell_handle remove_degree_3(Vertex_handle v); + Cell_handle remove_degree_2(Vertex_handle v); +public: + Cell_handle remove_from_maximal_dimension_simplex(Vertex_handle v); + void remove_decrease_dimension(Vertex_handle v) + { + remove_decrease_dimension (v, v); + } + void remove_decrease_dimension(Vertex_handle v, Vertex_handle w); + void decrease_dimension(Cell_handle f, int i); + + // Change orientation of the whole TDS. + void reorient() + { + CGAL_triangulation_precondition(dimension() >= 1); + for (Cell_iterator i = cells().begin(); + i != cells().end(); ++i) + change_orientation(i); + } + + // ITERATOR METHODS + + Cell_iterator cells_begin() const + { + if ( dimension() < 3 ) + return cells_end(); + return cells().begin(); + } + + Cell_iterator cells_end() const + { + return cells().end(); + } + + Cell_iterator raw_cells_begin() const + { + return cells().begin(); + } + + Cell_iterator raw_cells_end() const + { + return cells().end(); + } + + Facet_iterator facets_begin() const + { + if ( dimension() < 2 ) + return facets_end(); + return Facet_iterator(this); + } + + Facet_iterator facets_end() const + { + return Facet_iterator(this, 1); + } + + Edge_iterator edges_begin() const + { + if ( dimension() < 1 ) + return edges_end(); + return Edge_iterator(this); + } + + Edge_iterator edges_end() const + { + return Edge_iterator(this,1); + } + + Vertex_iterator vertices_begin() const + { + return vertices().begin(); + } + + Vertex_iterator vertices_end() const + { + return vertices().end(); + } + + // CIRCULATOR METHODS + + // cells around an edge + Cell_circulator incident_cells(const Edge & e) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Cell_circulator(e); + } + Cell_circulator incident_cells(Cell_handle ce, int i, int j) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Cell_circulator(ce, i, j); + } + + Cell_circulator incident_cells(const Edge &e, Cell_handle start) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Cell_circulator(e, start); + } + Cell_circulator incident_cells(Cell_handle ce, int i, int j, + Cell_handle start) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Cell_circulator(ce, i, j, start); + } + + //facets around an edge + Facet_circulator incident_facets(const Edge & e) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Facet_circulator(e); + } + Facet_circulator incident_facets(Cell_handle ce, int i, int j) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Facet_circulator(ce, i, j); + } + Facet_circulator incident_facets(const Edge & e, const Facet & start) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Facet_circulator(e, start); + } + Facet_circulator incident_facets(Cell_handle ce, int i, int j, + const Facet & start) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Facet_circulator(ce, i, j, start); + } + Facet_circulator incident_facets(const Edge & e, + Cell_handle start, int f) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Facet_circulator(e, start, f); + } + Facet_circulator incident_facets(Cell_handle ce, int i, int j, + Cell_handle start, int f) const + { + CGAL_triangulation_precondition( dimension() == 3 ); + return Facet_circulator(ce, i, j, start, f); + } + + // 2D : circulates on the faces adjacent to a vertex. + Face_circulator incident_faces(Vertex_handle v) const + { + CGAL_triangulation_precondition( dimension() == 2 ); + return Face_circulator(v, v->cell()); + } + + // around a vertex +private: + + template + std::pair + incident_cells_3(Vertex_handle v, Cell_handle d, + std::pair it) const + { + CGAL_triangulation_precondition(dimension() == 3); + + std::stack cell_stack; + cell_stack.push(d); + d->tds_data().mark_in_conflict(); + *it.first++ = d; + + do { + Cell_handle c = cell_stack.top(); + cell_stack.pop(); + + for (int i=0; i<4; ++i) { + if (c->vertex(i) == v) + continue; + Cell_handle next = c->neighbor(i); + if (c < next) + *it.second++ = Facet(c, i); // Incident facet. + if (! next->tds_data().is_clear()) + continue; + cell_stack.push(next); + next->tds_data().mark_in_conflict(); + *it.first++ = next; + } + } while(!cell_stack.empty()); + + return it; + } + + + template + void + incident_cells_2(Vertex_handle v, Cell_handle c, + OutputIterator cells) const + { + CGAL_triangulation_precondition(dimension() == 2); + + // TODO : in 2D, there's no real need for tds_data, we could use + // a smarter algorithm. We could use the 2D Face_circulator. + // Should we just have this Face_circulator ? + + // Flag values : + // 1 : incident cell already visited + // 0 : unknown + c->tds_data().mark_in_conflict(); + *cells++ = c; + + for (int i=0; i<3; ++i) { + if (c->vertex(i) == v) + continue; + Cell_handle next = c->neighbor(i); + if (! next->tds_data().is_clear()) + continue; + incident_cells_2(v, next, cells); + } + } + +public: + + class False_filter { + public: + False_filter() {} + template + bool operator() (T) { + return false; + } + }; + + // Visitor for visit_incident_cells: + // outputs the facets + template + class Facet_extractor { + OutputIterator output; + Filter filter; + public: + Facet_extractor(Vertex_handle, OutputIterator _output, const Tds*, Filter _filter): + output(_output), filter(_filter){} + void operator() (Cell_handle) {} + + OutputIterator result() { + return output; + } + + class Facet_it { + OutputIterator& output; + Filter& filter; + public: + Facet_it(OutputIterator& _output, Filter& _filter): output(_output), filter(_filter) {} + Facet_it& operator*() {return *this;}; + Facet_it& operator++() {return *this;}; + Facet_it operator++(int) {return *this;}; + template + Facet_it& operator=(const T& e) { + if(filter(e)) + return *this; + *output++ = e; + return *this; + } + Facet_it& operator=(const Facet_it& f) { + output = f.output; + filter = f.filter; + return *this; + } + }; + Facet_it facet_it() { + return Facet_it(output, filter); + } + }; + + // Visitor for visit_incident_cells: + // outputs the cells + template + class Cell_extractor { + OutputIterator output; + Filter filter; + public: + Cell_extractor(Vertex_handle, OutputIterator _output, const Tds*, Filter _filter): + output(_output), filter(_filter) {} + + void operator()(Cell_handle c) { + if(filter(c)) + return; + *output++ = c; + } + CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} + OutputIterator result() { + return output; + } + }; + + // Visitor for visit_incident_cells: + // WARNING: 2D ONLY + // outputs the faces obtained as degenerated cells + template + class DegCell_as_Facet_extractor { + OutputIterator output; + Filter filter; + public: + DegCell_as_Facet_extractor(Vertex_handle, OutputIterator _output, const Tds*, Filter _filter): + output(_output), filter(_filter) {} + + void operator()(Cell_handle c) { + Facet f = Facet(c,3); + if(filter(f)) + return; + *output++ = f; + } + CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} + OutputIterator result() { + return output; + } + }; + + + // Visitor for visit_incident_cells: + // outputs the result of Treatment applied to the vertices + template + class Vertex_extractor { + Vertex_handle v; + std::set tmp_vertices; + Treatment treat; + const Tds* t; + Filter filter; + public: + Vertex_extractor(Vertex_handle _v, OutputIterator _output, const Tds* _t, Filter _filter): + v(_v), treat(_output), t(_t), filter(_filter) {} + void operator()(Cell_handle c) { + for (int j=0; j<= t->dimension(); ++j) { + Vertex_handle w = c->vertex(j); + if(filter(w)) + continue; + if (w != v) + if(tmp_vertices.insert(w).second) { + treat(c, v, j); + } + } + } + + CGAL::Emptyset_iterator facet_it() {return CGAL::Emptyset_iterator();} + OutputIterator result() { + return treat.result(); + } + }; + + // Treatment for Vertex_extractor: + // outputs the vertices + template + class Vertex_feeder_treatment { + OutputIterator output; + public: + Vertex_feeder_treatment(OutputIterator _output): output(_output) {}; + void operator()(Cell_handle c, Vertex_handle, int index) { + *output++ = c->vertex(index); + } + OutputIterator result() { + return output; + } + }; + + // Treatment for Vertex_extractor: + // outputs the edges corresponding to the vertices + template + class Edge_feeder_treatment { + OutputIterator output; + public: + Edge_feeder_treatment(OutputIterator _output): output(_output) {}; + void operator()(Cell_handle c, Vertex_handle v, int index) { + *output++ = Edge(c, c->index(v), index); + } + OutputIterator result() { + return output; + } + }; + + template + OutputIterator + incident_cells(Vertex_handle v, OutputIterator cells, Filter f = Filter()) const + { + return visit_incident_cells, + OutputIterator>(v, cells, f); + } + + template + OutputIterator + incident_cells(Vertex_handle v, OutputIterator cells) const + { + return incident_cells(v, cells); + } + + template + OutputIterator + incident_facets(Vertex_handle v, OutputIterator facets, Filter f = Filter()) const + { + CGAL_triangulation_precondition( dimension() > 1 ); + if(dimension() == 3) + return visit_incident_cells, OutputIterator>(v, facets, f); + else + return visit_incident_cells, OutputIterator>(v, facets, f); + } + + template + OutputIterator + incident_facets(Vertex_handle v, OutputIterator facets) const + { + return incident_facets(v, facets); + } + + template + OutputIterator + incident_edges(Vertex_handle v, OutputIterator edges, Filter f = Filter()) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_precondition( dimension() >= 1 ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + CGAL_triangulation_expensive_precondition( is_valid() ); + + if (dimension() == 1) { + CGAL_triangulation_assertion( number_of_vertices() >= 3); + Cell_handle n0 = v->cell(); + Cell_handle n1 = n0->neighbor(1-n0->index(v)); + *edges++ = Edge(n0, n0->index(v), 1-n0->index(v)); + *edges++ = Edge(n1, n1->index(v), 1-n1->index(v)); + return edges; + } + return visit_incident_cells, + OutputIterator, Filter>, + OutputIterator>(v, edges, f); + } + + template + OutputIterator + incident_edges(Vertex_handle v, OutputIterator edges) const + { + return incident_edges(v, edges); + } + + template + OutputIterator + adjacent_vertices(Vertex_handle v, OutputIterator vertices, Filter f = Filter()) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_precondition( dimension() >= -1 ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + CGAL_triangulation_expensive_precondition( is_valid() ); + + if (dimension() == -1) + return vertices; + + if (dimension() == 0) { + *vertices++ = v->cell()->neighbor(0)->vertex(0); + return vertices; + } + + if (dimension() == 1) { + CGAL_triangulation_assertion( number_of_vertices() >= 3); + Cell_handle n0 = v->cell(); + Cell_handle n1 = n0->neighbor(1-n0->index(v)); + *vertices++ = n0->vertex(1-n0->index(v)); + *vertices++ = n1->vertex(1-n1->index(v)); + return vertices; + } + return visit_incident_cells, + OutputIterator, Filter>, + OutputIterator>(v, vertices, f); + } + + // old name - kept for backwards compatibility but not documented + template + OutputIterator + incident_vertices(Vertex_handle v, OutputIterator vertices) const + { + return adjacent_vertices(v, vertices); + } + + // correct name + template + OutputIterator + adjacent_vertices(Vertex_handle v, OutputIterator vertices) const + { + return adjacent_vertices(v, vertices); + } + + template + OutputIterator + visit_incident_cells(Vertex_handle v, OutputIterator output, Filter f) const + { + CGAL_triangulation_precondition( v != Vertex_handle() ); + CGAL_triangulation_expensive_precondition( is_vertex(v) ); + + if ( dimension() < 2 ) + return output; + + Visitor visit(v, output, this, f); + + std::vector tmp_cells; + tmp_cells.reserve(64); + if ( dimension() == 3 ) + incident_cells_3(v, v->cell(), std::make_pair(std::back_inserter(tmp_cells), visit.facet_it())); + else + incident_cells_2(v, v->cell(), std::back_inserter(tmp_cells)); + + typename std::vector::iterator cit; + for(cit = tmp_cells.begin(); + cit != tmp_cells.end(); + ++cit) + { + (*cit)->tds_data().clear(); + visit(*cit); + } + return visit.result(); + } + + size_type degree(Vertex_handle v) const; + + // CHECKING + bool is_valid(bool verbose = false, int level = 0) const; + bool is_valid(Vertex_handle v, bool verbose = false, int level = 0) const; + bool is_valid(Cell_handle c, bool verbose = false, int level = 0) const; + + // Helping functions + Vertex_handle copy_tds(const Tds & tds, + Vertex_handle vert = Vertex_handle() ); + // returns the new vertex corresponding to vert in the new tds + + void swap(Tds & tds); + + void clear(); + + void set_adjacency(Cell_handle c0, int i0, + Cell_handle c1, int i1) const + { + CGAL_triangulation_assertion(i0 >= 0 && i0 <= dimension()); + CGAL_triangulation_assertion(i1 >= 0 && i1 <= dimension()); + CGAL_triangulation_assertion(c0 != c1); + c0->set_neighbor(i0,c1); + c1->set_neighbor(i1,c0); + } + + int mirror_index(Cell_handle c, int i) const + { + CGAL_triangulation_precondition ( i>=0 && i<4 ); + return c->neighbor(i)->index(c); + } + + Vertex_handle mirror_vertex(Cell_handle c, int i) const + { + return c->neighbor(i)->vertex(mirror_index(c, i)); + } + + Facet mirror_facet(Facet f) const + { + Cell_handle neighbor_cell = f.first->neighbor(f.second); + const int opposite_index = neighbor_cell->index(f.first); + return Facet(neighbor_cell, opposite_index); + } + + // We need the const_cast<>s because TDS is not const-correct. + Cell_range & cells() { return _cells; } + Cell_range & cells() const + { return const_cast(this)->_cells; } + + Vertex_range & vertices() {return _vertices;} + Vertex_range & vertices() const + { return const_cast(this)->_vertices; } + +private: + + // Change the orientation of the cell by swapping indices 0 and 1. + void change_orientation(Cell_handle c) const + { + Vertex_handle tmp_v = c->vertex(0); + c->set_vertex(0, c->vertex(1)); + c->set_vertex(1, tmp_v); + Cell_handle tmp_c = c->neighbor(0); + c->set_neighbor(0, c->neighbor(1)); + c->set_neighbor(1, tmp_c); + } + + // in dimension i, number of vertices >= i+2 + // ( the boundary of a simplex in dimension i+1 has i+2 vertices ) + int _dimension; + + Cell_range _cells; + Vertex_range _vertices; + + // used by is-valid : + bool count_vertices(size_type &i, bool verbose = false, int level = 0) const; + // counts AND checks the validity + bool count_facets(size_type &i, bool verbose = false, int level = 0) const; + // counts but does not check + bool count_edges(size_type &i, bool verbose = false, int level = 0) const; + // counts but does not check + bool count_cells(size_type &i, bool verbose = false, int level = 0) const; + // counts AND checks the validity +}; + +#ifdef CGAL_TDS_USE_OLD_CREATE_STAR_3 +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: +create_star_3(Vertex_handle v, Cell_handle c, int li, + int prev_ind2) +{ + CGAL_triangulation_precondition( dimension() == 3); + CGAL_triangulation_precondition( c->tds_data().is_in_conflict() ); + CGAL_triangulation_precondition( ! c->neighbor(li)->tds_data().is_in_conflict() ); + + Cell_handle cnew = create_cell(c->vertex(0), + c->vertex(1), + c->vertex(2), + c->vertex(3)); + cnew->set_vertex(li, v); + Cell_handle c_li = c->neighbor(li); + set_adjacency(cnew, li, c_li, c_li->index(c)); + + // Look for the other neighbors of cnew. + for (int ii=0; ii<4; ++ii) { + if (ii == prev_ind2 || cnew->neighbor(ii) != Cell_handle()) + continue; + cnew->vertex(ii)->set_cell(cnew); + + // Indices of the vertices of cnew such that ii,vj1,vj2,li positive. + Vertex_handle vj1 = c->vertex(next_around_edge(ii, li)); + Vertex_handle vj2 = c->vertex(next_around_edge(li, ii)); + Cell_handle cur = c; + int zz = ii; + Cell_handle n = cur->neighbor(zz); + // turn around the oriented edge vj1 vj2 + while ( n->tds_data().is_in_conflict() ) { + CGAL_triangulation_assertion( n != c ); + cur = n; + zz = next_around_edge(n->index(vj1), n->index(vj2)); + n = cur->neighbor(zz); + } + // Now n is outside region, cur is inside. + + n->tds_data().clear(); // Reset the flag for boundary cells. + + int jj1 = n->index(vj1); + int jj2 = n->index(vj2); + Vertex_handle vvv = n->vertex(next_around_edge(jj1, jj2)); + Cell_handle nnn = n->neighbor(next_around_edge(jj2, jj1)); + int zzz = nnn->index(vvv); + if (nnn == cur) { + // Neighbor relation is reciprocal, ie + // the cell we are looking for is not yet created. + nnn = create_star_3(v, nnn, zz, zzz); + } + + set_adjacency(nnn, zzz, cnew, ii); + } + + return cnew; +} +#else +//This function used to be recursive. +//This design resulted in call stack overflow in some cases. +//When we rewrote it, to emulate the class stack, we use a c++ stack. +//The stack used is a enriched std::vector that call reserve(N) when constructed +//(faster that testing capacity>N at each call of create_star_3). +//We use the class iAdjacency_info instead of a tuple because +//at the moment we made the change it was faster like this. +//The stack is a static variable of the function because it was also +//faster when we tested it. +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: +create_star_3(Vertex_handle v, Cell_handle c, int li, + int prev_ind2) +{ + CGAL_triangulation_precondition( dimension() == 3); + CGAL_triangulation_precondition( c->tds_data().is_in_conflict() ); + CGAL_triangulation_precondition( ! c->neighbor(li)->tds_data().is_in_conflict() ); + + Cell_handle cnew = create_cell(c->vertex(0), + c->vertex(1), + c->vertex(2), + c->vertex(3)); + cnew->set_vertex(li, v); + Cell_handle c_li = c->neighbor(li); + set_adjacency(cnew, li, c_li, c_li->index(c)); + +#ifdef CGAL_HAS_THREADS + static boost::thread_specific_ptr< std::vector > stack_safe_ptr; + if (stack_safe_ptr.get() == NULL) { + stack_safe_ptr.reset(new std::vector()); + stack_safe_ptr.get()->reserve(64); + } + std::vector& adjacency_info_stack=* stack_safe_ptr.get(); +#else + static std::vector adjacency_info_stack; + adjacency_info_stack.reserve(64); +#endif + + int ii=0; + do + { + // Look for the other neighbors of cnew. + if ( ! (ii == prev_ind2 || cnew->neighbor(ii) != Cell_handle()) ){ + cnew->vertex(ii)->set_cell(cnew); + + // Indices of the vertices of cnew such that ii,vj1,vj2,li positive. + Vertex_handle vj1 = c->vertex(next_around_edge(ii, li)); + Vertex_handle vj2 = c->vertex(next_around_edge(li, ii)); + Cell_handle cur = c; + int zz = ii; + Cell_handle n = cur->neighbor(zz); + // turn around the oriented edge vj1 vj2 + while ( n->tds_data().is_in_conflict() ) { + CGAL_triangulation_assertion( n != c ); + cur = n; + zz = next_around_edge(n->index(vj1), n->index(vj2)); + n = cur->neighbor(zz); + } + // Now n is outside region, cur is inside. + + n->tds_data().clear(); // Reset the flag for boundary cells. + + int jj1 = n->index(vj1); + int jj2 = n->index(vj2); + Vertex_handle vvv = n->vertex(next_around_edge(jj1, jj2)); + Cell_handle nnn = n->neighbor(next_around_edge(jj2, jj1)); + int zzz = nnn->index(vvv); + if (nnn == cur) { + // Neighbor relation is reciprocal, ie + // the cell we are looking for is not yet created. + //re-run the loop + adjacency_info_stack.push_back( iAdjacency_info(zzz,cnew,ii,c,li,prev_ind2) ); + c=nnn; li=zz; prev_ind2=zzz; ii=0; + //copy-pasted from beginning to avoid if ii==0 + CGAL_triangulation_precondition( c->tds_data().is_in_conflict() ); + CGAL_triangulation_precondition( ! c->neighbor(li)->tds_data().is_in_conflict() ); + cnew = create_cell(c->vertex(0),c->vertex(1),c->vertex(2),c->vertex(3)); + cnew->set_vertex(li, v); + c_li = c->neighbor(li); + set_adjacency(cnew, li, c_li, c_li->index(c)); + continue; + } + set_adjacency(nnn, zzz, cnew, ii); + } + while (++ii==4){ + if ( adjacency_info_stack.empty() ) return cnew; + Cell_handle nnn=cnew; + int zzz; + adjacency_info_stack.back().update_variables(zzz,cnew,ii,c,li,prev_ind2); + adjacency_info_stack.pop_back(); + set_adjacency(nnn, zzz, cnew, ii); + } + } + while (true); +} +#endif + +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: +create_star_2(Vertex_handle v, Cell_handle c, int li ) +{ + CGAL_triangulation_assertion( dimension() == 2 ); + Cell_handle cnew; + + // i1 i2 such that v,i1,i2 positive + int i1=ccw(li); + // traversal of the boundary of region in ccw order to create all + // the new facets + Cell_handle bound = c; + Vertex_handle v1 = c->vertex(i1); + int ind = c->neighbor(li)->index(c); // to be able to find the + // first cell that will be created + Cell_handle cur; + Cell_handle pnew = Cell_handle(); + do { + cur = bound; + // turn around v2 until we reach the boundary of region + while ( cur->neighbor(cw(i1))->tds_data().is_in_conflict() ) { + // neighbor in conflict + cur = cur->neighbor(cw(i1)); + i1 = cur->index( v1 ); + } + cur->neighbor(cw(i1))->tds_data().clear(); + // here cur has an edge on the boundary of region + cnew = create_face( v, v1, cur->vertex( ccw(i1) ) ); + set_adjacency(cnew, 0, cur->neighbor(cw(i1)), + cur->neighbor(cw(i1))->index(cur)); + cnew->set_neighbor(1, Cell_handle()); + cnew->set_neighbor(2, pnew); + // pnew is null at the first iteration + v1->set_cell(cnew); + //pnew->set_neighbor( cw(pnew->index(v1)), cnew ); + if (pnew != Cell_handle()) { pnew->set_neighbor( 1, cnew );} + + bound = cur; + i1 = ccw(i1); + v1 = bound->vertex(i1); + pnew = cnew; + //} while ( ( bound != c ) || ( li != cw(i1) ) ); + } while ( v1 != c->vertex(ccw(li)) ); + // missing neighbors between the first and the last created cells + cur = c->neighbor(li)->neighbor(ind); // first created cell + set_adjacency(cnew, 1, cur, 2); + return cnew; +} + +template < class Vb, class Cb> +std::istream& +operator>>(std::istream& is, Triangulation_data_structure_3& tds) + // reads : + // the dimension + // the number of vertices + // the number of cells + // the cells by the indices of their vertices + // the neighbors of each cell by their index in the preceding list of cells + // when dimension < 3 : the same with faces of maximal dimension +{ + typedef Triangulation_data_structure_3 Tds; + typedef typename Tds::Vertex_handle Vertex_handle; + typedef typename Tds::Cell_handle Cell_handle; + + tds.clear(); + + std::size_t n; + int d; + if(is_ascii(is)) + is >> d >> n; + else { + read(is, n); + read(is,d); + } + tds.set_dimension(d); + + if(n == 0) + return is; + + std::map V; + + // creation of the vertices + for (std::size_t i=0; i < n; i++) { + // is >> p; + // V[i] = tds.create_vertex(); + // V[i]->set_point(p); + V[i] = tds.create_vertex(); + } + + std::map< std::size_t, Cell_handle > C; + std::size_t m; + + tds.read_cells(is, V, m, C); + CGAL_triangulation_assertion( tds.is_valid() ); + return is; +} + +template < class Vb, class Cb> +std::ostream& +operator<<(std::ostream& os, const Triangulation_data_structure_3 &tds) + // writes : + // the dimension + // the number of vertices + // the number of cells + // the cells by the indices of their vertices + // the neighbors of each cell by their index in the preceding list of cells + // when dimension < 3 : the same with faces of maximal dimension +{ + typedef Triangulation_data_structure_3 Tds; + typedef typename Tds::size_type size_type; + typedef typename Tds::Vertex_handle Vertex_handle; + typedef typename Tds::Vertex_iterator Vertex_iterator; + + std::map V; + + // outputs dimension and number of vertices + size_type n = tds.number_of_vertices(); + + if (is_ascii(os)) + os << tds.dimension() << std::endl << n << std::endl; + else + { + write(os,tds.dimension()); + write(os,n); + } + + if (n == 0) + return os; + + // index the vertices + size_type i = 0; + for (Vertex_iterator it=tds.vertices_begin(); it != tds.vertices_end(); ++it) + V[it] = i++; + + CGAL_triangulation_assertion( i == n ); + + tds.print_cells(os, V); + + return os; +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_simplex( Cell_handle c ) const +{ + switch(dimension()) { + case 3 : return is_cell(c); + case 2 : return is_facet(c, 3); + case 1 : return is_edge(c, 0, 1); + case 0 : return is_vertex(c->vertex(0)); + case -1 : return c == cells().begin(); + } + return false; +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_vertex(Vertex_handle v) const +{ + return vertices().owns_dereferencable(v); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_edge(Vertex_handle u, Vertex_handle v, + Cell_handle &c, int &i, int &j) const + // returns false when dimension <1 or when indices wrong +{ + CGAL_triangulation_expensive_precondition( is_vertex(u) && is_vertex(v) ); + + if (u==v) + return false; + + std::vector cells; + cells.reserve(64); + incident_cells(u, std::back_inserter(cells)); + + for (typename std::vector::iterator cit = cells.begin(); + cit != cells.end(); ++cit) + if ((*cit)->has_vertex(v, j)) { + c = *cit; + i = c->index(u); + return true; + } + return false; +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_edge(Vertex_handle u, Vertex_handle v) const +{ + Cell_handle c; + int i, j; + return is_edge(u, v, c, i, j); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_edge(Cell_handle c, int i, int j) const +{ + if (dimension() < 1) + return false; + + if ( i==j ) return false; + if ( (i<0) || (j<0) ) return false; + if ( (dimension() == 1) && ((i>1) || (j>1)) ) return false; + if ( (dimension() == 2) && ((i>2) || (j>2)) ) return false; + if ((i>3) || (j>3)) return false; + + return cells().owns_dereferencable(c); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_facet(Vertex_handle u, Vertex_handle v, + Vertex_handle w, + Cell_handle & c, int & i, int & j, int & k) const + // returns false when dimension <2 or when indices wrong +{ + CGAL_triangulation_expensive_precondition( is_vertex(u) && + is_vertex(v) && + is_vertex(w) ); + + if ( u==v || u==w || v==w ) + return false; + if (dimension() < 2) + return false; + + std::vector cells; + cells.reserve(64); + incident_cells(u, std::back_inserter(cells)); + + for (typename std::vector::iterator cit = cells.begin(); + cit != cells.end(); ++cit) + if ((*cit)->has_vertex(v, j) && (*cit)->has_vertex(w, k)) { + c = *cit; + i = c->index(u); + return true; + } + return false; +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_facet(Cell_handle c, int i) const +{ + CGAL_triangulation_precondition(i>=0 && i<4); + + if ( dimension() < 2 ) + return false; + + if ( (dimension() == 2) && (i!=3) ) + return false; + + return cells().owns_dereferencable(c); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_cell( Cell_handle c ) const + // returns false when dimension <3 +{ + if (dimension() < 3) + return false; + + return cells().owns_dereferencable(c); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle t, + Cell_handle & c, int & i, int & j, int & k, int & l) const + // returns false when dimension <3 +{ + CGAL_triangulation_expensive_precondition( is_vertex(u) && + is_vertex(v) && + is_vertex(w) && + is_vertex(t) ); + + if ( u==v || u==w || u==t || v==w || v==t || w==t ) + return false; + + std::vector cells; + cells.reserve(64); + incident_cells(u, std::back_inserter(cells)); + + for (typename std::vector::iterator cit = cells.begin(); + cit != cells.end(); ++cit) + if ((*cit)->has_vertex(v, j) && (*cit)->has_vertex(w, k) && + (*cit)->has_vertex(t, l)) { + c = *cit; + i = c->index(u); + return true; + } + return false; +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +is_cell(Vertex_handle u, Vertex_handle v, + Vertex_handle w, Vertex_handle t) + const + // returns false when dimension <3 +{ + Cell_handle c; + int i, j, k, l; + return is_cell(u, v, w, t, c, i, j, k, l); +} + +template < class Vb, class Cb> +inline +bool +Triangulation_data_structure_3:: +has_vertex(Cell_handle c, int i, Vertex_handle v, int & j) const + // computes the index j of the vertex in the cell c giving the query + // facet (c,i) + // j has no meaning if false is returned +{ + CGAL_triangulation_precondition( dimension() == 3 ); + return ( c->has_vertex(v,j) && (j != i) ); +} + +template < class Vb, class Cb> +inline +bool +Triangulation_data_structure_3:: +has_vertex(Cell_handle c, int i, Vertex_handle v) const + // checks whether the query facet (c,i) has vertex v +{ + CGAL_triangulation_precondition( dimension() == 3 ); + int j; + return ( c->has_vertex(v,j) && (j != i) ); +} + +template < class Vb, class Cb> +inline +bool +Triangulation_data_structure_3:: +has_vertex(const Facet & f, Vertex_handle v, int & j) const +{ + return has_vertex(f.first, f.second, v, j); +} + +template < class Vb, class Cb> +inline +bool +Triangulation_data_structure_3:: +has_vertex(const Facet & f, Vertex_handle v) const +{ + return has_vertex(f.first, f.second, v); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +are_equal(Cell_handle c, int i, Cell_handle n, int j) const + // tests whether facets c,i and n,j, have the same 3 vertices + // the triangulation is supposed to be valid, the orientation of the + // facets is not checked here + // the neighbor relations between c and n are not tested either, + // which allows to use this method before setting these relations + // (see remove in Delaunay_3) + // if ( c->neighbor(i) != n ) return false; + // if ( n->neighbor(j) != c ) return false; +{ + CGAL_triangulation_precondition( dimension() == 3 ); + + if ( (c==n) && (i==j) ) return true; + + int j1,j2,j3; + return( n->has_vertex( c->vertex((i+1)&3), j1 ) && + n->has_vertex( c->vertex((i+2)&3), j2 ) && + n->has_vertex( c->vertex((i+3)&3), j3 ) && + ( j1+j2+j3+j == 6 ) ); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +are_equal(const Facet & f, const Facet & g) const +{ + return are_equal(f.first, f.second, g.first, g.second); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +are_equal(const Facet & f, Cell_handle n, int j) const +{ + return are_equal(f.first, f.second, n, j); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +flip( Cell_handle c, int i ) + // returns false if the facet is not flippable + // true other wise and + // flips facet i of cell c + // c will be replaced by one of the new cells +{ + CGAL_triangulation_precondition( (dimension() == 3) && (0<=i) && (i<4) + && (number_of_vertices() >= 6) ); + CGAL_triangulation_expensive_precondition( is_cell(c) ); + + Cell_handle n = c->neighbor(i); + int in = n->index(c); + + // checks that the facet is flippable, + // ie the future edge does not already exist + if (is_edge(c->vertex(i), n->vertex(in))) + return false; + + flip_really(c,i,n,in); + return true; +} + +template < class Vb, class Cb> +void +Triangulation_data_structure_3:: +flip_flippable(Cell_handle c, int i ) + // flips facet i of cell c + // c will be replaced by one of the new cells +{ + CGAL_triangulation_precondition( (dimension() == 3) && (0<=i) && (i<4) + && (number_of_vertices() >= 6) ); + CGAL_triangulation_expensive_precondition( is_cell(c) ); + + Cell_handle n = c->neighbor(i); + int in = n->index(c); + + // checks that the facet is flippable, + // ie the future edge does not already exist + CGAL_triangulation_expensive_precondition( !is_edge(c->vertex(i), + n->vertex(in))); + flip_really(c,i,n,in); +} + +template < class Vb, class Cb> +inline +void +Triangulation_data_structure_3:: +flip_really( Cell_handle c, int i, Cell_handle n, int in ) + // private - used by flip and flip_flippable +{ + int i1 = (i+1)&3; + int i2 = (i+2)&3; + int i3 = (i+3)&3; + + int in1 = n->index(c->vertex(i1)); + int in2 = n->index(c->vertex(i2)); + int in3 = n->index(c->vertex(i3)); + + set_adjacency(c, i, n->neighbor(in3), n->neighbor(in3)->index(n)); + c->set_vertex( i3, n->vertex(in) ); + + set_adjacency(n, in, c->neighbor(i1), c->neighbor(i1)->index(c)); + n->set_vertex( in1, c->vertex(i) ); + + Cell_handle cnew = create_cell(c->vertex(i), c->vertex(i1), + n->vertex(in), n->vertex(in3)); + + set_adjacency(cnew, 0, n->neighbor(in2), n->neighbor(in2)->index(n)); + set_adjacency(cnew, 1, n, in2); + set_adjacency(cnew, 2, c->neighbor(i2), c->neighbor(i2)->index(c)); + set_adjacency(cnew, 3, c, i2); + set_adjacency(c, i1, n, in3); + + if ((i&1) != 0) + change_orientation(cnew); + + c->vertex(i1)->set_cell(cnew); + c->vertex(i2)->set_cell(c); + n->vertex(in3)->set_cell(n); + // to be implemented : 2d case + // CGAL_triangulation_precondition( (0<=i) && (i<3) ); +} + +template < class Vb, class Cb> +bool +Triangulation_data_structure_3:: +flip( Cell_handle c, int i, int j ) + // returns false if the edge is not flippable + // true otherwise and + // flips edge i,j of cell c + // c will be deleted +{ + CGAL_triangulation_precondition( (dimension() == 3) + && (0<=i) && (i<4) + && (0<=j) && (j<4) + && ( i != j ) + && (number_of_vertices() >= 6) ); + CGAL_triangulation_expensive_precondition( is_cell(c) ); + + // checks that the edge is flippable ie degree 3 + int degree = 0; + Cell_circulator ccir = incident_cells(c,i,j); + Cell_circulator cdone = ccir; + do { + ++degree; + ++ccir; + } while ( ccir != cdone ); + + if ( degree != 3 ) return false; + + int next = next_around_edge(i,j); + Cell_handle c1 = c->neighbor( next ); + Vertex_handle v1 = c->vertex( next ); // will become vertex of c1 + int i1 = c1->index( c->vertex(i) ); + int j1 = c1->index( c->vertex(j) ); + + int next1 = next_around_edge(i1,j1); + Cell_handle c2 = c1->neighbor( next1 ); + Vertex_handle v2 = c1->vertex( next1 ); // will become vertex of c2 + int i2 = c2->index( c->vertex(i) ); + int j2 = c2->index( c->vertex(j) ); + + int next2 = next_around_edge(i2,j2); + Vertex_handle v3 = c2->vertex( next2 ); + + // checks that the edge is flippable, + // is the future cells do not already exist + if ( is_cell(v1,v2,v3,c->vertex(i)) ) return false; + if ( is_cell(v1,v2,v3,c->vertex(j)) ) return false; + + flip_really(c,i,j,c1,v1,i1,j1,next1,c2,v2,i2,j2,next2,v3); + + return true; +} + +template < class Vb, class Cb> +void +Triangulation_data_structure_3:: +flip_flippable( Cell_handle c, int i, int j ) + // flips edge i,j of cell c + // c will be deleted +{ + CGAL_triangulation_precondition( (dimension() == 3) + && (0<=i) && (i<4) + && (0<=j) && (j<4) + && ( i != j ) + && (number_of_vertices() >= 6) ); + CGAL_triangulation_expensive_precondition( is_cell(c) ); + + // checks that the edge is flippable ie degree 3 + CGAL_triangulation_precondition_code( int degree = 0; ); + CGAL_triangulation_precondition_code + ( Cell_circulator ccir = incident_cells(c,i,j); ); + CGAL_triangulation_precondition_code( Cell_circulator cdone = ccir; ); + CGAL_triangulation_precondition_code( do { + ++degree; + ++ccir; + } while ( ccir != cdone ); ); + + CGAL_triangulation_precondition( degree == 3 ); + + int next = next_around_edge(i,j); + Cell_handle c1 = c->neighbor( next ); + Vertex_handle v1 = c->vertex( next ); // will become vertex of c1 + int i1 = c1->index( c->vertex(i) ); + int j1 = c1->index( c->vertex(j) ); + + int next1 = next_around_edge(i1,j1); + Cell_handle c2 = c1->neighbor( next1 ); + Vertex_handle v2 = c1->vertex( next1 ); // will become vertex of c2 + int i2 = c2->index( c->vertex(i) ); + int j2 = c2->index( c->vertex(j) ); + + int next2 = next_around_edge(i2,j2); + Vertex_handle v3 = c2->vertex( next2 ); + + // checks that the edge is flippable, + // is the future cells do not already exist + CGAL_triangulation_expensive_precondition( !is_cell(v1,v2,v3,c->vertex(i)) ); + CGAL_triangulation_expensive_precondition( !is_cell(v1,v2,v3,c->vertex(j)) ); + + flip_really(c,i,j,c1,v1,i1,j1,next1,c2,v2,i2,j2,next2,v3); +} + +template < class Vb, class Cb> +inline +void +Triangulation_data_structure_3:: +flip_really( Cell_handle c, int i, int j, + Cell_handle c1, Vertex_handle v1, + int i1, int j1, int next1, + Cell_handle c2, Vertex_handle v2, + int i2, int j2, int next2, + Vertex_handle v3 ) +{ + c->vertex(i)->set_cell(c1); + c->vertex(j)->set_cell(c2); + + c1->set_vertex( j1, v1 ); + v1->set_cell(c1); + c2->set_vertex( i2, v2 ); + v2->set_cell(c2); + + set_adjacency(c1, next1,c2->neighbor(j2), c2->neighbor(j2)->index(c2)); + set_adjacency(c2,c2->index(v1),c1->neighbor(i1),c1->neighbor(i1)->index(c1)); + + set_adjacency(c1, i1, c2, j2); + + set_adjacency(c1, 6-i1-j1-next1, c->neighbor(j), c->neighbor(j)->index(c)); + set_adjacency(c2, next2, c->neighbor(i), c->neighbor(i)->index(c)); + + v3->set_cell( c2 ); + + delete_cell( c ); +} + +template < class Vb, class Cb > +void +Triangulation_data_structure_3:: +read_cells(std::istream& is, std::map< std::size_t, Vertex_handle > &V, + std::size_t & m, std::map< std::size_t, Cell_handle > &C) +{ + // creation of the cells and neighbors + switch (dimension()) { + case 3: + case 2: + case 1: + { + if(is_ascii(is)) + is >> m; + else + read(is, m); + + for(std::size_t i = 0; i < m; i++) { + Cell_handle c = create_cell(); + for (int k=0; k<=dimension(); ++k) { + std::size_t ik; + if(is_ascii(is)) + is >> ik; + else + read(is, ik); + c->set_vertex(k, V[ik]); + V[ik]->set_cell(c); + } + C[i] = c; + } + for(std::size_t j = 0; j < m; j++) { + Cell_handle c = C[j]; + for (int k=0; k<=dimension(); ++k) { + std::size_t ik; + if(is_ascii(is)) + is >> ik; + else + read(is, ik); + c->set_neighbor(k, C[ik]); + } + } + break; + } + case 0: + { + m = 2; + + // CGAL_triangulation_assertion( n == 2 ); + for (int i=0; i < 2; i++) { + Cell_handle c = create_face(V[i], Vertex_handle(), Vertex_handle()); + C[i] = c; + V[i]->set_cell(c); + } + for (int j=0; j < 2; j++) { + Cell_handle c = C[j]; + c->set_neighbor(0, C[1-j]); + } + break; + } + case -1: + { + m = 1; + // CGAL_triangulation_assertion( n == 1 ); + Cell_handle c = create_face(V[0], Vertex_handle(), Vertex_handle()); + C[0] = c; + V[0]->set_cell(c); + break; + } + } +} + +template < class Vb, class Cb> +void +Triangulation_data_structure_3:: +print_cells(std::ostream& os, const std::map &V ) const +{ + std::map C; + std::size_t i = 0; + + switch ( dimension() ) { + case 3: + { + std::size_t m = number_of_cells(); + if(is_ascii(os)) + os << m << std::endl; + else + write(os, m); + + // write the cells + Cell_iterator it; + for(it = cells_begin(); it != cells_end(); ++it) { + C[it] = i++; + for(int j = 0; j < 4; j++){ + if(is_ascii(os)) { + os << V.find(it->vertex(j))->second; + if ( j==3 ) + os << std::endl; + else + os << ' '; + } + else + write(os, V.find(it->vertex(j))->second); + } + } + CGAL_triangulation_assertion( i == m ); + + // write the neighbors + for(it = cells_begin(); it != cells_end(); ++it) { + for (int j = 0; j < 4; j++) { + if(is_ascii(os)){ + os << C[it->neighbor(j)]; + if(j==3) + os << std::endl; + else + os << ' '; + } + else + write(os, C[it->neighbor(j)]); + } + } + break; + } + case 2: + { + size_type m = number_of_facets(); + if(is_ascii(os)) + os << m << std::endl; + else + write(os, m); + + // write the facets + Facet_iterator it; + for(it = facets_begin(); it != facets_end(); ++it) { + C[(*it).first] = i++; + for(int j = 0; j < 3; j++){ + if(is_ascii(os)) { + os << V.find((*it).first->vertex(j))->second; + if ( j==2 ) + os << std::endl; + else + os << ' '; + } + else { + write(os, V.find((*it).first->vertex(j))->second); + } + } + } + CGAL_triangulation_assertion( i == m ); + + // write the neighbors + for(it = facets_begin(); it != facets_end(); ++it) { + for (int j = 0; j < 3; j++) { + if(is_ascii(os)){ + os << C[(*it).first->neighbor(j)]; + if(j==2) + os << std::endl; + else + os << ' '; + } + else { + write(os, C[(*it).first->neighbor(j)]); + } + } + } + break; + } + case 1: + { + size_type m = number_of_edges(); + if(is_ascii(os)) + os << m << std::endl; + else + write(os, m); + // write the edges + Edge_iterator it; + for(it = edges_begin(); it != edges_end(); ++it) { + C[(*it).first] = i++; + for(int j = 0; j < 2; j++){ + if(is_ascii(os)) { + os << V.find((*it).first->vertex(j))->second; + if ( j==1 ) + os << std::endl; + else + os << ' '; + } + else { + write(os, V.find((*it).first->vertex(j))->second); + } + } + } + CGAL_triangulation_assertion( i == m ); + + // write the neighbors + for(it = edges_begin(); it != edges_end(); ++it) { + for (int j = 0; j < 2; j++) { + if(is_ascii(os)){ + os << C[(*it).first->neighbor(j)]; + if(j==1) + os << std::endl; + else + os << ' '; + } + else { + write(os, C[(*it).first->neighbor(j)]); + } + } + } + break; + } + } +} + +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: +insert_in_cell(Cell_handle c) +{ + CGAL_triangulation_precondition( dimension() == 3 ); + CGAL_triangulation_precondition( c != Cell_handle() ); + CGAL_triangulation_expensive_precondition( is_cell(c) ); + + Vertex_handle v = create_vertex(); + + Vertex_handle v0 = c->vertex(0); + Vertex_handle v1 = c->vertex(1); + Vertex_handle v2 = c->vertex(2); + Vertex_handle v3 = c->vertex(3); + + Cell_handle n1 = c->neighbor(1); + Cell_handle n2 = c->neighbor(2); + Cell_handle n3 = c->neighbor(3); + + // c will be modified to have v,v1,v2,v3 as vertices + Cell_handle c3 = create_cell(v0,v1,v2,v); + Cell_handle c2 = create_cell(v0,v1,v,v3); + Cell_handle c1 = create_cell(v0,v,v2,v3); + + set_adjacency(c3, 0, c, 3); + set_adjacency(c2, 0, c, 2); + set_adjacency(c1, 0, c, 1); + + set_adjacency(c2, 3, c3, 2); + set_adjacency(c1, 3, c3, 1); + set_adjacency(c1, 2, c2, 1); + + set_adjacency(n1, n1->index(c), c1, 1); + set_adjacency(n2, n2->index(c), c2, 2); + set_adjacency(n3, n3->index(c), c3, 3); + + c->set_vertex(0,v); + + v0->set_cell(c1); + v->set_cell(c); + + return v; +} + +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: +insert_in_facet(Cell_handle c, int i) +{ // inserts v in the facet opposite to vertex i of cell c + + CGAL_triangulation_precondition( c != Cell_handle() ); + CGAL_triangulation_precondition( dimension() >= 2 ); + + Vertex_handle v = create_vertex(); + + switch ( dimension() ) { + + case 3: + { + CGAL_triangulation_expensive_precondition( is_cell(c) ); + CGAL_triangulation_precondition( i == 0 || i == 1 || + i == 2 || i == 3 ); + // c will be modified to have v replacing vertex(i+3) + int i1,i2,i3; + + if ( (i&1) == 0 ) { + i1=(i+1)&3; i2=(i+2)&3; i3=6-i-i1-i2; + } + else { + i1=(i+1)&3; i2=(i+3)&3; i3=6-i-i1-i2; + } + // i,i1,i2,i3 is well oriented + // so v will "replace" the vertices in this order + // when creating the new cells one after another from c + + Vertex_handle vi=c->vertex(i); + Vertex_handle v1=c->vertex(i1); + Vertex_handle v2=c->vertex(i2); + Vertex_handle v3=c->vertex(i3); + + // new cell with v in place of i1 + Cell_handle nc = c->neighbor(i1); + Cell_handle cnew1 = create_cell(vi,v,v2,v3); + set_adjacency(cnew1, 1, nc, nc->index(c)); + set_adjacency(cnew1, 3, c, i1); + + v3->set_cell(cnew1); + + // new cell with v in place of i2 + nc = c->neighbor(i2); + Cell_handle cnew2 = create_cell(vi,v1,v,v3); + set_adjacency(cnew2, 2, nc, nc->index(c)); + set_adjacency(cnew2, 3, c, i2); + set_adjacency(cnew1, 2, cnew2, 1); + + // v replaces i3 in c + c->set_vertex(i3,v); + + // other side of facet containing v + Cell_handle d = c->neighbor(i); + int j = d->index(c); + int j1=d->index(v1);// triangulation supposed to be valid + int j2=d->index(v2); + int j3=6-j-j1-j2; + // then the orientation of j,j1,j2,j3 depends on the parity + // of i-j + + // new cell with v in place of j1 + Cell_handle nd = d->neighbor(j1); + Cell_handle dnew1 = create_cell(d->vertex(j),v,v3,v2); + set_adjacency(dnew1, 1, nd, nd->index(d)); + set_adjacency(dnew1, 2, d, j1); + set_adjacency(dnew1, 0, cnew1, 0); + + // new cell with v in place of j2 + nd = d->neighbor(j2); + Cell_handle dnew2 = create_cell(d->vertex(j),v1,v3,v); + + set_adjacency(dnew2, 3, nd, nd->index(d)); + set_adjacency(dnew2, 2, d, j2); + set_adjacency(dnew2, 0, cnew2, 0); + set_adjacency(dnew1, 3, dnew2, 1); + + // v replaces i3 in d + d->set_vertex(j3,v); + v->set_cell(d); + + break; + } + case 2: + { + CGAL_triangulation_expensive_precondition( is_facet(c,i) ); + Cell_handle n = c->neighbor(2); + Cell_handle cnew = create_face(c->vertex(0),c->vertex(1),v); + set_adjacency(cnew, 2, n, n->index(c)); + set_adjacency(cnew, 0, c, 2); + c->vertex(0)->set_cell(cnew); + + n = c->neighbor(1); + Cell_handle dnew = create_face(c->vertex(0),v,c->vertex(2)); + set_adjacency(dnew, 1, n, n->index(c)); + set_adjacency(dnew, 0, c, 1); + set_adjacency(dnew, 2, cnew, 1); + + c->set_vertex(0,v); + v->set_cell(c); + break; + } + } + + return v; +} + +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: +insert_in_edge(Cell_handle c, int i, int j) + // inserts a vertex in the edge of cell c with vertices i and j +{ + CGAL_triangulation_precondition( c != Cell_handle() ); + CGAL_triangulation_precondition( i != j ); + CGAL_triangulation_precondition( dimension() >= 1 ); + + switch ( dimension() ) { + case 3: + { + CGAL_triangulation_expensive_precondition( is_cell(c) ); + CGAL_triangulation_precondition( i>=0 && i<=3 && j>=0 && j<=3 ); + + std::vector cells; + cells.reserve(32); + Cell_circulator ccir = incident_cells(c, i, j); + do { + Cell_handle cc = ccir; + cells.push_back(cc); + cc->tds_data().mark_in_conflict(); + ++ccir; + } while (c != ccir); + + return _insert_in_hole(cells.begin(), cells.end(), c, i); + } + case 2: + { + CGAL_triangulation_expensive_precondition( is_edge(c,i,j) ); + + Vertex_handle v = create_vertex(); + int k=3-i-j; // index of the third vertex of the facet + Cell_handle d = c->neighbor(k); + int kd = d->index(c); + int id = d->index(c->vertex(i)); + int jd = d->index(c->vertex(j)); + + Cell_handle cnew = create_cell(); + cnew->set_vertex(i,c->vertex(i)); + c->vertex(i)->set_cell(cnew); + cnew->set_vertex(j,v); + cnew->set_vertex(k,c->vertex(k)); + c->set_vertex(i,v); + + Cell_handle dnew = create_cell(); + dnew->set_vertex(id,d->vertex(id)); + // d->vertex(id)->cell() is cnew OK + dnew->set_vertex(jd,v); + dnew->set_vertex(kd,d->vertex(kd)); + d->set_vertex(id,v); + + Cell_handle nj = c->neighbor(j); + set_adjacency(cnew, i, c, j); + set_adjacency(cnew, j, nj, nj->index(c)); + + nj = d->neighbor(jd); + set_adjacency(dnew, id, d, jd); + set_adjacency(dnew, jd, nj, nj->index(d)); + + set_adjacency(cnew, k, dnew, kd); + + v->set_cell(cnew); + return v; + } + default: // case 1: + { + Vertex_handle v = create_vertex(); + CGAL_triangulation_expensive_precondition( is_edge(c,i,j) ); + Cell_handle cnew = create_face(v, c->vertex(1), Vertex_handle()); + c->vertex(1)->set_cell(cnew); + c->set_vertex(1,v); + set_adjacency(cnew, 0, c->neighbor(0), 1); + set_adjacency(cnew, 1, c, 0); + + v->set_cell(cnew); + return v; + } + } +} + +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: +insert_increase_dimension(Vertex_handle star) + // star = vertex from which we triangulate the facet of the + // incremented dimension + // ( geometrically : star = infinite vertex ) + // = NULL only used to insert the 1st vertex (dimension -2 to dimension -1) + // changes the dimension +{ + CGAL_triangulation_precondition( dimension() < 3); + + Vertex_handle v = create_vertex(); + + int dim = dimension(); + if (dim != -2) { + CGAL_triangulation_precondition( star != Vertex_handle() ); + // In this case, this precondition is not relatively expensive. + CGAL_triangulation_precondition( is_vertex(star) ); + } + + // this is set now, so that it becomes allowed to reorient + // new facets or cells by iterating on them (otherwise the + // dimension is too small) + set_dimension( dimension()+1 ); + + switch ( dim ) { + case -2: + // insertion of the first vertex + // ( geometrically : infinite vertex ) + { + Cell_handle c = create_face(v, Vertex_handle(), Vertex_handle()); + v->set_cell(c); + break; + } + + case -1: + // insertion of the second vertex + // ( geometrically : first finite vertex ) + { + Cell_handle d = create_face(v, Vertex_handle(), Vertex_handle()); + v->set_cell(d); + set_adjacency(d, 0, star->cell(), 0); + break; + } + + case 0: + // insertion of the third vertex + // ( geometrically : second finite vertex ) + { + Cell_handle c = star->cell(); + Cell_handle d = c->neighbor(0); + + c->set_vertex(1,d->vertex(0)); + d->set_vertex(1,v); + d->set_neighbor(1,c); + Cell_handle e = create_face( v, star, Vertex_handle() ); + set_adjacency(e, 0, c, 1); + set_adjacency(e, 1, d, 0); + + v->set_cell(d); + break; + } + + case 1: + // general case : 4th vertex ( geometrically : 3rd finite vertex ) + // degenerate cases geometrically : 1st non collinear vertex + { + Cell_handle c = star->cell(); + int i = c->index(star); // i== 0 or 1 + int j = (1-i); + Cell_handle d = c->neighbor(j); + + c->set_vertex(2,v); + + Cell_handle e = c->neighbor(i); + Cell_handle cnew = c; + Cell_handle enew = Cell_handle(); + + while( e != d ){ + enew = create_cell(); + enew->set_vertex(i,e->vertex(j)); + enew->set_vertex(j,e->vertex(i)); + enew->set_vertex(2,star); + + set_adjacency(enew, i, cnew, j); + // false at the first iteration of the loop where it should + // be neighbor 2 + // it is corrected after the loop + set_adjacency(enew, 2, e, 2); + // neighbor j will be set during next iteration of the loop + + e->set_vertex(2,v); + + e = e->neighbor(i); + cnew = enew; + } + + d->set_vertex(2,v); + set_adjacency(enew, j, d, 2); + + // corrections for star->cell() : + c = star->cell(); + c->set_neighbor(2,c->neighbor(i)->neighbor(2)); + c->set_neighbor(j,d); + + v->set_cell(d); + + break; + } + + case 2: + // general case : 5th vertex ( geometrically : 4th finite vertex ) + // degenerate cases : geometrically 1st non coplanar vertex + { + // used to store the new cells, in order to be able to traverse only + // them to find the missing neighbors. + std::vector new_cells; + new_cells.reserve(16); + + Cell_iterator it = cells_begin(); + // allowed since the dimension has already been set to 3 + + v->set_cell(it); // ok since there is at least one ``cell'' + for(; it != cells_end(); ++it) { + // Here we must be careful since we create_cells in a loop controlled + // by an iterator. So we first take care of the cells newly created + // by the following test : + if (it->neighbor(0) == Cell_handle()) + continue; + it->set_neighbor(3, Cell_handle()); + it->set_vertex(3, v); + if ( ! it->has_vertex(star) ) { + Cell_handle cnew = create_cell( it->vertex(0), it->vertex(2), + it->vertex(1), star); + // The Intel compiler has a problem with passing "it" directly to + // function "set_adjacency": the adjacency is not changed. + Cell_handle ch_it = it; + set_adjacency(cnew, 3, ch_it, 3); + cnew->set_neighbor(0, Cell_handle()); + new_cells.push_back(cnew); + } + } + + // traversal of the new cells only, to add missing neighbors + for(typename std::vector::iterator ncit = new_cells.begin(); + ncit != new_cells.end(); ++ncit) { + Cell_handle n = (*ncit)->neighbor(3); // opposite to star + for ( int i=0; i<3; i++ ) { + int j; + if ( i==0 ) j=0; + else j=3-i; // vertex 1 and vertex 2 are always switched when + // creating a new cell (see above) + Cell_handle c = n->neighbor(i)->neighbor(3); + if ( c != Cell_handle() ) { + // i.e. star is not a vertex of n->neighbor(i) + (*ncit)->set_neighbor(j, c); + // opposite relation will be set when ncit arrives on c + // this avoids to look for the correct index + // and to test whether *ncit already has neighbor i + } + else { + // star is a vertex of n->neighbor(i) + set_adjacency(*ncit, j, n->neighbor(i), 3);//neighbor opposite to v + } + } + } + } + }// end switch + + return v; +} + +template +void +Triangulation_data_structure_3:: +remove_decrease_dimension(Vertex_handle v, Vertex_handle w) +{ + CGAL_triangulation_expensive_precondition( is_valid() ); + CGAL_triangulation_precondition( dimension() >= -1 ); + CGAL_triangulation_precondition( dimension() != 1 || + number_of_vertices() == 3); + CGAL_triangulation_precondition( number_of_vertices() > + (size_type) dimension() + 1 ); + CGAL_triangulation_precondition( degree(v) == number_of_vertices()-1 ); + + if (dimension() <= 0) { + delete_cell(v->cell()); + } + else { + // the cells incident to w are down graded one dimension + // the other cells are deleted + std::vector to_delete, to_downgrade; + + for (Cell_iterator ib = cells().begin(); + ib != cells().end(); ++ib) { + if ( ib->has_vertex(w) ) + to_downgrade.push_back(ib); + else + to_delete.push_back(ib); + } + + typename std::vector::iterator lfit=to_downgrade.begin(); + for( ; lfit != to_downgrade.end(); ++lfit) { + Cell_handle f = *lfit; + int j = f->index(w); + int k; if (f->has_vertex(v, k)) f->set_vertex(k, w); + if (j != dimension()) { + f->set_vertex(j, f->vertex(dimension())); + f->set_neighbor(j, f->neighbor(dimension())); + if (dimension() >= 1) + change_orientation(f); + } + f->set_vertex(dimension(), Vertex_handle()); + f->set_neighbor(dimension(), Cell_handle()); + + // Update vertex->cell() pointers. + for (int i = 0; i < dimension(); ++i) + f->vertex(i)->set_cell(f); + } + + delete_cells(to_delete.begin(), to_delete.end()); + } + delete_vertex(v); + set_dimension(dimension()-1); + CGAL_triangulation_postcondition(is_valid()); +} + +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: +remove_from_maximal_dimension_simplex(Vertex_handle v) +{ + CGAL_triangulation_precondition(dimension() >= 1); + CGAL_triangulation_precondition(degree(v) == (size_type) dimension() + 1); + CGAL_triangulation_precondition(number_of_vertices() > + (size_type) dimension() + 1); + + if (number_of_vertices() == (size_type) dimension() + 2) { + remove_decrease_dimension(v); + return Cell_handle(); + } + + if (dimension() == 3) + return remove_degree_4(v); + if (dimension() == 2) + return remove_degree_3(v); + + // dimension() == 1 + return remove_degree_2(v); +} + +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: +remove_degree_2(Vertex_handle v) +{ + CGAL_triangulation_precondition(dimension() == 1); + CGAL_triangulation_precondition(degree(v) == 2); + CGAL_triangulation_precondition(number_of_vertices() >= 4); + + // Cells to be killed. + Cell_handle c0, c1; + // Indices of v in these cells. + int i0, i1; + + c0 = v->cell(); + i0 = c0->index(v); + c1 = c0->neighbor(1-i0); + i1 = c1->index(v); + + // New cell : we copy the content of c0, so we keep the orientation. + Cell_handle newc = create_face(c0->vertex(0), + c0->vertex(1), + Vertex_handle()); + + newc->set_vertex(i0, c1->vertex(c1->index(c0))); + + set_adjacency(newc, i0, c0->neighbor(i0), mirror_index(c0, i0)); + set_adjacency(newc, 1-i0, c1->neighbor(i1), mirror_index(c1, i1)); + + newc->vertex(0)->set_cell(newc); + newc->vertex(1)->set_cell(newc); + + delete_cell(c0); + delete_cell(c1); + delete_vertex(v); + + return newc; +} + +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: +remove_degree_3(Vertex_handle v) +{ + CGAL_triangulation_precondition(dimension() == 2); + CGAL_triangulation_precondition(degree(v) == 3); + CGAL_triangulation_precondition(number_of_vertices() >= 5); + + // Cells to be killed. + Cell_handle c0, c1, c2; + // Indices of v in these cells. + int i0, i1, i2; + + c0 = v->cell(); + i0 = c0->index(v); + c1 = c0->neighbor(cw(i0)); + i1 = c1->index(v); + c2 = c0->neighbor(ccw(i0)); + i2 = c2->index(v); + + // New cell : we copy the content of c0, so we keep the orientation. + Cell_handle newc = create_face(c0->vertex(0), + c0->vertex(1), + c0->vertex(2)); + + newc->set_vertex(i0, c1->vertex(c1->index(c0))); + + set_adjacency(newc, i0, c0->neighbor(i0), mirror_index(c0, i0)); + set_adjacency(newc, cw(i0), c1->neighbor(i1), mirror_index(c1, i1)); + set_adjacency(newc, ccw(i0), c2->neighbor(i2), mirror_index(c2, i2)); + + newc->vertex(0)->set_cell(newc); + newc->vertex(1)->set_cell(newc); + newc->vertex(2)->set_cell(newc); + + delete_cell(c0); + delete_cell(c1); + delete_cell(c2); + delete_vertex(v); + + return newc; +} + +template +typename Triangulation_data_structure_3::Cell_handle +Triangulation_data_structure_3:: +remove_degree_4(Vertex_handle v) +{ + CGAL_triangulation_precondition(dimension() == 3); + CGAL_triangulation_precondition(degree(v) == 4); + CGAL_triangulation_precondition(number_of_vertices() >= 6); + + // Cells to be killed. + Cell_handle c0, c1, c2, c3; + // Indices of v in these cells. + int i0, i1, i2, i3; + + c0 = v->cell(); + i0 = c0->index(v); + c1 = c0->neighbor(i0^1); + i1 = c1->index(v); + c2 = c0->neighbor(i0^2); + i2 = c2->index(v); + c3 = c0->neighbor(i0^3); + i3 = c3->index(v); + + // New cell : we copy the content of c0, so we keep the orientation. + Cell_handle newc = create_cell(c0->vertex(0), + c0->vertex(1), + c0->vertex(2), + c0->vertex(3)); + + newc->set_vertex(i0, c1->vertex(c1->index(c0))); + + set_adjacency(newc, i0, c0->neighbor(i0), mirror_index(c0, i0)); + set_adjacency(newc, i0^1, c1->neighbor(i1), mirror_index(c1, i1)); + set_adjacency(newc, i0^2, c2->neighbor(i2), mirror_index(c2, i2)); + set_adjacency(newc, i0^3, c3->neighbor(i3), mirror_index(c3, i3)); + + newc->vertex(0)->set_cell(newc); + newc->vertex(1)->set_cell(newc); + newc->vertex(2)->set_cell(newc); + newc->vertex(3)->set_cell(newc); + + delete_cell(c0); + delete_cell(c1); + delete_cell(c2); + delete_cell(c3); + delete_vertex(v); + + return newc; +} + +template +void +Triangulation_data_structure_3:: +decrease_dimension(Cell_handle c, int i) +{ + CGAL_triangulation_expensive_precondition( is_valid() );; + CGAL_triangulation_precondition( dimension() >= 2); + CGAL_triangulation_precondition( number_of_vertices() > + (size_type) dimension() + 1 ); + CGAL_triangulation_precondition( degree(c->vertex(i)) == number_of_vertices()-1 ); + + Vertex_handle v = c->vertex(i); + Vertex_handle w = c->vertex(i); + + // the cells incident to w are down graded one dimension + // the other cells are deleted + std::vector to_delete, to_downgrade; + + for (Cell_iterator ib = cells().begin(); + ib != cells().end(); ++ib) { + if ( ib->has_vertex(w) ) + to_downgrade.push_back(ib); + else + to_delete.push_back(ib); + } + + typename std::vector::iterator lfit=to_downgrade.begin(); + for( ; lfit != to_downgrade.end(); ++lfit) { + Cell_handle f = *lfit; + int j = f->index(w); + int k; + if (f->has_vertex(v, k)) f->set_vertex(k, w); + if (j != dimension()) { + f->set_vertex(j, f->vertex(dimension())); + f->set_neighbor(j, f->neighbor(dimension())); + if (dimension() >= 1) + change_orientation(f); + } + f->set_vertex(dimension(), Vertex_handle()); + f->set_neighbor(dimension(), Cell_handle()); + + // Update vertex->cell() pointers. + for (int i = 0; i < dimension(); ++i) + f->vertex(i)->set_cell(f); + } + + delete_cells(to_delete.begin(), to_delete.end()); + + //delete_vertex(v); + set_dimension(dimension()-1); + + if(dimension() == 2) + { + Cell_handle n0 = c->neighbor(0); + Cell_handle n1 = c->neighbor(1); + Cell_handle n2 = c->neighbor(2); + Vertex_handle v0 = c->vertex(0); + Vertex_handle v1 = c->vertex(1); + Vertex_handle v2 = c->vertex(2); + + int i0 = 0, i1 = 0, i2 = 0; + + for(int i=0; i<3; i++) if(n0->neighbor(i) == c) { i0 = i; break; } + for(int i=0; i<3; i++) if(n1->neighbor(i) == c) { i1 = i; break; } + for(int i=0; i<3; i++) if(n2->neighbor(i) == c) { i2 = i; break; } + + Cell_handle c1 = create_cell(v, v0, v1, Vertex_handle()); + Cell_handle c2 = create_cell(v, v1, v2, Vertex_handle()); + + c->set_vertex(0, v); + c->set_vertex(1, v2); + c->set_vertex(2, v0); + c->set_vertex(3, Vertex_handle()); + + //Cell_handle c3 = create_cell(v, v2, v0, Vertex_handle()); + Cell_handle c3 = c; + + c1->set_neighbor(0, n2); n2->set_neighbor(i2, c1); + c1->set_neighbor(1, c2); + c1->set_neighbor(2, c3); + c1->set_neighbor(3, Cell_handle()); + + c2->set_neighbor(0, n0); n0->set_neighbor(i0, c2); + c2->set_neighbor(1, c3); + c2->set_neighbor(2, c1); + c2->set_neighbor(3, Cell_handle()); + + c3->set_neighbor(0, n1); n1->set_neighbor(i1, c3); + c3->set_neighbor(1, c1); + c3->set_neighbor(2, c2); + c3->set_neighbor(3, Cell_handle()); + + v->set_cell(c1); + v0->set_cell(c1); + v1->set_cell(c1); + v2->set_cell(c2); + } + + if(dimension() == 1) + { + Cell_handle n0 = c->neighbor(0); + Cell_handle n1 = c->neighbor(1); + Vertex_handle v0 = c->vertex(0); + Vertex_handle v1 = c->vertex(1); + + int i0 = 0 , i1 = 0; + + for(int i=0; i<2; i++) if(n0->neighbor(i) == c) { i0 = i; break; } + for(int i=0; i<2; i++) if(n1->neighbor(i) == c) { i1 = i; break; } + + Cell_handle c1 = create_cell(v0, v, Vertex_handle(), Vertex_handle()); + + c->set_vertex(0, v); + c->set_vertex(1, v1); + c->set_vertex(2, Vertex_handle()); + c->set_vertex(3, Vertex_handle()); + + //Cell_handle c2 = create_cell(v, v1, Vertex_handle(), Vertex_handle()); + Cell_handle c2 = c; + + c1->set_neighbor(0, c2); + c1->set_neighbor(1, n1); n1->set_neighbor(i1, c1); + c1->set_neighbor(2, Cell_handle()); + c1->set_neighbor(3, Cell_handle()); + + c2->set_neighbor(0, n0); n0->set_neighbor(i0, c2); + c2->set_neighbor(1, c1); + c2->set_neighbor(2, Cell_handle()); + c2->set_neighbor(3, Cell_handle()); + + v->set_cell(c1); + v0->set_cell(c1); + v1->set_cell(c2); + } + + CGAL_triangulation_postcondition(is_valid()); +} + + +template +typename Triangulation_data_structure_3::size_type +Triangulation_data_structure_3:: +degree(Vertex_handle v) const +{ + std::size_t res; + adjacent_vertices(v, Counting_output_iterator(&res)); + return res; +} + +template +bool +Triangulation_data_structure_3:: +is_valid(bool verbose, int level ) const +{ + switch ( dimension() ) { + case 3: + { + + if(number_of_vertices() <= 4) { + if (verbose) + std::cerr << "wrong number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + size_type vertex_count; + if ( ! count_vertices(vertex_count,verbose,level) ) + return false; + if ( number_of_vertices() != vertex_count ) { + if (verbose) + std::cerr << "wrong number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + size_type cell_count; + if ( ! count_cells(cell_count,verbose,level) ) + return false; + size_type edge_count; + if ( ! count_edges(edge_count,verbose,level) ) + return false; + size_type facet_count; + if ( ! count_facets(facet_count,verbose,level) ) + return false; + + // Euler relation + if ( cell_count - facet_count + edge_count - vertex_count != 0 ) { + if (verbose) + std::cerr << "Euler relation unsatisfied" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + break; + } + case 2: + { + + if(number_of_vertices() <= 3) { + if (verbose) + std::cerr << "wrong number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + size_type vertex_count; + + if ( ! count_vertices(vertex_count,verbose,level) ) + return false; + if ( number_of_vertices() != vertex_count ) { + if (verbose) + std::cerr << "false number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + size_type edge_count; + if ( ! count_edges(edge_count,verbose,level) ) + return false; + // Euler for edges + if ( edge_count != 3 * vertex_count - 6 ) { + if (verbose) + std::cerr << "Euler relation unsatisfied - edges/vertices" + << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + size_type facet_count; + if ( ! count_facets(facet_count,verbose,level) ) + return false; + // Euler for facets + if ( facet_count != 2 * vertex_count - 4 ) { + if (verbose) + std::cerr << "Euler relation unsatisfied - facets/vertices" + << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + break; + } + case 1: + { + + if(number_of_vertices() <= 1) { + if (verbose) + std::cerr << "wrong number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + size_type vertex_count; + if ( ! count_vertices(vertex_count,verbose,level) ) + return false; + if ( number_of_vertices() != vertex_count ) { + if (verbose) + std::cerr << "false number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + size_type edge_count; + if ( ! count_edges(edge_count,verbose,level) ) + return false; + // Euler for edges + if ( edge_count != vertex_count ) { + if (verbose) + std::cerr << "false number of edges" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + break; + } + case 0: + { + if ( number_of_vertices() < 2 ) { + if (verbose) + std::cerr << "less than 2 vertices but dimension 0" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + // no break; continue + } + case -1: + { + if ( number_of_vertices() < 1 ) { + if (verbose) + std::cerr << "no vertex but dimension -1" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + // vertex count + size_type vertex_count; + if ( ! count_vertices(vertex_count,verbose,level) ) + return false; + if ( number_of_vertices() != vertex_count ) { + if (verbose) + std::cerr << "false number of vertices" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } // end switch + if (verbose) + std::cerr << "valid data structure" << std::endl; + return true; +} + +template +bool +Triangulation_data_structure_3:: +is_valid(Vertex_handle v, bool verbose, int level) const +{ + bool result = v->is_valid(verbose,level); + result = result && v->cell()->has_vertex(v); + if ( ! result ) { + if ( verbose ) + std::cerr << "invalid vertex" << std::endl; + CGAL_triangulation_assertion(false); + } + return result; +} + +template +bool +Triangulation_data_structure_3:: +is_valid(Cell_handle c, bool verbose, int level) const +{ + if ( ! c->is_valid(verbose, level) ) + return false; + + switch (dimension()) { + case -2: + case -1: + { + if ( c->vertex(0) == Vertex_handle() ) { + if (verbose) + std::cerr << "vertex 0 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + is_valid(c->vertex(0),verbose,level); + if ( c->vertex(1) != Vertex_handle() || c->vertex(2) != Vertex_handle()) { + if (verbose) + std::cerr << "vertex 1 or 2 != NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( c->neighbor(0) != Cell_handle() || + c->neighbor(1) != Cell_handle() || + c->neighbor(2) != Cell_handle()) { + if (verbose) + std::cerr << "one neighbor != NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + break; + } + + case 0: + { + if ( c->vertex(0) == Vertex_handle() ) { + if (verbose) + std::cerr << "vertex 0 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + is_valid(c->vertex(0),verbose,level); + if ( c->neighbor (0) == Cell_handle() ) { + if (verbose) + std::cerr << "neighbor 0 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( c->vertex(1) != Vertex_handle() || + c->vertex(2) != Vertex_handle() ) { + if (verbose) + std::cerr << "vertex 1 or 2 != NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( c->neighbor(1) != Cell_handle() || + c->neighbor(2) != Cell_handle() ) { + if (verbose) + std::cerr << "neighbor 1 or 2 != NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + if ( ! c->neighbor(0)->has_vertex(c->vertex(0)) ) { + if (verbose) + std::cerr << "neighbor 0 does not have vertex 0" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + break; + } + + case 1: + { + Vertex_handle v0 = c->vertex(0); + Vertex_handle v1 = c->vertex(1); + Cell_handle n0 = c->neighbor(0); + Cell_handle n1 = c->neighbor(1); + + if ( v0 == Vertex_handle() || v1 == Vertex_handle() ) { + if (verbose) + std::cerr << "vertex 0 or 1 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + is_valid(c->vertex(0),verbose,level); + is_valid(c->vertex(1),verbose,level); + if ( n0 == Cell_handle() || n1 == Cell_handle() ) { + if (verbose) + std::cerr << "neighbor 0 or 1 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + if ( v0 != n1->vertex(1) ) { + if (verbose) + std::cerr << "neighbor 1 does not have vertex 0 as vertex 1" + << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( v1 != n0->vertex(0) ) { + if (verbose) + std::cerr << "neighbor 0 does not have vertex 1 as vertex 0" + << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + if ( n0->neighbor(1) != c ) { + if (verbose) + std::cerr << "neighbor 0 does not have this as neighbor 1" + << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( n1->neighbor(0) != c ) { + if (verbose) + std::cerr << "neighbor 1 does not have this as neighbor 0" + << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + break; + } + + case 2: + { + if ( c->vertex(0) == Vertex_handle() || + c->vertex(1) == Vertex_handle() || + c->vertex(2) == Vertex_handle() ) { + if (verbose) + std::cerr << "vertex 0, 1, or 2 NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + is_valid(c->vertex(0),verbose,level); + is_valid(c->vertex(1),verbose,level); + is_valid(c->vertex(2),verbose,level); + int in; + Cell_handle n; + for(int i = 0; i < 3; i++) { + n = c->neighbor(i); + if ( n == Cell_handle() ) { + if (verbose) + std::cerr << "neighbor " << i << " NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( ! n->has_vertex(c->vertex(cw(i)),in ) ) { + if (verbose) + std::cerr << "vertex " << cw(i) + << " not vertex of neighbor " << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + in = cw(in); + if ( n->neighbor(in) != c ) { + if (verbose) + std::cerr << "neighbor " << i + << " does not have this as neighbor " + << in << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + if ( c->vertex(ccw(i)) != n->vertex(cw(in)) ) { + if (verbose) + std::cerr << "vertex " << ccw(i) + << " is not vertex " << cw(in) + << " of neighbor " << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + break; + } + + case 3: + { + int i; + for(i = 0; i < 4; i++) { + if ( c->vertex(i) == Vertex_handle() ) { + if (verbose) + std::cerr << "vertex " << i << " NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + is_valid(c->vertex(i),verbose,level); + } + + for(i = 0; i < 4; i++) { + Cell_handle n = c->neighbor(i); + if ( n == Cell_handle() ) { + if (verbose) + std::cerr << "neighbor " << i << " NULL" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + int in = 5; + // if ( ! n->has_neighbor(handle(), in) ) { + if ( n->neighbor(0) == c) in = 0; + if ( n->neighbor(1) == c) in = 1; + if ( n->neighbor(2) == c) in = 2; + if ( n->neighbor(3) == c) in = 3; + if (in == 5) { + if (verbose) + std::cerr << "neighbor of c has not c as neighbor" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + + int j1n,j2n,j3n; + if ( ! n->has_vertex(c->vertex((i+1)&3),j1n) ) { + if (verbose) { std::cerr << "vertex " << ((i+1)&3) + << " not vertex of neighbor " + << i << std::endl; } + CGAL_triangulation_assertion(false); + return false; + } + if ( ! n->has_vertex(c->vertex((i+2)&3),j2n) ) { + if (verbose) { std::cerr << "vertex " << ((i+2)&3) + << " not vertex of neighbor " + << i << std::endl; } + CGAL_triangulation_assertion(false); + return false; + } + if ( ! n->has_vertex(c->vertex((i+3)&3),j3n) ) { + if (verbose) { std::cerr << "vertex " << ((i+3)&3) + << " not vertex of neighbor " + << i << std::endl; } + CGAL_triangulation_assertion(false); + return false; + } + + if ( in+j1n+j2n+j3n != 6) { + if (verbose) { std::cerr << "sum of the indices != 6 " + << std::endl; } + CGAL_triangulation_assertion(false); + return false; + } + + // tests whether the orientations of this and n are consistent + if ( ((i+in)&1) == 0 ) { // i and in have the same parity + if ( j1n == ((in+1)&3) ) { + if ( ( j2n != ((in+3)&3) ) || ( j3n != ((in+2)&3) ) ) { + if (verbose) + std::cerr << " pb orientation with neighbor " + << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + if ( j1n == ((in+2)&3) ) { + if ( ( j2n != ((in+1)&3) ) || ( j3n != ((in+3)&3) ) ) { + if (verbose) + std::cerr << " pb orientation with neighbor " + << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + if ( j1n == ((in+3)&3) ) { + if ( ( j2n != ((in+2)&3) ) || ( j3n != ((in+1)&3) ) ) { + if (verbose) + std::cerr << " pb orientation with neighbor " + << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + else { // i and in do not have the same parity + if ( j1n == ((in+1)&3) ) { + if ( ( j2n != ((in+2)&3) ) || ( j3n != ((in+3)&3) ) ) { + if (verbose) + std::cerr << " pb orientation with neighbor " + << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + if ( j1n == ((in+2)&3) ) { + if ( ( j2n != ((in+3)&3) ) || ( j3n != ((in+1)&3) ) ) { + if (verbose) + std::cerr << " pb orientation with neighbor " + << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + if ( j1n == ((in+3)&3) ) { + if ( ( j2n != ((in+1)&3) ) || ( j3n != ((in+2)&3) ) ) { + if (verbose) + std::cerr << " pb orientation with neighbor " + << i << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + } + } + } // end looking at neighbors + }// end case dim 3 + } // end switch + return true; +} + +template +typename Triangulation_data_structure_3::Vertex_handle +Triangulation_data_structure_3:: +copy_tds(const Tds & tds, Vertex_handle vert ) + // returns the new vertex corresponding to vert in the new tds +{ + CGAL_triangulation_expensive_precondition( vert == Vertex_handle() + || tds.is_vertex(vert) ); + + clear(); + + size_type n = tds.number_of_vertices(); + set_dimension(tds.dimension()); + + // Number of pointers to cell/vertex to copy per cell. + int dim = (std::max)(1, dimension() + 1); + + if (n == 0) + return vert; + + // Create the vertices. + std::vector TV(n); + size_type i = 0; + + for (Vertex_iterator vit = tds.vertices_begin(); + vit != tds.vertices_end(); ++vit) + TV[i++] = vit; + + CGAL_triangulation_assertion( i == n ); + + std::map< Vertex_handle, Vertex_handle > V; + std::map< Cell_handle, Cell_handle > F; + + for (size_type i=0; i <= n-1; ++i) + V[ TV[i] ] = create_vertex(TV[i]); + + // Create the cells. + for (Cell_iterator cit = tds.cells().begin(); + cit != tds.cells_end(); ++cit) { + F[cit] = create_cell(cit); + for (int j = 0; j < dim; j++) + F[cit]->set_vertex(j, V[cit->vertex(j)] ); + } + + // Link the vertices to a cell. + for (Vertex_iterator vit2 = tds.vertices_begin(); + vit2 != tds.vertices_end(); ++vit2) + V[vit2]->set_cell( F[vit2->cell()] ); + + // Hook neighbor pointers of the cells. + for (Cell_iterator cit2 = tds.cells().begin(); + cit2 != tds.cells_end(); ++cit2) { + for (int j = 0; j < dim; j++) + F[cit2]->set_neighbor(j, F[cit2->neighbor(j)] ); + } + + CGAL_triangulation_postcondition( is_valid() ); + + return (vert != Vertex_handle()) ? V[vert] : vert; +} + +template +void +Triangulation_data_structure_3:: +swap(Tds & tds) +{ + CGAL_triangulation_expensive_precondition(tds.is_valid() && is_valid()); + + std::swap(_dimension, tds._dimension); + cells().swap(tds.cells()); + vertices().swap(tds.vertices()); +} + +template +void +Triangulation_data_structure_3:: +clear() +{ + cells().clear(); + vertices().clear(); + set_dimension(-2); +} + +template +bool +Triangulation_data_structure_3:: +count_vertices(size_type & i, bool verbose, int level) const + // counts AND checks the validity +{ + i = 0; + + for (Vertex_iterator it = vertices_begin(); it != vertices_end(); ++it) { + if ( ! is_valid(it,verbose,level) ) { + if (verbose) + std::cerr << "invalid vertex" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + ++i; + } + return true; +} + +template +bool +Triangulation_data_structure_3:: +count_facets(size_type & i, bool verbose, int level) const + // counts but does not check +{ + i = 0; + + for (Facet_iterator it = facets_begin(); it != facets_end(); ++it) { + if ( ! is_valid((*it).first,verbose, level) ) { + if (verbose) + std::cerr << "invalid facet" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + ++i; + } + return true; +} + +template +bool +Triangulation_data_structure_3:: +count_edges(size_type & i, bool verbose, int level) const + // counts but does not check +{ + i = 0; + + for (Edge_iterator it = edges_begin(); it != edges_end(); ++it) { + if ( ! is_valid((*it).first,verbose, level) ) { + if (verbose) + std::cerr << "invalid edge" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + ++i; + } + return true; +} + +template +bool +Triangulation_data_structure_3:: +count_cells(size_type & i, bool verbose, int level) const + // counts AND checks the validity +{ + i = 0; + + for (Cell_iterator it = cells_begin(); it != cells_end(); ++it) { + if ( ! is_valid(it,verbose, level) ) { + if (verbose) + std::cerr << "invalid cell" << std::endl; + CGAL_triangulation_assertion(false); + return false; + } + ++i; + } + return true; +} + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_DATA_STRUCTURE_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_ds_cell_base_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_ds_cell_base_3.h new file mode 100644 index 00000000000..ce91f52da81 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_ds_cell_base_3.h @@ -0,0 +1,243 @@ +// Copyright (c) 1999-2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud +// Sylvain Pion + +// cell of a triangulation data structure of any dimension <=3 + +#ifndef CGAL_TRIANGULATION_DS_CELL_BASE_3_H +#define CGAL_TRIANGULATION_DS_CELL_BASE_3_H + +#include +#include +#include + +namespace CGAL { + +template < typename TDS = void > +class Triangulation_ds_cell_base_3 +{ +public: + typedef TDS Triangulation_data_structure; + typedef typename TDS::Vertex_handle Vertex_handle; + typedef typename TDS::Cell_handle Cell_handle; + typedef typename TDS::Vertex Vertex; + typedef typename TDS::Cell Cell; + typedef typename TDS::Cell_data TDS_data; + + template + struct Rebind_TDS { typedef Triangulation_ds_cell_base_3 Other; }; + + Triangulation_ds_cell_base_3() {} + + Triangulation_ds_cell_base_3(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) +#ifndef CGAL_CFG_ARRAY_MEMBER_INITIALIZATION_BUG + : V((Vertex_handle[4]) {v0, v1, v2, v3} ) {} +#else + { set_vertices(v0, v1, v2, v3); } +#endif + + Triangulation_ds_cell_base_3(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) +#ifndef CGAL_CFG_ARRAY_MEMBER_INITIALIZATION_BUG + : N((Cell_handle[4]) {n0, n1, n2, n3}), V((Vertex_handle[4]) {v0, v1, v2, v3} ) {} +#else + { + set_neighbors(n0, n1, n2, n3); + set_vertices(v0, v1, v2, v3); + } +#endif + + // ACCESS FUNCTIONS + + Vertex_handle vertex(int i) const + { + CGAL_triangulation_precondition( i >= 0 && i <= 3 ); + return V[i]; + } + + bool has_vertex(Vertex_handle v) const + { + return (V[0] == v) || (V[1] == v) || (V[2]== v) || (V[3]== v); + } + + bool has_vertex(Vertex_handle v, int & i) const + { + if (v == V[0]) { i = 0; return true; } + if (v == V[1]) { i = 1; return true; } + if (v == V[2]) { i = 2; return true; } + if (v == V[3]) { i = 3; return true; } + return false; + } + + int index(Vertex_handle v) const + { + if (v == V[0]) { return 0; } + if (v == V[1]) { return 1; } + if (v == V[2]) { return 2; } + CGAL_triangulation_assertion( v == V[3] ); + return 3; + } + + Cell_handle neighbor(int i) const + { + CGAL_triangulation_precondition( i >= 0 && i <= 3); + return N[i]; + } + + bool has_neighbor(Cell_handle n) const + { + return (N[0] == n) || (N[1] == n) || (N[2] == n) || (N[3] == n); + } + + bool has_neighbor(Cell_handle n, int & i) const + { + if(n == N[0]){ i = 0; return true; } + if(n == N[1]){ i = 1; return true; } + if(n == N[2]){ i = 2; return true; } + if(n == N[3]){ i = 3; return true; } + return false; + } + + int index(Cell_handle n) const + { + if (n == N[0]) return 0; + if (n == N[1]) return 1; + if (n == N[2]) return 2; + CGAL_triangulation_assertion( n == N[3] ); + return 3; + } + + // SETTING + + void set_vertex(int i, Vertex_handle v) + { + CGAL_triangulation_precondition( i >= 0 && i <= 3); + V[i] = v; + } + + void set_neighbor(int i, Cell_handle n) + { + CGAL_triangulation_precondition( i >= 0 && i <= 3); + CGAL_triangulation_precondition( this != &*n ); + N[i] = n; + } + + void set_vertices() + { + V[0] = V[1] = V[2] = V[3] = Vertex_handle(); + } + + void set_vertices(Vertex_handle v0, Vertex_handle v1, + Vertex_handle v2, Vertex_handle v3) + { + V[0] = v0; + V[1] = v1; + V[2] = v2; + V[3] = v3; + } + + void set_neighbors() + { + N[0] = N[1] = N[2] = N[3] = Cell_handle(); + } + + void set_neighbors(Cell_handle n0, Cell_handle n1, + Cell_handle n2, Cell_handle n3) + { + CGAL_triangulation_precondition( this != &*n0 ); + CGAL_triangulation_precondition( this != &*n1 ); + CGAL_triangulation_precondition( this != &*n2 ); + CGAL_triangulation_precondition( this != &*n3 ); + N[0] = n0; + N[1] = n1; + N[2] = n2; + N[3] = n3; + } + + // CHECKING + + // the following trivial is_valid allows + // the user of derived cell base classes + // to add their own purpose checking + bool is_valid(bool = false, int = 0) const + { return true; } + + // This is here in the *ds*_cell_base to ease its use as default + // template parameter, so that the .dual() functions of Delaunay_3 + // still work. + template < typename Traits > + typename Traits::Point_3 + circumcenter(const Traits& gt) const + { + return gt.construct_circumcenter_3_object()(this->vertex(0)->point(), + this->vertex(1)->point(), + this->vertex(2)->point(), + this->vertex(3)->point()); + } + + // For use by Compact_container. + void * for_compact_container() const { return N[0].for_compact_container(); } + void * & for_compact_container() { return N[0].for_compact_container(); } + + // TDS internal data access functions. + TDS_data& tds_data() { return _tds_data; } + const TDS_data& tds_data() const { return _tds_data; } + +private: + + Cell_handle N[4]; + Vertex_handle V[4]; + TDS_data _tds_data; +}; + +template < class TDS > +inline +std::istream& +operator>>(std::istream &is, Triangulation_ds_cell_base_3 &) + // non combinatorial information. Default = nothing +{ + return is; +} + +template < class TDS > +inline +std::ostream& +operator<<(std::ostream &os, const Triangulation_ds_cell_base_3 &) + // non combinatorial information. Default = nothing +{ + return os; +} + +// Specialization for void. +template <> +class Triangulation_ds_cell_base_3 +{ +public: + typedef internal::Dummy_tds_3 Triangulation_data_structure; + typedef Triangulation_data_structure::Vertex_handle Vertex_handle; + typedef Triangulation_data_structure::Cell_handle Cell_handle; + template + struct Rebind_TDS { typedef Triangulation_ds_cell_base_3 Other; }; +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_DS_CELL_BASE_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_ds_vertex_base_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_ds_vertex_base_3.h new file mode 100644 index 00000000000..79efe168772 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_ds_vertex_base_3.h @@ -0,0 +1,100 @@ +// Copyright (c) 1999,2000,2001,2002,2003 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud + +#ifndef CGAL_TRIANGULATION_DS_VERTEX_BASE_3_H +#define CGAL_TRIANGULATION_DS_VERTEX_BASE_3_H + +#include +#include + +namespace CGAL { + +template < typename TDS = void > +class Triangulation_ds_vertex_base_3 +{ +public: + typedef TDS Triangulation_data_structure; + typedef typename TDS::Vertex_handle Vertex_handle; + typedef typename TDS::Cell_handle Cell_handle; + + template + struct Rebind_TDS { typedef Triangulation_ds_vertex_base_3 Other; }; + + Triangulation_ds_vertex_base_3() + : _c() {} + + Triangulation_ds_vertex_base_3(Cell_handle c) + : _c(c) {} + + Cell_handle cell() const + { return _c; } + + void set_cell(Cell_handle c) + { _c = c; } + + // the following trivial is_valid allows + // the user of derived cell base classes + // to add their own purpose checking + bool is_valid(bool = false, int = 0) const + { + return cell() != Cell_handle(); + } + + // For use by the Compact_container. + void * for_compact_container() const + { return _c.for_compact_container(); } + void * & for_compact_container() + { return _c.for_compact_container(); } + +private: + Cell_handle _c; +}; + +template < class TDS > +inline +std::istream& +operator>>(std::istream &is, Triangulation_ds_vertex_base_3 &) + // no combinatorial information. +{ + return is; +} + +template < class TDS > +inline +std::ostream& +operator<<(std::ostream &os, const Triangulation_ds_vertex_base_3 &) + // no combinatorial information. +{ + return os; +} + +// Specialization for void. +template <> +class Triangulation_ds_vertex_base_3 +{ +public: + typedef internal::Dummy_tds_3 Triangulation_data_structure; + typedef Triangulation_data_structure::Vertex_handle Vertex_handle; + typedef Triangulation_data_structure::Cell_handle Cell_handle; + template + struct Rebind_TDS { typedef Triangulation_ds_vertex_base_3 Other; }; +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_DS_VERTEX_BASE_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_geom_traits_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_geom_traits_3.h new file mode 100644 index 00000000000..54ea53c1bdf --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_geom_traits_3.h @@ -0,0 +1,79 @@ +// Copyright (c) 1999 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Andreas Fabri +// Monique Teillaud + +// geometric traits for a <=3 D triangulation + +// OBSOLETE !!!!!!!!!!!!!!!!! + +#ifndef CGAL_TRIANGULATION_GEOM_TRAITS_3_H +#define CGAL_TRIANGULATION_GEOM_TRAITS_3_H + +#include + +#include + +namespace CGAL { + +template < class Repres > +class Triangulation_geom_traits_3 : public Repres +{ +public: + Triangulation_geom_traits_3() + { + bool The_class_Triangulation_geom_traits_3_is_obsolete; + } + + typedef Repres Rep; + + typedef typename Rep::Object_3 Object_3; + typedef typename Rep::Point_3 Point_3; + typedef typename Rep::Segment_3 Segment_3; + typedef typename Rep::Triangle_3 Triangle_3; + typedef typename Rep::Tetrahedron_3 Tetrahedron_3; + typedef typename Rep::Ray_3 Ray_3; + typedef typename Rep::Line_3 Line_3; + typedef typename Rep::Plane_3 Plane_3; + + // The next typedef is there for backward compatibility + // Some users take their point type from the traits class. + // Before this type was Point + typedef Point_3 Point; + + typedef typename Rep::Compare_x_3 Compare_x_3; + typedef typename Rep::Compare_y_3 Compare_y_3; + typedef typename Rep::Compare_z_3 Compare_z_3; + typedef typename Rep::Equal_3 Equal_3; + typedef typename Rep::Orientation_3 Orientation_3; + typedef typename Rep::Coplanar_orientation_3 Coplanar_orientation_3; + typedef typename Rep::Side_of_oriented_sphere_3 Side_of_oriented_sphere_3; + typedef typename Rep::Coplanar_side_of_bounded_circle_3 + Coplanar_side_of_bounded_circle_3; + + typedef typename Rep::Construct_segment_3 Construct_segment_3; + typedef typename Rep::Construct_triangle_3 Construct_triangle_3; + typedef typename Rep::Construct_tetrahedron_3 Construct_tetrahedron_3; + typedef typename Rep::Construct_object_3 Construct_object_3; + + // For the hierarchy : + typedef typename Rep::Compare_distance_3 Compare_distance_3; +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_GEOM_TRAITS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_hierarchy_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_hierarchy_3.h new file mode 100644 index 00000000000..49575e0e4bf --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_hierarchy_3.h @@ -0,0 +1,731 @@ +// Copyright (c) 1998, 2001, 2003 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Olivier Devillers +// Sylvain Pion + +#ifndef CGAL_TRIANGULATION_HIERARCHY_3_H +#define CGAL_TRIANGULATION_HIERARCHY_3_H + +#include +#include +#include +#include + +#include +#include +#include + +namespace CGAL { + +// This class is deprecated, but must be kept for backward compatibility. +// +// It would be better to move its content to the Delaunay_triangulation_3 +// specializations for Fast_location and make Triangulation_hierarchy_3 the +// empty nutshell instead. +// +// Then, later, maybe merge the Compact/Fast codes in a cleaner factorized way. + +template < class Tr > +class Triangulation_hierarchy_3 + : public Tr +{ + // parameterization of the hierarchy + // maximal number of points is 30^5 = 24 millions ! + enum { ratio = 30 }; + enum { minsize = 20}; + enum { maxlevel = 5}; + +public: + typedef Tr Tr_Base; + typedef Fast_location Location_policy; + typedef typename Tr_Base::Geom_traits Geom_traits; + typedef typename Tr_Base::Point Point; + typedef typename Tr_Base::size_type size_type; + typedef typename Tr_Base::Vertex_handle Vertex_handle; + typedef typename Tr_Base::Cell_handle Cell_handle; + typedef typename Tr_Base::Vertex_iterator Vertex_iterator; + typedef typename Tr_Base::Vertex Vertex; + typedef typename Tr_Base::Locate_type Locate_type; + typedef typename Tr_Base::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Tr_Base::Finite_cells_iterator Finite_cells_iterator; + typedef typename Tr_Base::Finite_facets_iterator Finite_facets_iterator; + typedef typename Tr_Base::Finite_edges_iterator Finite_edges_iterator; + + using Tr_Base::number_of_vertices; + using Tr_Base::geom_traits; + +private: + + // here is the stack of triangulations which form the hierarchy + Tr_Base* hierarchy[maxlevel]; + boost::rand48 random; + + void set_up_down(Vertex_handle up, Vertex_handle down) + { + up->set_down(down); + down->set_up(up); + } + +public: + + Triangulation_hierarchy_3(const Geom_traits& traits = Geom_traits()); + + Triangulation_hierarchy_3(const Triangulation_hierarchy_3& tr); + + template < typename InputIterator > + Triangulation_hierarchy_3(InputIterator first, InputIterator last, + const Geom_traits& traits = Geom_traits()) + : Tr_Base(traits) + { + hierarchy[0] = this; + for(int i=1; iinfinite_cell() : hint->cell()); + } + + Vertex_handle insert(const Point &p, Cell_handle start = Cell_handle ()); + + Vertex_handle insert(const Point &p, Locate_type lt, Cell_handle loc, + int li, int lj); + + template < class InputIterator > + std::ptrdiff_t insert(InputIterator first, InputIterator last) + { + size_type n = number_of_vertices(); + + std::vector points (first, last); + spatial_sort (points.begin(), points.end(), geom_traits()); + + // hints[i] is the vertex of the previously inserted point in level i. + // Thanks to spatial sort, they are better hints than what the hierarchy + // would give us. + Vertex_handle hints[maxlevel]; + for (typename std::vector::const_iterator p = points.begin(), end = points.end(); + p != end; ++p) + { + int vertex_level = random_level(); + + Vertex_handle v = hints[0] = hierarchy[0]->insert (*p, hints[0]); + Vertex_handle prev = v; + + for (int level = 1; level <= vertex_level; ++level) { + v = hints[level] = hierarchy[level]->insert (*p, hints[level]); + set_up_down(v, prev); + prev = v; + } + } + return number_of_vertices() - n; + } + + void remove(Vertex_handle v); + + template < typename InputIterator > + size_type remove(InputIterator first, InputIterator beyond) + { + size_type n = number_of_vertices(); + while (first != beyond) { + remove(*first); + ++first; + } + return n - number_of_vertices(); + } + + template < typename InputIterator > + size_type remove_cluster(InputIterator first, InputIterator beyond) + { + CGAL_triangulation_precondition(!this->does_repeat_in_range(first, beyond)); + CGAL_triangulation_precondition(!this->infinite_vertex_in_range(first, beyond)); + size_type n = this->number_of_vertices(); + std::vector vo(first, beyond), vc; + int l=0; + while(1) { + int n = vo.size(); + if(!n) break; + for(int i=0; iup() != Vertex_handle()) vc.push_back(vo[i]->up()); + } + hierarchy[l++]->remove_cluster(vo.begin(), vo.end()); + std::swap(vo,vc); + vc.clear(); + } + return n - this->number_of_vertices(); + } + +#ifndef CGAL_NO_DEPRECATED_CODE + CGAL_DEPRECATED Vertex_handle move_point(Vertex_handle v, const Point & p); +#endif + + Vertex_handle move_if_no_collision(Vertex_handle v, const Point &p); + Vertex_handle move(Vertex_handle v, const Point &p); + +public: // some internal methods + + // INSERT REMOVE DISPLACEMENT + // GIVING NEW FACES + + template + Vertex_handle insert_and_give_new_cells(const Point &p, + OutputItCells fit, + Cell_handle start = Cell_handle() ); + + template + Vertex_handle insert_and_give_new_cells(const Point& p, + OutputItCells fit, + Vertex_handle hint) + { + return insert_and_give_new_cells(p, hint == Vertex_handle() ? + this->infinite_cell() : hint->cell()); + } + + template + Vertex_handle insert_and_give_new_cells(const Point& p, + Locate_type lt, + Cell_handle c, int li, int lj, + OutputItCells fit); + + template + void remove_and_give_new_cells(Vertex_handle v, + OutputItCells fit); + + template + Vertex_handle move_if_no_collision_and_give_new_cells(Vertex_handle v, + const Point &p, OutputItCells fit); + +public: + + + //LOCATE + Cell_handle locate(const Point& p, Locate_type& lt, int& li, int& lj, + Vertex_handle hint) const + { + return locate(p, lt, li, lj, hint == Vertex_handle() ? this->infinite_cell() : hint->cell()); + } + + Cell_handle locate(const Point& p, Vertex_handle hint) const + { + return locate(p, hint == Vertex_handle() ? this->infinite_cell() : hint->cell()); + } + + Cell_handle locate(const Point& p, Locate_type& lt, int& li, int& lj, + Cell_handle start = Cell_handle ()) const; + + Cell_handle locate(const Point& p, Cell_handle start = Cell_handle ()) const; + + Vertex_handle + nearest_vertex(const Point& p, Cell_handle start = Cell_handle()) const; + +protected: + + struct locs { + Cell_handle pos; + int li, lj; + Locate_type lt; + }; + + void locate(const Point& p, Locate_type& lt, int& li, int& lj, + locs pos[maxlevel], Cell_handle start = Cell_handle ()) const; + + int random_level(); +}; + + +template +Triangulation_hierarchy_3:: +Triangulation_hierarchy_3(const Geom_traits& traits) + : Tr_Base(traits) +{ + hierarchy[0] = this; + for(int i=1;i +Triangulation_hierarchy_3:: +Triangulation_hierarchy_3(const Triangulation_hierarchy_3 &tr) + : Tr_Base(tr) +{ + hierarchy[0] = this; + for(int i=1; i V; + + for( Finite_vertices_iterator it = hierarchy[0]->finite_vertices_begin(), + end = hierarchy[0]->finite_vertices_end(); it != end; ++it) + if (it->up() != Vertex_handle()) + V[ it->up()->down() ] = it; + + for(int j=1; jfinite_vertices_begin(), + end = hierarchy[j]->finite_vertices_end(); it != end; ++it) { + // current it->down() pointer goes in original instead in copied triangulation + set_up_down(it, V[it->down()]); + // make map for next level + if (it->up() != Vertex_handle()) + V[ it->up()->down() ] = it; + } + } +} + +template +void +Triangulation_hierarchy_3:: +swap(Triangulation_hierarchy_3 &tr) +{ + Tr_Base::swap(tr); + for(int i=1; i +Triangulation_hierarchy_3:: +~Triangulation_hierarchy_3() +{ + clear(); + for(int i=1; i +void +Triangulation_hierarchy_3:: +clear() +{ + for(int i=0;iclear(); +} + +template +bool +Triangulation_hierarchy_3:: +is_valid(bool verbose, int level) const +{ + bool result = true; + + // verify correctness of triangulation at all levels + for(int i=0; iis_valid(verbose, level); + + // verify that lower level has no down pointers + for( Finite_vertices_iterator it = hierarchy[0]->finite_vertices_begin(), + end = hierarchy[0]->finite_vertices_end(); it != end; ++it) + result = result && (it->down() == Vertex_handle()); + + // verify that other levels has down pointer and reciprocal link is fine + for(int j=1; jfinite_vertices_begin(), + end = hierarchy[j]->finite_vertices_end(); it != end; ++it) + result = result && &*(it) == &*(it->down()->up()); + + // verify that other levels has down pointer and reciprocal link is fine + for(int k=0; kfinite_vertices_begin(), + end = hierarchy[k]->finite_vertices_end(); it != end; ++it) + result = result && ( it->up() == Vertex_handle() || + &*it == &*(it->up())->down() ); + + return result; +} + +template +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +insert(const Point &p, Cell_handle start) +{ + int vertex_level = random_level(); + Locate_type lt; + int i, j; + // locate using hierarchy + locs positions[maxlevel]; + locate(p, lt, i, j, positions, start); + // insert at level 0 + Vertex_handle vertex = hierarchy[0]->insert(p, + positions[0].lt, + positions[0].pos, + positions[0].li, + positions[0].lj); + Vertex_handle previous = vertex; + Vertex_handle first = vertex; + + int level = 1; + while (level <= vertex_level ){ + if (positions[level].pos == Cell_handle()) + vertex = hierarchy[level]->insert(p); + else + vertex = hierarchy[level]->insert(p, + positions[level].lt, + positions[level].pos, + positions[level].li, + positions[level].lj); + set_up_down(vertex, previous); + previous=vertex; + level++; + } + return first; +} + +template +template +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +insert_and_give_new_cells(const Point &p, OutputItCells fit, Cell_handle start) +{ + int vertex_level = random_level(); + Locate_type lt; + int i, j; + // locate using hierarchy + locs positions[maxlevel]; + locate(p, lt, i, j, positions, start); + // insert at level 0 + Vertex_handle vertex = hierarchy[0]->insert_and_give_new_cells(p, + positions[0].lt, + positions[0].pos, + positions[0].li, + positions[0].lj,fit); + Vertex_handle previous = vertex; + Vertex_handle first = vertex; + + int level = 1; + while (level <= vertex_level ){ + if (positions[level].pos == Cell_handle()) + vertex = hierarchy[level]->insert(p); + else + vertex = hierarchy[level]->insert(p, + positions[level].lt, + positions[level].pos, + positions[level].li, + positions[level].lj); + set_up_down(vertex, previous); + previous=vertex; + level++; + } + return first; +} + +template +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +insert(const Point &p, Locate_type lt, Cell_handle loc, int li, int lj) +{ + int vertex_level = random_level(); + // insert at level 0 + Vertex_handle vertex = hierarchy[0]->insert(p,lt,loc,li,lj); + Vertex_handle previous = vertex; + Vertex_handle first = vertex; + + if (vertex_level > 0) { + Locate_type lt; + int i, j; + // locate using hierarchy + locs positions[maxlevel]; + locate(p, lt, i, j, positions, vertex->cell()); + + int level = 1; + while (level <= vertex_level ){ + if (positions[level].pos == Cell_handle()) + vertex = hierarchy[level]->insert(p); + else + vertex = hierarchy[level]->insert(p, + positions[level].lt, + positions[level].pos, + positions[level].li, + positions[level].lj); + set_up_down(vertex, previous); + previous=vertex; + level++; + } + } + return first; +} + +template +template +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +insert_and_give_new_cells(const Point &p, Locate_type lt, Cell_handle loc, + int li, int lj, OutputItCells fit) +{ + int vertex_level = random_level(); + // insert at level 0 + Vertex_handle vertex = + hierarchy[0]->insert_and_give_new_cells(p,lt,loc,li,lj,fit); + Vertex_handle previous = vertex; + Vertex_handle first = vertex; + + if (vertex_level > 0) { + Locate_type lt; + int i, j; + // locate using hierarchy + locs positions[maxlevel]; + locate(p, lt, i, j, positions, vertex->cell()); + + int level = 1; + while (level <= vertex_level ){ + if (positions[level].pos == Cell_handle()) + vertex = hierarchy[level]->insert(p); + else + vertex = hierarchy[level]->insert(p, + positions[level].lt, + positions[level].pos, + positions[level].li, + positions[level].lj); + set_up_down(vertex, previous); + previous=vertex; + level++; + } + } + return first; +} + +template +void +Triangulation_hierarchy_3:: +remove(Vertex_handle v) +{ + CGAL_triangulation_precondition(v != Vertex_handle()); + for (int l = 0; l < maxlevel; ++l) { + Vertex_handle u = v->up(); + hierarchy[l]->remove(v); + if (u == Vertex_handle()) + break; + v = u; + } +} + +template +template +void +Triangulation_hierarchy_3:: +remove_and_give_new_cells(Vertex_handle v, OutputItCells fit) +{ + CGAL_triangulation_precondition(v != Vertex_handle()); + CGAL_triangulation_precondition(!is_infinite(v)); + for (int l = 0; l < maxlevel; ++l) { + Vertex_handle u = v->up(); + if(l) hierarchy[l]->remove(v); + else hierarchy[l]->remove_and_give_new_cells(v, fit); + if (u == Vertex_handle()) + break; + v = u; + } +} + +#ifndef CGAL_NO_DEPRECATED_CODE +template < class Tr > +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +move_point(Vertex_handle v, const Point & p) +{ + CGAL_triangulation_precondition(v != Vertex_handle()); + Vertex_handle old, ret; + + for (std::size_t l = 0; l < maxlevel; ++l) { + Vertex_handle u = v->up(); + Vertex_handle w = hierarchy[l]->move_point(v, p); + if (l == 0) { + ret = w; + } + else { + set_up_down(w, old); + } + if (u == Vertex_handle()) + break; + old = w; + v = u; + } + + return ret; +} +#endif + +template +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +move_if_no_collision(Vertex_handle v, const Point & p) +{ + CGAL_triangulation_precondition(!this->is_infinite(v)); + if(v->point() == p) return v; + Vertex_handle ans; + for (int l = 0; l < maxlevel; ++l) { + Vertex_handle u = v->up(); + if(l) hierarchy[l]->move_if_no_collision(v, p); + else ans = hierarchy[l]->move_if_no_collision(v, p); + if(ans != v) return ans; + if (u == Vertex_handle()) + break; + v = u; + } + return ans; +} + +template +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +move(Vertex_handle v, const Point & p) +{ + CGAL_triangulation_precondition(!this->is_infinite(v)); + if(v->point() == p) return v; + Vertex_handle w = move_if_no_collision(v,p); + if(w != v) { + remove(v); + return w; + } + return v; +} + +template +template +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +move_if_no_collision_and_give_new_cells( + Vertex_handle v, const Point & p, OutputItCells fit) +{ + CGAL_triangulation_precondition(!is_infinite(v)); + if(v->point() == p) return v; + Vertex_handle ans; + for (int l = 0; l < maxlevel; ++l) { + Vertex_handle u = v->up(); + if(l) hierarchy[l]->move_if_no_collision(v, p); + else ans = + hierarchy[l]->move_if_no_collision_and_give_new_cells(v, p, fit); + if(ans != v) return ans; + if (u == Vertex_handle()) + break; + v = u; + } + return ans; +} + +template +inline +typename Triangulation_hierarchy_3::Cell_handle +Triangulation_hierarchy_3:: +locate(const Point& p, Locate_type& lt, int& li, int& lj, Cell_handle start) const +{ + if (start != Cell_handle ()) + return Tr_Base::locate (p, lt, li, lj, start); + locs positions[maxlevel]; + locate(p, lt, li, lj, positions); + return positions[0].pos; +} + +template +inline +typename Triangulation_hierarchy_3::Cell_handle +Triangulation_hierarchy_3:: +locate(const Point& p, Cell_handle start) const +{ + if (start != Cell_handle ()) + return Tr_Base::locate (p, start); + Locate_type lt; + int li, lj; + return locate(p, lt, li, lj); +} + +template +void +Triangulation_hierarchy_3:: +locate(const Point& p, Locate_type& lt, int& li, int& lj, + locs pos[maxlevel], Cell_handle start) const +{ + int level = maxlevel; + + // find the highest level with enough vertices + while (hierarchy[--level]->number_of_vertices() < (size_type) minsize) { + if ( ! level) + break; // do not go below 0 + } + + for (int i=level+1; i 0) { + // locate at that level from "position" + // result is stored in "position" for the next level + pos[level].pos = position = hierarchy[level]->locate(p, + pos[level].lt, + pos[level].li, + pos[level].lj, + position); + // find the nearest vertex. + Vertex_handle nearest = hierarchy[level]->nearest_vertex_in_cell(p, position); + + // go at the same vertex on level below + nearest = nearest->down(); + position = nearest->cell(); // incident cell + --level; + } + + if (start != Cell_handle()) + position = start; + + pos[0].pos = hierarchy[0]->locate(p, lt, li, lj, position); // at level 0 + pos[0].lt = lt; + pos[0].li = li; + pos[0].lj = lj; +} + +template +typename Triangulation_hierarchy_3::Vertex_handle +Triangulation_hierarchy_3:: +nearest_vertex(const Point& p, Cell_handle start) const +{ + return Tr_Base::nearest_vertex(p, start != Cell_handle() ? start : locate(p)); +} + +template +int +Triangulation_hierarchy_3:: +random_level() +{ + boost::geometric_distribution<> proba(1.0/ratio); + boost::variate_generator > die(random, proba); + + return (std::min)(die(), (int)maxlevel)-1; +} + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_HIERARCHY_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_hierarchy_vertex_base_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_hierarchy_vertex_base_3.h new file mode 100644 index 00000000000..8803067afe2 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_hierarchy_vertex_base_3.h @@ -0,0 +1,65 @@ +// Copyright (c) 1998, 2001, 2003 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Olivier Devillers +// Sylvain Pion + +#ifndef CGAL_TRIANGULATION_HIERARCHY_VERTEX_BASE_3_H +#define CGAL_TRIANGULATION_HIERARCHY_VERTEX_BASE_3_H + +#include + +namespace CGAL { + +template < class Vbb > +class Triangulation_hierarchy_vertex_base_3 + : public Vbb +{ + typedef Vbb Base; + typedef typename Base::Triangulation_data_structure Tds; +public: + typedef typename Tds::Vertex_handle Vertex_handle; + typedef typename Tds::Cell_handle Cell_handle; + typedef typename Base::Point Point; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Vbb::template Rebind_TDS::Other Vb2; + typedef Triangulation_hierarchy_vertex_base_3 Other; + }; + + Triangulation_hierarchy_vertex_base_3() + : Base(), _up(), _down() {} + + Triangulation_hierarchy_vertex_base_3(const Point & p, Cell_handle f) + : Base(p,f), _up(), _down() {} + + Triangulation_hierarchy_vertex_base_3(const Point & p) + : Base(p), _up(), _down() {} + + Vertex_handle up() const { return _up; } + Vertex_handle down() const { return _down; } + void set_up(Vertex_handle u) { _up=u; } + void set_down(Vertex_handle d) { _down=d; } + +private: + Vertex_handle _up; // same vertex one level above + Vertex_handle _down; // same vertex one level below +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_HIERARCHY_VERTEX_BASE_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_simplex_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_simplex_3.h new file mode 100644 index 00000000000..cd26ac81d5c --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_simplex_3.h @@ -0,0 +1,284 @@ +// Copyright (c) 2005 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Nico Kruithof +// Developed at Rijksuniversiteit Groningen (Netherlands) + +#ifndef CGAL_TRIANGULATION_SIMPLEX_3_H +#define CGAL_TRIANGULATION_SIMPLEX_3_H + +namespace CGAL { + +template < class TriangulationDataStructure_3 > +class Triangulation_simplex_3 { + typedef TriangulationDataStructure_3 TDS; + typedef Triangulation_simplex_3 Self; +public: + typedef Self Simplex; + + typedef typename TDS::Vertex_handle Vertex_handle; + typedef typename TDS::Edge Edge; + typedef typename TDS::Facet Facet; + typedef typename TDS::Cell_handle Cell_handle; + + typedef typename TDS::Cell_circulator Cell_circulator; + typedef typename TDS::Facet_circulator Facet_circulator; + + typedef typename TDS::Edge_iterator Edge_iterator; + typedef typename TDS::Facet_iterator Facet_iterator; + + // Constructors + + // Default constructor initialises to undefined simplex: + Triangulation_simplex_3() : ref(-1), ch() { } + + Triangulation_simplex_3(Vertex_handle vh) { + set_vertex(vh); + } + Triangulation_simplex_3(const Edge &e) { + set_edge(e); + } + Triangulation_simplex_3(const Facet &f) { + set_facet(f); + } + Triangulation_simplex_3(Cell_handle ch_) { + set_cell(ch_); + } + + Triangulation_simplex_3(Cell_circulator ccir) { + set_cell(ccir); + } + Triangulation_simplex_3(Facet_circulator fcir) { + set_facet(*fcir); + } + + Triangulation_simplex_3(Edge_iterator eit) { + set_edge(*eit); + } + Triangulation_simplex_3(Facet_iterator fit) { + set_facet(*fit); + } + + // Conversions: + operator Vertex_handle () const + { + CGAL_assertion(dimension() == 0); + return ch->vertex(index(0)); + } + operator Edge () const + { + CGAL_assertion(dimension() == 1); + return Edge(ch,index(0),index(1)); + } + operator Facet () const + { + CGAL_assertion(dimension() == 2); + return Facet(ch,index(0)); + } + operator Cell_handle () const + { + CGAL_assertion(dimension() == 3); + return ch; + } + + // returns the dimension of the simplex + int dimension () const { + return (ref & 3); + } + // returns an incident cell: + Cell_handle incident_cell() { + return ch; + } + + template < class TDS2 > + friend bool operator==(Triangulation_simplex_3 s0, + Triangulation_simplex_3 s1); + template < class TDS2 > + friend bool operator< (Triangulation_simplex_3 s0, + Triangulation_simplex_3 s1); + +private: + void set_vertex(const Vertex_handle vh) { + ch = vh->cell(); + ref = (ch->index(vh) << 2); /* dim == 0 */ + CGAL_assertion (ch != Cell_handle()); + } + void set_edge(const Edge &e) { + ch = e.first; + ref = (((e.third<< 2) + e.second) << 2) + 1; /* dim */ + CGAL_assertion (ch != Cell_handle()); + } + void set_facet(const Facet &f) { + ch = f.first; + ref = (f.second << 2) + 2; /* dim */ + CGAL_assertion (ch != Cell_handle()); + } + void set_cell(Cell_handle ch_) { + ch = ch_; + ref = 3; /* dim */ + CGAL_assertion (ch != Cell_handle()); + } + + inline int index(int i) const { + CGAL_assertion (i==0 || ((i==1) && (dimension()==1))); + return (ref >> (2*(i+1))) & 3; + } + + int ref; // storage iijjdd (index i, index j, dimension of simplex) + Cell_handle ch; // Corresponding cell handle +}; + +/////////////////////////////// +// Simplex functions +/////////////////////////////// +template < class TriangulationDataStructure_3 > +bool +operator!=(Triangulation_simplex_3 s0, + Triangulation_simplex_3 s1) { + return !(s0==s1); +} + +template < class TriangulationDataStructure_3 > +bool +operator==(Triangulation_simplex_3 s0, + Triangulation_simplex_3 s1) { + typedef Triangulation_simplex_3 Sim; + if (s0.dimension() != s1.dimension()) return false; + + typename Sim::Cell_handle neighbor; + + switch (s0.dimension()) { + case (0): // Vertex + return (s0.ch->vertex(s0.index(0)) == s1.ch->vertex(s1.index(0))); + case (1): // Edge + return ((s0.ch->vertex(s0.index(0)) == s1.ch->vertex(s1.index(0)) && + s0.ch->vertex(s0.index(1)) == s1.ch->vertex(s1.index(1))) || + (s0.ch->vertex(s0.index(1)) == s1.ch->vertex(s1.index(0)) && + s0.ch->vertex(s0.index(0)) == s1.ch->vertex(s1.index(1)))); + case (2): + if (s0.ch == s1.ch && s0.index(0) == s1.index(0)) { + return true; + } + + neighbor = s0.ch->neighbor(s0.index(0)); + if (neighbor == s1.ch && + neighbor->index(s0.ch) == s1.index(0)) { + return true; + } + return false; + case (3): + return (&(*s0.ch) == &(*s1.ch)); + } + CGAL_error(); + return false; +} + +template < class TriangulationDataStructure_3 > +bool +operator<(Triangulation_simplex_3 s0, + Triangulation_simplex_3 s1) { + typedef Triangulation_simplex_3 Sim; + + if (s0 == s1) return false; + if (s0.dimension() < s1.dimension()) return true; + if (s0.dimension() > s1.dimension()) return false; + + // Dimensions are equal, compare the memory addresses of the simplices + typename Sim::Cell_handle ch1, ch2; + typename Sim::Vertex_handle vh1, vh2, vh3, vh4; + switch (s0.dimension()) { + case (0): // Vertex + // Vertextices are not equal + return (&(*s0.ch->vertex(s0.index(0))) < + &(*s1.ch->vertex(s1.index(0)))); + case (1): // Edge + vh1 = s0.ch->vertex(s0.index(0)); + vh2 = s0.ch->vertex(s0.index(1)); + vh3 = s1.ch->vertex(s1.index(0)); + vh4 = s1.ch->vertex(s1.index(1)); + + if ((std::min)(&(*vh1), &(*vh2)) < (std::min)(&(*vh3), &(*vh4))) + return true; + + if ((std::min)(&(*vh1), &(*vh2)) > (std::min)(&(*vh3), &(*vh4))) + return false; + + if ((std::max)(&(*vh1), &(*vh2)) < (std::max)(&(*vh3), &(*vh4))) + return true; + + return false; + case (2): // Facet + ch1 = s0.ch->neighbor(s0.index(0)); + ch2 = s1.ch->neighbor(s1.index(0)); + + if ((std::min)(&(*s0.ch), &(*ch1)) < (std::min)(&(*s1.ch), &(*ch2))) + return true; + + if ((std::min)(&(*s0.ch), &(*ch1)) > (std::min)(&(*s1.ch), &(*ch2))) + return false; + + if ((std::max)(&(*s0.ch), &(*ch1)) < (std::max)(&(*s1.ch), &(*ch2))) + return true; + + return false; + case (3): // Cell + return (&(*s0.ch) < &(*s1.ch)); + } + CGAL_error(); + return false; +} + +template < class TriangulationDataStructure_3 > +std::ostream & +operator<< (std::ostream& os, + const Triangulation_simplex_3 &s) +{ + typename TriangulationDataStructure_3::Vertex_handle vh; + typename TriangulationDataStructure_3::Edge e; + typename TriangulationDataStructure_3::Facet f; + typename TriangulationDataStructure_3::Cell_handle ch; + switch (s.dimension()) { + case 0: + vh = s; + os << &*vh; + break; + case 1: + e = s; + os << &*(e.first->vertex(e.second)) << " " + << &*(e.first->vertex(e.third)); + break; + case 2: + f = s; + os << &*(f.first->vertex((f.second+1)&3)) << " " + << &*(f.first->vertex((f.second+2)&3)) << " " + << &*(f.first->vertex((f.second+3)&3)); + break; + case 3: + ch = s; + os << &*(ch->vertex(0)) << " " + << &*(ch->vertex(1)) << " " + << &*(ch->vertex(2)) << " " + << &*(ch->vertex(3)); + break; + } + return os; +} + + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_SIMPLEX_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_utils_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_utils_3.h new file mode 100644 index 00000000000..ebee5f81a2c --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_utils_3.h @@ -0,0 +1,84 @@ +// Copyright (c) 1999 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud + +#ifndef CGAL_TRIANGULATION_UTILS_3_H +#define CGAL_TRIANGULATION_UTILS_3_H + +#include +#include +#include + +namespace CGAL { + +// We use the following template class in order to avoid having a static data + // member of a non-template class which would require src/Triangulation_3.C . +template < class T = void > +struct Triangulation_utils_base_3 +{ + static const char tab_next_around_edge[4][4]; + static const int tab_vertex_triple_index[4][3]; +}; + +template < class T > +const char Triangulation_utils_base_3::tab_next_around_edge[4][4] = { + {5, 2, 3, 1}, + {3, 5, 0, 2}, + {1, 3, 5, 0}, + {2, 0, 1, 5} }; + +template < class T > +const int Triangulation_utils_base_3::tab_vertex_triple_index[4][3] = { + {1, 3, 2}, + {0, 2, 3}, + {0, 3, 1}, + {0, 1, 2} +}; + +// We derive from Triangulation_cw_ccw_2 because we still use cw() and ccw() +// in the 2D part of the code. Ideally, this should go away when we re-use +// T2D entirely. + +struct Triangulation_utils_3 + : public Triangulation_cw_ccw_2, + public Triangulation_utils_base_3<> +{ + static int next_around_edge(const int i, const int j) + { + // index of the next cell when turning around the + // oriented edge vertex(i) vertex(j) in 3d + CGAL_triangulation_precondition( ( i >= 0 && i < 4 ) && + ( j >= 0 && j < 4 ) && + ( i != j ) ); + return tab_next_around_edge[i][j]; + } + + + static int vertex_triple_index(const int i, const int j) + { + // indexes of the jth vertex of the facet of a cell + // opposite to vertx i + CGAL_triangulation_precondition( ( i >= 0 && i < 4 ) && + ( j >= 0 && j < 3 ) ); + return tab_vertex_triple_index[i][j]; + } + +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_UTILS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_vertex_base_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_vertex_base_3.h new file mode 100644 index 00000000000..b4f4e94467c --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_vertex_base_3.h @@ -0,0 +1,86 @@ +// Copyright (c) 1999 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud + +#ifndef CGAL_TRIANGULATION_VERTEX_BASE_3_H +#define CGAL_TRIANGULATION_VERTEX_BASE_3_H + +#include +#include + +namespace CGAL { + +template < typename GT, typename DSVb = Triangulation_ds_vertex_base_3<> > +class Triangulation_vertex_base_3 + : public DSVb +{ +public: + + typedef typename DSVb::Cell_handle Cell_handle; + typedef GT Geom_traits; + typedef typename GT::Point_3 Point; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename DSVb::template Rebind_TDS::Other DSVb2; + typedef Triangulation_vertex_base_3 Other; + }; + + Triangulation_vertex_base_3() + : DSVb() {} + + Triangulation_vertex_base_3(const Point & p) + : DSVb(), _p(p) {} + + Triangulation_vertex_base_3(const Point & p, Cell_handle c) + : DSVb(c), _p(p) {} + + Triangulation_vertex_base_3(Cell_handle c) + : DSVb(c), _p() {} + + const Point & point() const + { return _p; } + + Point & point() + { return _p; } + + void set_point(const Point & p) + { _p = p; } + +private: + Point _p; +}; + +template < class GT, class DSVb > +std::istream& +operator>>(std::istream &is, Triangulation_vertex_base_3 &v) + // non combinatorial information. Default = point +{ + return is >> static_cast(v) >> v.point(); +} + +template < class GT, class DSVb > +std::ostream& +operator<<(std::ostream &os, const Triangulation_vertex_base_3 &v) + // non combinatorial information. Default = point +{ + return os << static_cast(v) << v.point(); +} + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_VERTEX_BASE_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/Triangulation_vertex_base_with_info_3.h b/Triangulation_3_copy_tds/include/CGAL/Triangulation_vertex_base_with_info_3.h new file mode 100644 index 00000000000..04cd5517e98 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/Triangulation_vertex_base_with_info_3.h @@ -0,0 +1,63 @@ +// Copyright (c) 2003 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_TRIANGULATION_VERTEX_BASE_WITH_INFO_3_H +#define CGAL_TRIANGULATION_VERTEX_BASE_WITH_INFO_3_H + +#include + +namespace CGAL { + +template < typename Info_, typename GT, + typename Vb = Triangulation_vertex_base_3 > +class Triangulation_vertex_base_with_info_3 + : public Vb +{ + Info_ _info; +public: + + typedef typename Vb::Cell_handle Cell_handle; + typedef typename Vb::Point Point; + typedef Info_ Info; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef Triangulation_vertex_base_with_info_3 Other; + }; + + Triangulation_vertex_base_with_info_3() + : Vb() {} + + Triangulation_vertex_base_with_info_3(const Point & p) + : Vb(p) {} + + Triangulation_vertex_base_with_info_3(const Point & p, Cell_handle c) + : Vb(p, c) {} + + Triangulation_vertex_base_with_info_3(Cell_handle c) + : Vb(c) {} + + const Info& info() const { return _info; } + Info& info() { return _info; } +}; + +} //namespace CGAL + +#endif // CGAL_TRIANGULATION_VERTEX_BASE_WITH_INFO_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/constructions/constructions_on_weighted_points_cartesian_3.h b/Triangulation_3_copy_tds/include/CGAL/constructions/constructions_on_weighted_points_cartesian_3.h new file mode 100644 index 00000000000..3abdd511039 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/constructions/constructions_on_weighted_points_cartesian_3.h @@ -0,0 +1,498 @@ +// Copyright (c) 2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Mariette Yvinec + +#ifndef CGAL_CONSTRUCTIONS_ON_WEIGHTED_POINTS_CARTESIAN_3_H +#define CGAL_CONSTRUCTIONS_ON_WEIGHTED_POINTS_CARTESIAN_3_H + +namespace CGAL { + +template +void +determinants_for_weighted_circumcenterC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + const FT &sx, const FT &sy, const FT &sz, const FT &sw, + FT &num_x, FT &num_y, FT &num_z, FT& den) +{ + // translate origin to p + // and compute determinants for weighted_circumcenter and + // circumradius + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + FT qp2 = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + + CGAL_NTS square(qpz) - qw + pw; + FT rpx = rx-px; + FT rpy = ry-py; + FT rpz = rz-pz; + FT rp2 = CGAL_NTS square(rpx) + CGAL_NTS square(rpy) + + CGAL_NTS square(rpz) - rw + pw; + FT spx = sx-px; + FT spy = sy-py; + FT spz = sz-pz; + FT sp2 = CGAL_NTS square(spx) + CGAL_NTS square(spy) + + CGAL_NTS square(spz) - sw + pw; + + num_x = determinant(qpy,qpz,qp2, + rpy,rpz,rp2, + spy,spz,sp2); + num_y = determinant(qpx,qpz,qp2, + rpx,rpz,rp2, + spx,spz,sp2); + num_z = determinant(qpx,qpy,qp2, + rpx,rpy,rp2, + spx,spy,sp2); + den = determinant(qpx,qpy,qpz, + rpx,rpy,rpz, + spx,spy,spz); +} + + +template < class FT> +void +weighted_circumcenterC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + const FT &sx, const FT &sy, const FT &sz, const FT &sw, + FT &x, FT &y, FT &z) +{ + // this function compute the weighted circumcenter point only + + // Translate p to origin and compute determinants + FT num_x, num_y, num_z, den; + determinants_for_weighted_circumcenterC3(px, py, pz, pw, + qx, qy, qz, qw, + rx, ry, rz, rw, + sx, sy, sz, sw, + num_x, num_y, num_z,den); + + CGAL_triangulation_assertion( ! CGAL_NTS is_zero(den) ); + FT inv = FT(1)/(FT(2) * den); + + x = px + num_x*inv; + y = py - num_y*inv; + z = pz + num_z*inv; +} + +template < class FT> +void +weighted_circumcenterC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + const FT &sx, const FT &sy, const FT &sz, const FT &sw, + FT &x, FT &y, FT &z, FT &w) +{ + // this function compute the weighted circumcenter point + // and the squared weighted circumradius + + // Translate p to origin and compute determinants + FT num_x, num_y, num_z, den; + determinants_for_weighted_circumcenterC3(px, py, pz, pw, + qx, qy, qz, qw, + rx, ry, rz, rw, + sx, sy, sz, sw, + num_x, num_y, num_z, den); + + CGAL_triangulation_assertion( ! CGAL_NTS is_zero(den) ); + FT inv = FT(1)/(FT(2) * den); + + x = px + num_x*inv; + y = py - num_y*inv; + z = pz + num_z*inv; + + w = (CGAL_NTS square(num_x)+CGAL_NTS square(num_y)+CGAL_NTS square(num_z)) + *CGAL_NTS square(inv) - pw; +} + + +template< class FT > +FT +squared_radius_orthogonal_sphereC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + const FT &sx, const FT &sy, const FT &sz, const FT &sw) +{ + + // this function compute the squared weighted circumradius only + + // Translate p to origin and compute determinants + FT num_x, num_y, num_z, den; + determinants_for_weighted_circumcenterC3(px, py, pz, pw, + qx, qy, qz, qw, + rx, ry, rz, rw, + sx, sy, sz, sw, + num_x, num_y, num_z,den); + + CGAL_triangulation_assertion( ! CGAL_NTS is_zero(den) ); + FT inv = FT(1)/(FT(2) * den); + + return + (CGAL_NTS square(num_x)+CGAL_NTS square(num_y)+CGAL_NTS square(num_z)) + *CGAL_NTS square(inv) - pw; +} + + +template +void +determinants_for_weighted_circumcenterC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + FT &num_x, FT &num_y, FT &num_z, FT &den) +{ + // translate origin to p + // and compute determinants for weighted_circumcenter and + // circumradius + + // Translate s to origin to simplify the expression. + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + FT qp2 = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + + CGAL_NTS square(qpz) - qw + pw; + FT rpx = rx-px; + FT rpy = ry-py; + FT rpz = rz-pz; + FT rp2 = CGAL_NTS square(rpx) + CGAL_NTS square(rpy) + + CGAL_NTS square(rpz) - rw + pw; + + FT sx = qpy*rpz-qpz*rpy; + FT sy = qpz*rpx-qpx*rpz; + FT sz = qpx*rpy-qpy*rpx; + + // The following determinants can be developped and simplified. + // + // FT num_x = determinant(qpy,qpz,qp2, + // rpy,rpz,rp2, + // sy,sz,FT(0)); + // FT num_y = determinant(qpx,qpz,qp2, + // rpx,rpz,rp2, + // sx,sz,FT(0)); + // FT num_z = determinant(qpx,qpy,qp2, + // rpx,rpy,rp2, + // sx,sy,FT(0)); + + num_x = qp2 * determinant(rpy,rpz,sy,sz) + - rp2 * determinant(qpy,qpz,sy,sz); + + num_y = qp2 * determinant(rpx,rpz,sx,sz) + - rp2 * determinant(qpx,qpz,sx,sz); + + num_z = qp2 * determinant(rpx,rpy,sx,sy) + - rp2 * determinant(qpx,qpy,sx,sy); + + den = determinant(qpx,qpy,qpz, + rpx,rpy,rpz, + sx,sy,sz); +} + +template < class FT > +void +weighted_circumcenterC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + FT &x, FT &y, FT &z) +{ + // this function compute the weighted circumcenter point only + +// Translate p to origin and compute determinants + FT num_x, num_y, num_z, den; + determinants_for_weighted_circumcenterC3(px, py, pz, pw, + qx, qy, qz, qw, + rx, ry, rz, rw, + num_x, num_y, num_z, den); + + CGAL_triangulation_assertion( den != FT(0) ); + FT inv = FT(1)/(FT(2) * den); + + x = px + num_x*inv; + y = py - num_y*inv; + z = pz + num_z*inv; +} + + +template < class FT > +void +weighted_circumcenterC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + FT &x, FT &y, FT &z, FT &w) +{ + // this function compute the weighted circumcenter and + // the weighted squared circumradius + +// Translate p to origin and compute determinants + FT num_x, num_y, num_z, den; + determinants_for_weighted_circumcenterC3(px, py, pz, pw, + qx, qy, qz, qw, + rx, ry, rz, rw, + num_x, num_y, num_z, den); + + CGAL_triangulation_assertion( den != FT(0) ); + FT inv = FT(1)/(FT(2) * den); + + x = px + num_x*inv; + y = py - num_y*inv; + z = pz + num_z*inv; + + w = (CGAL_NTS square(num_x)+CGAL_NTS square(num_y)+CGAL_NTS square(num_z)) + *CGAL_NTS square(inv) - pw; +} + + +template< class FT > +CGAL_MEDIUM_INLINE +FT +squared_radius_smallest_orthogonal_sphereC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw) +{ + // this function compute the weighted squared circumradius only + +// Translate p to origin and compute determinants + FT num_x, num_y, num_z, den; + determinants_for_weighted_circumcenterC3(px, py, pz, pw, + qx, qy, qz, qw, + rx, ry, rz, rw, + num_x, num_y, num_z, den); + + CGAL_triangulation_assertion( den != FT(0) ); + FT inv = FT(1)/(FT(2) * den); + + return + (CGAL_NTS square(num_x)+CGAL_NTS square(num_y)+CGAL_NTS square(num_z)) + *CGAL_NTS square(inv) - pw; +} + + + +template < class FT > +void +weighted_circumcenterC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + FT &x, FT &y, FT &z) +{ +// this function compute the weighted circumcenter point only + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + FT qp2 = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + + CGAL_NTS square(qpz); + FT inv = FT(1)/(FT(2)*qp2); + FT alpha = 1/FT(2) + (pw-qw)*inv; + + x = px + alpha * qpx; + y = py + alpha * qpy; + z = pz + alpha * qpz; +} + + +template < class FT > +void +weighted_circumcenterC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + FT &x, FT &y, FT &z, FT &w) +{ + // this function compute the weighted circumcenter point and + // the weighted circumradius + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + FT qp2 = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + + CGAL_NTS square(qpz); + FT inv = FT(1)/(FT(2)*qp2); + FT alpha = 1/FT(2) + (pw-qw)*inv; + + x = px + alpha * qpx; + y = py + alpha * qpy; + z = pz + alpha * qpz; + + w = CGAL_NTS square(alpha)*qp2 - pw; +} + + +template< class FT > +CGAL_MEDIUM_INLINE +FT +squared_radius_smallest_orthogonal_sphereC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw) +{ + // this function computes + // the weighted circumradius only + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + FT qp2 = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + + CGAL_NTS square(qpz); + FT inv = FT(1)/(FT(2)*qp2); + FT alpha = 1/FT(2) + (pw-qw)*inv; + + return CGAL_NTS square(alpha)*qp2 - pw; +} + + +template< class FT > +FT +power_productC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw) +{ + // computes the power product of two weighted points + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + FT qp2 = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + + CGAL_NTS square(qpz); + return qp2 - pw - qw ; +} + +template < class RT , class We> +void +radical_axisC3(const RT &px, const RT &py, const RT &pz, const We &pw, + const RT &qx, const RT &qy, const RT &qz, const We &qw, + const RT &rx, const RT &ry, const RT &rz, const We &rw, + RT &a, RT &b, RT& c ) +{ + RT dqx=qx-px, dqy=qy-py, dqz=qz-pz, drx=rx-px, dry=ry-py, drz=rz-pz; + + //il manque des tests... + + a= RT(1)*determinant(dqy, dqz, dry, drz); + b= - RT(1)*determinant(dqx, dqz, drx, drz); + c= RT(1)*determinant(dqx, dqy, drx, dry); +} + +// function used in critical_squared_radiusC3 +// power ( t, tw) with respect to +// circle orthogonal (p,pw), (q,qw), (r,rw), (s,sw) +template < class FT> +FT +power_to_orthogonal_sphereC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + const FT &sx, const FT &sy, const FT &sz, const FT &sw, + const FT &tx, const FT &ty, const FT &tz, const FT &tw) +{ + //to get the value of the determinant + // We translate the points so that t becomes the origin. + FT dpx = px - tx; + FT dpy = py - ty; + FT dpz = pz - tz; + FT dpt = CGAL_NTS square(dpx) + CGAL_NTS square(dpy) + + CGAL_NTS square(dpz) - pw + tw ; + FT dqx = qx - tx; + FT dqy = qy - ty; + FT dqz = qz - tz; + FT dqt = CGAL_NTS square(dqx) + CGAL_NTS square(dqy) + + CGAL_NTS square(dqz) - qw + tw; + FT drx = rx - tx; + FT dry = ry - ty; + FT drz = rz - tz; + FT drt = CGAL_NTS square(drx) + CGAL_NTS square(dry) + + CGAL_NTS square(drz) - rw + tw; + FT dsx = sx - tx; + FT dsy = sy - ty; + FT dsz = sz - tz; + FT dst = CGAL_NTS square(dsx) + CGAL_NTS square(dsy) + + CGAL_NTS square(dsz) - sw + tw; + + return determinant(dpx, dpy, dpz, dpt, + dqx, dqy, dqz, dqt, + drx, dry, drz, drt, + dsx, dsy, dsz, dst); + +} + + + +// compute the critical weight tw +// where weighted point t is orthogonal to weighted points p, q,r,s +template < class FT> +FT +critical_squared_radiusC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + const FT &sx, const FT &sy, const FT &sz, const FT &sw, + const FT &tx, const FT &ty, const FT &tz, const FT & ) +{ + // the 5x5 det is a linear function of tw ff(tw)= ff(0) + tw ff(1) + // the critical value for tw is - ff(0)/( ff(1) - ff(0)) + + + FT ff0 = power_to_orthogonal_sphereC3(px, py, pz, pw, + qx, qy, qz, qw, + rx, ry, rz, rw, + sx, sy, sz, sw, + tx, ty, tz, FT(0)); + + FT ff1 = power_to_orthogonal_sphereC3(px, py, pz, pw, + qx, qy, qz, qw, + rx, ry, rz, rw, + sx, sy, sz, sw, + tx, ty, tz, FT(1)); + + return -ff0/(ff1 - ff0); +} + + + + // I will use this to test if the radial axis of three spheres + // intersect the triangle formed by the centers. +// // resolution of the system (where we note c the center) +// // | dc^2 = cw + rw +// // | (dp-dc)^2 = pw + cw +// // | (dq-dc)^2 = qw + cw +// // | dc = Lamdba*dp + Mu*dq + +// FT FT2(2); +// FT dpx = px-rx; +// FT dpy = py-ry; +// FT dpz = pz-rz; +// FT dp = CGAL_NTS square(dpx)+CGAL_NTS square(dpy)+CGAL_NTS square(dpz); +// FT dpp = dp-pw+rw; +// FT dqx = qx-rx; +// FT dqy = qy-ry; +// FT dqz = qz-rz; +// FT dq = CGAL_NTS square(dqx)+CGAL_NTS square(dqy)+CGAL_NTS square(dqz); +// FT dqq = dq-qw+rw; +// FT dpdq = dpx*dqx+dpy*dqy+dpz*dqz; +// FT denom = FT2*(dp*dq-CGAL_NTS square(dpdq)); +// FT Lambda = (dpp*dq-dqq*dpdq)/denom; +// FT Mu = (dqq*dp-dpp*dpdq)/denom; + +// return (CGAL_NTS square(Lambda)*dp+CGAL_NTS square(Mu)*dq +// +FT2*Lambda*Mu*dpdq - rw); + + + + +} //namespace CGAL +#endif //CGAL_CONSTRUCTIONS_ON_WEIGHTED_POINTS_CARTESIAN_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/Delaunay_triangulation_hierarchy_3.h b/Triangulation_3_copy_tds/include/CGAL/internal/Delaunay_triangulation_hierarchy_3.h new file mode 100644 index 00000000000..a4b8527a1c4 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/Delaunay_triangulation_hierarchy_3.h @@ -0,0 +1,118 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_INTERNAL_DELAUNAY_TRIANGULATION_HIERARCHY_3_H +#define CGAL_INTERNAL_DELAUNAY_TRIANGULATION_HIERARCHY_3_H + +#if !defined CGAL_DELAUNAY_TRIANGULATION_3_H +# error "Other header files need to be included first..." +#endif + +#include + +namespace CGAL { + +// Specializations of Delaunay_triangulation_3 for Fast_location, +// as 2nd as well as 3rd positions (deduced parameter). + +#define CGAL_TDS_3 \ +typename Default::Get,\ + Triangulation_cell_base_3 > >::type + +template < class Gt, class Tds_ > +class Delaunay_triangulation_3 + : public Triangulation_hierarchy_3 >::Other> > +{ + typedef Triangulation_hierarchy_3 >::Other> > Base; + +public: + + Delaunay_triangulation_3(const Gt& traits = Gt()) + : Base(traits) {} + + template < typename InputIterator > + Delaunay_triangulation_3(InputIterator first, InputIterator last, + const Gt& traits = Gt()) + : Base(first, last, traits) {} +}; + +#undef CGAL_TDS_3 + +template < class Gt, class Tds_ > +class Delaunay_triangulation_3 + : public Delaunay_triangulation_3 +{ + typedef Delaunay_triangulation_3 Base; + +public: + + Delaunay_triangulation_3(const Gt& traits = Gt()) + : Base(traits) {} + + template < typename InputIterator > + Delaunay_triangulation_3(InputIterator first, InputIterator last, + const Gt& traits = Gt()) + : Base(first, last, traits) {} +}; + +// 2 cases for Location_policy<> in 2nd position. + +template < class Gt > +class Delaunay_triangulation_3 + : public Triangulation_hierarchy_3 >, + Triangulation_cell_base_3 > > > +{ + typedef Triangulation_hierarchy_3 >, + Triangulation_cell_base_3 > > > Base; + +public: + + Delaunay_triangulation_3(const Gt& traits = Gt()) + : Base(traits) {} + + template < typename InputIterator > + Delaunay_triangulation_3(InputIterator first, InputIterator last, + const Gt& traits = Gt()) + : Base(first, last, traits) {} +}; + +template < class Gt > +class Delaunay_triangulation_3 + : public Delaunay_triangulation_3 +{ + typedef Delaunay_triangulation_3 Base; + +public: + + Delaunay_triangulation_3(const Gt& traits = Gt()) + : Base(traits) {} + + template < typename InputIterator > + Delaunay_triangulation_3(InputIterator first, InputIterator last, + const Gt& traits = Gt()) + : Base(first, last, traits) {} +}; + +} // namespace CGAL + +#endif // CGAL_INTERNAL_DELAUNAY_TRIANGULATION_HIERARCHY_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/Dummy_tds_3.h b/Triangulation_3_copy_tds/include/CGAL/internal/Dummy_tds_3.h new file mode 100644 index 00000000000..bfd3c4e5dcf --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/Dummy_tds_3.h @@ -0,0 +1,46 @@ +// Copyright (c) 2003 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_INTERNAL_TRIANGULATION_DUMMY_TDS_3_H +#define CGAL_INTERNAL_TRIANGULATION_DUMMY_TDS_3_H + +namespace CGAL { namespace internal { + +// Dummy TDS which provides all types that a vertex_base or cell_base can use. +struct Dummy_tds_3 { + struct Vertex {}; + struct Cell {}; + struct Facet {}; + struct Edge {}; + + struct Vertex_handle {}; + struct Cell_handle {}; + + struct Vertex_iterator {}; + struct Cell_iterator {}; + struct Facet_iterator {}; + struct Edge_iterator {}; + + struct Cell_circulator {}; + struct Facet_circulator {}; +}; + +}} // namespace CGAL::internal + +#endif // CGAL_INTERNAL_TRIANGULATION_DUMMY_TDS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/Regular_triangulation_filtered_traits_3.h b/Triangulation_3_copy_tds/include/CGAL/internal/Regular_triangulation_filtered_traits_3.h new file mode 100644 index 00000000000..bb44079366d --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/Regular_triangulation_filtered_traits_3.h @@ -0,0 +1,172 @@ +// Copyright (c) 2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_INTERNAL_REGULAR_TRIANGULATION_FILTERED_TRAITS_3_H +#define CGAL_INTERNAL_REGULAR_TRIANGULATION_FILTERED_TRAITS_3_H + +#include +#include +#include +#include + +namespace CGAL{ + + +// The Weighted_converter is parametrized by a usual kernel converter, +// and adds the conversions for the Weighted_point. +template < typename Converter, + typename Source_traits= Regular_triangulation_euclidean_traits_base_3, + typename Target_traits= Regular_triangulation_euclidean_traits_base_3 + > +struct Weighted_converter_3 + : public Converter +{ + typedef typename Converter::Source_kernel Source_kernel; + typedef typename Converter::Target_kernel Target_kernel; + + typedef typename Source_traits::Weighted_point_3 Source_wp; + typedef typename Target_traits::Weighted_point_3 Target_wp; + + typedef typename Source_kernel::Point_3 Source_p; + typedef typename Target_kernel::Point_3 Target_p; + + using Converter::operator(); + + // Needed for MSVC 2005/2008 to avoid a matching ambiguity + Target_p + operator()(const Source_p &p) const + { + return Converter::operator()(p); + } + + Target_wp + operator()(const Source_wp &wp) const + { + return Target_wp(Converter::operator()(wp.point()), + Converter::operator()(wp.weight())); + } +}; + + +namespace internal{ + +// The argument is supposed to be a Filtered_kernel like kernel. +template < typename K> +class Regular_triangulation_filtered_traits_base_3 + : public Regular_triangulation_euclidean_traits_base_3 +{ + // Exact traits is based on the exact kernel. + typedef Regular_triangulation_euclidean_traits_3 + Exact_traits; + // Filtering traits is based on the filtering kernel. + typedef Regular_triangulation_euclidean_traits_3 + Filtering_traits; + + typedef typename K::C2E C2E; + typedef typename K::C2F C2F; + +public: + + typedef K Kernel; + + typedef Filtered_predicate< + typename Exact_traits::Power_test_3, + typename Filtering_traits::Power_test_3, + Weighted_converter_3, + Weighted_converter_3 > Power_test_3; + + typedef Filtered_predicate< + typename Exact_traits::Compare_power_distance_3, + typename Filtering_traits::Compare_power_distance_3, + Weighted_converter_3, + Weighted_converter_3 > Compare_power_distance_3; + + typedef Filtered_predicate< + typename Exact_traits::In_smallest_orthogonal_sphere_3, + typename Filtering_traits::In_smallest_orthogonal_sphere_3, + Weighted_converter_3, + Weighted_converter_3 > In_smallest_orthogonal_sphere_3; + + typedef Filtered_predicate< + typename Exact_traits::Side_of_bounded_orthogonal_sphere_3, + typename Filtering_traits::Side_of_bounded_orthogonal_sphere_3, + Weighted_converter_3, + Weighted_converter_3 > Side_of_bounded_orthogonal_sphere_3; + + typedef Filtered_predicate< + typename Exact_traits::Does_simplex_intersect_dual_support_3, + typename Filtering_traits::Does_simplex_intersect_dual_support_3, + Weighted_converter_3, + Weighted_converter_3 > Does_simplex_intersect_dual_support_3; + + typedef Filtered_predicate< + typename Exact_traits::Compare_weighted_squared_radius_3, + typename Filtering_traits::Compare_weighted_squared_radius_3, + Weighted_converter_3, + Weighted_converter_3 > Compare_weighted_squared_radius_3; + + enum { Has_filtered_predicates = true }; + + Power_test_3 power_test_3_object() const + { return Power_test_3();} + + Compare_power_distance_3 compare_power_distance_3_object() const + { return Compare_power_distance_3();} + + In_smallest_orthogonal_sphere_3 + in_smallest_orthogonal_sphere_3_object() const + { return In_smallest_orthogonal_sphere_3(); } + + Side_of_bounded_orthogonal_sphere_3 + side_of_bounded_orthogonal_sphere_3_object() const + { return Side_of_bounded_orthogonal_sphere_3(); } + + Does_simplex_intersect_dual_support_3 + does_simplex_intersect_dual_support_3_object() const + { return Does_simplex_intersect_dual_support_3(); } + + Compare_weighted_squared_radius_3 + compare_weighted_squared_radius_3_object() const + { return Compare_weighted_squared_radius_3(); } + // The following are inherited since they are constructions : + // Construct_weighted_circumcenter_3 + // Compute_squared_radius_smallest_orthogonal_sphere_3 + // Compute_power_product_3 +}; + +template < typename K,bool UseStaticFilters = K::Has_static_filters> +class Regular_triangulation_filtered_traits_3 + : public Regular_triangulation_filtered_traits_base_3 +{ +public: + enum { Has_static_filters = false }; +}; + +template < typename K> +class Regular_triangulation_filtered_traits_3 + : public internal::Regular_triangulation_static_filters_traits_3< Regular_triangulation_filtered_traits_base_3 > +{ +public: + enum { Has_static_filters = true }; +}; + + + +} } //namespace CGAL::internal + +#endif // CGAL_INTERNAL_REGULAR_TRIANGULATION_FILTERED_TRAITS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Compare_weighted_squared_radius_3.h b/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Compare_weighted_squared_radius_3.h new file mode 100644 index 00000000000..f3d01ab3f62 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Compare_weighted_squared_radius_3.h @@ -0,0 +1,362 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Sebastien Loriot +// This predicates was generated using the fpg tool written by Andreas Meyer. +// + +#ifndef CGAL_INTERNAL_STATIC_FILTERS_COMPARE_WEIGHTED_SQUARED_RADIUS_3_H +#define CGAL_INTERNAL_STATIC_FILTERS_COMPARE_WEIGHTED_SQUARED_RADIUS_3_H + +#include +#include +#include + + +namespace CGAL { namespace internal { namespace Static_filters_predicates { + + + template + class Compare_weighted_squared_radius_3: + public K_base::Compare_weighted_squared_radius_3 + { + typedef typename K_base::Weighted_point_3 Weighted_point_3; + typedef typename K_base::FT FT; + typedef typename K_base::Compare_weighted_squared_radius_3 Base; + public: + typedef typename Base::result_type result_type; + + #ifndef CGAL_CFG_MATCHING_BUG_6 + using Base::operator(); + #else + result_type + operator()(const Weighted_point_3& p, const FT& w) const + { + return Base::operator()(p,w); + } + #endif + + + result_type operator() ( + const Weighted_point_3& p, + const Weighted_point_3& q, + const Weighted_point_3& r, + const Weighted_point_3& s, + const FT& w + ) const { + + CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to : Compare_weighted_squared_radius_3 with 4 wpoints", tmp); + using std::fabs; + + double px, py, pz, pw, qx, qy, qz, qw, rx, ry, rz, rw, sx, sy, sz, sw, alpha; + if( fit_in_double(p.x(), px) && fit_in_double(p.y(), py) && + fit_in_double(p.z(), pz) && fit_in_double(p.weight(), pw) && + fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) && + fit_in_double(q.z(), qz) && fit_in_double(q.weight(), qw) && + fit_in_double(r.x(), rx) && fit_in_double(r.y(), ry) && + fit_in_double(r.z(), rz) && fit_in_double(r.weight(), rw) && + fit_in_double(s.x(), sx) && fit_in_double(s.y(), sy) && + fit_in_double(s.z(), sz) && fit_in_double(s.weight(), sw) && + fit_in_double(w, alpha) + ) + { + CGAL_BRANCH_PROFILER_BRANCH_1(tmp); + + double qpx = (qx - px); + double qpy = (qy - py); + double qpz = (qz - pz); + double pw_qw = (pw - qw); + double qp2 = (((CGAL::square( qpx ) + CGAL::square( qpy )) + CGAL::square( qpz )) + pw_qw); + double rpx = (rx - px); + double rpy = (ry - py); + double rpz = (rz - pz); + double pw_rw = (pw - rw); + double rp2 = (((CGAL::square( rpx ) + CGAL::square( rpy )) + CGAL::square( rpz )) + pw_rw); + double spx = (sx - px); + double spy = (sy - py); + double spz = (sz - pz); + double pw_sw = (pw - sw); + double sp2 = (((CGAL::square( spx ) + CGAL::square( spy )) + CGAL::square( spz )) + pw_sw); + double num_x = CGAL::determinant( qpy, qpz, qp2, rpy, rpz, rp2, spy, spz, sp2 ); + double num_y = CGAL::determinant( qpx, qpz, qp2, rpx, rpz, rp2, spx, spz, sp2 ); + double num_z = CGAL::determinant( qpx, qpy, qp2, rpx, rpy, rp2, spx, spy, sp2 ); + double den = CGAL::determinant( qpx, qpy, qpz, rpx, rpy, rpz, spx, spy, spz ); + double alpha_pw = (alpha + pw); + CGAL::Sign int_tmp_result; + double eps; + double double_tmp_result = (((alpha_pw * 4.00000000000000000000e+00) * CGAL::square( den )) - ((CGAL::square( num_x ) + CGAL::square( num_y )) + CGAL::square( num_z ))); + double max4 = fabs(qpy); + if( (max4 < fabs(rpy)) ) max4 = fabs(rpy); + if( (max4 < fabs(spy)) ) max4 = fabs(spy); + double max2 = max4; + if( (max2 < fabs(qpx)) ) max2 = fabs(qpx); + if( (max2 < fabs(rpx)) ) max2 = fabs(rpx); + if( (max2 < fabs(spx)) ) max2 = fabs(spx); + double max1 = max2; + double max3 = max4; + double max5 = fabs(qpz); + if( (max5 < fabs(rpz)) ) max5 = fabs(rpz); + if( (max5 < fabs(spz)) ) max5 = fabs(spz); + if( (max3 < max5) ) max3 = max5; + if( (max1 < max3) ) max1 = max3; + if( (max1 < max4) ) max1 = max4; + if( (max1 < max5) ) max1 = max5; + double max6 = fabs(pw_qw); + if( (max6 < fabs(pw_rw)) ) max6 = fabs(pw_rw); + if( (max6 < fabs(pw_sw)) ) max6 = fabs(pw_sw); + double max7 = max6; + if( (max7 < fabs(alpha_pw)) ) max7 = fabs(alpha_pw); + double lower_bound_1; + double upper_bound_1; + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max2 < lower_bound_1) ) lower_bound_1 = max2; + if( (max3 < lower_bound_1) ) lower_bound_1 = max3; + if( (max4 < lower_bound_1) ) lower_bound_1 = max4; + if( (max5 < lower_bound_1) ) lower_bound_1 = max5; + double lower_bound_2; + double upper_bound_2; + lower_bound_2 = max6; + upper_bound_2 = max6; + if( (max7 < lower_bound_2) ) lower_bound_2 = max7; + else + { + if( (max7 > upper_bound_2) ) upper_bound_2 = max7; + } + if( ((lower_bound_1 < 8.99995159231796093217e-38) || (lower_bound_2 < 8.09991286640666077573e-75)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,s,w); + } + else + { + if( ((upper_bound_1 > 2.59614842926741294957e+33) || (upper_bound_2 > 6.73998666678765545893e+66)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,s,w); + } + eps = (5.16919651938288206243e-12 * (((((max2 * max3) * max1) * max1) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION ( max7, (max1 * max1) )) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION ( CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION ( max6, (max4 * max5) ), (max1 * max1) ))); + if( (double_tmp_result > eps) ) + { + int_tmp_result = CGAL::NEGATIVE; + } + else + { + if( (double_tmp_result < -eps) ) + { + int_tmp_result = CGAL::POSITIVE; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,s,w); + } + } + } + return int_tmp_result; + } + else + return Base::operator()(p,q,r,s,w); + } + + result_type + operator() ( + const Weighted_point_3& p, + const Weighted_point_3& q , + const Weighted_point_3& r, + const FT& w + ) const { + + CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to : Compare_weighted_squared_radius_3 with 3 wpoints", tmp); + using std::fabs; + + double px, py, pz, pw, qx, qy, qz, qw, rx, ry, rz, rw, alpha; + if( fit_in_double(p.x(), px) && fit_in_double(p.y(), py) && + fit_in_double(p.z(), pz) && fit_in_double(p.weight(), pw) && + fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) && + fit_in_double(q.z(), qz) && fit_in_double(q.weight(), qw) && + fit_in_double(r.x(), rx) && fit_in_double(r.y(), ry) && + fit_in_double(r.z(), rz) && fit_in_double(r.weight(), rw) && + fit_in_double(w, alpha) + ) + { + CGAL_BRANCH_PROFILER_BRANCH_1(tmp); + + double qpx = (qx - px); + double qpy = (qy - py); + double qpz = (qz - pz); + double pw_qw = (pw - qw); + double qp2 = (((CGAL::square( qpx ) + CGAL::square( qpy )) + CGAL::square( qpz )) + pw_qw); + double rpx = (rx - px); + double rpy = (ry - py); + double rpz = (rz - pz); + double pw_rw = (pw - rw); + double rp2 = (((CGAL::square( rpx ) + CGAL::square( rpy )) + CGAL::square( rpz )) + pw_rw); + double sx = ((qpy * rpz) - (qpz * rpy)); + double sy = ((qpz * rpx) - (qpx * rpz)); + double sz = ((qpx * rpy) - (qpy * rpx)); + double num_x = ((qp2 * CGAL::determinant( rpy, rpz, sy, sz )) - (rp2 * CGAL::determinant( qpy, qpz, sy, sz ))); + double num_y = ((qp2 * CGAL::determinant( rpx, rpz, sx, sz )) - (rp2 * CGAL::determinant( qpx, qpz, sx, sz ))); + double num_z = ((qp2 * CGAL::determinant( rpx, rpy, sx, sy )) - (rp2 * CGAL::determinant( qpx, qpy, sx, sy ))); + double den = CGAL::determinant( qpx, qpy, qpz, rpx, rpy, rpz, sx, sy, sz ); + double alpha_pw = (alpha + pw); + CGAL::Sign int_tmp_result; + double eps; + double double_tmp_result = ((alpha_pw * CGAL::square( den )) - (2.50000000000000000000e-01 * ((CGAL::square( num_x ) + CGAL::square( num_y )) + CGAL::square( num_z )))); + double max2 = fabs(qpx); + if( (max2 < fabs(qpy)) ) max2 = fabs(qpy); + if( (max2 < fabs(rpx)) ) max2 = fabs(rpx); + if( (max2 < fabs(rpy)) ) max2 = fabs(rpy); + double max1 = max2; + if( (max1 < fabs(qpz)) ) max1 = fabs(qpz); + if( (max1 < fabs(rpz)) ) max1 = fabs(rpz); + double max3 = fabs(pw_qw); + if( (max3 < fabs(pw_rw)) ) max3 = fabs(pw_rw); + double max4 = max3; + if( (max4 < fabs(alpha_pw)) ) max4 = fabs(alpha_pw); + double lower_bound_1; + double upper_bound_1; + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max2 < lower_bound_1) ) lower_bound_1 = max2; + double lower_bound_2; + double upper_bound_2; + lower_bound_2 = max3; + upper_bound_2 = max3; + if( (max4 < lower_bound_2) ) lower_bound_2 = max4; + else + { + if( (max4 > upper_bound_2) ) upper_bound_2 = max4; + } + if( ((lower_bound_1 < 2.13354839219409151500e-30) || (lower_bound_2 < 4.55202874183399304187e-60)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,w); + } + else + { + if( ((upper_bound_1 > 1.23794003928538000002e+27) || (upper_bound_2 > 1.53249554086588817779e+54)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,w); + } + eps = (1.13846439714120896721e-11 * (((((((max1 * max2) * max1) * max1) * max1) * max1) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION ( max4, (max1 * max1) )) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION ( max3, (max1 * max1) ))); + if( (double_tmp_result > eps) ) + { + int_tmp_result = CGAL::NEGATIVE; + } + else + { + if( (double_tmp_result < -eps) ) + { + int_tmp_result = CGAL::POSITIVE; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,w); + } + } + } + return int_tmp_result; + } + else + return Base::operator()(p,q,r,w); + } + + result_type + operator() ( + const Weighted_point_3& p, + const Weighted_point_3& q, + const FT& w + ) const { + + CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to : Compare_weighted_squared_radius_3 with 2 wpoints", tmp); + using std::fabs; + + double px, py, pz, pw, qx, qy, qz, qw, alpha; + if( fit_in_double(p.x(), px) && fit_in_double(p.y(), py) && + fit_in_double(p.z(), pz) && fit_in_double(p.weight(), pw) && + fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) && + fit_in_double(q.z(), qz) && fit_in_double(q.weight(), qw) && + fit_in_double(w, alpha) + ) + { + CGAL_BRANCH_PROFILER_BRANCH_1(tmp); + + double qpx = (qx - px); + double qpy = (qy - py); + double qpz = (qz - pz); + double qp2 = ((CGAL::square( qpx ) + CGAL::square( qpy )) + CGAL::square( qpz )); + double alpha_pw = (alpha + pw); + double pw_qw = (pw - qw); + CGAL::Sign int_tmp_result; + double eps; + double double_tmp_result = (((4.00000000000000000000e+00 * qp2) * alpha_pw) - CGAL::square( (qp2 + pw_qw) )); + double max1 = fabs(qpx); + if( (max1 < fabs(qpy)) ) max1 = fabs(qpy); + if( (max1 < fabs(qpz)) ) max1 = fabs(qpz); + double max2; + double max3 = fabs(pw_qw); + max2 = max3; + if( (max2 < fabs(alpha_pw)) ) max2 = fabs(alpha_pw); + double lower_bound_2; + double upper_bound_2; + lower_bound_2 = max2; + upper_bound_2 = max2; + if( (max3 < lower_bound_2) ) lower_bound_2 = max3; + if( ((max1 < 3.12497063152273477754e-74) || (lower_bound_2 < 9.76544144787960039738e-148)) ){ + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,w); + } + else + { + if( ((max1 > 6.42775217703595896130e+60) || (upper_bound_2 > 4.13159980493905099125e+121)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,w); + } + eps = (2.33324675561911025753e-14 * (CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION ( max2, (max1 * max1) ) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION ( max3, (max1 * max1) ))); + if( (double_tmp_result > eps) ) + { + int_tmp_result = CGAL::NEGATIVE; + } + else + { + if( (double_tmp_result < -eps) ) + { + int_tmp_result = CGAL::POSITIVE; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,w); + } + } + } + return int_tmp_result; + } + else + return Base::operator()(p,q,w); + } + + }; + + +} } }//namespace CGAL::internal::Static_filters_predicates + + +#endif //CGAL_INTERNAL_STATIC_FILTERS_COMPARE_WEIGHTED_SQUARED_RADIUS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Power_test_3.h b/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Power_test_3.h new file mode 100644 index 00000000000..6ec1f177c4d --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Power_test_3.h @@ -0,0 +1,664 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Sebastien Loriot +// This predicates was generated using the fpg tool written by Andreas Meyer. +// + +#ifndef CGAL_INTERNAL_STATIC_FILTERS_POWER_TEST_3_H +#define CGAL_INTERNAL_STATIC_FILTERS_POWER_TEST_3_H + +#include +#include +#include + + +namespace CGAL { namespace internal { namespace Static_filters_predicates { + + template + class Power_test_3: + public K_base::Power_test_3 + { + typedef typename K_base::Weighted_point_3 Weighted_point_3; + typedef typename K_base::FT FT; + typedef typename K_base::Power_test_3 Base; + public: + typedef typename Base::result_type result_type; + + #ifndef CGAL_CFG_MATCHING_BUG_6 + using Base::operator(); + #else + result_type + operator()(const Weighted_point_3& p, const Weighted_point_3& q) const + { + return Base::operator()(p,q); + } + #endif + + + result_type operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & s, + const Weighted_point_3 & t) const + { + CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to : Power_test_3 with 4+1 wpoints", tmp); + using std::fabs; + + double px, py, pz, pwt, qx, qy, qz, qwt, rx, ry, rz, rwt, sx, sy, sz, swt, tx, ty, tz, twt; + if( fit_in_double(p.x(), px) && fit_in_double(p.y(), py) && + fit_in_double(p.z(), pz) && fit_in_double(p.weight(), pwt) && + fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) && + fit_in_double(q.z(), qz) && fit_in_double(q.weight(), qwt) && + fit_in_double(r.x(), rx) && fit_in_double(r.y(), ry) && + fit_in_double(r.z(), rz) && fit_in_double(r.weight(), rwt) && + fit_in_double(s.x(), sx) && fit_in_double(s.y(), sy) && + fit_in_double(s.z(), sz) && fit_in_double(s.weight(), swt) && + fit_in_double(t.x(), tx) && fit_in_double(t.y(), ty) && + fit_in_double(t.z(), tz) && fit_in_double(t.weight(), twt) + ) + { + CGAL_BRANCH_PROFILER_BRANCH_1(tmp); + using std::fabs; + + double dpx = (px - tx); + double dpy = (py - ty); + double dpz = (pz - tz); + double twt_pwt = (twt - pwt); + double dpt = (((square( dpx ) + square( dpy )) + square( dpz )) + twt_pwt); + double dqx = (qx - tx); + double dqy = (qy - ty); + double dqz = (qz - tz); + double twt_qwt = (twt - qwt); + double dqt = (((square( dqx ) + square( dqy )) + square( dqz )) + twt_qwt); + double drx = (rx - tx); + double dry = (ry - ty); + double drz = (rz - tz); + double twt_rwt = (twt - rwt); + double drt = (((square( drx ) + square( dry )) + square( drz )) + twt_rwt); + double dsx = (sx - tx); + double dsy = (sy - ty); + double dsz = (sz - tz); + double twt_swt = (twt - swt); + double dst = (((square( dsx ) + square( dsy )) + square( dsz )) + twt_swt); + result_type int_tmp_result; + double eps; + double RT_tmp_result = CGAL::determinant( dpx, dpy, dpz, dpt, dqx, dqy, dqz, dqt, drx, dry, drz, drt, dsx, dsy, dsz, dst ); + double max2 = fabs(dpx); + if( (max2 < fabs(dqx)) ) max2 = fabs(dqx); + if( (max2 < fabs(drx)) ) max2 = fabs(drx); + if( (max2 < fabs(dsx)) ) max2 = fabs(dsx); + double max1 = max2; + double max3 = fabs(dpy); + if( (max3 < fabs(dqy)) ) max3 = fabs(dqy); + if( (max3 < fabs(dry)) ) max3 = fabs(dry); + if( (max3 < fabs(dsy)) ) max3 = fabs(dsy); + if( (max1 < max3) ) max1 = max3; + double max4 = fabs(dpz); + if( (max4 < fabs(dqz)) ) max4 = fabs(dqz); + if( (max4 < fabs(drz)) ) max4 = fabs(drz); + if( (max4 < fabs(dsz)) ) max4 = fabs(dsz); + if( (max1 < max4) ) max1 = max4; + double max5 = fabs(twt_pwt); + if( (max5 < fabs(twt_qwt)) ) max5 = fabs(twt_qwt); + if( (max5 < fabs(twt_rwt)) ) max5 = fabs(twt_rwt); + if( (max5 < fabs(twt_swt)) ) max5 = fabs(twt_swt); + double lower_bound_1; + double upper_bound_1; + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max2 < lower_bound_1) ) lower_bound_1 = max2; + if( (max3 < lower_bound_1) ) lower_bound_1 = max3; + if( (max4 < lower_bound_1) ) lower_bound_1 = max4; + //handwritten workaround to handle case where all weights are equal + //if( ((lower_bound_1 < 1.05893684636332247212e-59) || (max5 < 1.12134724458589890404e-118)) ) + if( ((lower_bound_1 < 1.05893684636332247212e-59) || (max5 < 1.12134724458589890404e-118 && max5!=0)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,s,t); + } + else + { + if( ((upper_bound_1 > 3.21387608851797948065e+60) || (max5 > 1.03289995123476274781e+121)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,s,t); + } + eps = (1.67106803095990471147e-13 * (((max2 * max3) * max4) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION( max5, (max1 * max1) ))); + if( (RT_tmp_result > eps) ) + { + int_tmp_result = NEGATIVE; + } + else + { + if( (RT_tmp_result < -eps) ) + { + int_tmp_result = POSITIVE; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,s,t); + } + } + } + return int_tmp_result; + } + else + return Base::operator()(p,q,r,s,t); + } + + result_type operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & r, + const Weighted_point_3 & t) const + { + + CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to : Power_test_3 with 3+1 wpoints", tmp); + using std::fabs; + + double px, py, pz, pwt, qx, qy, qz, qwt, rx, ry, rz, rwt, tx, ty, tz, twt; + if( fit_in_double(p.x(), px) && fit_in_double(p.y(), py) && + fit_in_double(p.z(), pz) && fit_in_double(p.weight(), pwt) && + fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) && + fit_in_double(q.z(), qz) && fit_in_double(q.weight(), qwt) && + fit_in_double(r.x(), rx) && fit_in_double(r.y(), ry) && + fit_in_double(r.z(), rz) && fit_in_double(r.weight(), rwt) && + fit_in_double(t.x(), tx) && fit_in_double(t.y(), ty) && + fit_in_double(t.z(), tz) && fit_in_double(t.weight(), twt) + ) + { + CGAL_BRANCH_PROFILER_BRANCH_1(tmp); + using std::fabs; + + double dpx = (px - tx); + double dpy = (py - ty); + double dpz = (pz - tz); + double twt_pwt = (twt - pwt); + double dpt = (((square( dpx ) + square( dpy )) + square( dpz )) + twt_pwt); + double dqx = (qx - tx); + double dqy = (qy - ty); + double dqz = (qz - tz); + double twt_qwt = (twt - qwt); + double dqt = (((square( dqx ) + square( dqy )) + square( dqz )) + twt_qwt); + double drx = (rx - tx); + double dry = (ry - ty); + double drz = (rz - tz); + double twt_rwt = (twt - rwt); + double drt = (((square( drx ) + square( dry )) + square( drz )) + twt_rwt); + int cmp; + int int_tmp_result; + double eps; + double RT_tmp_result = CGAL::determinant( dpx, dpy, dpt, dqx, dqy, dqt, drx, dry, drt ); + double max7 = fabs(dpz); + if( (max7 < fabs(dqz)) ) max7 = fabs(dqz); + if( (max7 < fabs(drz)) ) max7 = fabs(drz); + double max1 = max7; + double max2 = fabs(dpx); + if( (max2 < fabs(dqx)) ) max2 = fabs(dqx); + if( (max2 < fabs(drx)) ) max2 = fabs(drx); + if( (max1 < max2) ) max1 = max2; + double max3 = fabs(dpy); + if( (max3 < fabs(dqy)) ) max3 = fabs(dqy); + if( (max3 < fabs(dry)) ) max3 = fabs(dry); + if( (max1 < max3) ) max1 = max3; + double max4 = fabs(twt_pwt); + if( (max4 < fabs(twt_qwt)) ) max4 = fabs(twt_qwt); + if( (max4 < fabs(twt_rwt)) ) max4 = fabs(twt_rwt); + double lower_bound_1; + double upper_bound_1; + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max2 < lower_bound_1) ) lower_bound_1 = max2; + if( (max3 < lower_bound_1) ) lower_bound_1 = max3; + //handwritten workaround to handle case where all weights are equal + //if( ((lower_bound_1 < 2.92391967062015793913e-74) || (max4 < 8.54930624023949352313e-148)) ) + if( ((lower_bound_1 < 2.92391967062015793913e-74) || (max4 < 8.54930624023949352313e-148 && max4!=0)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + else + { + if( ((upper_bound_1 > 7.23700557733225980357e+75) || (max4 > 5.23742497263382350320e+151)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + eps = (3.04426660386257731823e-14 * ((max2 * max3) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION( max4, (max1 * max1) ))); + if( (RT_tmp_result > eps) ) + { + int_tmp_result = 1; + } + else + { + if( (RT_tmp_result < -eps) ) + { + int_tmp_result = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + } + } + cmp = int_tmp_result; + double px_rx = (px - rx); + double qy_ry = (qy - ry); + double qx_rx = (qx - rx); + double py_ry = (py - ry); + double max5 = fabs(px_rx); + if( (max5 < fabs(qx_rx)) ) max5 = fabs(qx_rx); + double max6 = fabs(qy_ry); + if( (max6 < fabs(py_ry)) ) max6 = fabs(py_ry); + if( (cmp != 0) ) + { + int int_tmp_result_FFWKCAA; + double double_tmp_result; + double_tmp_result = ((px_rx * qy_ry) - (qx_rx * py_ry)); + lower_bound_1 = max5; + upper_bound_1 = max5; + if( (max6 < lower_bound_1) ) lower_bound_1 = max6; + else + { + if( (max6 > upper_bound_1) ) upper_bound_1 = max6; + } + if( (lower_bound_1 < 5.00368081960964690982e-147) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + else + { + if( (upper_bound_1 > 7.23700557733225980357e+75) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + eps = (8.88720573725927976811e-16 * (max5 * max6)); + if( (double_tmp_result > eps) ) int_tmp_result_FFWKCAA = 1; + else + { + if( (double_tmp_result < -eps) ) + { + int_tmp_result_FFWKCAA = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + } + } + return static_cast(cmp * int_tmp_result_FFWKCAA); + } + int int_tmp_result_k60Ocge; + double RT_tmp_result_3SPBwDj = CGAL::determinant( dpx, dpz, dpt, dqx, dqz, dqt, drx, drz, drt ); + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max7 < lower_bound_1) ) lower_bound_1 = max7; + if( (max2 < lower_bound_1) ) lower_bound_1 = max2; + //handwritten workaround to handle case where all weights are equal + //if( ((lower_bound_1 < 2.92391967062015793913e-74) || (max4 < 8.54930624023949352313e-148)) ) + if( ((lower_bound_1 < 2.92391967062015793913e-74) || (max4 < 8.54930624023949352313e-148 && max4!=0)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + else + { + if( ((upper_bound_1 > 7.23700557733225980357e+75) || (max4 > 5.23742497263382350320e+151)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + eps = (3.04426660386257731823e-14 * ((max2 * max7) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION( max4, (max1 * max1) ))); + if( (RT_tmp_result_3SPBwDj > eps) ) + { + int_tmp_result_k60Ocge = 1; + } + else + { + if( (RT_tmp_result_3SPBwDj < -eps) ) + { + int_tmp_result_k60Ocge = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + } + } + cmp = int_tmp_result_k60Ocge; + double qz_rz = (qz - rz); + double pz_rz = (pz - rz); + double max8 = fabs(qz_rz); + if( (max8 < fabs(pz_rz)) ) max8 = fabs(pz_rz); + if( (cmp != 0) ) + { + int int_tmp_result_k3Lzf6g; + double double_tmp_result_Gx4H; + double_tmp_result_Gx4H = ((px_rx * qz_rz) - (qx_rx * pz_rz)); + lower_bound_1 = max5; + upper_bound_1 = max5; + if( (max8 < lower_bound_1) ) lower_bound_1 = max8; + else + { + if( (max8 > upper_bound_1) ) upper_bound_1 = max8; + } + if( (lower_bound_1 < 5.00368081960964690982e-147) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + else + { + if( (upper_bound_1 > 7.23700557733225980357e+75) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + eps = (8.88720573725927976811e-16 * (max5 * max8)); + if( (double_tmp_result_Gx4H > eps) ) + { + int_tmp_result_k3Lzf6g = 1; + } + else + { + if( (double_tmp_result_Gx4H < -eps) ) + { + int_tmp_result_k3Lzf6g = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + } + } + return static_cast(cmp * int_tmp_result_k3Lzf6g); + } + int int_tmp_result_AvrrXBP; + double RT_tmp_result_feLwnHn = CGAL::determinant( dpy, dpz, dpt, dqy, dqz, dqt, dry, drz, drt ); + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max7 < lower_bound_1) ) lower_bound_1 = max7; + if( (max3 < lower_bound_1) ) lower_bound_1 = max3; + //handwritten workaround to handle case where all weights are equal + //if( ((lower_bound_1 < 2.92391967062015793913e-74) || (max4 < 8.54930624023949352313e-148)) ) + if( ((lower_bound_1 < 2.92391967062015793913e-74) || (max4 < 8.54930624023949352313e-148 && max4!=0)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + else + { + if( ((upper_bound_1 > 7.23700557733225980357e+75) || (max4 > 5.23742497263382350320e+151)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + eps = (3.04426660386257731823e-14 * ((max3 * max7) * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION( max4, (max1 * max1) ))); + if( (RT_tmp_result_feLwnHn > eps) ) + { + int_tmp_result_AvrrXBP = 1; + } + else + { + if( (RT_tmp_result_feLwnHn < -eps) ) + { + int_tmp_result_AvrrXBP = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + } + } + cmp = int_tmp_result_AvrrXBP; + int int_tmp_result_agX3WsT; + double double_tmp_result_Dw20Kqh = ((py_ry * qz_rz) - (qy_ry * pz_rz)); + lower_bound_1 = max8; + upper_bound_1 = max8; + if( (max6 < lower_bound_1) ) + { + lower_bound_1 = max6; + } + else + { + if( (max6 > upper_bound_1) ) upper_bound_1 = max6; + } + if( (lower_bound_1 < 5.00368081960964690982e-147) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + else + { + if( (upper_bound_1 > 7.23700557733225980357e+75) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + eps = (8.88720573725927976811e-16 * (max6 * max8)); + if( (double_tmp_result_Dw20Kqh > eps) ) + { + int_tmp_result_agX3WsT = 1; + } + else + { + if( (double_tmp_result_Dw20Kqh < -eps) ) + { + int_tmp_result_agX3WsT = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,r,t); + } + } + } + return static_cast(cmp * int_tmp_result_agX3WsT); + } + else + return Base::operator()(p,q,r,t); + } + + result_type operator() ( const Weighted_point_3 & p, + const Weighted_point_3 & q, + const Weighted_point_3 & t) const + { + + CGAL_BRANCH_PROFILER_3("semi-static failures/attempts/calls to : Power_test_3 with 2+1 wpoints", tmp); + using std::fabs; + + double px, py, pz, pwt, qx, qy, qz, qwt, tx, ty, tz, twt; + if( fit_in_double(p.x(), px) && fit_in_double(p.y(), py) && + fit_in_double(p.z(), pz) && fit_in_double(p.weight(), pwt) && + fit_in_double(q.x(), qx) && fit_in_double(q.y(), qy) && + fit_in_double(q.z(), qz) && fit_in_double(q.weight(), qwt) && + fit_in_double(t.x(), tx) && fit_in_double(t.y(), ty) && + fit_in_double(t.z(), tz) && fit_in_double(t.weight(), twt) + ) + { + CGAL_BRANCH_PROFILER_BRANCH_1(tmp); + + double dpx = (px - tx); + double dpy = (py - ty); + double dpz = (pz - tz); + double twt_pwt = (twt - pwt); + double dpt = (((square( dpx ) + square( dpy )) + square( dpz )) + twt_pwt); + double dqx = (qx - tx); + double dqy = (qy - ty); + double dqz = (qz - tz); + double twt_qwt = (twt - qwt); + double dqt = (((square( dqx ) + square( dqy )) + square( dqz )) + twt_qwt); + int cmp = ((px > qx) ? 1 : ((px < qx) ? -1 : 0)); + double eps; + double max1; + double max4 = fabs(dpy); + if( (max4 < fabs(dqy)) ) max4 = fabs(dqy); + max1 = max4; + double max5 = fabs(dpz); + if( (max5 < fabs(dqz)) ) max5 = fabs(dqz); + if( (max1 < max5) ) max1 = max5; + double max2 = fabs(dpx); + if( (max2 < fabs(dqx)) ) max2 = fabs(dqx); + if( (max1 < max2) ) max1 = max2; + double max3 = fabs(twt_pwt); + if( (max3 < fabs(twt_qwt)) ) max3 = fabs(twt_qwt); + double lower_bound_1; + double upper_bound_1; + if( (cmp != 0) ) + { + int int_tmp_result; + double double_tmp_result; + double_tmp_result = ((dpx * dqt) - (dqx * dpt)); + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max2 < lower_bound_1) ) lower_bound_1 = max2; + //handwritten workaround to handle case where all weights are equal + //if( ((lower_bound_1 < 4.89808663633813414271e-98) || (max3 < 2.39912526970742181620e-195)) ) + if( ((lower_bound_1 < 4.89808663633813414271e-98) || (max3 < 2.39912526970742181620e-195 && max3!=0)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + else + { + if( ((upper_bound_1 > 5.59936185544450928309e+101) || (max3 > 3.13528531882069776730e+203)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + eps = (6.88858782307641768480e-15 * (max2 * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION( max3, (max1 * max1) ))); + if( (double_tmp_result > eps) ) + { + int_tmp_result = 1; + } + else + { + if( (double_tmp_result < -eps) ) + { + int_tmp_result = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + } + } + return static_cast(cmp * int_tmp_result); + } + cmp = ((py > qy) ? 1 : ((py < qy) ? -1 : 0)); + if( (cmp != 0) ) + { + int int_tmp_result_FFWKCAA; + double double_tmp_result_k60Ocge; + double_tmp_result_k60Ocge = ((dpy * dqt) - (dqy * dpt)); + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max4 < lower_bound_1) ) lower_bound_1 = max4; + //handwritten workaround to handle case where all weights are equal + //if( ((lower_bound_1 < 4.89808663633813414271e-98) || (max3 < 2.39912526970742181620e-195)) ) + if( ((lower_bound_1 < 4.89808663633813414271e-98) || (max3 < 2.39912526970742181620e-195 && max3!=0)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + else + { + if( ((upper_bound_1 > 5.59936185544450928309e+101) || (max3 > 3.13528531882069776730e+203)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + eps = (6.88858782307641768480e-15 * (max4 * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION( max3, (max1 * max1) ))); + if( (double_tmp_result_k60Ocge > eps) ) + { + int_tmp_result_FFWKCAA = 1; + } + else + { + if( (double_tmp_result_k60Ocge < -eps) ) + { + int_tmp_result_FFWKCAA = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + } + } + return static_cast(cmp * int_tmp_result_FFWKCAA); + } + cmp = ((pz > qz) ? 1 : ((pz < qz) ? -1 : 0)); + int int_tmp_result_3SPBwDj; + double double_tmp_result_k3Lzf6g = ((dpz * dqt) - (dqz * dpt)); + lower_bound_1 = max1; + upper_bound_1 = max1; + if( (max5 < lower_bound_1) ) + { + lower_bound_1 = max5; + } + //handwritten workaround to handle case where all weights are equal + //if( ((lower_bound_1 < 4.89808663633813414271e-98) || (max3 < 2.39912526970742181620e-195)) ) + if( ((lower_bound_1 < 4.89808663633813414271e-98) || (max3 < 2.39912526970742181620e-195 && max3!=0)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + else + { + if( ((upper_bound_1 > 5.59936185544450928309e+101) || (max3 > 3.13528531882069776730e+203)) ) + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + eps = (6.88858782307641768480e-15 * (max5 * CGAL::max BOOST_PREVENT_MACRO_SUBSTITUTION( max3, (max1 * max1) ))); + if( (double_tmp_result_k3Lzf6g > eps) ) + { + int_tmp_result_3SPBwDj = 1; + } + else + { + if( (double_tmp_result_k3Lzf6g < -eps) ) + { + int_tmp_result_3SPBwDj = -1; + } + else + { + CGAL_BRANCH_PROFILER_BRANCH_2(tmp); + return Base::operator()(p,q,t); + } + } + } + return static_cast(cmp * int_tmp_result_3SPBwDj); + } + else + return Base::operator()(p,q,t); + } + + }; + +} } }//namespace CGAL::internal::Static_filters_predicates + +#endif //CGAL_INTERNAL_STATIC_FILTERS_POWER_TEST_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Regular_triangulation_static_filters_traits_3.h b/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Regular_triangulation_static_filters_traits_3.h new file mode 100644 index 00000000000..6aef1e98a6c --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/Static_filters/Regular_triangulation_static_filters_traits_3.h @@ -0,0 +1,51 @@ +// Copyright (c) 2009 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Sebastien Loriot + +#ifndef CGAL_INTERNAL_STATIC_FILTERS_REGULAR_TRIANGULATION_STATIC_FILTERS_TRAITS_3_H +#define CGAL_INTERNAL_STATIC_FILTERS_REGULAR_TRIANGULATION_STATIC_FILTERS_TRAITS_3_H + +#include +#include +#include + +namespace CGAL{ namespace internal { + +template +class Regular_triangulation_static_filters_traits_3:public K_base{ + +public: + typedef Static_filters_predicates::Compare_weighted_squared_radius_3 Compare_weighted_squared_radius_3; + typedef Static_filters_predicates::Power_test_3 Power_test_3; + + + + Power_test_3 power_test_3_object() const + { return Power_test_3();} + + Compare_weighted_squared_radius_3 + compare_weighted_squared_radius_3_object() const + { return Compare_weighted_squared_radius_3(); } + + +}; + + + +} } //namespace CGAL::internal + +#endif //CGAL_INTERNAL_STATIC_FILTERS_REGULAR_TRIANGULATION_STATIC_FILTERS_TRAITS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/Triangulation_ds_circulators_3.h b/Triangulation_3_copy_tds/include/CGAL/internal/Triangulation_ds_circulators_3.h new file mode 100644 index 00000000000..1b84881b137 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/Triangulation_ds_circulators_3.h @@ -0,0 +1,497 @@ +// Copyright (c) 1999 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud + +#ifndef CGAL_INTERNAL_TRIANGULATION_DS_CIRCULATORS_3_H +#define CGAL_INTERNAL_TRIANGULATION_DS_CIRCULATORS_3_H + +#include +#include +#include + +namespace CGAL { namespace internal { + +template < class Tds_ > +class Triangulation_ds_cell_circulator_3 + : public Bidirectional_circulator_base +{ + // circulates on cells around a given edge + + typedef Tds_ Tds; + typedef typename Tds::Cell Cell; + typedef typename Tds::Edge Edge; + typedef typename Tds::Vertex_handle Vertex_handle; + typedef typename Tds::Cell_handle Cell_handle; + + typedef Triangulation_ds_cell_circulator_3 Cell_circulator; + +public: + + Triangulation_ds_cell_circulator_3() + : _s(), _t(), pos() + {} + + Triangulation_ds_cell_circulator_3(Cell_handle c, int s, int t) + : _s(c->vertex(s)), _t(c->vertex(t)), pos(c) + { + CGAL_triangulation_precondition( c != Cell_handle() && + s >= 0 && s < 4 && + t >= 0 && t < 4 ); + } + + Triangulation_ds_cell_circulator_3(const Edge & e) + : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)), pos(e.first) + { + CGAL_triangulation_precondition( e.first != Cell_handle() && + e.second >=0 && e.second < 4 && + e.third >=0 && e.third < 4); + } + + Triangulation_ds_cell_circulator_3(Cell_handle c, int s, int t, + Cell_handle start) + : _s(c->vertex(s)), _t(c->vertex(t)), pos(start) + { + CGAL_triangulation_precondition( c != Cell_handle() && + s >= 0 && s < 4 && + t >= 0 && t < 4 && + start->has_vertex( _s ) && + start->has_vertex( _t ) ); + } + + Triangulation_ds_cell_circulator_3(const Edge & e, Cell_handle start) + : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)), pos(start) + { + CGAL_triangulation_precondition( e.first != Cell_handle() && + e.second >=0 && e.second < 4 && + e.third >=0 && e.third < 4 && + start->has_vertex( _s ) && + start->has_vertex( _t ) ); + } + + Cell_circulator & operator++() + { + CGAL_triangulation_precondition( pos != Cell_handle() ); + //then dimension() cannot be < 3 + + pos = pos->neighbor(next_around_edge(pos->index(_s), pos->index(_t))); + return *this; + } + + Cell_circulator operator++(int) + { + Cell_circulator tmp(*this); + ++(*this); + return tmp; + } + + Cell_circulator & operator--() + { + CGAL_triangulation_precondition( pos != Cell_handle() ); + + pos = pos->neighbor(next_around_edge(pos->index(_t), pos->index(_s))); + return *this; + } + + Cell_circulator operator--(int) + { + Cell_circulator tmp(*this); + --(*this); + return tmp; + } + + Cell& operator*() const + { + return *pos; + } + + Cell* operator->() const + { + return &*pos; + } + + bool operator==(const Cell_circulator & ccir) const + { + return pos == ccir.pos && _s == ccir._s && _t == ccir._t; + } + + bool operator!=(const Cell_circulator & ccir) const + { + return ! (*this == ccir); + } + + bool operator==(Cell_handle ch) const + { + return ch == pos; + } + + bool operator!=(Cell_handle ch) const + { + return ch != pos; + } + + bool operator==(Nullptr_t CGAL_triangulation_assertion_code(n)) const + { + CGAL_triangulation_assertion( n == NULL); + return pos == Cell_handle(); + } + + bool operator!=(Nullptr_t n) const + { + return ! (*this == n); + } + + // For TDS's private use only. + Cell_handle base() const { return pos; } + operator Cell_handle() const { return pos; } + +private: + Vertex_handle _s; // source vertex of the edge + Vertex_handle _t; // target vertex of the edge + Cell_handle pos; // current cell + + static int next_around_edge(const int i, const int j) + { + return Triangulation_utils_3::next_around_edge(i,j); + } +}; + +template < class Tds_ > +inline +bool +operator==(typename Tds_::Cell_handle ch, Triangulation_ds_cell_circulator_3 cc) +{ + return (cc==ch); +} + +template < class Tds_ > +inline +bool +operator!=(typename Tds_::Cell_handle ch, Triangulation_ds_cell_circulator_3 cc) +{ + return !(cc==ch); +} + +template < class Tds_ > +class Triangulation_ds_facet_circulator_3 + : public Bidirectional_circulator_base +{ + // circulates on facets around a given edge + + typedef Tds_ Tds; + typedef typename Tds::Cell Cell; + typedef typename Tds::Cell_handle Cell_handle; + typedef typename Tds::Facet Facet; + typedef typename Tds::Edge Edge; + typedef typename Tds::Vertex_handle Vertex_handle; + + typedef Triangulation_ds_facet_circulator_3 Facet_circulator; + +public: + + Triangulation_ds_facet_circulator_3() + : _s(), _t(), pos() + {} + + Triangulation_ds_facet_circulator_3(Cell_handle c, int s, int t) + : _s(c->vertex(s)), _t(c->vertex(t)), pos(c) + { + CGAL_triangulation_precondition( c != Cell_handle() && + s >= 0 && s < 4 && + t >= 0 && t < 4 ); + } + + Triangulation_ds_facet_circulator_3(const Edge & e) + : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)), pos(e.first) + { + CGAL_triangulation_precondition( e.first != Cell_handle() && + e.second >= 0 && e.second < 4 && + e.third >= 0 && e.third < 4); + } + + Triangulation_ds_facet_circulator_3(Cell_handle c, int s, int t, + Cell_handle start, int f) + : _s(c->vertex(s)), _t(c->vertex(t)) + { + CGAL_triangulation_precondition( c != Cell_handle() && + s >= 0 && s < 4 && + t >= 0 && t < 4 && + f >= 0 && f < 4 && + start->has_vertex( _s ) && + start->has_vertex( _t ) ); + + int i = start->index( _s ); + int j = start->index( _t ); + + CGAL_triangulation_precondition( f!=i && f!=j ); + + if ( f == next_around_edge(i,j) ) + pos = start; + else + pos = start->neighbor(f); // other cell with same facet + } + + Triangulation_ds_facet_circulator_3(Cell_handle c, int s, int t, + const Facet & start) + : _s(c->vertex(s)), _t(c->vertex(t)) + { + CGAL_triangulation_precondition( c != Cell_handle() && + s >= 0 && s < 4 && + t >= 0 && t < 4 && + start.first->has_vertex( _s ) && + start.first->has_vertex( _t ) ); + + int i = start.first->index( _s ); + int j = start.first->index( _t ); + + CGAL_triangulation_precondition( start.second !=i && start.second !=j ); + + if ( start.second == next_around_edge(i,j) ) + pos = start.first; + else + pos = start.first->neighbor(start.second); // other cell with same facet + } + + Triangulation_ds_facet_circulator_3(const Edge & e, Cell_handle start, int f) + : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)) + { + CGAL_triangulation_precondition( e.first != Cell_handle() && + e.second >= 0 && e.second < 4 && + e.third >= 0 && e.third < 4 && + f >= 0 && f < 4 && + start->has_vertex( _s ) && + start->has_vertex( _t ) ); + + int i = start->index( _s ); + int j = start->index( _t ); + + CGAL_triangulation_precondition( f!=i && f!=j ); + + if ( f == next_around_edge(i,j) ) + pos = start; + else + pos = start->neighbor(f); // other cell with same facet + } + + Triangulation_ds_facet_circulator_3(const Edge & e, const Facet & start) + : _s(e.first->vertex(e.second)), _t(e.first->vertex(e.third)) + { + CGAL_triangulation_precondition( e.first != Cell_handle() && + e.second >= 0 && e.second < 4 && + e.third >= 0 && e.third < 4 && + start.first->has_vertex( _s ) && + start.first->has_vertex( _t ) ); + + int i = start.first->index( _s ); + int j = start.first->index( _t ); + + if ( start.second == next_around_edge(i,j) ) + pos = start.first; + else + pos = start.first->neighbor(start.second); + } + + Facet_circulator & operator++() + { + CGAL_triangulation_precondition( pos != Cell_handle() ); + //then dimension() cannot be < 3 + + pos = pos->neighbor( next_around_edge( pos->index(_s), pos->index(_t) ) ); + return *this; + } + + Facet_circulator operator++(int) + { + Facet_circulator tmp(*this); + ++(*this); + return tmp; + } + + Facet_circulator & operator--() + { + CGAL_triangulation_precondition( pos != Cell_handle() ); + + pos = pos->neighbor( next_around_edge( pos->index(_t), pos->index(_s) ) ); + return *this; + } + + Facet_circulator operator--(int) + { + Facet_circulator tmp(*this); + --(*this); + return tmp; + } + + Facet operator*() const + { + return Facet(pos, next_around_edge( pos->index(_s), pos->index(_t) ) ); + } + + struct Proxy_Facet { + Proxy_Facet(const Facet & ff) : f(ff) {} + Facet f; + const Facet* operator->() const { return &f; } + }; + + Proxy_Facet operator->() const + { + return Proxy_Facet(* *this); + } + + bool operator==(const Facet_circulator & ccir) const + { + return pos == ccir.pos && _s == ccir._s && _t == ccir._t; + } + + bool operator!=(const Facet_circulator & ccir) const + { + return ! (*this == ccir); + } + + bool operator==(Nullptr_t CGAL_triangulation_assertion_code(c)) const + { + CGAL_triangulation_assertion(c == NULL); + return pos == Cell_handle(); + } + + bool operator!=(Nullptr_t c) const + { + return ! (*this == c); + } + +private: + Vertex_handle _s; // source vertex of the edge + Vertex_handle _t; // target vertex of the edge + Cell_handle pos; // current cell + // the current facet is the facet of pos numbered + // next_around_edge( pos->index(_c->vertex(_s)), + // pos->index(_c->vertex(_t)) ) + + static int next_around_edge(const int i, const int j) + { + return Triangulation_utils_3::next_around_edge(i,j); + } +}; + +template < class Tds_ > +class Triangulation_ds_face_circulator_3 + : public Bidirectional_circulator_base +{ + // circulates on faces (Cell) around a given vertex, + // valid in dimension 2 only. + + typedef Tds_ Tds; + typedef typename Tds::Cell Cell; + typedef typename Tds::Vertex Vertex; + typedef typename Tds::Vertex_handle Vertex_handle; + typedef typename Tds::Cell_handle Cell_handle; + + typedef Triangulation_ds_face_circulator_3 Face_circulator; + +public: + + Triangulation_ds_face_circulator_3() + : _s(), pos() {} + + Triangulation_ds_face_circulator_3(Vertex_handle v, Cell_handle c) + : _s(v), pos(c) {} + + Face_circulator & operator++() + { + CGAL_triangulation_precondition( pos != Cell_handle() ); + //then dimension() cannot be < 3 + + pos = pos->neighbor(ccw(pos->index(_s))); + return *this; + } + + Face_circulator operator++(int) + { + Face_circulator tmp(*this); + ++(*this); + return tmp; + } + + Face_circulator & operator--() + { + CGAL_triangulation_precondition( pos != Cell_handle() ); + + pos = pos->neighbor(cw(pos->index(_s))); + return *this; + } + + Face_circulator operator--(int) + { + Face_circulator tmp(*this); + --(*this); + return tmp; + } + + Cell& operator*() const + { + return *pos; + } + + Cell* operator->() const + { + return &*pos; + } + + bool operator==(const Face_circulator & ccir) const + { + return pos == ccir.pos && _s == ccir._s; + } + + bool operator!=(const Face_circulator & ccir) const + { + return ! (*this == ccir); + } + + bool operator==(Nullptr_t CGAL_triangulation_assertion_code(c)) const + { + CGAL_triangulation_assertion(c == NULL); + return pos == Cell_handle(); + } + + bool operator!=(Nullptr_t c) const + { + return ! (*this == c); + } + + // For TDS's private use only. + Cell_handle base() const { return pos; } + operator Cell_handle() const { return pos; } + +private: + Vertex_handle _s; // source vertex + Cell_handle pos; // current cell + + static int cw(int i) + { + return Triangulation_utils_3::cw(i); + } + static int ccw(int i) + { + return Triangulation_utils_3::ccw(i); + } +}; + +}} // namespace CGAL::internal + +#endif // CGAL_INTERNAL_TRIANGULATION_DS_CIRCULATORS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/Triangulation_ds_iterators_3.h b/Triangulation_3_copy_tds/include/CGAL/internal/Triangulation_ds_iterators_3.h new file mode 100644 index 00000000000..633c2879486 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/Triangulation_ds_iterators_3.h @@ -0,0 +1,458 @@ +// Copyright (c) 1999 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// Author(s) : Monique Teillaud + +#ifndef CGAL_INTERNAL_TRIANGULATION_DS_ITERATORS_3_H +#define CGAL_INTERNAL_TRIANGULATION_DS_ITERATORS_3_H + +#include + +#include +#include + +namespace CGAL { namespace internal { + +template < class Tds > +class Triangulation_ds_facet_iterator_3 +{ +// traverses the list of cells and reports all facets. +public: + + typedef typename Tds::Facet value_type; + typedef const typename Tds::Facet * pointer; + typedef const typename Tds::Facet & reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + typedef typename Tds::Facet Facet; + typedef Triangulation_ds_facet_iterator_3 Facet_iterator; + typedef typename Tds::Cell_iterator Cell_iterator; + + Triangulation_ds_facet_iterator_3() + {} + + Triangulation_ds_facet_iterator_3(const Tds * tds) + : _tds(tds) + { + facet.second = 0; + switch ( _tds->dimension() ) { + case 2: + pos = _tds->cells().begin(); + facet.second = 3; + return; + case 3: + pos = _tds->cells().begin(); + while (// there must be at least one facet + pos->neighbor(facet.second) < pos ) { + increment(); + } + return; + default: + pos = _tds->cells().end(); + return; + } + } + + // used to initialize the past-the end iterator + Triangulation_ds_facet_iterator_3(const Tds* tds, int) + : _tds(tds) + { + facet.second = 0; + pos = _tds->cells().end(); + if (_tds->dimension() == 2) + facet.second = 3; + } + + Facet_iterator& operator++() + { + if (_tds->dimension() < 2) + return *this; + + if (_tds->dimension() == 3) { + do { + increment(); + } while ( pos != _tds->cells().end() + && pos->neighbor(facet.second) < pos ); + // reports a facet when the current cell has a pointer inferior + // to the pointer of the neighbor cell + return *this; + } + + ++pos; // dimension 2 + return *this; + } + + Facet_iterator& operator--() + { + if (_tds->dimension() < 2) + return *this; + + if ( _tds->dimension() == 2 ) { + --pos; // index remains 3 + return *this; + } + + // dimension 3 + do{ + if (facet.second == 0) { + // all the facets of the current cell have been examined + facet.second = 3; + --pos; + } + else + --facet.second; + } while ( pos != _tds->cells().end() + && pos->neighbor(facet.second) < pos ); + // reports a facet when the current cell has a pointer inferior + // to the pointer of the neighbor cell + return *this; + } + + Facet_iterator operator++(int) + { + Facet_iterator tmp(*this); + ++(*this); + return tmp; + } + + Facet_iterator operator--(int) + { + Facet_iterator tmp(*this); + --(*this); + return tmp; + } + + bool operator==(const Facet_iterator& fi) const + { + return _tds == fi._tds && pos == fi.pos && + facet.second == fi.facet.second; + } + + bool operator!=(const Facet_iterator& fi) const + { + return !(*this == fi); + } + + reference operator*() const + { + facet.first = pos; + return facet; + } + + pointer operator->() const + { + facet.first = pos; + return &facet; + } + +private: + const Tds* _tds; + Cell_iterator pos; // current "cell". + mutable Facet facet; // current facet. + + void increment() + { + if (facet.second == 3) { + // all the faces of the current cell have been examined + facet.second = 0; + ++pos; + } + // be careful : facet.second should always be 0 when pos = cells_end + else + ++facet.second; + } +}; + +template < class Tds > +class Triangulation_ds_edge_iterator_3 +{ +// traverses the list of cells and reports each edge. +public: + + typedef typename Tds::Edge value_type; + typedef const typename Tds::Edge * pointer; + typedef const typename Tds::Edge & reference; + typedef std::size_t size_type; + typedef std::ptrdiff_t difference_type; + typedef std::bidirectional_iterator_tag iterator_category; + + typedef typename Tds::Edge Edge; + typedef Triangulation_ds_edge_iterator_3 Edge_iterator; + typedef typename Tds::Cell_iterator Cell_iterator; + typedef typename Tds::Cell_handle Cell_handle; + typedef internal::Triangulation_ds_cell_circulator_3 Cell_circulator; + + Triangulation_ds_edge_iterator_3() + : _tds(NULL) + { + edge.second = 0; + edge.third = 1; + } + + Triangulation_ds_edge_iterator_3(const Tds * tds) + : _tds(tds) + { + edge.second = 0; + edge.third = 1; + switch ( _tds->dimension() ) { + case 1: + { + pos = _tds->cells().begin(); + return; + } + case 2: + { + pos = _tds->cells().begin(); + while ( // there must be at least one edge + pos->neighbor(3-edge.second-edge.third) < pos ) { + increment2(); + } + return; + } + case 3: + { + pos = _tds->cells().begin(); + bool notfound = true; + while ( // there must be at least one edge + notfound ) { + edge.first = pos; + Cell_circulator ccir = _tds->incident_cells(edge); + do { + ++ccir; + } while ( pos < ccir ); + // loop terminates since it stops at least when ccir = pos + if ( Cell_handle(ccir) == Cell_handle(pos) ) + // pos is the cell with minimal pointer + notfound = false; + else + increment3(); + } + return; + } + default: + { + pos = _tds->cells().end(); + return; + } + } + } + + // used to initialize the past-the end iterator + Triangulation_ds_edge_iterator_3(const Tds* tds, int) + : _tds(tds) + { + edge.second = 0; + edge.third = 1; + pos = _tds->cells().end(); + } + + Edge_iterator& operator++() + { + switch ( _tds->dimension() ) { + case 1: + { + ++pos; + break; + } + case 2: + { + do { + increment2(); + } while ( pos != _tds->cells().end() && + pos->neighbor(3-edge.second-edge.third) < pos ); + break; + } + case 3: + { + bool notfound = true; + do { + increment3(); + if (pos != _tds->cells().end()) { + edge.first = pos; + Cell_circulator ccir = _tds->incident_cells(edge); + do { + ++ccir; + } while ( Cell_handle(pos) < Cell_handle(ccir) ); + if ( Cell_handle(ccir) == Cell_handle(pos) ) + // pos is the cell with minimal pointer + notfound = false; + } + else { + edge.second=0; edge.third=1; + } + } while ( pos != _tds->cells().end() && notfound ); + break; + } + default: + { + return *this; + } + } + return *this; + } + + Edge_iterator& operator--() + { + switch ( _tds->dimension() ) { + case 1: + { + --pos; // edge.second, edge.third remain 0, 1 + break; + } + case 2: + { + do { + if (edge.second == 0) { + edge.second = 2; edge.third = 0; + --pos; + } + else { + --edge.second; + edge.third = edge.second+1; + // case edge.second==2, edge.third==0 forbids to write edge.third-- + } + } while ( pos != _tds->cells().end() && + pos->neighbor(3-edge.second-edge.third) < pos ); + break; + } + case 3: + { + bool notfound = true; + do { + if (edge.second == 0) { + if (edge.third == 1) { + // all the edges of the current cell have been examined + edge.second = 2; edge.third = 3; + --pos; + } + else + --edge.third; + } + else { + if (edge.third == edge.second+1) { + --edge.second; + edge.third = 3; + } + else + --edge.third; + } + if (pos != _tds->cells().end()) { + edge.first = pos; + Cell_circulator ccir = _tds->incident_cells(edge); + do { + ++ccir; + } while ( Cell_handle(pos) < Cell_handle(ccir) ); + if ( Cell_handle(pos) == Cell_handle(ccir) ) + // pos is the cell with minimum pointer + notfound = false; + } + else { + edge.second=0; edge.third=1; + } + } while ( pos != _tds->cells().end() && notfound ); + break; + } + default : + return *this; + } + // reports an edge when the current cell has a pointer inferior + // to the pointer of the neighbor cell + return *this; + } + + Edge_iterator operator++(int) + { + Edge_iterator tmp(*this); + ++(*this); + return tmp; + } + + Edge_iterator operator--(int) + { + Edge_iterator tmp(*this); + --(*this); + return tmp; + } + + bool operator==(const Edge_iterator& ei) const + { + return _tds == ei._tds && pos == ei.pos && + edge.second == ei.edge.second && edge.third == ei.edge.third; + } + + bool operator!=(const Edge_iterator& ei) const + { + return !(*this == ei); + } + + reference operator*() const + { + edge.first = pos; + return edge; + } + + pointer operator->() const + { + edge.first = pos; + return &edge; + } + +private: + const Tds* _tds; + Cell_iterator pos; // current "cell". Even if the dimension is <3 when + // there is no true cell yet. + mutable Edge edge; // keeps the indices of the current edge. + + void increment2() + { + if (edge.second == 2) { // edge.third == 0 + // all the edges of the current cell have been examined + edge.second = 0; edge.third = 1; + ++pos; + } + // be careful : index should always be 0 when pos = cells_end + else { + ++edge.second; + if ( edge.second == 2 ) + edge.third = 0; + else // edge.second==1 + edge.third = 2; + } + } + + void increment3() + { + if (edge.second == 2) { // then edge.third == 3 + // all the edges of the current cell have been examined + edge.second = 0; edge.third = 1; + ++pos; + } + else { + if (edge.third == 3) { + edge.second++; + edge.third = edge.second+1; + } + else + ++edge.third; + } + } +}; + +}} // namespace CGAL::internal + +#endif // CGAL_INTERNAL_TRIANGULATION_DS_ITERATORS_3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/internal/spatial_sorting_traits_with_indices.h b/Triangulation_3_copy_tds/include/CGAL/internal/spatial_sorting_traits_with_indices.h new file mode 100644 index 00000000000..dd08b4f7c8c --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/internal/spatial_sorting_traits_with_indices.h @@ -0,0 +1,148 @@ +// Copyright (c) 2010 GeometryFactory (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sebastien Loriot +// + +#ifndef CGAL_INTERNAL_SPATIAL_SORTING_TRAITS_WITH_INDICES +#define CGAL_INTERNAL_SPATIAL_SORTING_TRAITS_WITH_INDICES + +#include +#include + +namespace CGAL { + +namespace internal{ + +BOOST_MPL_HAS_XXX_TRAIT_NAMED_DEF(Has_typedef_Info,Info,false) + +template ::value> + struct Info_check{ + struct type{}; +}; + +template +struct Info_check{ + typedef typename T::Info type; +}; + +template sizeof(int*))> +struct Arg_type_selection; + +template +struct Arg_type_selection{ + typedef T type; +}; + +template +struct Arg_type_selection{ + typedef const T& type; +}; + +template +class Vector_property_map{ + const std::vector& data; +public: + typedef std::size_t key_type; + Vector_property_map(const std::vector& input):data(input){} + + const T& operator[](key_type i) const{ + return data[i]; + } +}; + +template +class Spatial_sort_traits_with_property_map_3:public Base_traits{ + PointPropertyMap accessor_; +public: + Spatial_sort_traits_with_property_map_3(Base_traits base=Base_traits()):Base_traits(base){} + Spatial_sort_traits_with_property_map_3(const PointPropertyMap& accessor,Base_traits base=Base_traits()) + :Base_traits(base),accessor_(accessor){} + + typedef Base_traits Gt; + typedef typename PointPropertyMap::key_type Point_3; + typedef typename Arg_type_selection::type Arg_type; + + struct Less_x_3 : public Base_traits::Less_x_3{ + Less_x_3(const PointPropertyMap& accessor,const typename Base_traits::Less_x_3& base): + Base_traits::Less_x_3(base),accessor_(accessor){} + const PointPropertyMap& accessor_; + bool operator()(Arg_type p,Arg_type q) const { + return static_cast(this)->operator()(accessor_[p],accessor_[q]); + } + }; + + struct Less_y_3 : public Base_traits::Less_y_3{ + Less_y_3(const PointPropertyMap& accessor,const typename Base_traits::Less_y_3& base): + Base_traits::Less_y_3(base),accessor_(accessor){} + const PointPropertyMap& accessor_; + bool operator()(Arg_type p,Arg_type q) const { + return static_cast(this)->operator()(accessor_[p],accessor_[q]); + } + }; + + struct Less_z_3 : public Base_traits::Less_z_3{ + Less_z_3(const PointPropertyMap& accessor,const typename Base_traits::Less_z_3& base): + Base_traits::Less_z_3(base),accessor_(accessor){} + const PointPropertyMap& accessor_; + bool operator()(Arg_type p,Arg_type q) const { + return static_cast(this)->operator()(accessor_[p],accessor_[q]); + } + }; + + Less_x_3 less_x_3_object () const {return Less_x_3(accessor_,static_cast(this)->less_x_3_object() );} + Less_y_3 less_y_3_object () const {return Less_y_3(accessor_,static_cast(this)->less_y_3_object() );} + Less_z_3 less_z_3_object () const {return Less_z_3(accessor_,static_cast(this)->less_z_3_object() );} +}; + +template +class Spatial_sort_traits_with_property_map_2:public Base_traits{ + PointPropertyMap accessor_; +public: + Spatial_sort_traits_with_property_map_2(Base_traits base=Base_traits()):Base_traits(base){} + Spatial_sort_traits_with_property_map_2(const PointPropertyMap& accessor,Base_traits base=Base_traits()) + :Base_traits(base),accessor_(accessor){} + + typedef Base_traits Gt; + typedef typename PointPropertyMap::key_type Point_2; + typedef typename Arg_type_selection::type Arg_type; + + struct Less_x_2 : public Base_traits::Less_x_2{ + Less_x_2(const PointPropertyMap& accessor,const typename Base_traits::Less_x_2& base): + Base_traits::Less_x_2(base),accessor_(accessor){} + const PointPropertyMap& accessor_; + bool operator()(Arg_type p,Arg_type q) const { + return static_cast(this)->operator()(accessor_[p],accessor_[q]); + } + }; + + struct Less_y_2 : public Base_traits::Less_y_2{ + Less_y_2(const PointPropertyMap& accessor,const typename Base_traits::Less_y_2& base): + Base_traits::Less_y_2(base),accessor_(accessor){} + const PointPropertyMap& accessor_; + bool operator()(Arg_type p,Arg_type q) const { + return static_cast(this)->operator()(accessor_[p],accessor_[q]); + } + }; + + Less_x_2 less_x_2_object () const {return Less_x_2(accessor_,static_cast(this)->less_x_2_object() );} + Less_y_2 less_y_2_object () const {return Less_y_2(accessor_,static_cast(this)->less_y_2_object() );} + +}; +} } //namespace CGAL::internal + +#endif //CGAL_INTERNAL_SPATIAL_SORTING_TRAITS_WITH_INDICES diff --git a/Triangulation_3_copy_tds/include/CGAL/predicates/Regular_triangulation_ftC3.h b/Triangulation_3_copy_tds/include/CGAL/predicates/Regular_triangulation_ftC3.h new file mode 100644 index 00000000000..2eeecc20abe --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/predicates/Regular_triangulation_ftC3.h @@ -0,0 +1,160 @@ +// Copyright (c) 1999 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_REGULAR_TRIANGULATION_FTC3_H +#define CGAL_REGULAR_TRIANGULATION_FTC3_H + +// This file contains the low level cartesian predicates +// used by the 3D regular triangulation. + +namespace CGAL { + +// return minus the sign of the 5x5 determinant [P,Q,R,S,T] +// where column [P] = transpose[px,py,pz,p^2 -wp,1] +template +Oriented_side +power_testC3( const FT &px, const FT &py, const FT &pz, const FT &pwt, + const FT &qx, const FT &qy, const FT &qz, const FT &qwt, + const FT &rx, const FT &ry, const FT &rz, const FT &rwt, + const FT &sx, const FT &sy, const FT &sz, const FT &swt, + const FT &tx, const FT &ty, const FT &tz, const FT &twt) +{ + // We translate the points so that T becomes the origin. + FT dpx = px - tx; + FT dpy = py - ty; + FT dpz = pz - tz; + FT dpt = CGAL_NTS square(dpx) + CGAL_NTS square(dpy) + + CGAL_NTS square(dpz) + (twt - pwt); + FT dqx = qx - tx; + FT dqy = qy - ty; + FT dqz = qz - tz; + FT dqt = CGAL_NTS square(dqx) + CGAL_NTS square(dqy) + + CGAL_NTS square(dqz) + (twt - qwt); + FT drx = rx - tx; + FT dry = ry - ty; + FT drz = rz - tz; + FT drt = CGAL_NTS square(drx) + CGAL_NTS square(dry) + + CGAL_NTS square(drz) + (twt - rwt); + FT dsx = sx - tx; + FT dsy = sy - ty; + FT dsz = sz - tz; + FT dst = CGAL_NTS square(dsx) + CGAL_NTS square(dsy) + + CGAL_NTS square(dsz) + (twt - swt); + + return - sign_of_determinant(dpx, dpy, dpz, dpt, + dqx, dqy, dqz, dqt, + drx, dry, drz, drt, + dsx, dsy, dsz, dst); +} + + +template +Oriented_side +power_testC3( const FT &px, const FT &py, const FT &pz, const FT &pwt, + const FT &qx, const FT &qy, const FT &qz, const FT &qwt, + const FT &rx, const FT &ry, const FT &rz, const FT &rwt, + const FT &tx, const FT &ty, const FT &tz, const FT &twt) +{ + // Same translation as above. + FT dpx = px - tx; + FT dpy = py - ty; + FT dpz = pz - tz; + FT dpt = CGAL_NTS square(dpx) + CGAL_NTS square(dpy) + + CGAL_NTS square(dpz) + (twt - pwt); + FT dqx = qx - tx; + FT dqy = qy - ty; + FT dqz = qz - tz; + FT dqt = CGAL_NTS square(dqx) + CGAL_NTS square(dqy) + + CGAL_NTS square(dqz) + (twt - qwt); + FT drx = rx - tx; + FT dry = ry - ty; + FT drz = rz - tz; + FT drt = CGAL_NTS square(drx) + CGAL_NTS square(dry) + + CGAL_NTS square(drz) + (twt - rwt); + Sign cmp; + + // Projection on the (xy) plane. + cmp = sign_of_determinant(dpx, dpy, dpt, + dqx, dqy, dqt, + drx, dry, drt); + if (cmp != ZERO) + return cmp * sign_of_determinant(px-rx, py-ry, + qx-rx, qy-ry); + + // Projection on the (xz) plane. + cmp = sign_of_determinant(dpx, dpz, dpt, + dqx, dqz, dqt, + drx, drz, drt); + if (cmp != ZERO) + return cmp * sign_of_determinant(px-rx, pz-rz, + qx-rx, qz-rz); + + // Projection on the (yz) plane. + cmp = sign_of_determinant(dpy, dpz, dpt, + dqy, dqz, dqt, + dry, drz, drt); + return cmp * sign_of_determinant(py-ry, pz-rz, + qy-ry, qz-rz); +} + + +template +Oriented_side +power_testC3( const FT &px, const FT &py, const FT &pz, const FT &pwt, + const FT &qx, const FT &qy, const FT &qz, const FT &qwt, + const FT &tx, const FT &ty, const FT &tz, const FT &twt) +{ + // Same translation as above. + FT dpx = px - tx; + FT dpy = py - ty; + FT dpz = pz - tz; + FT dpt = CGAL_NTS square(dpx) + CGAL_NTS square(dpy) + + CGAL_NTS square(dpz) + (twt - pwt); + FT dqx = qx - tx; + FT dqy = qy - ty; + FT dqz = qz - tz; + FT dqt = CGAL_NTS square(dqx) + CGAL_NTS square(dqy) + + CGAL_NTS square (dqz) + (twt - qwt); + Comparison_result cmp; + + // We do an orthogonal projection on the (x) axis, if possible. + cmp = CGAL_NTS compare(px, qx); + if (cmp != EQUAL) + return cmp * sign_of_determinant(dpx, dpt, dqx, dqt); + + // We do an orthogonal projection on the (y) axis, if possible. + cmp = CGAL_NTS compare(py, qy); + if (cmp != EQUAL) + return cmp * sign_of_determinant(dpy, dpt, dqy, dqt); + + // We do an orthogonal projection on the (z) axis. + cmp = CGAL_NTS compare(pz, qz); + return cmp * sign_of_determinant(dpz, dpt, dqz, dqt); +} + +template +Oriented_side +power_testC3(const FT &pwt, const FT &qwt) +{ + return CGAL_NTS compare(qwt, pwt); +} + +} //namespace CGAL + +#endif // CGAL_REGULAR_TRIANGULATION_FTC3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/predicates/Regular_triangulation_rtH3.h b/Triangulation_3_copy_tds/include/CGAL/predicates/Regular_triangulation_rtH3.h new file mode 100644 index 00000000000..70d780a70f3 --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/predicates/Regular_triangulation_rtH3.h @@ -0,0 +1,86 @@ +// Copyright (c) 1999 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +#ifndef CGAL_REGULAR_TRIANGULATION_RTH3_H +#define CGAL_REGULAR_TRIANGULATION_RTH3_H + +// This file contains the low level homogeneous predicates +// used by the 3D regular triangulation. + +#include + +namespace CGAL { + +template +Oriented_side +power_testH3( + const RT &phx, const RT &phy, const RT &phz, const RT &phw, const RT &pwt, + const RT &qhx, const RT &qhy, const RT &qhz, const RT &qhw, const RT &qwt, + const RT &rhx, const RT &rhy, const RT &rhz, const RT &rhw, const RT &rwt, + const RT &shx, const RT ­, const RT &shz, const RT &shw, const RT &swt, + const RT &thx, const RT &thy, const RT &thz, const RT &thw, const RT &twt) +{ + RT dphx = phx*phw; + RT dphy = phy*phw; + RT dphz = phz*phw; + RT dphw = CGAL_NTS square(phw); + RT dpz = CGAL_NTS square(phx) + CGAL_NTS square(phy) + + CGAL_NTS square(phz) - pwt*dphw; + + RT dqhx = qhx*qhw; + RT dqhy = qhy*qhw; + RT dqhz = qhz*qhw; + RT dqhw = CGAL_NTS square(qhw); + RT dqz = CGAL_NTS square(qhx) + CGAL_NTS square(qhy) + + CGAL_NTS square(qhz) - qwt*dqhw; + + RT drhx = rhx*rhw; + RT drhy = rhy*rhw; + RT drhz = rhz*rhw; + RT drhw = CGAL_NTS square(rhw); + RT drz = CGAL_NTS square(rhx) + CGAL_NTS square(rhy) + + CGAL_NTS square(rhz) - rwt*drhw; + + RT dshx = shx*shw; + RT dshy = shy*shw; + RT dshz = shz*shw; + RT dshw = CGAL_NTS square(shw); + RT dsz = CGAL_NTS square(shx) + CGAL_NTS square(shy) + + CGAL_NTS square(shz) - swt*dshw; + + RT dthx = thx*thw; + RT dthy = thy*thw; + RT dthz = thz*thw; + RT dthw = CGAL_NTS square(thw); + RT dtz = CGAL_NTS square(thx) + CGAL_NTS square(thy) + + CGAL_NTS square(thz) - twt*dthw; + + return - sign_of_determinant(dphx, dphy, dphz, dpz, dphw, + dqhx, dqhy, dqhz, dqz, dqhw, + drhx, drhy, drhz, drz, drhw, + dshx, dshy, dshz, dsz, dshw, + dthx, dthy, dthz, dtz, dthw); +} + +// The 2 degenerate are not speed critical, and they are quite boring and error +// prone to write, so we use the Cartesian version, using FT. + +} //namespace CGAL + +#endif // CGAL_REGULAR_TRIANGULATION_RTH3_H diff --git a/Triangulation_3_copy_tds/include/CGAL/predicates/predicates_on_weighted_points_cartesian_3.h b/Triangulation_3_copy_tds/include/CGAL/predicates/predicates_on_weighted_points_cartesian_3.h new file mode 100644 index 00000000000..22eeefeeebc --- /dev/null +++ b/Triangulation_3_copy_tds/include/CGAL/predicates/predicates_on_weighted_points_cartesian_3.h @@ -0,0 +1,283 @@ +// Copyright (c) 1997 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ + +// $Id$ +// +// +// Author(s) : Tran Kai Frank DA + +#ifndef CGAL_PREDICATES_ON_WEIGHTED_POINTS_CARTESIAN_3 +#define CGAL_PREDICATES_ON_WEIGHTED_POINTS_CARTESIAN_3 + +#include +#include + +namespace CGAL { + +template < class FT > +Comparison_result +compare_power_distanceC3( + const FT &px, const FT &py, const FT &pz, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw) +{ + FT dqx = qx - px; + FT dqy = qy - py; + FT dqz = qz - pz; + FT drx = rx - px; + FT dry = ry - py; + FT drz = rz - pz; + return CGAL_NTS compare(dqx*dqx + dqy*dqy + dqz*dqz - qw, + drx*drx + dry*dry + drz*drz - rw); +} + + +//return the sign of the power test of weighted point (sx,sy,sz,sw) +//with respect to the smallest sphere orthogonal to +//p,q,r +template< class FT > +CGAL_MEDIUM_INLINE +Sign +in_smallest_orthogonal_sphereC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + const FT &sx, const FT &sy, const FT &sz, const FT &sw) +{ + // Translate p to origin and compute determinants + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + + FT rpx = rx-px; + FT rpy = ry-py; + FT rpz = rz-pz; + + FT qq = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + CGAL_NTS square(qpz); + FT rr = CGAL_NTS square(rpx) + CGAL_NTS square(rpy) + CGAL_NTS square(rpz); + FT qr = qpx*rpx + qpy*rpy + qpz*rpz; + + FT qpw = qq - qw + pw ; + FT rpw = rr - rw + pw ; + + FT den = determinant(qq,qr, + qr,rr); + FT detq = determinant(qpw,qr, + rpw,rr); + FT detr = determinant(qq,qpw, + qr,rpw); + + // Smallest smallest orthogonal sphere center + // c = detq/2*den q + detr/2*den r (origin at p) + // square radius c^2 - pw + + FT spx = sx-px; + FT spy = sy-py; + FT spz = sz-pz; + FT ss = CGAL_NTS square(spx) + CGAL_NTS square(spy) + CGAL_NTS square(spz); + FT sq = spx*qpx + spy*qpy + spz*qpz; + FT sr = spx*rpx + spy*rpy + spz*rpz; + + CGAL_triangulation_assertion( ! CGAL_NTS is_zero(den) ); + // return sign of (c- s)^2 - (c^2 - pw) - sw note that den >= 0 - + return CGAL_NTS sign( den*(ss - sw + pw)- detq*sq - detr*sr); +} + + + +// return the sign of the power test of weighted point (rx,ry,rz,rw) + // with respect to the smallest sphere orthogoanal to +// p,q +template< class FT > +Sign +in_smallest_orthogonal_sphereC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw) +{ + FT FT2(2); + FT FT4(4); + FT dpx = px - qx; + FT dpy = py - qy; + FT dpz = pz - qz; + FT dpw = pw - qw; + FT dp2 = CGAL_NTS square(dpx) + CGAL_NTS square(dpy) + CGAL_NTS square(dpz); + FT drx = rx - (px + qx)/FT2; + FT dry = ry - (py + qy)/FT2; + FT drz = rz - (pz + qz)/FT2; + FT drw = rw - (pw + qw)/FT2; + FT dr2 = CGAL_NTS square(drx) + CGAL_NTS square(dry) + CGAL_NTS square(drz); + FT dpr = dpx*drx + dpy*dry +dpz*drz; + return CGAL_NTS sign (dr2 - dp2/FT4 + dpr*dpw/dp2 - drw ); +} + + + + +// return ON_UNBOUNDED_SIDE, ON_BOUNDARY or ON_BOUNDED_SIDE according +// to the position of the weighted circumcenter of pqrs +// with respect with the tertraedron formed by bare points in p, q,r,s +template +Bounded_side +does_simplex_intersect_weighted_dual_supportC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw, + const FT &sx, const FT &sy, const FT &sz, const FT &sw) +{ + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + + FT rpx = rx-px; + FT rpy = ry-py; + FT rpz = rz-pz; + + FT spx = sx-px; + FT spy = sy-py; + FT spz = sz-pz; + + FT qq = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + CGAL_NTS square(qpz); + FT rr = CGAL_NTS square(rpx) + CGAL_NTS square(rpy) + CGAL_NTS square(rpz); + FT ss = CGAL_NTS square(spx) + CGAL_NTS square(spy) + CGAL_NTS square(spz); + FT qr = qpx*rpx + qpy*rpy + qpz*rpz; + FT rs = rpx*spx + rpy*spy + rpz*spz; + FT qs = spx*qpx + spy*qpy + spz*qpz; + FT qpw = qq - qw + pw ; + FT rpw = rr - rw + pw ; + FT spw = ss - sw + pw ; + + FT den = determinant(qq,qr,qs, + qr,rr,rs, + qs,rs,ss); + FT detq = determinant(qpw,qr,qs, + rpw,rr,rs, + spw,rs,ss); + FT detr = determinant(qq,qpw,qs, + qr,rpw,rs, + qs,spw,ss); + FT dets = determinant(qq,qr,qpw, + qr,rr,rpw, + qs,rs,spw); + CGAL_triangulation_assertion( ! CGAL_NTS is_zero(den) ); + + + // The barycentrique coordinate of the smallest orthogonal sphere center + // are detq/2*den detr/2*den dets/2*den + // and 1-(detq+ detr+dets)/2*den + + CGAL::Sign sign1 = CGAL_NTS sign(FT(2)*den - detq -detr -dets); + if ( + (CGAL_NTS sign(detq) == CGAL_NTS sign(den) || CGAL_NTS sign(detq)== ZERO) && + (CGAL_NTS sign(detr) == CGAL_NTS sign(den) || CGAL_NTS sign(detr)== ZERO) && + (CGAL_NTS sign(dets) == CGAL_NTS sign(den) || CGAL_NTS sign(dets)== ZERO) && + ( sign1 == POSITIVE || sign1 == ZERO )) { // inside or on boundary + if (CGAL_NTS sign(detq) != ZERO && + CGAL_NTS sign(detr) != ZERO && + CGAL_NTS sign(dets) != ZERO && + sign1 != ZERO) + return ON_BOUNDED_SIDE; + else return ON_BOUNDARY ; + } + return ON_UNBOUNDED_SIDE; +} + +// return ON_UNBOUNDED_SIDE, ON_BOUNDARY or ON_BOUNDED_SIDE according +// to the position of the intersection if the radialaxis +// of weighted circumcenter of pqr with affine hull of bare p,q,r +// with respect with the triangle formed by bare points in p, q,r. +template +Bounded_side +does_simplex_intersect_weighted_dual_supportC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw, + const FT &rx, const FT &ry, const FT &rz, const FT &rw) +{ + // returns true if weighted circumcenter of pqr is in + // triangle pqr or on boundary + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + + FT rpx = rx-px; + FT rpy = ry-py; + FT rpz = rz-pz; + + FT qq = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + CGAL_NTS square(qpz); + FT rr = CGAL_NTS square(rpx) + CGAL_NTS square(rpy) + CGAL_NTS square(rpz); + FT qr = qpx*rpx + qpy*rpy + qpz*rpz; + + FT qpw = qq - qw + pw ; + FT rpw = rr - rw + pw ; + + FT den = determinant(qq,qr, + qr,rr); + FT detq = determinant(qpw,qr, + rpw,rr); + FT detr = determinant(qq,qpw, + qr,rpw); + + CGAL_triangulation_assertion( ! CGAL_NTS is_zero(den) ); + + // The barycentrique coordinate of the smallest orthogonal sphere center + // are detq/2*den detr/2*den + // and 1-(detq+ detr)/2*den + + CGAL::Sign sign1 = CGAL_NTS sign(FT(2)*den - detq - detr); + if ( + (CGAL_NTS sign(detq) == CGAL_NTS sign(den) || CGAL_NTS sign(detq)== ZERO) && + (CGAL_NTS sign(detr) == CGAL_NTS sign(den) || CGAL_NTS sign(detr)== ZERO) && + ( sign1 == POSITIVE || sign1 == ZERO )) { // inside or on boundary + if ( CGAL_NTS sign(detq) != ZERO && + CGAL_NTS sign(detr) != ZERO && + sign1 != ZERO) + return ON_BOUNDED_SIDE; + else return ON_BOUNDARY; + } + return ON_UNBOUNDED_SIDE; +} + + +template +Bounded_side +does_simplex_intersect_weighted_dual_supportC3( + const FT &px, const FT &py, const FT &pz, const FT &pw, + const FT &qx, const FT &qy, const FT &qz, const FT &qw) +{ + // returns true if weighted circumcenter of pq is in + // segment pq or on boundary + FT qpx = qx-px; + FT qpy = qy-py; + FT qpz = qz-pz; + + FT qq = CGAL_NTS square(qpx) + CGAL_NTS square(qpy) + CGAL_NTS square(qpz); + FT dw = pw - qw; + + CGAL::Sign sign1 = CGAL_NTS sign( qq + dw); + CGAL::Sign sign2 = CGAL_NTS sign( qq - dw); + + if( ( sign1 == POSITIVE || sign1 == ZERO ) && + ( sign2 == POSITIVE || sign2 == ZERO )) { // inside or on boundary + if (sign1 != ZERO && sign2 != ZERO) return ON_BOUNDED_SIDE; + else return ON_BOUNDARY; + } + return ON_UNBOUNDED_SIDE; +} + +//------------------------------------------------------------------- +} //namespace CGAL +//------------------------------------------------------------------- + +#endif //CGAL_PREDICATES_ON_WEIGHTED_POINTS_CARTESIAN_3 diff --git a/Triangulation_3_copy_tds/package_info/Triangulation_3/description.txt b/Triangulation_3_copy_tds/package_info/Triangulation_3/description.txt new file mode 100644 index 00000000000..ac759ef683c --- /dev/null +++ b/Triangulation_3_copy_tds/package_info/Triangulation_3/description.txt @@ -0,0 +1,3 @@ +Package Triangulation_3 : +triangulation data structure, triangulation, Delaunay triangulation and +regular triangulation for dimension <= 3 diff --git a/Triangulation_3_copy_tds/package_info/Triangulation_3/maintainer b/Triangulation_3_copy_tds/package_info/Triangulation_3/maintainer new file mode 100644 index 00000000000..fec7225a53c --- /dev/null +++ b/Triangulation_3_copy_tds/package_info/Triangulation_3/maintainer @@ -0,0 +1 @@ +Monique Teillaud diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/data/regular_remove_3 b/Triangulation_3_copy_tds/test/Triangulation_3/data/regular_remove_3 new file mode 100644 index 00000000000..2787c31e16d --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/data/regular_remove_3 @@ -0,0 +1,83 @@ +5 +0 0 0 1 +1 0 0 1 +0 1 0 1 +0 0 0 0 +0 0 1 1 + +4 +0 0 0 1 +1 0 0 0 +0 0 0 1 +0 1 0 1 + +3 +0 0 0 1 +0 0 0 0 +1 0 0 0 + +5 +9 8 1 6 +3 9 4 8 +1 4 0 2 +0 3 0 9 +0 3 0 5 + +6 +0 3 0 5 +6 9 6 1 +0 8 0 1 +2 1 9 5 +0 3 0 9 +3 5 1 9 + +2 +7 9 9 4 +7 9 9 1 + +13 +0 6 5 1 +6 0 3 2 +7 1 3 2 +3 8 5 7 +7 7 1 0 +7 1 4 3 +1 7 7 3 +9 2 1 7 +8 8 5 6 +7 7 0 6 +1 8 5 2 +0 9 4 9 +9 2 5 7 + +5 +3 2 0 0 +1 4 7 5 +4 4 1 5 +3 3 0 1 +4 0 1 5 + +4 +0 1 0 0 +0 0 0 0 +1 0 0 0 +0 2 0 2 + +5 +6 0 0 0 +1 0 0 1 +2 0 0 8 +1 0 0 0 +5 0 0 3 + +5 +4 2 0 9 +1 2 0 8 +0 0 0 9 +2 0 0 3 +2 0 0 4 + +2 +0 3 0 5 +0 3 0 9 + diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_circulator.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_circulator.h new file mode 100644 index 00000000000..4fadb97528d --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_circulator.h @@ -0,0 +1,230 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Francois Rebufat (Francois.Rebufat@sophia.inria.fr) +// Monique Teillaud + +#ifndef CGAL_TEST_CLS_CIRCULATOR_C +#define CGAL_TEST_CLS_CIRCULATOR_C + +#include + +template < class Triangulation > +int +_test_circulator( const Triangulation &T ) +{ + typedef typename Triangulation::Finite_edges_iterator Finite_edges_iterator; + typedef typename Triangulation::Edge_iterator Edge_iterator; + typedef typename Triangulation::Vertex_iterator Vertex_iterator; + typedef typename Triangulation::Facet_circulator Facet_circulator; + typedef typename Triangulation::Cell_circulator Cell_circulator; + typedef typename Triangulation::Cell Cell; + typedef typename Triangulation::Vertex Vertex; + typedef typename Triangulation::Vertex_handle Vertex_handle; + typedef typename Triangulation::Cell_handle Cell_handle; + typedef typename Triangulation::Facet Facet; + + int n = 0; + Cell_circulator cc, cc0; + Edge_iterator eit; + Finite_edges_iterator feit; + + // testing incident_cells(edge *); +// for (eit=T.edges_begin(); eit!=T.edges_end(); eit++) + eit=T.edges_begin(); + { + cc0=cc=T.incident_cells(*eit); + + Cell_circulator i = cc0; + CGAL_For_all(i, cc0) { *i; } + + Cell_handle ch = cc0; // Test the conversion. + (void) ch; + do { + assert(cc->has_vertex(eit->first->vertex(eit->second))); + assert(cc->has_vertex(eit->first->vertex(eit->third))); + cc++; n++; + } while (cc != cc0); + } + // test of incident_cells(cellhandle,int,int) and -- + feit=T.finite_edges_begin(); + { + cc0=cc=T.incident_cells(feit->first, feit->second, feit->third); + do { + assert(cc->has_vertex(feit->first->vertex(feit->second))); + assert(cc->has_vertex(feit->first->vertex(feit->third))); + cc--; n++; + } while (cc != cc0); + } + // testing incident_cells(edge *,cell *); and ++ +// for (eit=T.edges_begin(); eit!=T.edges_end(); eit++) + eit=T.edges_begin(); + { + cc0=cc=T.incident_cells(*eit, eit->first); + do { + assert(cc->has_vertex(eit->first->vertex(eit->second))); + assert(cc->has_vertex(eit->first->vertex(eit->third))); + cc++; n++; + } while (cc != cc0); + } + // test of incident_cells(cellhandle,int,int,cellhandle) and -- + feit=T.finite_edges_begin(); + { + cc0=cc=T.incident_cells(feit->first, feit->second, feit->third, + feit->first); + do { + assert(cc->has_vertex(feit->first->vertex(feit->second))); + assert(cc->has_vertex(feit->first->vertex(feit->third))); + cc--; n++; + } while (cc != cc0); + } + // the following is not useful here, it tests iterators more than + // circulators +// for (eit=T.finite_edges_begin(); eit!=T.edges_end(); eit++) +// { +// cc0=cc=T.incident_cells(*eit); +// do { +// cc++; n++; +// } while (cc != cc0); +// } +// for (eit=T.finite_edges_begin(); eit!=T.edges_end(); eit++) +// { +// cc0=cc=T.incident_cells(*eit, eit->first); +// do { +// cc++; n++; +// } while (cc != cc0); +// } + + std::vector cells; + std::vector vertices_old; + std::vector vertices; + std::vector facets; + + Vertex_handle vh = T.vertices_begin(); + + T.incident_cells(vh, std::back_inserter(cells)); + // old name (up to CGAL 3.4) + // kept for backwards compatibility but not documented + T.incident_vertices(vh, std::back_inserter(vertices_old)); + // correct name + T.adjacent_vertices(vh, std::back_inserter(vertices)); + T.incident_facets(vh, std::back_inserter(facets)); + + for(typename std::vector::const_iterator cit = cells.begin(), + end = cells.end(); + cit != end; ++cit) + assert((*cit)->has_vertex(vh)); + + for(typename std::vector::const_iterator fit = facets.begin(), + end = facets.end(); + fit != end; ++fit) + { + assert( (fit->first)->has_vertex(vh) ); + assert( fit->second != (fit->first)->index(vh) ); + } + + Facet_circulator fc, fc0, fc1; + assert(fc1 == 0); + int i,j; + // for (eit=T.edges_begin(); eit!=T.edges_end(); eit++) + eit=T.edges_begin(); // test (edge) + { + fc0=fc=T.incident_facets(*eit); + do { + assert(fc->first->has_vertex(eit->first->vertex(eit->second), i)); + assert(fc->first->has_vertex(eit->first->vertex(eit->third), j)); + assert(fc->second == T.next_around_edge(i, j) ); + fc++; n++; + } while (fc != fc0); + } + // for (eit=T.edges_begin(); eit!=T.edges_end(); eit++) + feit=T.finite_edges_begin(); // test (cell*,int,int) + { + fc0=fc=T.incident_facets(feit->first, feit->second, feit->third); + do { + assert(fc->first->has_vertex(feit->first->vertex(feit->second), i)); + assert(fc->first->has_vertex(feit->first->vertex(feit->third), j)); + assert(fc->second == T.next_around_edge(i, j) ); + fc--; n++; + } while (fc != fc0); + } +// int fi; + // for (eit=T.edges_begin(); eit!=T.edges_end(); eit++) + eit=T.edges_begin(); // test (edge, Cell*,int) + { +// for (fi=0; fi!=4 ; fi++) +// { +// if (t.dimension()==2) {fi=3;} + fc0=fc=T.incident_facets(*eit, eit->first, + T.next_around_edge(eit->second, eit->third)); + do { + assert(fc->first->has_vertex(eit->first->vertex(eit->second), i)); + assert(fc->first->has_vertex(eit->first->vertex(eit->third), j)); + assert(fc->second == T.next_around_edge(i, j) ); + fc++; n++; + } while (fc != fc0); +// } + } + // for (eit=T.edges_begin(); eit!=T.edges_end(); eit++) + feit=T.finite_edges_begin(); // test (Cell*,int,int,cell*,int) + { + fc0=fc=T.incident_facets(feit->first, feit->second, feit->third, + feit->first, + T.next_around_edge(feit->second, feit->third)); + do { + assert(fc->first->has_vertex(feit->first->vertex(feit->second), i)); + assert(fc->first->has_vertex(feit->first->vertex(feit->third), j)); + assert(fc->second == T.next_around_edge(i, j) ); + fc--; n++; + } while (fc != fc0); + } + + eit=T.edges_begin(); // test (edge, Facet) + { +// for (fi=0; fi!=4 ; fi++) +// { +// if (t.dimension()==2) {fi=3;} + fc0=fc=T.incident_facets(*eit, std::make_pair( eit->first, + T.next_around_edge(eit->second, + eit->third)) ); + do { + assert(fc->first->has_vertex(eit->first->vertex(eit->second), i)); + assert(fc->first->has_vertex(eit->first->vertex(eit->third), j)); + assert(fc->second == T.next_around_edge(i, j) ); + fc++; n++; + } while (fc != fc0); +// } + } + // for (eit=T.edges_begin(); eit!=T.edges_end(); eit++) + feit=T.finite_edges_begin(); // test (Cell*,int,int,Facet) + { + fc0=fc=T.incident_facets(feit->first, feit->second, feit->third, + std::make_pair( feit->first, + T.next_around_edge(feit->second, + feit->third)) ); + do { + assert(fc->first->has_vertex(feit->first->vertex(feit->second), i)); + assert(fc->first->has_vertex(feit->first->vertex(feit->third), j)); + assert(fc->second == T.next_around_edge(i, j) ); + fc--; n++; + } while (fc != fc0); + } + + return n; +} + +#endif // CGAL_TEST_CLS_CIRCULATOR_C diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h new file mode 100644 index 00000000000..c2d403fb754 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_delaunay_3.h @@ -0,0 +1,1196 @@ +// Copyright (c) 1998-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Francois Rebufat, Monique Teillaud, Sylvain Pion +// Mariette Yvinec + +#ifndef CGAL_TEST_CLS_DELAUNAY_C +#define CGAL_TEST_CLS_DELAUNAY_C + +#include +#include +#include +#include +#include + +#include "_test_cls_iterator.h" +#include "_test_cls_circulator.h" +#include "_test_remove_cluster.h" + +#include + +// Accessory set of functions to differentiate between +// Delaunay::nearest_vertex[_in_cell] and +// Regular::nearest_power_vertex[_in_cell]. + +template < typename T, typename Weighted_tag = typename T::Weighted_tag > +struct Test_location_policy { + typedef typename T::Location_policy Location_policy; +}; + +template < typename T > +struct Test_location_policy { + struct Location_policy{}; +}; + +template < typename T, typename P > +typename T::Vertex_handle +nearest_vertex(const T&t, const P&p, CGAL::Tag_true) +{ + return t.nearest_power_vertex(p); +} + +template < typename T, typename P > +typename T::Vertex_handle +nearest_vertex(const T&t, const P&p, CGAL::Tag_false) +{ + return t.nearest_vertex(p); +} + +template < typename T, typename P > +typename T::Vertex_handle +nearest_vertex(const T&t, const P&p) +{ + return nearest_vertex(t, p, typename T::Weighted_tag()); +} + +template < typename T, typename P > +typename T::Vertex_handle +nearest_vertex_in_cell(const T&t, const P&p, const typename T::Cell_handle c, CGAL::Tag_true) +{ + return t.nearest_power_vertex_in_cell(p, c); +} + +template < typename T, typename P > +typename T::Vertex_handle +nearest_vertex_in_cell(const T&t, const P&p, const typename T::Cell_handle c, CGAL::Tag_false) +{ + return t.nearest_vertex_in_cell(p, c); +} + +template < typename T, typename P > +typename T::Vertex_handle +nearest_vertex_in_cell(const T&t, const P&p, const typename T::Cell_handle c) +{ + return nearest_vertex_in_cell(t, p, c, typename T::Weighted_tag()); +} + +// Template meta programming if. +template < typename Cond, typename Then, typename Else > +struct If; + +template < typename Then, typename Else > +struct If +{ + typedef Then type; +}; + +template < typename Then, typename Else > +struct If +{ + typedef Else type; +}; + +template < typename T, typename P > +void test_conflicts(T& T3_13, const P *q) +{ + typedef T Cls; + typedef typename Cls::Locate_type Locate_type; + typedef typename Cls::Vertex_handle Vertex_handle; + typedef typename Cls::Cell_handle Cell_handle; + typedef typename Cls::Facet Facet; + + for (int i=0; i<22; ++i) { + if (T3_13.dimension() < 2) + T3_13.insert(q[i]); + else { + // First locate the point. + Locate_type lt; + int li, lj; + Cell_handle c = T3_13.locate(q[i], lt, li, lj); + if (lt == Cls::VERTEX) // Already exist, skip. + continue; + if (lt == Cls::OUTSIDE_AFFINE_HULL) { // Increases dimension. + T3_13.insert_outside_affine_hull(q[i]); + continue; + } + // Get the stuff in conflicts. + std::vector C; + std::vector F; + std::vector V; + + T3_13.vertices_on_conflict_zone_boundary(q[i], c, std::back_inserter(V)); +#ifndef CGAL_NO_DEPRECATED_CODE + // test deprecated vertices_in_conflict + std::vector V2; + T3_13.vertices_in_conflict(q[i], c, std::back_inserter(V2)); + assert(V2.size() == V.size()); +#endif + + T3_13.find_conflicts(q[i], c, std::back_inserter(F), + std::back_inserter(C)); + + if (T3_13.dimension() == 3) + assert(F.size() == 2*V.size() - 4); // Euler relation. + if (T3_13.dimension() == 2) + assert(F.size() == V.size()); + + if (i%2 == 0) + T3_13.insert_in_hole(q[i], C.begin(), C.end(), + F.begin()->first, F.begin()->second); + else { + // alternately test the overload which takes a Vertex_handle. + Vertex_handle v = T3_13.tds().create_vertex(); + T3_13.insert_in_hole(q[i], C.begin(), C.end(), + F.begin()->first, F.begin()->second, v); + } + } + } +} + +template +void +_test_cls_delaunay_3(const Triangulation &) +{ + typedef Triangulation Cls; + + typedef typename Test_location_policy::Location_policy Location_policy; + + // We assume the traits class has been tested already + // actually, any traits is good if it has been tested + + // typedef typename Cls::Point Point; // Delaunay + // typedef typename Cls::Point::Point Point; // Regular + typedef typename If::type::Point Point; + + typedef typename Cls::Segment Segment; + typedef typename Cls::Triangle Triangle; + typedef typename Cls::Tetrahedron Tetrahedron; + + typedef typename Cls::Vertex Vertex; + typedef typename Cls::Cell Cell; + typedef typename Cls::Facet Facet; + typedef typename Cls::Edge Edge; + + typedef typename Cls::size_type size_type; + + typedef typename Cls::Vertex_handle Vertex_handle; + typedef typename Cls::Cell_handle Cell_handle; + typedef typename Cls::Vertex_iterator Vertex_iterator; + typedef typename Cls::Cell_iterator Cell_iterator; + typedef typename Cls::Locate_type Locate_type; + typedef std::list list_point; + + typedef typename Cls::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Cls::Finite_cells_iterator Finite_cells_iterator; + + + // +++ We define now some points for building triangulations +++++// + +// list of Points for T1_0 , T1_1, T1_2 : + + + Point p[5]= + { Point(0,0,0),Point(0,0,1),Point(0,0,2),Point(0,0,3),Point(0,0,4)}; + list_point l1; + int i; + for (i=0;i<5;i++) + l1.push_back(p[i]); + + Point pp[5] = { Point(0,0,0),Point(0,0,4),Point(0,0,1),Point(0,0,2),Point(0,0,3)}; + list_point l2; + for (i=0;i<5;i++) + l2.push_back(pp[i]); + + Point ppp[5] ={Point(0,0,1),Point(0,0,2),Point(0,0,3),Point(0,0,0),Point(0,0,4)}; + list_point l3; + for (i=0;i<5;i++) + l3.push_back(ppp[i]); + +// Points for T2_0 : + Point p1=Point(5,5,0); + Point p2=Point(4,4,0); + Point p3=Point(6,6,0); // 1- dimensional until this point + Point p4=Point(5,3,0); // 2-dimensional + Point p5=Point(5,7,0); + Point p6=Point(5,4,0); + Point p7=Point(5,6,0); + Point p8=Point(0,0,0); + Point p9=Point(5,5,0); + + // Points for T3_1 : + Point q[22] = + { + Point(0,0,0), Point(4,4,0), Point(0,4,0), Point(4,0,0), + Point(1,3,1), Point(3,1,1), Point(3,3,1), Point(1,1,1), Point(2,2,2), + Point(1,3,3), Point(3,1,3), Point(3,3,3), Point(1,1,3), + Point(0,0,4), Point(4,4,4), Point(0,4,4), Point(4,0,4), + Point(1,3,5), Point(3,1,5), Point(3,3,5), Point(1,1,5), Point(2,2,6)}; + + // Points for T3_2 : + + list_point lp; + int a, b, d; +// for (a=0;a!=10;a++) +// for (b=0;b!=10;b++) +// for (d=0;d!=10;d++) +// lp.push_back(Point(a*b-d*a + (a-b)*10 +a ,a-b+d +5*b, +// a*a-d*d+b)); + + for (a=0;a!=10;a++) + for (b=0;b!=10;b++) + for (d=0;d!=5;d++) + lp.push_back(Point(a*b-d*a + (a-b)*10 +a ,a-b+d +5*b, + a*a-d*d+b)); + + // Points for T3_2 : + + list_point lp2; + for (a=0;a!=4;a++) + for (b=0;b!=4;b++) + for (d=0;d!=4;d++) + lp2.push_back(Point((a*b-d*a)*10 +a ,(a-b+d +5*b)*100, + a*a-d*d-b)); + + //######################################################################## + + + /**************CONSTRUCTORS (1)*********************/ + /************** and I/O ****************************/ + + std::cout << " Constructor " << std::endl; + // Begining with an empty triangulation and adding point until reaching + // 3-dimentional triangulation. + Cls T0; + assert(T0.dimension() == -1); + assert(T0.number_of_vertices() == 0); + assert(T0.is_valid()); + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT1("Test1_triangulation_IO_3",std::ios::out); + oFileT1 << T0; + } + std::ifstream iFileT1("Test1_triangulation_IO_3",std::ios::in); + iFileT1 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == -1); + assert(Tfromfile.number_of_vertices() == 0); + } + + std::cout << " Constructor1 " << std::endl; + Point p10(0,0,0); + Vertex_handle v0=T0.insert(p10); + assert(T0.dimension() == 0); + assert(T0.number_of_vertices() == 1); + assert(T0.is_valid()); + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT2("Test2_triangulation_IO_3",std::ios::out); + oFileT2 << T0; + } + std::ifstream iFileT2("Test2_triangulation_IO_3",std::ios::in); + iFileT2 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == 0); + assert(Tfromfile.number_of_vertices() == 1); + } + + std::cout << " Constructor2 " << std::endl; + + Point p11(100,100,0); + v0=T0.insert(p11); + assert(T0.dimension() == 1); + assert(T0.number_of_vertices() == 2); + assert(T0.is_valid()); + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT3("Test3_triangulation_IO_3",std::ios::out); + oFileT3 << T0; + } + std::ifstream iFileT3("Test3_triangulation_IO_3",std::ios::in); + iFileT3 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == 1); + assert(Tfromfile.number_of_vertices() == 2); + } + + std::cout << " Constructor3 " << std::endl; + + Point p12(100,-100,0); + v0=T0.insert(p12); + assert(T0.dimension() == 2); + assert(T0.number_of_vertices() == 3); + assert(T0.is_valid()); + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT4("Test4_triangulation_IO_3",std::ios::out); + oFileT4 << T0; + } + std::ifstream iFileT4("Test4_triangulation_IO_3",std::ios::in); + iFileT4 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == 2); + assert(Tfromfile.number_of_vertices() == 3); + } + + std::cout << " Constructor4 " << std::endl; + + Point p13(50,0,100); + v0=T0.insert(p13); + assert(T0.dimension() == 3); + assert(T0.number_of_vertices() == 4); + assert(T0.is_valid()); + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT5("Test5_triangulation_IO_3",std::ios::out); + oFileT5 << T0; + } + std::ifstream iFileT5("Test5_triangulation_IO_3",std::ios::in); + iFileT5 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == 3); + assert(Tfromfile.number_of_vertices() == 4); + } + + std::cout << " Constructor5 " << std::endl; + + Point p14(50,0,100); + v0=T0.insert(p14); + assert(T0.dimension() == 3); + assert(T0.number_of_vertices() == 4); + assert(T0.is_valid()); + + // copy constructor + Cls T1(T0); + assert(T1.dimension() == 3); + assert(T1.number_of_vertices() == 4); + assert(T1.is_valid()); + + T1.clear(); + assert(T1.dimension() == -1); + assert(T1.number_of_vertices() == 0); + assert(T1.is_valid()); + + + + // Affectation : + T1=T0; + assert(T1.dimension() == 3); + assert(T1.number_of_vertices() == 4); + assert(T1.is_valid()); + T1.clear(); + + + T1.swap(T0); + assert(T1.dimension() == 3); + assert(T1.number_of_vertices() == 4); + assert(T1.is_valid()); + assert(T0.dimension() == -1); + assert(T0.number_of_vertices() == 0); + assert(T0.is_valid()); + T0.swap(T1); + + assert(T0.dimension() == 3); + assert(T0.number_of_vertices() == 4); + assert(T0.is_valid()); + assert(T1.dimension() == -1); + + // Building some psychotics triangulations : + std::cout << " Constructor6 " << std::endl; + // triangulation 1-dimensional : vertical line. + Cls T1_0; + size_type n = T1_0.insert(l1.begin(),l1.end()); + assert(n==5); + assert(T1_0.dimension()==1); + assert(T1_0.number_of_vertices()==n); + assert(T1_0.is_valid()); + std::cout << " Constructor7 " << std::endl; + Cls T1_1; + n = T1_1.insert(l2.begin(),l2.end()); + assert(n==5); + assert(T1_1.dimension()==1); + assert(T1_1.number_of_vertices()==n); + assert(T1_1.is_valid()); + std::cout << " Constructor8 " << std::endl; + Cls T1_2; + n = T1_2.insert(l3.begin(),l3.end()); + assert(n==5); + assert(T1_2.dimension()==1); + assert(T1_2.number_of_vertices()==n); + assert(T1_2.is_valid()); + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT6("Test6_triangulation_IO_3",std::ios::out); + oFileT6 << T1_2; + } + std::ifstream iFileT6("Test6_triangulation_IO_3",std::ios::in); + iFileT6 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == 1); + assert(Tfromfile.number_of_vertices() == n); + } + + std::cout << " Constructor9 " << std::endl; + // 2-dimensional triangulations + + Cls T2_0; + v0=T2_0.insert(p1); + + v0=T2_0.insert(p2); + + v0=T2_0.insert(p3); + + assert(T2_0.is_valid()); + assert(T2_0.dimension()==1); + assert(T2_0.number_of_vertices()==3); + + + v0=T2_0.insert(p4); + assert(T2_0.is_valid()); + assert(T2_0.dimension()==2); + assert(T2_0.number_of_vertices()==4); + + + v0=T2_0.insert(p5); + v0=T2_0.insert(p6); + v0=T2_0.insert(p7); + v0=T2_0.insert(p8); + v0=T2_0.insert(p9); + + assert(T2_0.is_valid()); + assert(T2_0.dimension()==2); + assert(T2_0.number_of_vertices()==8); + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT7("Test7_triangulation_IO_3",std::ios::out); + oFileT7 << T2_0; + } + std::ifstream iFileT7("Test7_triangulation_IO_3",std::ios::in); + iFileT7 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == 2); + assert(Tfromfile.number_of_vertices() == 8); + } + + std::cout << " Constructor10 " << std::endl; + // test grid insert + Cls T2_1; + int m; + int px=1, py=1; + int qx=-1, qy=2; + Point qq[400]; + for (m=0; m<20; m++) + for (n=0; n<20; n++) + { + qq[m+20*n] = Point(m*px+(int)n*qx, m*py+(int)n*qy, 1); + T2_1.insert( qq[m+20*n] ); + } + assert( T2_1.number_of_vertices() == m*n ); + assert( T2_1.dimension()==2 ); + assert( T2_1.is_valid() ); + + std::cout << " Constructor11 " << std::endl; + // 3-dimensional triangulations + // This is a simple grid : + int x,y,z; + Cls T3_0; + Point r[225]; + for (z=0 ; z<5 ; z++) + for (y=0 ; y<5 ; y++) + for (x=0 ; x<5 ; x++) + { + r[x+5*y+25*z] = Point(x,y,z); + v0=T3_0.insert(r[x+5*y+25*z]); + } + assert(T3_0.is_valid()); + assert(T3_0.number_of_vertices()==125); + assert(T3_0.dimension()==3); + + if (del) { + std::cout << " deletion in Delaunay - grid case - (dim 3) " << + std::endl; + Cls Tdel( T3_0 ); + + std::vector vertices; + for (Finite_vertices_iterator vi = Tdel.finite_vertices_begin(); + vi != Tdel.finite_vertices_end(); ++vi) + vertices.push_back(vi); + + size_type n = Tdel.number_of_vertices(); + size_type m = Tdel.remove(vertices.begin(), vertices.end()); + assert(m == n - Tdel.number_of_vertices()); + assert(Tdel.is_valid(false)); + std::cout << " successfull" << std::endl; + } + + + std::cout << " Constructor12 " << std::endl; + Cls T3_1; + for (i=0;i<22;i++) + T3_1.insert(q[i]); + assert(T3_1.is_valid()); + assert(T3_1.number_of_vertices()==22); + assert(T3_1.dimension()==3); + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT8("Test8_triangulation_IO_3",std::ios::out); + oFileT8 << T3_1; + } + std::ifstream iFileT8("Test8_triangulation_IO_3",std::ios::in); + iFileT8 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == 3); + assert(Tfromfile.number_of_vertices() == 22); + } + + // Testing find_conflicts(), vertices_on_conflict_zone_boundary(), insert_in_hole() + // FIXME : Note that we do not test the version of find_conflicts() + // which returns the internal facets too... + std::cout << " Testing find_conflicts/vertices_on_conflict_zone_boundary/insert_in_hole" + << std::endl; + Cls T3_13; + + test_conflicts(T3_13, q); + + assert(T3_13.is_valid()); + assert(T3_13.number_of_vertices()==22); + assert(T3_13.dimension()==3); + +#ifndef CGAL_NO_DEPRECATED_CODE + { + std::cout << " Testing move_point()" << std::endl; + Cls T; + std::list L; + for (i=0; i<22; ++i) + L.push_back(T.insert(q[i])); + assert(T.is_valid()); + assert(T.number_of_vertices()==22); + assert(T.dimension()==3); + + for (i=0; i<100; ++i) { + assert(!L.empty()); + Vertex_handle v = L.front(); + L.pop_front(); + size_type nbv = T.number_of_vertices(); + L.push_back(T.move_point(v, q[(3*i)%22])); + + if (nbv != T.number_of_vertices()) + L.pop_back(); // it means we move onto an already existing point. + + assert(T.is_valid()); + assert(T.number_of_vertices()<=22); + } + } +#endif + + { + std::cout << " Testing move()" << std::endl; + Cls T; + std::list L; + for (i=0; i<22; ++i) + L.push_back(T.insert(q[i])); + assert(T.is_valid()); + assert(T.number_of_vertices()==22); + assert(T.dimension()==3); + + for (i=0; i<100; ++i) { + assert(!L.empty()); + Vertex_handle v = L.front(); + L.pop_front(); + size_type nbv = T.number_of_vertices(); + L.push_back(T.move(v, q[(3*i)%22])); + + if (nbv != T.number_of_vertices()) + L.pop_back(); // it means we move onto an already existing point. + + assert(T.is_valid()); + assert(T.number_of_vertices()<=22); + } + } + + { + std::cout << " Testing nearest_vertex()" << std::endl; + // We do a nearest_vertex() and two nearest_vertex_in_cell() + // queries on all points with integer coordinate + // in the cube [-1;6]^3. In each case we check explicitely that the + // output is correct by comparing distance to other vertices. + Cell_handle c1 = T3_13.finite_cells_begin(); + Cell_handle c2 = T3_13.infinite_vertex()->cell(); + for (int x = -1; x < 7; ++x) + for (int y = -1; y < 7; ++y) + for (int z = -1; z < 7; ++z) { + Point p(x, y, z); + Vertex_handle v = nearest_vertex(T3_13, p); + for (typename Cls::Finite_vertices_iterator + fvit = T3_13.finite_vertices_begin(); + fvit != T3_13.finite_vertices_end(); ++fvit) + assert(CGAL::squared_distance(p, v->point()) <= + CGAL::squared_distance(p, fvit->point())); + Vertex_handle v1 = nearest_vertex_in_cell(T3_13, p, c1); + int i1 = c1->index(v1); + for(int i=0; i<4; ++i) { + if (i != i1) + assert(CGAL::squared_distance(p, v1->point()) <= + CGAL::squared_distance(p, c1->vertex(i)->point())); + } + Vertex_handle v2 = nearest_vertex_in_cell(T3_13, p, c2); + int i2 = c2->index(v2); + for(int i=0; i<4; ++i) { + if (i != i2 && c2->vertex(i) != T3_13.infinite_vertex()) + assert(CGAL::squared_distance(p, v2->point()) <= + CGAL::squared_distance(p, c2->vertex(i)->point())); + } + } + } + + { + Cls Tfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT8("Test13_triangulation_IO_3",std::ios::out); + oFileT8 << T3_13; + } + std::ifstream iFileT8("Test13_triangulation_IO_3",std::ios::in); + iFileT8 >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == 3); + assert(Tfromfile.number_of_vertices() == 22); + } + + + //####################################################################### + std::cout << " list insertion"<< std::endl; + Cls T3_2_1; + T3_2_1.insert(lp2.begin(),lp2.end()); + assert(T3_2_1.is_valid()); + + assert(T3_2_1.dimension()==3); + // assert(T3_2.number_of_vertices()==1000); + std::cout << " end of insertion " << std::endl; + + std::cout << " insertion of located point"<< std::endl; + Locate_type lt; + int li, lj; + Cell_handle ch = T3_2_1.locate(p7,lt,li,lj); + T3_2_1.insert(p7,lt,ch,li,lj); + + assert(T3_2_1.is_valid()); + assert(T3_2_1.dimension()==3); + + // Same as above but using the template ctor. + std::cout << " template constructor"<< std::endl; + Cls T3_2_2(lp2.begin(), lp2.end()); + assert(T3_2_2.is_valid()); + + assert(T3_2_2.dimension()==3); + std::cout << " end of insertion " << std::endl; + + //######################################################################## + + + std::cout << " 500 points insertion"<< std::endl; + Cls T3_2; + typename list_point::iterator it; + int count = 0 ; + std::cout << " number of inserted points : " ; + for (it=lp.begin(); it!=lp.end();it++){ + count++; + T3_2.insert(*it); + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + if (count < 1000) + std::cout << count << '\b' << '\b' << '\b' ; + else + std::cout << count << std::endl; + std::cout.flush(); + } + std::cout << std::endl; + assert(T3_2.is_valid()); + assert(T3_2.dimension()==3); + assert(T3_2.number_of_vertices()==500); + + + + Point p110(-5,5,0), p111(-2,-5,2), p112(-2,-9,6), p113(4,8,9), p114(5,-6,0), + p115(3,0,5), p116(-9,0,-10), p117(1,6,-2), p118(-3,2,-4), p119(3,-3,-1); + Cls T3_5; + v0=T3_5.insert(p110); + v0=T3_5.insert(p111); + v0=T3_5.insert(p112); + v0=T3_5.insert(p113); + v0=T3_5.insert(p114); + v0=T3_5.insert(p115); + v0=T3_5.insert(p116); + v0=T3_5.insert(p117); + v0=T3_5.insert(p118); + v0=T3_5.insert(p119); + + assert(T3_5.is_valid()); + assert(T3_5.number_of_vertices()==10); + + // %%%%%%%%%% deletion in Delaunay + if (del) { + std::cout << " deletion in a 10 points Delaunay triangulation"; + Vertex_handle v; + while ( T3_5.number_of_vertices() >= 1 ) { + if ( T3_5.dimension() == 3 ) + v = T3_5.infinite_cell()->vertex + ( (T3_5.infinite_cell()->index( T3_5.infinite_vertex() ) +1 )&3 ); + else if ( T3_5.dimension() == 2 ) + v = T3_5.infinite_cell()->vertex + ( (T3_5.infinite_cell()->index( T3_5.infinite_vertex() ) +1 )%3 ); + else if ( T3_5.dimension() == 1 ) + v = T3_5.infinite_cell()->vertex + ( (T3_5.infinite_cell()->index( T3_5.infinite_vertex() ) +1 )%2 ); + else + v = T3_5.infinite_cell()->neighbor(0)->vertex(0); + + T3_5.remove( v ); + } + assert(T3_5.is_valid(false)); + } + std::cout << " done" << std::endl; + +// // Test random triangulation : + +// Cls T3_4; +// CGAL::Random random; +// for (n=1;n<50;n++) { +// x=random.get_int(-500,500); +// y=random.get_int(-500,500); +// z=random.get_int(-500,500); +// v0=T3_4.insert(Point(x,y,z)); +// } +// assert(T3_4.is_valid()); +// assert(T3_4.dimension()==3); +// assert(T3_4.is_valid()); + +// // %%%%%%%%%% deletion in Delaunay +// bool success(true); +// if (del) { +// std::cout << " deletion in a Delaunay of " +// << T3_4.number_of_vertices() << " random points"; +// Vertex_handle v; +// while ( T3_4.number_of_vertices() >= 1 ) { +// if ( T3_4.dimension() > 1 ) +// v = T3_4.infinite_cell()->vertex +// ( (T3_4.infinite_cell()->index( T3_4.infinite_vertex() ) +1 )&3 ); +// else +// if ( T3_4.dimension() == 1 ) +// v = T3_4.infinite_cell()->vertex +// ( (T3_4.infinite_cell()->index( T3_4.infinite_vertex() ) +1 )%2 ); +// else +// v = T3_4.infinite_cell()->neighbor(0)->vertex(0); + +// success = T3_4.remove( v ); +// } +// if (success) assert(T3_4.is_valid(false)); +// } +// std::cout << " done" << std::endl; + + // Iterator and circulator test + + Cls T0_1; + Point p28(1,3,5); + v0=T0_1.insert(p28); + + { + std::cout << " Testing Iterator "<< std::endl; + _test_vertex_iterator(T0_1); + _test_triangulation_iterator(T0_1); + _test_vertex_iterator(T0); + _test_triangulation_iterator(T0); + _test_vertex_iterator(T2_0); + _test_triangulation_iterator(T2_0); + _test_vertex_iterator(T1_0); + _test_triangulation_iterator(T1_0); + _test_vertex_iterator(T3_1); + _test_triangulation_iterator(T3_1); + _test_vertex_iterator(T3_0); + _test_triangulation_iterator(T3_0); + _test_vertex_iterator(T3_2); + _test_triangulation_iterator(T3_2); + + + std::cout << " Testing Circulator "<< std::endl; + _test_circulator(T0); + _test_circulator(T3_1); + _test_circulator(T3_0); + _test_circulator(T3_2); + } + + + std::cout << " Test is_Gabriel " << std::endl; + Point q0(0.,0.,0.); + Point q1(2.,0.,0.); + Point q2(0.,2.,0.); + Point q3(0.,0.,2.); + Cls T4; + v0 = T4.insert(q0); + Vertex_handle v1 = T4.insert(q1); + Vertex_handle v2 = T4.insert(q2, v1); // testing with the hint + Vertex_handle v3 = T4.insert(q3, v2->cell()); // testing with the hint + Cell_handle c; + int j,k,l; + assert(T4.is_facet(v0,v1,v2,c,j,k,l)); + i = 6 - (j+k+l); + Facet f = std::make_pair(c,i); + assert(T4.is_Gabriel(c,i)); + assert(T4.is_Gabriel(f)); + assert(T4.is_facet(v1,v2,v3,c,j,k,l)); + i = 6 - (j+k+l); + assert(!T4.is_Gabriel(c,i)); + assert(T4.is_edge(v0,v1,c,i,j)); + assert(T4.is_Gabriel(c,i,j)); + Edge e = make_triple(c,i,j); + assert(T4.is_Gabriel(e)); + assert(T4.is_edge(v2,v3,c,i,j)); + assert(T4.is_Gabriel(c,i,j)); + + std::cout <<" Test dual (minimal test for now)" << std::endl; + + // We only test return types and instantiation, basically. + { + Cell_handle c = T4.finite_cells_begin(); + Point p = T4.dual(c); + Facet f = Facet(c, 2); + CGAL::Object o = T4.dual(f); + o = T4.dual(f.first, f.second); + } + + std::cout <<" Test destructors and quit "<< std::endl; + + T0.clear(); + assert(T0.is_valid()); + T3_0.clear(); + assert(T3_0.is_valid()); + assert(T3_0.dimension()==-1); + assert(T3_0.number_of_vertices()==0); + + // "Determinism" test : + // Triangulations built with the same order of input points + // must have the same order of the vertex and cell iterator. + { + Cls Ta (q, q+22), Tb(q, q+22); + assert(Ta == Tb); + for (Finite_vertices_iterator ita = Ta.finite_vertices_begin(), + itb = Tb.finite_vertices_begin(), + end = Ta.finite_vertices_end(); + ita != end; ++ita, ++itb) + assert(ita->point() == itb->point()); + for (Finite_cells_iterator ita = Ta.finite_cells_begin(), + itb = Tb.finite_cells_begin(), + end = Ta.finite_cells_end(); + ita != end; ++ita, ++itb) { + assert(ita->vertex(0)->point() == itb->vertex(0)->point()); + assert(ita->vertex(1)->point() == itb->vertex(1)->point()); + assert(ita->vertex(2)->point() == itb->vertex(2)->point()); + assert(ita->vertex(3)->point() == itb->vertex(3)->point()); + } + } + + /**********************/ + /******* MOVE *********/ + std::cout << " displacements" << std::endl; + + std::cout << " degenerate cases: " << std::endl; + + Cls TM_0; + Vertex_handle tmv1 = TM_0.insert(Point(0,0,0)); + Vertex_handle tmv2 = TM_0.insert(Point(0,1,0)); + + TM_0.move_if_no_collision(tmv1, Point(0, 2, 1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + TM_0.move_if_no_collision(tmv1, Point(0, 0, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + Vertex_handle tmv3 = TM_0.insert(Point(0,2,1)); + + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv3, Point(0, 2, 2)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv3, Point(0, 2, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + Vertex_handle tmv4 = TM_0.insert(Point(0,1,1)); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv3, Point(1, 1, 1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 3); + + TM_0.move_if_no_collision(tmv3, Point(4, 2, 1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 3); + + TM_0.move_if_no_collision(tmv3, Point(0, 2, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv4, Point(0, 2, 1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv4, Point(0, 2, -1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv4, Point(0, 3, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + TM_0.move_if_no_collision(tmv3, Point(0, 1, 1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv3, Point(0, -1, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + TM_0.move_if_no_collision(tmv2, Point(0, -1, 0, 2)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + TM_0.move_if_no_collision(tmv2, Point(0, -1, 0, 4)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + TM_0.move_if_no_collision(tmv2, Point(0, -1, 0, 2)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + TM_0.move_if_no_collision(tmv2, Point(0, -1, 1, 2)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv1, Point(0, 0, 2)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv1, Point(0, 0, 1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv1, Point(0, 0, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + assert(TM_0.move_if_no_collision(tmv1, Point(0, 3, 0)) != tmv1); + + TM_0.move_if_no_collision(tmv1, Point(0, 0, 1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv4, Point(0, 1, 2)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + TM_0.move_if_no_collision(tmv4, Point(0, 3, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv1, Point(0, 2, 3)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv4, Point(0, 1, 2)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 1); + + Vertex_handle tmv5 = TM_0.insert(Point(0,2,0)); + Vertex_handle tmv6 = TM_0.insert(Point(1,0,0)); + assert(TM_0.dimension() == 3); + + TM_0.move_if_no_collision(tmv6, Point(0, 0, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv6, Point(2, 0, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 3); + + TM_0.move_if_no_collision(tmv6, Point(2, 1, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 3); + + TM_0.move_if_no_collision(tmv6, Point(0, 99, 99)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv6, Point(2, 1, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 3); + + TM_0.move_if_no_collision(tmv6, Point(2, 2, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 3); + + TM_0.move_if_no_collision(tmv6, Point(-2, 2, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 3); + + TM_0.move_if_no_collision(tmv6, Point(0, 1, 1)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 2); + + TM_0.move_if_no_collision(tmv6, Point(-2, 2, 0)); + assert(TM_0.tds().is_valid()); + assert(TM_0.is_valid()); + assert(TM_0.dimension() == 3); + + std::cout << " random 1D: " << std::endl; + Cls TM_1; + // non-degenerate cases + std::list points; + for(int count=0; count<50; count++) { + points.push_back(Point(0, 0, rand()%30000)); + } + TM_1.insert(points.begin(), points.end()); + Vertex_handle vTM_1; + for(int i=0; i<2; i++) { + for(typename Cls::Finite_vertices_iterator + fvi = TM_1.finite_vertices_begin(); + fvi != TM_1.finite_vertices_end(); fvi++) { + Point p = Point(0, 0, rand()%30000); + vTM_1 = TM_1.move_if_no_collision(fvi, p); + assert(TM_1.is_valid()); + } + } + assert(TM_1.is_valid()); + + std::cout << " random 2D: " << std::endl; + Cls TM_2; + // non-degenerate cases + points.clear(); TM_2.clear(); + for(int count=0; count<10; count++) { + points.push_back(Point(0, rand()%30000, rand()%30000)); + } + TM_2.insert(points.begin(), points.end()); + Vertex_handle vTM_2; + for(int i=0; i<2; i++) { + for(typename Cls::Finite_vertices_iterator + fvi = TM_2.finite_vertices_begin(); + fvi != TM_2.finite_vertices_end(); fvi++) { + Point p = Point(0, rand()%30000, rand()%30000); + vTM_2 = TM_2.move_if_no_collision(fvi, p); + assert(TM_2.is_valid()); + } + } + assert(TM_2.is_valid()); + + std::cout << " random 3D: " << std::endl; + Cls TM_3; + // non-degenerate cases + points.clear(); TM_3.clear(); + for(int count=0; count<50; count++) { + points.push_back(Point(rand()%30000, rand()%30000, rand()%30000)); + } + TM_3.insert(points.begin(), points.end()); + + assert(TM_3.is_valid()); + + Vertex_handle vTM_3; + for(int i=0; i<2; i++) { + for(typename Cls::Finite_vertices_iterator + fvi = TM_3.finite_vertices_begin(); + fvi != TM_3.finite_vertices_end(); fvi++) { + Point p = Point(rand()%30000, rand()%30000, rand()%30000); + vTM_3 = TM_3.move_if_no_collision(fvi, p); + assert(TM_3.is_valid()); + } + } + + // A simple test to see if move return the good vertex + // when there is a collision + assert(TM_3.move(TM_3.finite_vertices_begin(), vTM_3->point()) == vTM_3); + + // Test remove cluster + { + _test_remove_cluster(); + } + +} + +#endif // CGAL_TEST_CLS_DELAUNAY_C diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_iterator.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_iterator.h new file mode 100644 index 00000000000..015c8f845eb --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_iterator.h @@ -0,0 +1,210 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Francois Rebufat (Francois.Rebufat@sophia.inria.fr) + +#ifndef CGAL_TEST_CLS_ITERATOR_C +#define CGAL_TEST_CLS_ITERATOR_C + +template < class Triangulation > +typename Triangulation::size_type +_test_vertex_iterator( const Triangulation &T ) +{ + typedef typename Triangulation::size_type size_type; + typedef typename Triangulation::Vertex Vertex; + typedef typename Triangulation::Vertex_handle Vertex_handle; + typedef typename Triangulation::Cell_handle Cell_handle; + typedef typename Triangulation::Vertex_iterator Vertex_iterator; + typedef typename Triangulation::Finite_vertices_iterator + Finite_vertices_iterator; + size_type n = 0; + + for (Vertex_iterator vit = T.vertices_begin(); vit != T.vertices_end(); ++vit) + { + Vertex_handle vh = vit; // Test the conversion. + n++; + const Vertex & v = *vit; // Test operator*; + Cell_handle c = vit->cell(); // Test operator->; + (void) vh; + (void) v; + (void) c; + } + assert( n-1 == T.number_of_vertices() ); + n=0; + for (Finite_vertices_iterator fvit = T.finite_vertices_begin(); + fvit != T.finite_vertices_end(); ++fvit) + { + Vertex_handle vh = fvit; // Test the conversion. + const Vertex & v = *fvit; // Test operator*; + Cell_handle c = fvit->cell(); // Test operator->; + n++; + (void) vh; + (void) v; + (void) c; + } + assert( n == T.number_of_vertices() ); + + // Test Backward-ness of the iterators. + n=0; + for (Vertex_iterator vit = T.vertices_end(); vit != T.vertices_begin(); --vit) + { + Vertex_handle vh = vit; // Test the conversion. + (void) vh; + n++; + } + assert( n-1 == T.number_of_vertices() ); + n=0; + for (Finite_vertices_iterator fvit = T.finite_vertices_end(); + fvit != T.finite_vertices_begin(); --fvit) + { + Vertex_handle vh = fvit; // Test the conversion. + (void) vh; + n++; + } + assert( n == T.number_of_vertices() ); + + return n; +} + +template < class Triangulation > +int +_test_triangulation_iterator( const Triangulation &T ) +{ + typedef typename Triangulation::Finite_cells_iterator Finite_cells_iterator; + typedef typename Triangulation::Finite_facets_iterator Finite_facets_iterator; + typedef typename Triangulation::Finite_edges_iterator Finite_edges_iterator; + typedef typename Triangulation::Finite_vertices_iterator Finite_vertices_iterator; + + typedef typename Triangulation::Cell_iterator Cell_iterator; + typedef typename Triangulation::Facet_iterator Facet_iterator; + typedef typename Triangulation::Edge_iterator Edge_iterator; + typedef typename Triangulation::Vertex_iterator Vertex_iterator; + + typedef typename Triangulation::Cell Cell; + typedef typename Triangulation::Facet Facet; + typedef typename Triangulation::Edge Edge; + typedef typename Triangulation::Vertex Vertex; + typedef typename Triangulation::Cell_handle Cell_handle; + + int n=0 , m=0 , f=0 , t=0; + Cell_iterator Cit; + Facet_iterator Fit; + Edge_iterator Eit; + Vertex_iterator Vit; + Finite_cells_iterator FCit; + Finite_facets_iterator FFit; + Finite_edges_iterator FEit; + Finite_vertices_iterator FVit; + for (Cit = T.tds().raw_cells_begin(); Cit != T.tds().raw_cells_end(); ++Cit) { + Cell_handle ch = Cit; + (void) ch; + } + if (T.dimension()==3) { + for (FCit = T.finite_cells_begin(); FCit != T.finite_cells_end(); ++FCit) + { + Cell_handle ch = FCit; // Test the conversion. + const Cell & c = *FCit; // Test operator*. + Cell_handle ch2 = FCit->neighbor(0); // Test operator->. + (void) ch; + (void) c; + (void) ch2; + t++; + } + for (FFit = T.finite_facets_begin(); FFit != T.finite_facets_end(); ++FFit) { + const Facet & f2 = *FFit; // Test operator*. + Cell_handle ch = FFit->first; // Test operator->. + (void) f2; + (void) ch; + f++; + } + for (FEit = T.finite_edges_begin(); FEit != T.finite_edges_end(); ++FEit) { + const Edge & e = *FEit; // Test operator*. + Cell_handle ch = FEit->first; // Test operator->. + (void) e; + (void) ch; + m++; + } + for (FVit = T.finite_vertices_begin(); FVit != T.finite_vertices_end(); ++FVit) { + const Vertex & v = *FVit; // Test operator*. + Cell_handle ch = FVit->cell(); // Test operator->. + (void) v; + (void) ch; + n++; + } + // Test Backward-ness of the iterators. + for (FCit = T.finite_cells_end(); FCit != T.finite_cells_begin(); --FCit) ; + for (FFit = T.finite_facets_end(); FFit != T.finite_facets_begin(); --FFit) ; + for (FEit = T.finite_edges_end(); FEit != T.finite_edges_begin(); --FEit) ; + for (FVit = T.finite_vertices_end(); FVit != T.finite_vertices_begin(); --FVit) ; + + assert((n-m+f-t)==1); + n=0 ; m=0 ; f=0 ; t=0; + for (Cit = T.cells_begin(); Cit != T.cells_end(); ++Cit) + { + Cell_handle ch = Cit; // Test the conversion. + (void) ch; + t++; + } + for (Fit = T.facets_begin(); Fit != T.facets_end(); ++Fit) + f++; + for (Eit = T.edges_begin(); Eit != T.edges_end(); ++Eit) + m++; + for (Vit = T.vertices_begin(); Vit != T.vertices_end(); ++Vit) + n++; + assert((n-m+f-t)==0); + } + if (T.dimension()==3) + { + Finite_cells_iterator Cit2; + FCit = T.finite_cells_begin(); + Cit2=FCit; + assert(T.tetrahedron(FCit)==T.tetrahedron(Cit2)); + FCit++ ; FCit-- ; ++FCit ; --FCit ; + assert(FCit==Cit2); + assert(T.tetrahedron(FCit)==T.tetrahedron(Cit2)); + } + if (T.dimension() >=2) + { + Finite_facets_iterator Fit2; + FFit = T.finite_facets_begin(); + Fit2=FFit; + assert(*FFit==*Fit2); + FFit++ ; FFit-- ; ++FFit ; --FFit ; + assert(FFit==Fit2); + assert(*FFit==*Fit2); + } + if (T.dimension() >=1) + { + Finite_edges_iterator Eit2; + FEit = T.finite_edges_begin(); + Eit2=FEit; + assert(*FEit==*Eit2); + FEit++ ; FEit-- ; ++FEit ; --FEit ; + assert(FEit==Eit2); + assert(*FEit==*Eit2); + } + Finite_vertices_iterator Vit2; + FVit = T.finite_vertices_begin(); + Vit2=FVit; + assert(FVit->point()==Vit2->point()); + FVit++ ; FVit-- ; ++FVit ; --FVit ; + assert(FVit==Vit2); + assert(FVit->point()==Vit2->point()); + return(n-m+f-t); +} + +#endif // CGAL_TEST_CLS_ITERATOR_C diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_regular_3.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_regular_3.h new file mode 100644 index 00000000000..13f0f0a3b1a --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_regular_3.h @@ -0,0 +1,210 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Monique Teillaud (Monique.Teillaud@sophia.inria.fr) + +// This stuff is not used (obsolete) at the moment. +#if 0 +#include +#include +#include + +template +void +_test_cls_regular_3(const Triangulation &) +{ + typedef Triangulation Cls; + typedef typename Triangulation::Traits Tr; + typedef typename Tr::Traits_base Tb; + + typedef typename Tb::Point Bare_point; + // We assume the traits class has been tested already + // actually, any traits is good if it has been tested + // typedef typename Cls::Bare_point Point; + typedef typename Cls::Weighted_point Weighted_point; + + typedef std::list list_point; + + // temporary version + + int n,m; + int count = 0 ; + + std::cout << " test dimension 1 " << std::endl; + Cls T1; + std::cout << " number of inserted points : " ; + for ( m=0; m<5; m++) { + if ( (m%2)== 0 ) + T1.insert( Weighted_point( Point( 2*m,0,0 ), 2 ) ); + else T1.insert( Weighted_point( Point( -2*m+1,0,0 ), 2 ) ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + assert( T1.is_valid() ); + std::cout << std::endl << " number of vertices : " + << T1.number_of_vertices() << std::endl; + + std::cout << " number of inserted points : " ; + for ( m=0; m<5; m++) { + if ( (m%2)== 0 ) + T1.insert( Weighted_point( Point( 2*m+1,0,0 ), 5 ) ); + else T1.insert( Weighted_point( Point( -2*m+1,0,0 ), 5 ) ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + assert( T1.is_valid() ); + std::cout << std::endl << " number of vertices : " + << T1.number_of_vertices() << std::endl; + + std::cout << " number of inserted points : " ; + for ( m=0; m<10; m++) { + if ( (m%2)== 0 ) + T1.insert( Weighted_point( Point( m,0,0 ), 1 ) ); + else T1.insert( Weighted_point( Point( -m,0,0 ), 1 ) ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + assert( T1.is_valid() ); + std::cout << std::endl << " number of vertices : " + << T1.number_of_vertices() << std::endl; + assert( T1.dimension()==1 ); + + std::cout << " test dimension 2 " << std::endl; + std::cout << " number of inserted points : " ; + Cls T2; + + count = 0 ; + int px=1, py=1; + int qx=-1, qy=2; + for (m=0; m<10; m++) + for (n=0; n<10; n++) { + T2.insert( Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), 1 ) ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + for (m=10; m<20; m++) + for (n=0; n<10; n++) { + T2.insert( Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), -1 ) ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + for (m=0; m<10; m++) + for (n=10; n<20; n++) { + T2.insert( Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), -2 ) ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + for (m=10; m<20; m++) + for (n=10; n<20; n++) { + T2.insert( Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), 5 ) ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + + std::cout << std::endl << " number of vertices : " + << T2.number_of_vertices() << std::endl; + assert( T2.dimension()==2 ); + assert( T2.is_valid() ); + + // dimension 3 + std::cout << " test dimension 3" << std::endl; + Cls T; + + list_point lp; + int a, b, d; + for (a=0;a!=10;a++) + for (b=0;b!=10;b++) + for (d=0;d!=10;d++) + lp.push_back(Weighted_point( Point(a*b-d*a + (a-b)*10 +a , + a-b+d +5*b, + a*a-d*d+b), + a*b-a*d) ); + list_point::iterator it; + count = 0 ; + std::cout << " number of inserted points : " ; + for (it=lp.begin(); it!=lp.end();it++){ + count++; + T.insert(*it); + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + if (count < 1000) + std::cout << count << '\b' << '\b' << '\b' ; + else + std::cout << count << std::endl; + std::cout.flush(); + } + + std::cout << " number of vertices : " + << T.number_of_vertices() << std::endl; + assert(T.is_valid()); + assert(T.dimension()==3); +} + +#endif diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_regular_euclidean_traits_3.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_regular_euclidean_traits_3.h new file mode 100644 index 00000000000..710cbe43d35 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_regular_euclidean_traits_3.h @@ -0,0 +1,241 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// $Date$ + +// Author(s) : Mariette Yvinec + +template +void +_test_cls_regular_euclidean_traits_3 (const Traits & ) +{ + typedef typename Traits::Weighted_point Weighted_point; + typedef typename Traits::Bare_point Bare_point; + typedef typename Traits::Power_test_3 Power_test_3; + typedef typename Traits::Compare_power_distance_3 + Compare_power_distance_3; + typedef typename Traits::In_smallest_orthogonal_sphere_3 + In_smallest_orthogonal_sphere_3; + typedef typename Traits::Side_of_bounded_orthogonal_sphere_3 + Side_of_bounded_orthogonal_sphere_3; + typedef typename Traits::Does_simplex_intersect_dual_support_3 + Does_simplex_intersect_dual_support_3; + typedef typename Traits::Construct_weighted_circumcenter_3 + Construct_weighted_circumcenter_3; + typedef typename Traits::Compute_power_product_3 + Compute_power_product_3; + typedef typename Traits:: + Compute_squared_radius_smallest_orthogonal_sphere_3 + Compute_squared_radius_smallest_orthogonal_sphere_3; + + typedef typename Traits:: + Compute_critical_squared_radius_3 + Compute_critical_squared_radius_3; + + Traits traits; + Power_test_3 power_test = traits.power_test_3_object(); + Compare_power_distance_3 compare_power_distance = + traits.compare_power_distance_3_object(); + In_smallest_orthogonal_sphere_3 in_smallest_orthogonal_sphere = + traits.in_smallest_orthogonal_sphere_3_object(); + Side_of_bounded_orthogonal_sphere_3 side_of_bounded_orthogonal_sphere = + traits.side_of_bounded_orthogonal_sphere_3_object(); + Does_simplex_intersect_dual_support_3 does_simplex_intersect_dual_support = + traits.does_simplex_intersect_dual_support_3_object(); + Construct_weighted_circumcenter_3 weighted_circumcenter = + traits.construct_weighted_circumcenter_3_object(); + Compute_power_product_3 power_product = + traits.compute_power_product_3_object(); + Compute_squared_radius_smallest_orthogonal_sphere_3 + squared_radius_smallest_orthogonal_sphere = + traits.compute_squared_radius_smallest_orthogonal_sphere_3_object(); + Compute_critical_squared_radius_3 critical_squared_radius = + traits.compute_critical_squared_radius_3_object(); + + + // test of Does_simplex_intersect_dual_support_3 + std::cout << "test of Does_simplex_intersect_dual_support_3" << std::endl; + Bare_point p0(0.,0.,0.); + Bare_point p1(3.,0.,0.); + Bare_point p2(0.,3.,0.); + Bare_point p3(0.,0.,3.); + + Weighted_point wp0(p0,9.); + Weighted_point wp1(p1,9.); + Weighted_point wp2(p2,9.); + Weighted_point wp3(p3,9.); + Weighted_point wp01(p0,6.); + Weighted_point wp02(p0,3.); + Weighted_point wp03(p0,12.); + Weighted_point wp04(p0,18.); + Weighted_point wp05(p0,24.); + + assert(does_simplex_intersect_dual_support(wp0,wp1,wp2,wp3) + == CGAL::ON_UNBOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp1,wp0,wp2,wp3) + == CGAL::ON_UNBOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp01,wp1,wp2,wp3) + == CGAL::ON_BOUNDARY); + assert(does_simplex_intersect_dual_support(wp01,wp2,wp1,wp3) + == CGAL::ON_BOUNDARY); + assert(does_simplex_intersect_dual_support(wp02,wp1,wp2,wp3) + == CGAL::ON_BOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp2,wp1,wp02,wp3) + == CGAL::ON_BOUNDED_SIDE); + + assert(does_simplex_intersect_dual_support(wp0,wp1,wp2) + == CGAL::ON_BOUNDARY); + assert(does_simplex_intersect_dual_support(wp1,wp0,wp2) + == CGAL::ON_BOUNDARY); + assert(does_simplex_intersect_dual_support(wp01,wp1,wp2) + == CGAL::ON_BOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp01,wp2,wp1) + == CGAL::ON_BOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp03,wp1,wp2) + == CGAL::ON_UNBOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp2,wp1,wp03) + == CGAL::ON_UNBOUNDED_SIDE); + + assert(does_simplex_intersect_dual_support(wp0,wp1) + == CGAL::ON_BOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp1,wp0) + == CGAL::ON_BOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp04,wp1) + == CGAL::ON_BOUNDARY); + assert(does_simplex_intersect_dual_support(wp1,wp04) + == CGAL::ON_BOUNDARY); + assert(does_simplex_intersect_dual_support(wp05,wp1) + == CGAL::ON_UNBOUNDED_SIDE); + assert(does_simplex_intersect_dual_support(wp1,wp05) + == CGAL::ON_UNBOUNDED_SIDE); + + // test of Construct_weighted_circumcenter_3 and compare_power_distance + std::cout << "test of Construct_weighted_circumcenter_3" << std::endl; + std::cout << "test Of Compare_power_distance_3" << std::endl; + Bare_point c ; + c = weighted_circumcenter(wp0,wp1,wp2,wp3); + assert (compare_power_distance(c,wp0,wp1) == CGAL::EQUAL); + assert (compare_power_distance(c,wp01,wp1) == CGAL::LARGER); + assert (compare_power_distance(c,wp03,wp1) == CGAL::SMALLER); + + c = weighted_circumcenter(wp01,wp1,wp2,wp3); + assert (compare_power_distance(c,wp01,wp2) == CGAL::EQUAL); + + c = weighted_circumcenter(wp02,wp1,wp2,wp3); + assert (compare_power_distance(c,wp02,wp3) == CGAL::EQUAL); + + // test In_smallest_orthogonal_sphere_3 + // test Side_of_bounded_orthogonal_sphere_3 + std::cout << " test In_smallest_orthogonal_sphere_3" << std::endl; + std::cout << " test Side_of_bounded_orthogonal_sphere_3" << std::endl; + Bare_point q0(0.,0.,0.); + Bare_point q1(2.,0.,0.); + Bare_point q2(0.,2.,0.); + Bare_point q3(0.,0.,2.); + Bare_point q4(2.,2.,2.); + + Weighted_point wq0(q0,0.); + Weighted_point wq1(q1,0.); + Weighted_point wq2(q2,0.); + Weighted_point wq3(q3,0.); + Weighted_point wq4(q4,0.); + Weighted_point wq01(q0,2.); + Weighted_point wq11(q1,2.); + Weighted_point wq21(q2,2.); + Weighted_point wq31(q3,2.); + Weighted_point wq41(q4,2.); + + typedef typename Traits::FT FT; + FT ww02 = FT(2)/FT(3); + Weighted_point wq02(q0, ww02); + + + assert(in_smallest_orthogonal_sphere(wq0, wq1, wq2) + == CGAL::POSITIVE); + assert(in_smallest_orthogonal_sphere(wq1, wq0, wq2) + == CGAL::POSITIVE); + assert(in_smallest_orthogonal_sphere(wq1, wq2, wq0) + == CGAL::ZERO); + assert(in_smallest_orthogonal_sphere(wq1, wq2, wq01) + == CGAL::NEGATIVE); + assert(in_smallest_orthogonal_sphere(wq2, wq1, wq01) + == CGAL::NEGATIVE); + assert(in_smallest_orthogonal_sphere(wq11, wq21, wq0) + == CGAL::POSITIVE); + assert(in_smallest_orthogonal_sphere(wq21, wq11, wq0) + == CGAL::POSITIVE); + assert(side_of_bounded_orthogonal_sphere(wq21, wq11, wq0) + == CGAL::ON_UNBOUNDED_SIDE); + + + assert(in_smallest_orthogonal_sphere(wq0, wq1, wq2, wq3) + == CGAL::POSITIVE); + assert(in_smallest_orthogonal_sphere(wq1, wq0, wq2, wq3) + == CGAL::POSITIVE); + assert(side_of_bounded_orthogonal_sphere(wq1, wq0, wq2, wq3) + == CGAL::ON_UNBOUNDED_SIDE); + assert(in_smallest_orthogonal_sphere(wq1, wq2, wq3, wq0) + == CGAL::NEGATIVE); + assert(in_smallest_orthogonal_sphere(wq1, wq3, wq2, wq0) + == CGAL::NEGATIVE); + assert(in_smallest_orthogonal_sphere(wq11, wq21, wq31, wq02) + == CGAL::ZERO); + assert(in_smallest_orthogonal_sphere(wq31, wq21, wq11, wq02) + == CGAL::ZERO); + + + assert(in_smallest_orthogonal_sphere(wq0, wq1, wq2, wq3, wq4) + == CGAL::ZERO); + assert(in_smallest_orthogonal_sphere(wq1, wq0, wq2, wq3, wq4) + == CGAL::ZERO); + assert(in_smallest_orthogonal_sphere(wq01, wq11, wq21, wq31, wq4) + == CGAL::POSITIVE); + assert(in_smallest_orthogonal_sphere(wq01, wq21, wq11, wq31, wq4) + == CGAL::POSITIVE); + assert(in_smallest_orthogonal_sphere(wq0, wq1, wq2, wq3, wq41) + == CGAL::NEGATIVE); + assert(in_smallest_orthogonal_sphere(wq0, wq1, wq3, wq2, wq41) + == CGAL::NEGATIVE); + assert(side_of_bounded_orthogonal_sphere(wq0, wq1, wq3, wq2, wq41) + == CGAL::ON_BOUNDED_SIDE); + + + // test weighted_circumcenter + // test squared_radius_smallest_orthogonal_sphere + // test critical_squared_radius + std::cout << "test of squared_radius_smallest_orthogonal_sphere" + << std::endl; + std::cout << "test of critical_squared_radius" << std::endl; + Weighted_point wc( + weighted_circumcenter(wq11,wq21,wq31,wq41), + squared_radius_smallest_orthogonal_sphere(wq11,wq21,wq31,wq41)); + Weighted_point wt(Bare_point(1.,1.,1.), 0.); + // this test requires a weighted point with a zero weight + assert( power_product(wc,wt) == + critical_squared_radius(wq11,wq21,wq31,wq41,wt)); + + wc = Weighted_point( + weighted_circumcenter(wp0,wp1,wp2,wp3), + squared_radius_smallest_orthogonal_sphere(wp0,wp1,wp2,wp3)); + assert( power_product(wc,wt) == + critical_squared_radius(wp0,wp1,wp2,wp3,wt)); + + wc = Weighted_point( + weighted_circumcenter(wp01,wp1,wp2,wp3), + squared_radius_smallest_orthogonal_sphere(wp01,wp1,wp2,wp3)); + assert( power_product(wc,wt) == + critical_squared_radius(wp01,wp1,wp2,wp3,wt)); + +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_3.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_3.h new file mode 100644 index 00000000000..21a2663f2e9 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_3.h @@ -0,0 +1,323 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Francois Rebufat +// Monique Teillaud + +#include +#include +#include + +#include "_test_cls_tds_vertex.h" +#include "_test_cls_tds_cell.h" + +#include +#include + +template +void +_test_cls_tds_3( const Tds &) +{ + typedef typename Tds::Vertex_range Vertex_range; + typedef typename Tds::Cell_range Cell_range; + + typedef typename Tds::Vertex Vertex; + typedef typename Tds::Cell Cell; + typedef typename Tds::Edge Edge; + typedef typename Tds::Facet Facet; + + typedef typename Tds::Vertex_handle Vertex_handle; + typedef typename Tds::Vertex_iterator Vertex_iterator; + typedef typename Tds::Facet_iterator Facet_iterator; + typedef typename Tds::Edge_iterator Edge_iterator; + typedef typename Tds::Cell_handle Cell_handle; + typedef typename Tds::Cell_iterator Cell_iterator; + + // test rebinds : + typedef CGAL::Triangulation_cell_base_with_info_3 New_cell_base; + // I can't rebind the vertex that easily as the with_info needs a Point... :( + // so let's fake a rebind vertex. + // typedef CGAL::Triangulation_vertex_base_with_info_3 New_vertex_base; + + typedef typename Tds::template Rebind_vertex::Other New_TDS_1; + typedef typename New_TDS_1::template Rebind_cell::Other New_TDS; + + // test Vertex and cell : + std::cout << " Test Vertex " << std::endl; + _test_vertex_tds_3(Vertex()); + + std::cout << " Test Cell " << std::endl; + _test_cell_tds_3(Tds()); + + std::cout << " Testing TDS " << std::endl; + + // Test constructors + std::cout << " constructors" << std::endl; + Tds tds1; + Tds tds2; + + // Test I/O for dimension -2 + // the other dimensions are not tested here + // (they are implicitely tested in triangulation) + Tds tdsfromfile; + std::cout << " I/O" << std::endl; + { + std::ofstream oFileT("Test_tds_IO_3", std::ios::out); + oFileT << tds1; + } + std::ifstream iFileT("Test_tds_IO_3", std::ios::in); + iFileT >> tdsfromfile; + assert(tdsfromfile.is_valid()); + assert(tdsfromfile.dimension() == -2); + assert(tdsfromfile.number_of_vertices() == 0); + + std::cout << " copy" << std::endl; + tds2.insert_increase_dimension(); + assert( tds2.number_of_vertices() == 1 ); + Tds tds3(tds2); + + Vertex_iterator vit; + vit=tds3.vertices_begin(); + tds3.insert_increase_dimension(vit); + std::cout << "ok" << std::endl; + assert(tds3.is_valid()); + Tds tds4 = tds3; + vit=tds4.vertices_begin(); + tds4.insert_increase_dimension(vit); + std::cout << "ok" << std::endl; + assert(tds4.is_valid()); + Tds tds5; + tds5.swap(tds4); + tds4=tds5; + vit=tds5.vertices_begin(); + tds5.insert_increase_dimension(vit); + std::cout << "ok" << std::endl; + assert(tds5.is_valid()); + Tds tds6; + tds6.swap(tds5); + tds5=tds6; + vit=tds6.vertices_begin(); + tds6.insert_increase_dimension(vit); + std::cout << "ok" << std::endl; + assert(tds6.is_valid()); + + std::cout << " Insert are tested in test_triangulation_3 " << std::endl; + + std::cout << " Iterator and circulator are tested in test_triangulation_3 " << std::endl; + + // Access functions + + assert(tds1.dimension()==-2); + assert(tds2.dimension()==-1); + assert(tds3.dimension()==0); + assert(tds4.dimension()==1); + assert(tds5.dimension()==2); + assert(tds6.dimension()==3); + + assert(tds3.number_of_vertices()==2); + + // Containers + Vertex_range & vertex_c = tds3.vertices(); + Cell_range & cell_c = tds3.cells(); + + assert(vertex_c.size() == 2); + assert(cell_c.size() == 2); + + // Flips + std::cout << " Test flip " << std::endl; + assert(tds6.is_valid()); + Cell_iterator cit, cdone; + int nbflips=0; + int i; + cit = tds6.cells_begin(); + tds6.insert_in_cell(cit); + cit = tds6.cells_begin(); + tds6.insert_in_cell(cit); + cit = tds6.cells_begin(); + tds6.insert_in_cell(cit); + assert(tds6.number_of_vertices()==8); +// std::cout << tds6.number_of_cells()<< " cells" << std::endl; + + // We can't use the Cell_iterator while we modify the TDS. + // However, we can store all Cell_handles beforehand, + // since 2-3 flips do not affect the validity of existing cells. + std::vector Cell_v; + for (cit = tds6.cells_begin(); cit != tds6.cells_end(); ++cit) + Cell_v.push_back(cit); + + for (typename std::vector::const_iterator ccit = Cell_v.begin(); + ccit != Cell_v.end(); ++ccit) { + for ( i=0; i<4; i++ ) { + assert(tds6.is_valid()); + assert(tds6.is_cell(*ccit)); + // old name (up to CGAL 3.4) + // kept for backwards compatibility but not documented + std::set< Vertex_handle > set_of_vertices_old; + tds6.incident_vertices( (*ccit)->vertex(i), + std::inserter(set_of_vertices_old, + set_of_vertices_old.begin() ) ); + if ( set_of_vertices_old.find(tds6.mirror_vertex(*ccit, i)) + == set_of_vertices_old.end() ) { + nbflips++; + tds6.flip_flippable( *ccit, i ); + assert(tds6.is_valid()); +// if ( tds6.flip( cit, i ) ) { +// tds6.is_valid(true); +// nbflips++; +// } + } + // correct name + std::set< Vertex_handle > set_of_vertices; + tds6.adjacent_vertices( (*ccit)->vertex(i), + std::inserter(set_of_vertices, + set_of_vertices.begin() ) ); + if ( set_of_vertices.find(tds6.mirror_vertex(*ccit, i)) + == set_of_vertices.end() ) { + nbflips++; + tds6.flip_flippable( *ccit, i ); + assert(tds6.is_valid()); +// if ( tds6.flip( cit, i ) ) { +// tds6.is_valid(true); +// nbflips++; +// } + } + } + } + + for (typename std::vector::const_iterator ccit = Cell_v.begin(); + ccit != Cell_v.end(); ++ccit) { + for ( i=0; i<4; i++ ) { + std::vector< Vertex_handle > vector_of_vertices_old; + std::vector< Vertex_handle > vector_of_vertices; + std::vector< Edge > vector_of_edges; + + // old name (up to CGAL 3.4) + // kept for backwards compatibility but not documented + tds6.incident_vertices + ( (*ccit)->vertex(i), std::back_inserter(vector_of_vertices_old)); + // correct name + tds6.adjacent_vertices + ( (*ccit)->vertex(i), std::back_inserter(vector_of_vertices)); + + tds6.incident_edges + ( (*ccit)->vertex(i), std::back_inserter(vector_of_edges)); + + assert(vector_of_edges.size() == vector_of_vertices_old.size()); + assert(vector_of_edges.size() == vector_of_vertices.size()); + } + } + + + std::cout << nbflips << " flips 2-3" << std::endl; + assert(tds6.number_of_vertices()==8); +// std::cout << tds6.number_of_cells()<< " cells" << std::endl; + + nbflips=0; + bool flipped; + int j; + cit = tds6.cells_begin(); + cdone = tds6.cells_end(); + Cell_iterator next_cell; + while ( cit != cdone ) { + // NOTE : cells are deleted during loop + // the cell_iterator is modified "by hand" (not using ++) + flipped = false; i=0; j=1; + next_cell = ++cit; --cit; + while ( (! flipped) && (i<4) ) { + if ( (i!=j) ) { + // The Intel compiler has a bug and needs the explicit handle. + Cell_handle ch = cit; + flipped = tds6.flip( ch, i, j ) ; + if (flipped) { + nbflips++; + assert(tds6.is_valid()); + } + } + if ( j==3 ) { i++; j=0; } + else j++; + } + cit = next_cell; + } + std::cout << nbflips << " flips 3-2" << std::endl; + assert(tds6.number_of_vertices()==8); + + // test destructor and return + std::cout << " test destructors and return" << std::endl; + + assert(tds1.is_valid()); + assert(tds2.is_valid()); + assert(tdsfromfile.is_valid()); + assert(tds3.is_valid()); + assert(tds4.is_valid()); + assert(tds5.is_valid()); + assert(tds6.is_valid()); + + std::cout << " test decrease dimension" << std::endl; + Tds tds7; + Vertex_handle v7_0 = tds7.insert_increase_dimension(); + Vertex_handle v7_1 = tds7.insert_increase_dimension(v7_0); + Vertex_handle v7_2 = tds7.insert_increase_dimension(v7_1); + Vertex_handle v7_3 = tds7.insert_increase_dimension(v7_2); + Cell_handle fa = v7_3->cell(); + int i7 = fa->index(v7_3); + tds7.decrease_dimension(fa, i7); + assert(tds7.dimension() == 1); + assert(tds7.is_valid()); + Vertex_handle v7_4 = tds7.insert_increase_dimension(v7_3); + Cell_handle fb = v7_4->cell(); + i7 = fb->index(v7_4); + tds7.decrease_dimension(fb, i7); + assert(tds7.dimension() == 1); + assert(tds7.is_valid()); + Vertex_handle v7_5 = tds7.insert_increase_dimension(v7_4); + assert(tds7.dimension() == 2); + assert(tds7.is_valid()); + Vertex_handle v7_6 = tds7.insert_increase_dimension(v7_5); + assert(tds7.dimension() == 3); + assert(tds7.is_valid()); + Cell_handle fc = v7_6->cell(); + i7 = fc->index(v7_6); + tds7.decrease_dimension(fc, i7); + assert(tds7.dimension() == 2); + assert(tds7.is_valid()); + Vertex_handle v7_7 = tds7.insert_increase_dimension(v7_6); + assert(tds7.dimension() == 3); + assert(tds7.is_valid()); + Cell_handle fd = v7_7->cell(); + i7 = fd->index(v7_7); + tds7.decrease_dimension(fd, i7); + assert(tds7.dimension() == 2); + assert(tds7.is_valid()); + Cell_handle fe = v7_7->cell(); + i7 = fe->index(v7_7); + tds7.insert_in_facet(fe, i7); + assert(tds7.dimension() == 2); + assert(tds7.is_valid()); + Vertex_handle v7_8 = tds7.insert_increase_dimension(v7_7); + assert(tds7.dimension() == 3); + assert(tds7.is_valid()); + Cell_handle ff = v7_8->cell(); + i7 = ff->index(v7_8); + tds7.decrease_dimension(ff, i7); + assert(tds7.dimension() == 2); + assert(tds7.is_valid()); + +// tds1.clear(); +// tds2.clear(); +// tds3.clear(); + +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_cell.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_cell.h new file mode 100644 index 00000000000..ad73e73351c --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_cell.h @@ -0,0 +1,133 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Rebufat Francois (Francois.Rebufat@sophia.inria.fr) + +#include + +template +void +_test_cell_tds_3(const Tds &) +{ + typedef typename Tds::Vertex_handle Vertex_handle; + typedef typename Tds::Cell_handle Cell_handle; + + std::cout << " Cells Tds Constructors " << std::endl; + int ind; + Tds tds; + tds.set_dimension(3); + Vertex_handle v0= tds.create_vertex(); + Vertex_handle v1= tds.create_vertex(); + Vertex_handle v2= tds.create_vertex(); + Vertex_handle v3= tds.create_vertex(); + Cell_handle c1 = tds.create_cell(v0, v1, v2, v3); + assert(c1->has_vertex(v0)); + assert(c1->has_vertex(v1)); + assert(c1->has_vertex(v2)); + assert(c1->has_vertex(v3)); + Cell_handle n0=tds.create_cell(); + Cell_handle n1=tds.create_cell(); + Cell_handle n2=tds.create_cell(); + Cell_handle n3=tds.create_cell(); + Cell_handle c2 = tds.create_cell(v0, v1, v2, v3, n0, n1, n2, n3); + + std::cout << " Access cell's functions " << std::endl; + assert(c2->has_vertex(v0)); + ind=c2->index(v0); + assert(c2->vertex(ind)==v0); + assert(c2->has_vertex(v0, ind)); + + assert(c2->has_vertex(v1)); + ind=c2->index(v1); + assert(c2->vertex(ind)==v1); + assert(c2->has_vertex(v1, ind)); + + assert(c2->has_vertex(v2)); + ind=c2->index(v2); + assert(c2->vertex(ind)==v2); + assert(c2->has_vertex(v2, ind)); + + assert(c2->has_vertex(v3)); + ind=c2->index(v3); + assert(c2->vertex(ind)==v3); + assert(c2->has_vertex(v3, ind)); + + assert(c2->has_neighbor(n0)); + ind=c2->index(n0); + assert(c2->neighbor(ind)==n0); + assert(c2->has_neighbor(n0,ind)); + + assert(c2->has_neighbor(n1)); + ind=c2->index(n1); + assert(c2->neighbor(ind)==n1); + assert(c2->has_neighbor(n1,ind)); + + assert(c2->has_neighbor(n2)); + ind=c2->index(n2); + assert(c2->neighbor(ind)==n2); + assert(c2->has_neighbor(n2,ind)); + + assert(c2->has_neighbor(n3)); + ind=c2->index(n3); + assert(c2->neighbor(ind)==n3); + assert(c2->has_neighbor(n3,ind)); + + std::cout << " setting cell's functions " << std::endl; + c2->set_vertex(0,v1); + c2->set_vertex(1,v2); + c2->set_vertex(2,v3); + c2->set_vertex(3,v0); + assert(c2->index(v0)==3); + assert(c2->index(v1)==0); + assert(c2->index(v2)==1); + assert(c2->index(v3)==2); + // c2->set_vertices(); + // assert(c2->vertex(0)==NULL); + // assert(c2->vertex(1)==NULL); + // assert(c2->vertex(2)==NULL); + // assert(c2->vertex(3)==NULL); + c2->set_vertices(v0, v1, v2, v3); + assert(c2->index(v0)==0); + assert(c2->index(v1)==1); + assert(c2->index(v2)==2); + assert(c2->index(v3)==3); + + c2->set_neighbor(0,n1); + c2->set_neighbor(1,n2); + c2->set_neighbor(2,n3); + c2->set_neighbor(3,n0); + assert(c2->index(n0)==3); + assert(c2->index(n1)==0); + assert(c2->index(n2)==1); + assert(c2->index(n3)==2); + // c2->set_neighbors(); + // assert(c2->neighbor(0)==NULL); + // assert(c2->neighbor(1)==NULL); + // assert(c2->neighbor(2)==NULL); + // assert(c2->neighbor(3)==NULL); + c2->set_neighbors(n0, n1, n2, n3); + assert(c2->index(n0)==0); + assert(c2->index(n1)==1); + assert(c2->index(n2)==2); + assert(c2->index(n3)==3); + + std::cout << " Tds Destructors " << std::endl; + tds.delete_vertex(v0); + tds.delete_vertex(v1); + tds.delete_vertex(v2); + tds.delete_vertex(v3); +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_vertex.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_vertex.h new file mode 100644 index 00000000000..484e4ff08ed --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_tds_vertex.h @@ -0,0 +1,58 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Rebufat Francois + +#include + +template +void +_test_vertex_tds_3(const Vertex &) +{ + typedef typename Vertex::Triangulation_data_structure Tds; + typedef typename Tds::Cell_handle Cell_handle; + typedef typename Tds::Vertex_handle Vertex_handle; + + Tds tds; + + Cell_handle c1 = tds.create_cell(); + Vertex_handle v1 = tds.create_vertex(); + v1->set_cell(c1); + assert(v1->cell() == c1); + c1->set_vertex(0, v1); + assert(tds.is_valid(v1)); + + Cell_handle c2 = tds.create_cell(); + v1->set_cell(c2); + c2->set_vertex(0, v1); + assert(tds.is_valid(v1)); + + // Unicity of the default constructed handle. + Vertex_handle v = Vertex_handle(); + v = Vertex_handle(); + assert(v == Vertex_handle()); + assert(v1 != Vertex_handle()); + + Cell_handle c = Cell_handle(); + c = Cell_handle(); + assert(c == Cell_handle()); + assert(c1 != Cell_handle()); + + // We want the following comparisons to work for use in std::set<>... + bool b1 = v +#include +#include +#include +#include + +#include "_test_cls_iterator.h" +#include "_test_cls_circulator.h" + +#include + +template +void +_test_cls_triangulation_3_input_output(const Triangulation & T, + const char* filename) +{ + const int dim = T.dimension(); + const typename Triangulation::size_type n = T.number_of_vertices(); + std::cout << " I/O" << std::endl; + { + std::ofstream oFile(filename, std::ios::out); + oFile << T; + } + std::ifstream iFile(filename, std::ios::in); + Triangulation Tfromfile; + iFile >> Tfromfile; + assert(Tfromfile.is_valid()); + assert(Tfromfile.dimension() == dim); + assert(Tfromfile.number_of_vertices() == n); + + + std::string filename_bin = filename; + filename_bin = filename_bin + "_binary"; + + const char* filename2 = filename_bin.c_str(); + std::cout << " I/O (binary)" << std::endl; + { + std::ofstream oFileBin(filename2, std::ios::out|std::ios::binary); + CGAL::set_binary_mode(oFileBin); + oFileBin << T; + } + std::ifstream iFileBin(filename2, std::ios::in|std::ios::binary); + CGAL::set_binary_mode(iFileBin); + Triangulation Tfromfile_binary; + iFileBin >> Tfromfile_binary; + assert(Tfromfile_binary.is_valid()); + assert(Tfromfile_binary.dimension() == dim); + assert(Tfromfile_binary.number_of_vertices() == n); +} + +template +void +_test_cls_triangulation_3(const Triangulation &) +{ + typedef Triangulation Cls; + + // We assume the traits class has been tested already + // actually, any traits is good if it has been tested + + typedef typename Cls::Point Point; + typedef typename Cls::Segment Segment; + typedef typename Cls::Triangle Triangle; + typedef typename Cls::Tetrahedron Tetrahedron; + + typedef typename Cls::Vertex Vertex; + typedef typename Cls::Cell Cell; + typedef typename Cls::Facet Facet; + typedef typename Cls::Edge Edge; + + typedef typename Cls::size_type size_type; + typedef typename Cls::difference_type difference_type; + + typedef typename Cls::Vertex_handle Vertex_handle; + typedef typename Cls::Cell_handle Cell_handle; + typedef typename Cls::Vertex_iterator Vertex_iterator; + typedef typename Cls::Cell_iterator Cell_iterator; + // typedef typename Cls::Point_iterator Point_iterator; + typedef typename Cls::Locate_type Locate_type; + typedef std::list list_point; + + typedef typename Cls::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Cls::Finite_edges_iterator Finite_edges_iterator; + typedef typename Cls::Finite_facets_iterator Finite_facets_iterator; + typedef typename Cls::Finite_cells_iterator Finite_cells_iterator; + + + // +++ We define now some points for building triangulations +++++// + +// list of Points for T1_0 , T1_1, T1_2 : + + + Point p[5]= + { Point(0,0,0),Point(0,0,1),Point(0,0,2),Point(0,0,3),Point(0,0,4)}; + list_point l1; + int i; + for (i=0;i<5;i++) + l1.push_back(p[i]); + + Point pp[5] = { Point(0,0,0),Point(0,0,4),Point(0,0,1),Point(0,0,2),Point(0,0,3)}; + list_point l2; + for (i=0;i<5;i++) + l2.push_back(pp[i]); + + Point ppp[5] ={Point(0,0,1),Point(0,0,2),Point(0,0,3),Point(0,0,0),Point(0,0,4)}; + list_point l3; + for (i=0;i<5;i++) + l3.push_back(ppp[i]); + +// Points for T2_0 : + Point p1=Point(5,5,0); + Point p2=Point(4,4,0); + Point p3=Point(6,6,0); // 1- dimensional until this point + Point p4=Point(5,3,0); // 2-dimensional + Point p5=Point(5,7,0); + Point p6=Point(5,4,0); + Point p7=Point(5,6,0); + Point p8=Point(0,0,0); + Point p9=Point(5,5,0); + + // Points for T3_1 : + Point q[22] = + { + Point(0,0,0), Point(4,4,0), Point(0,4,0), Point(4,0,0), + Point(1,3,1), Point(3,1,1), Point(3,3,1), Point(1,1,1), Point(2,2,2), + Point(1,3,3), Point(3,1,3), Point(3,3,3), Point(1,1,3), + Point(0,0,4), Point(4,4,4), Point(0,4,4), Point(4,0,4), + Point(1,3,5), Point(3,1,5), Point(3,3,5), Point(1,1,5), Point(2,2,6)}; + + // Points for T3_2 : + + list_point lp; + int a, b, d; +// for (a=0;a!=10;a++) +// for (b=0;b!=10;b++) +// for (d=0;d!=10;d++) +// lp.push_back(Point(a*b-d*a + (a-b)*10 +a ,a-b+d +5*b, +// a*a-d*d+b)); + + for (a=0;a!=10;a++) + for (b=0;b!=10;b++) + for (d=0;d!=5;d++) + lp.push_back(Point(a*b-d*a + (a-b)*10 +a ,a-b+d +5*b, + a*a-d*d+b)); + + // Points for T3_2 : + + list_point lp2; + for (a=0;a!=4;a++) + for (b=0;b!=4;b++) + for (d=0;d!=4;d++) + lp2.push_back(Point((a*b-d*a)*10 +a ,(a-b+d +5*b)*100, + a*a-d*d-b)); + + //######################################################################## + + + /**************CONSTRUCTORS (1)*********************/ + /************** and I/O ****************************/ + + std::cout << " Constructor " << std::endl; + // Beginning with an empty triangulation and adding points until reaching + // 3-dimensional triangulation. + Cls T0; + assert(T0.dimension() == -1); + assert(T0.number_of_vertices() == 0); + assert(T0.is_valid()); + + if (! del) // to avoid doing the following tests for both Delaunay + // and non Delaunay triangulations + { + _test_cls_triangulation_3_input_output(T0, "Test1_triangulation_IO_3"); + } + + std::cout << " Constructor1 " << std::endl; + Point p10(0,0,0); + Vertex_handle v0=T0.insert(p10); + assert(T0.dimension() == 0); + assert(T0.number_of_vertices() == 1); + assert(T0.is_valid()); + + if (! del) // to avoid doing the following tests for both Delaunay + // and non Delaunay triangulations + { + _test_cls_triangulation_3_input_output(T0, "Test2_triangulation_IO_3"); + } + + std::cout << " Constructor2 " << std::endl; + + Point p11(100,100,0); + v0=T0.insert(p11); + assert(T0.dimension() == 1); + assert(T0.number_of_vertices() == 2); + assert(T0.is_valid()); + + if (! del) // to avoid doing the following tests for both Delaunay + // and non Delaunay triangulations + { + _test_cls_triangulation_3_input_output(T0, "Test3_triangulation_IO_3"); + } + + std::cout << " Constructor3 " << std::endl; + + Point p12(100,-100,0); + v0=T0.insert(p12); + assert(T0.dimension() == 2); + assert(T0.number_of_vertices() == 3); + assert(T0.is_valid()); + + if (! del) // to avoid doing the following tests for both Delaunay + // and non Delaunay triangulations + { + _test_cls_triangulation_3_input_output(T0, "Test4_triangulation_IO_3"); + } + + std::cout << " Constructor4 " << std::endl; + + Point p13(50,0,100); + v0=T0.insert(p13); + assert(T0.dimension() == 3); + assert(T0.number_of_vertices() == 4); + assert(T0.is_valid()); + + if (! del) // to avoid doing the following tests for both Delaunay + // and non Delaunay triangulations + { + _test_cls_triangulation_3_input_output(T0, "Test5_triangulation_IO_3"); + } + + std::cout << " Constructor5 " << std::endl; + + Point p14(50,0,100); + v0=T0.insert(p14); + assert(T0.dimension() == 3); + assert(T0.number_of_vertices() == 4); + assert(T0.is_valid()); + + // copy constructor + Cls T1(T0); + assert(T1.dimension() == 3); + assert(T1.number_of_vertices() == 4); + assert(T1.is_valid()); + + std::cout << " Testing operator==" << std::endl; + assert(T0 == T0); + assert(T0 == T1); + assert(T1 == T0); + assert(T1 == T1); + + T1.clear(); + assert(T1.dimension() == -1); + assert(T1.number_of_vertices() == 0); + assert(T1.is_valid()); + + + + // Assignment + T1=T0; + assert(T1.dimension() == 3); + assert(T1.number_of_vertices() == 4); + assert(T1.is_valid()); + T1.clear(); + + + T1.swap(T0); + assert(T1.dimension() == 3); + assert(T1.number_of_vertices() == 4); + assert(T1.is_valid()); + assert(T0.dimension() == -1); + assert(T0.number_of_vertices() == 0); + assert(T0.is_valid()); + T0.swap(T1); + + assert(T0.dimension() == 3); + assert(T0.number_of_vertices() == 4); + assert(T0.is_valid()); + assert(T1.dimension() == -1); + + // Building some psychotic triangulations : + std::cout << " Constructor6 " << std::endl; + // triangulation 1-dimensional : vertical line. + Cls T1_0; + size_type n = T1_0.insert(l1.begin(),l1.end()); + assert(n==5); + assert(T1_0.dimension()==1); + assert(T1_0.number_of_vertices()==n); + assert(T1_0.is_valid()); + std::cout << " Constructor7 " << std::endl; + Cls T1_1; + n = T1_1.insert(l2.begin(),l2.end()); + assert(n==5); + assert(T1_1.dimension()==1); + assert(T1_1.number_of_vertices()==n); + assert(T1_1.is_valid()); + std::cout << " Constructor8 " << std::endl; + Cls T1_2; + n = T1_2.insert(l3.begin(),l3.end()); + assert(n==5); + assert(T1_2.dimension()==1); + assert(T1_2.number_of_vertices()==n); +// // test for point_iterator +// Point_iterator pit; +// Point pppp; +// int nbpt=0; +// for (pit = T1_2.points_begin(); pit != T1_2.points_end(); ++pit) { +// nbpt++; +// pppp = *pit; +// } +// assert(nbpt==n); + assert(T1_2.is_valid()); + + if (! del) // to avoid doing the following tests for both Delaunay + // and non Delaunay triangulations + { + _test_cls_triangulation_3_input_output(T1_2, "Test6_triangulation_IO_3"); + } + + std::cout << " Constructor9 " << std::endl; + // 2-dimensional triangulations + + Cls T2_0; + v0=T2_0.insert(p1); + + v0=T2_0.insert(p2); + + v0=T2_0.insert(p3); + + assert(T2_0.is_valid()); + assert(T2_0.dimension()==1); + assert(T2_0.number_of_vertices()==3); + + + v0=T2_0.insert(p4); + assert(T2_0.is_valid()); + assert(T2_0.dimension()==2); + assert(T2_0.number_of_vertices()==4); + + + v0=T2_0.insert(p5); + v0=T2_0.insert(p6); + v0=T2_0.insert(p7); + v0=T2_0.insert(p8); + v0=T2_0.insert(p9); + + assert(T2_0.is_valid()); + assert(T2_0.dimension()==2); + assert(T2_0.number_of_vertices()==8); + + if (! del) // to avoid doing the following tests for both Delaunay + // and non Delaunay triangulations + { + _test_cls_triangulation_3_input_output(T2_0, "Test7_triangulation_IO_3"); + } + + std::cout << " Constructor10 " << std::endl; + // test grid insert + Cls T2_1; + int m; + int px=1, py=1; + int qx=-1, qy=2; + Point qq[400]; + for (m=0; m<20; m++) + for (n=0; n<20; n++) + { + qq[m+20*n] = Point(m*px+(int)n*qx, m*py+(int)n*qy, 1); + T2_1.insert( qq[m+20*n] ); + } + assert( T2_1.number_of_vertices() == m*n ); + assert( T2_1.dimension()==2 ); + assert( T2_1.is_valid() ); + + std::cout << " Constructor11 " << std::endl; + // 3-dimensional triangulations + // This is a simple grid : + int x,y,z; + Cls T3_0; + Point r[225]; + for (z=0 ; z<5 ; z++) + for (y=0 ; y<5 ; y++) + for (x=0 ; x<5 ; x++) + { + r[x+5*y+25*z] = Point(x,y,z); + v0=T3_0.insert(r[x+5*y+25*z]); + } + assert(T3_0.is_valid()); + assert(T3_0.number_of_vertices()==125); + assert(T3_0.dimension()==3); + + + std::cout << " Constructor12 " << std::endl; + Cls T3_1; + for (i=0;i<22;i++) + T3_1.insert(q[i]); + assert(T3_1.is_valid()); + assert(T3_1.number_of_vertices()==22); + assert(T3_1.dimension()==3); + + if (! del) // to avoid doing the following tests for both Delaunay + // and non Delaunay triangulations + { + _test_cls_triangulation_3_input_output(T3_1, "Test8_triangulation_IO_3"); + } + + + //####################################################################### + std::cout << " list insertion"<< std::endl; + Cls T3_2_1; + T3_2_1.insert(lp2.begin(),lp2.end()); + assert(T3_2_1.is_valid()); + + assert(T3_2_1.dimension()==3); + // assert(T3_2.number_of_vertices()==1000); + std::cout << " end of insertion " << std::endl; + + // The same using the template constructor. + std::cout << " template ctor"<< std::endl; + Cls T3_2_2(lp2.begin(), lp2.end()); + assert(T3_2_2.is_valid()); + + assert(T3_2_2.dimension()==3); + std::cout << " end of insertion " << std::endl; + + //######################################################################## + + + std::cout << " 500 points insertion"<< std::endl; + Cls T3_2; + typename list_point::iterator it; + int count = 0 ; + std::cout << " number of inserted points : " ; + for (it=lp.begin(); it!=lp.end();it++){ + count++; + T3_2.insert(*it); + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + if (count < 1000) + std::cout << count << '\b' << '\b' << '\b' ; + else + std::cout << count << std::endl; + std::cout.flush(); + } + std::cout << std::endl; + assert(T3_2.is_valid()); + assert(T3_2.dimension()==3); + assert(T3_2.number_of_vertices()==500); + + + + Point p110(-5,5,0), p111(-2,-5,2), p112(-2,-9,6), p113(4,8,9), p114(5,-6,0), + p115(3,0,5), p116(-9,0,-10), p117(1,6,-2), p118(-3,2,-4), p119(3,-3,-1); + Cls T3_5; + v0=T3_5.insert(p110); + v0=T3_5.insert(p111); + v0=T3_5.insert(p112); + v0=T3_5.insert(p113); + v0=T3_5.insert(p114); + v0=T3_5.insert(p115); + v0=T3_5.insert(p116); + v0=T3_5.insert(p117); + v0=T3_5.insert(p118, v0->cell()); // testing with the hint + v0=T3_5.insert(p119, v0); // testing with the hint + + assert(T3_5.is_valid()); + assert(T3_5.number_of_vertices()==10); + +// // Test random triangulation : + +// Cls T3_4; +// CGAL::Random random; +// for (n=1;n<50;n++) { +// x=random.get_int(-500,500); +// y=random.get_int(-500,500); +// z=random.get_int(-500,500); +// v0=T3_4.insert(Point(x,y,z)); +// } +// assert(T3_4.is_valid()); +// assert(T3_4.dimension()==3); +// assert(T3_4.is_valid()); + +// // %%%%%%%%%% deletion in Delaunay +// bool success(true); +// if (del) { +// std::cout << " deletion in a Delaunay of " +// << T3_4.number_of_vertices() << " random points"; +// Vertex_handle v; +// while ( T3_4.number_of_vertices() >= 1 ) { +// if ( T3_4.dimension() > 1 ) +// v = T3_4.infinite_cell()->vertex +// ( (T3_4.infinite_cell()->index( T3_4.infinite_vertex() ) +1 )&3 ); +// else +// if ( T3_4.dimension() == 1 ) +// v = T3_4.infinite_cell()->vertex +// ( (T3_4.infinite_cell()->index( T3_4.infinite_vertex() ) +1 )%2 ); +// else +// v = T3_4.infinite_cell()->neighbor(0)->vertex(0); + +// success = T3_4.remove( v ); +// } +// if (success) assert(T3_4.is_valid(false)); +// } +// std::cout << " done" << std::endl; + + + // Test inserts function separatelly. + + std::cout << " Testing insertions " << std::endl; + Locate_type lt; + int li,lj,i1,i2; + Cls Ti = T0; + Point p20(50,0,50); + v0=Ti.insert_in_cell(p20,Ti.locate(Point(50,0,50))); + assert(Ti.is_valid()); + assert(Ti.number_of_vertices() == 5); + Ti=T0; + Point p120(50,0,0); + v0=Ti.insert_in_facet(p120,Ti.locate(Point(50,0,1)),3); + assert(Ti.is_valid()); + assert(Ti.number_of_vertices() == 5); + Ti=T0; + Point p21(50,0,0); + v0=Ti.insert_in_facet(p21,Facet(Ti.locate(Point(50,0,1)),3)); + assert(Ti.is_valid()); + assert(Ti.number_of_vertices() == 5); + Ti=T0; + Cell_handle c= Ti.locate(Point(0,0,0),lt,li,lj); + assert(lt==Cls::VERTEX); + i1=li; + c= Ti.locate(Point(100,100,0),lt,li,lj); + assert(lt==Cls::VERTEX); + i2=li; + + // testing the locate with hint. + Cell_handle ccc = Ti.locate(Point(100,100,0),c); + assert(c == ccc); + ccc = Ti.locate(Point(100,100,0),c->vertex(0)); + + Point p22(50,50,0); + v0=Ti.insert_in_edge(p22,Ti.locate(Point(50,40,1)),i1,i2); + assert(Ti.is_valid()); + assert(Ti.number_of_vertices() == 5); + + Ti=T0; + c= Ti.locate(Point(0,0,0),lt,li,lj); + assert(lt==Cls::VERTEX); + i1=li; + c= Ti.locate(Point(100,100,0),lt,li,lj); + assert(lt==Cls::VERTEX); + i2=li; + Point p23(50,50,0); + v0=Ti.insert_in_edge(p23,Edge(Ti.locate(Point(50,50,0)),i1,i2)); + assert(Ti.is_valid()); + assert(Ti.number_of_vertices() == 5); + + Ti=T0; + + assert(T0.dimension() == 3); + assert(T0.number_of_vertices() == 4); + assert(T0.is_valid()); + + + c= Ti.locate(Point(50,50,50),lt,li,lj); + + Point p24(50,50,50); + v0= Ti.insert_outside_convex_hull(p24,c); + assert(Ti.is_valid()); + + assert(Ti.number_of_vertices() == 5); + + Cls T3_3=T1_0; + Point p25(2,0,0); + v0=T3_3.insert_outside_affine_hull(p25); + assert(T3_3.is_valid()); + assert(T3_3.dimension()==2); + c= T3_3.locate(Point(4,0,0),lt,li,lj); + Point p26(4,0,0); + v0=T3_3.insert_outside_convex_hull(p26,c); + assert(T3_3.is_valid()); + assert(T3_3.dimension()==2); + Point p27(0,5,0); + v0=T3_3.insert_outside_affine_hull(p27); + assert(T3_3.is_valid()); + assert(T3_3.dimension()==3); + + // ################## Operations + newly created cells ################ + // Small test for inserting and returning the newly created cells + // (the code is mainly the usual insert + incident_{edges,facets,cells} + // depending on the dimension) + + std::cout << " Test insertion + newly created cells: " << std::endl; + + std::cout << " 1 dimension" << std::endl; + // dimension 1 + Cls TAI1; + for(int i=0; i<50; i++) + { + double x = (double) (2*i); + TAI1.insert(Point(x, x, x)); + } + std::list lis_tai1; + for(int i=0; i<51; i++) + { + lis_tai1.clear(); + double x = (double) (2*i - 1); + Vertex_handle taiv = + TAI1.insert_and_give_new_cells( + Point(x, x, x), + std::back_inserter(lis_tai1)); + assert(TAI1.is_valid()); + assert(TAI1.dimension() == 1); + assert(lis_tai1.size() == 2); + while(!lis_tai1.empty()) + { + Cell_handle c = lis_tai1.front(); + lis_tai1.pop_front(); + assert(TAI1.tds().is_simplex(c)); + } + } + TAI1.clear(); + + std::cout << " 2 dimensions" << std::endl; + CGAL::Random grand; + for(int i=0; i<50; i++) + { + double x = grand.get_double(); + double y = grand.get_double(); + TAI1.insert(Point(x, y, 0)); + } + for(int i=0; i<50; i++) + { + lis_tai1.clear(); + double x = grand.get_double(); + double y = grand.get_double(); + Vertex_handle taiv = + TAI1.insert_and_give_new_cells( + Point(x, y, 0), + std::back_inserter(lis_tai1)); + assert(TAI1.is_valid()); + assert(TAI1.dimension() == 2); + while(!lis_tai1.empty()) + { + Cell_handle c = lis_tai1.front(); + lis_tai1.pop_front(); + assert(TAI1.tds().is_simplex(c)); + } + } + TAI1.clear(); + + std::cout << " 3 dimensions" << std::endl; + for(int i=0; i<50; i++) + { + double x = grand.get_double(); + double y = grand.get_double(); + double z = grand.get_double(); + TAI1.insert(Point(x, y, z)); + } + for(int i=0; i<50; i++) + { + lis_tai1.clear(); + double x = grand.get_double(); + double y = grand.get_double(); + double z = grand.get_double(); + Vertex_handle taiv = + TAI1.insert_and_give_new_cells( + Point(x, y, z), + std::back_inserter(lis_tai1)); + assert(TAI1.is_valid()); + assert(TAI1.dimension() == 3); + while(!lis_tai1.empty()) + { + Cell_handle c = lis_tai1.front(); + lis_tai1.pop_front(); + assert(TAI1.tds().is_simplex(c)); + } + } + TAI1.clear(); + + // the other two insertion methods is exactly the same + // with different version of the basic insert method + // Vertex_handle insert_and_give_new_cells(const Point& p, + // OutputItCells fit, + // Vertex_handle hint) + // Vertex_handle insert_and_give_new_cells(const Point& p, + // Locate_type lt, Cell_handle c, int li, int lj, + // OutputItCells fit + + + // ################################################################## + + + // testing some simple basic methods (access functions) + + std::cout << " Boolean and query functions " <index(T0.infinite_vertex()); + + Facet f ; + for (i=0;i<4;i++) + if (i!=ind) { + assert(T0.is_infinite(c,i)); + f=Facet(c,i); + assert(T0.is_infinite(f)); + } + int j; + + for (i=0;i<4;i++) + for (j=0;i<4;i++) + if ((i!=j) && ((i==ind) || (j==ind))) { + assert(T0.is_infinite(c,i,j)); + assert(T0.is_infinite(Edge(c,i,j))); + } + + + v0=T0.infinite_vertex(); + assert(T0.is_infinite(v0)); + + Finite_vertices_iterator vit; + Vertex_handle w; + for (vit=T3_1.finite_vertices_begin();vit!=T3_1.finite_vertices_end();vit++) + assert(T3_1.is_vertex(vit->point(), w)); + + // test mirrors + c = T0.infinite_cell(); + for (i=0;i<4;i++) { + Cell_handle d = c->neighbor(i); + int j = T0.mirror_index(c,i); + assert(d->vertex(j) == T0.mirror_vertex(c,i)); + assert(Facet(d,j) == T0.mirror_facet(Facet(c,i))); + } + + + + // geometric functions + std::cout << "Geometric functions " << std::endl; + c= T0.locate(Point(50,0,1),lt,li,lj); + Tetrahedron tr1=T0.tetrahedron(c); + c= T0.locate(Point(10,0,1),lt,li,lj); + Tetrahedron tr2=T0.tetrahedron(c); + assert(tr1==tr2); + c= T0.locate(Point(50,0,5),lt,li,lj); + Triangle tri1=T0.triangle(c,1); + c= T0.locate(Point(10,0,1),lt,li,lj); + Triangle tri2=T0.triangle(Facet(c,1)); + assert(tri1==tri2); + c= T0.locate(Point(10,0,1),lt,li,lj); + Segment s1 = T0.segment(c,0,1); + c= T0.locate(Point(50,0,5),lt,li,lj); + Segment s2 = T0.segment(Edge(c,0,1)); + assert(s1==s2); + c= T0.locate(Point(50,0,5),lt,li,lj); + Point pt1 = T0.point(c,0); + c= T0.locate(Point(10,0,1),lt,li,lj); + Point pt2 = T0.point(c->vertex(0)); + assert(pt1==pt2); + c= T0.locate(Point(20,0,2),lt,li,lj); + Point pt3 = c->vertex(0)->point(); + assert(pt2==pt3); + + if (! del) { // Delaunay should not be flipped + // or it will not be Delaunay any longer --> not valid + std::cout << " Test flip " << std::endl; + assert( T3_1.is_valid()); + Finite_cells_iterator cit, cdone = T3_1.finite_cells_end(); + int nbflips=0; + bool flipped; + cit = T3_1.finite_cells_begin(); + Finite_cells_iterator next_cell; + while ( cit != cdone ) { + // NOTE : cells are deleted during loop + // the cell_iterator is modified "by hand" (not using ++) + flipped = false; i=0; j=1; + next_cell = ++cit; --cit; + while ( (! flipped) && (i<4) ) { + if ( (i!=j) ) { + flipped = T3_1.flip( cit, i, j ) ; + if (flipped) { + nbflips++; + assert(T3_1.is_valid()); + } + } + if ( j==3 ) { i++; j=0; } + else j++; + } + cit = next_cell; + } + std::cout << nbflips << " flips 3-2" << std::endl; + + nbflips=0; + for ( cit = T3_1.finite_cells_begin(); cit != cdone; cit++ ) { + // NOTE : the triangulation is modified during loop + // --> the cell_iterator does not mean a lot + for ( i=0; i<4; i++ ) { + flipped = T3_1.flip( cit, i ); + if (flipped) { + nbflips++; + assert(T3_1.is_valid()); + } + } + } + std::cout << nbflips << " flips 2-3" << std::endl; + } + + // Finite incident_* in dimension 2 test + std::cout << " Testing finite_incident_* in dim 2 "<< std::endl; + Cls* T2[2]; + T2[0] = &T2_0; + T2[1] = &T2_1; + + for(int k = 0; k < 2; ++k) { + std::cout << " with triangulation " << k + 1 << ": "; + + std::vector f_vertices_old; + std::vector f_vertices; + std::vector f_edges; + std::vector f_facets; + std::vector f_cells; + + f_vertices.clear(); + f_edges.clear(); + f_facets.clear(); + f_cells.clear(); + + for(Finite_vertices_iterator i = T2[k]->finite_vertices_begin(); + i != T2[k]->finite_vertices_end(); ++i) { + // old name (up to CGAL 3.4) + // kept for backwards compatibility but not documented + T2[k]->finite_incident_vertices(i, std::back_inserter(f_vertices_old)); + // correct name + T2[k]->finite_adjacent_vertices(i, std::back_inserter(f_vertices)); + T2[k]->finite_incident_edges(i, std::back_inserter(f_edges)); + T2[k]->finite_incident_facets(i, std::back_inserter(f_facets)); + T2[k]->finite_incident_cells(i, std::back_inserter(f_cells)); + } + unsigned int nb_f_edges = 0; + Finite_edges_iterator feit = T2[k]->finite_edges_begin(); + while(feit != T2[k]->finite_edges_end()) { + ++nb_f_edges; + ++feit; + } + unsigned int nb_f_facets = 0; + Finite_facets_iterator ffait = T2[k]->finite_facets_begin(); + while(ffait != T2[k]->finite_facets_end()) { + ++nb_f_facets; + ++ffait; + } + + // incidences + assert(f_edges.size() == f_vertices_old.size()); + assert(f_edges.size() == f_vertices.size()); + assert(2*nb_f_edges == f_edges.size()); + assert(3*nb_f_facets == f_facets.size()); + assert(3*nb_f_facets == f_cells.size()); + + typename Cls::size_type nb_f_vertices = T2[k]->number_of_vertices(); + + // Euler relation + assert(nb_f_vertices - nb_f_edges + nb_f_facets == 1); + std::cout << "ok\n"; + } + + // Finite incident_* to vertex test + std::cout << " Testing finite_incident_* in dim 3 "<< std::endl; + + Cls* T3[6]; + T3[0] = &T3_0; + T3[1] = &T3_1; + T3[2] = &T3_2_1; + T3[3] = &T3_2_2; + T3[4] = &T3_2; + T3[5] = &T3_3; + + for(int k = 0; k < 6; ++k) { + std::cout << " with triangulation " << k + 1 << ": "; + + std::vector f_vertices_old; + std::vector f_vertices; + std::vector f_edges; + std::vector f_facets; + std::vector f_cells; + + f_vertices.clear(); + f_edges.clear(); + f_facets.clear(); + f_cells.clear(); + + for(Finite_vertices_iterator i = T3[k]->finite_vertices_begin(); + i != T3[k]->finite_vertices_end(); ++i) { + // old name (up to CGAL 3.4) + // kept for backwards compatibility but not documented + T3[k]->finite_incident_vertices(i, std::back_inserter(f_vertices_old)); + // correct name + T3[k]->finite_adjacent_vertices(i, std::back_inserter(f_vertices)); + T3[k]->finite_incident_edges(i, std::back_inserter(f_edges)); + T3[k]->finite_incident_facets(i, std::back_inserter(f_facets)); + T3[k]->finite_incident_cells(i, std::back_inserter(f_cells)); + } + unsigned int nb_f_edges = 0; + Finite_edges_iterator feit = T3[k]->finite_edges_begin(); + while(feit != T3[k]->finite_edges_end()) { + ++nb_f_edges; + ++feit; + } + unsigned int nb_f_facets = 0; + Finite_facets_iterator ffait = T3[k]->finite_facets_begin(); + while(ffait != T3[k]->finite_facets_end()) { + ++nb_f_facets; + ++ffait; + } + unsigned int nb_f_cells = 0; + Finite_cells_iterator fcit = T3[k]->finite_cells_begin(); + while(fcit != T3[k]->finite_cells_end()) { + ++nb_f_cells; + ++fcit; + } + + // incidences + assert(f_edges.size() == f_vertices_old.size()); + assert(f_edges.size() == f_vertices.size()); + assert(2*nb_f_edges == f_edges.size()); + assert(3*nb_f_facets == f_facets.size()); + assert(4*nb_f_cells == f_cells.size()); + + typename Cls::size_type nb_f_vertices = T3[k]->number_of_vertices(); + + // Euler relation + assert(nb_f_vertices - nb_f_edges + nb_f_facets - nb_f_cells == 1); + std::cout << "ok\n"; + } + // Iterator and circulator test + + Cls T0_1; + Point p28(1,3,5); + v0=T0_1.insert(p28); + + std::cout << " Testing Iterator "<< std::endl; + _test_vertex_iterator(T0_1); + _test_triangulation_iterator(T0_1); + _test_vertex_iterator(T0); + _test_triangulation_iterator(T0); + _test_vertex_iterator(T2_0); + _test_triangulation_iterator(T2_0); + _test_vertex_iterator(T1_0); + _test_triangulation_iterator(T1_0); + _test_vertex_iterator(T3_1); + _test_triangulation_iterator(T3_1); + _test_vertex_iterator(T3_0); + _test_triangulation_iterator(T3_0); + _test_vertex_iterator(T3_2); + _test_triangulation_iterator(T3_2); + _test_vertex_iterator(T3_3); + _test_triangulation_iterator(T3_3); + + std::cout << " Testing Circulator "<< std::endl; + _test_circulator(T0); + _test_circulator(T3_1); + _test_circulator(T3_0); + _test_circulator(T3_2); + _test_circulator(T3_3); + + std::cout <<" Test destructors and quit "<< std::endl; + + T0.clear(); + assert(T0.is_valid()); + T3_0.clear(); + assert(T3_0.is_valid()); + assert(T3_0.dimension()==-1); + assert(T3_0.number_of_vertices()==0); +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_triangulation_simplex_3.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_triangulation_simplex_3.h new file mode 100644 index 00000000000..69ba75e7e78 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_cls_triangulation_simplex_3.h @@ -0,0 +1,147 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Nico Kruithof + +#include +#include + +template +void +_test_cls_triangulation_simplex_3(const Triangulation &) +{ + typedef Triangulation Cls; + + typedef typename Cls::Simplex Simplex; + + typedef typename Cls::Point Point; + + typedef typename Cls::Vertex Vertex; + typedef typename Cls::Cell Cell; + typedef typename Cls::Facet Facet; + typedef typename Cls::Edge Edge; + + typedef typename Cls::size_type size_type; + typedef typename Cls::difference_type difference_type; + + typedef typename Cls::Vertex_handle Vertex_handle; + typedef typename Cls::Cell_handle Cell_handle; + + typedef typename Cls::Cell_circulator Cell_circulator; + typedef typename Cls::Facet_circulator Facet_circulator; + + typedef typename Cls::Cell_iterator Cell_iterator; + typedef typename Cls::Facet_iterator Facet_iterator; + typedef typename Cls::Edge_iterator Edge_iterator; + typedef typename Cls::Vertex_iterator Vertex_iterator; + + typedef typename Cls::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Cls::Finite_edges_iterator Finite_edges_iterator; + typedef typename Cls::Finite_facets_iterator Finite_facets_iterator; + typedef typename Cls::Finite_cells_iterator Finite_cells_iterator; + + //######################################################################## + Cls t; + + // Initialise to a 3D triangulation: + t.insert(Point(0,0,0)); + t.insert(Point(1,0,0)); + t.insert(Point(0,1,0)); + t.insert(Point(0,0,1)); + + { // Check vertices: + Finite_vertices_iterator vit = t.finite_vertices_begin(); + Vertex_handle vh = vit; + + Simplex s1 = vh; + + Simplex s2(vit); + Simplex s3(vh); + + Simplex s4(s1); + + CGAL_assertion(s1.dimension() == 0); + CGAL_assertion(s1 == s2); + CGAL_assertion(s1 == s3); + CGAL_assertion(s1 == s4); + Vertex_handle vh2 = s1; + CGAL_assertion(vh == vh2); + } + + { // Check edges + Finite_edges_iterator eit = t.finite_edges_begin(); + Edge e = *eit; + + Simplex s1 = *eit; + Simplex s2 = e; + + Simplex s3(*eit); + Simplex s4(e); + + Simplex s5(s1); + + CGAL_assertion(s1.dimension() == 1); + CGAL_assertion(s1 == s2); + CGAL_assertion(s1 == s3); + CGAL_assertion(s1 == s4); + CGAL_assertion(s1 == s5); + Edge e2 = s1; + CGAL_assertion(e == e2); + } + + { // Check facets + Finite_facets_iterator fit = t.finite_facets_begin(); + Facet f = *fit; + + Simplex s1 = *fit; + Simplex s2 = f; + + Simplex s3(*fit); + Simplex s4(f); + + Simplex s5(s1); + + CGAL_assertion(s1.dimension() == 2); + CGAL_assertion(s1 == s2); + CGAL_assertion(s1 == s3); + CGAL_assertion(s1 == s4); + CGAL_assertion(s1 == s5); + Facet f2 = s1; + CGAL_assertion(f == f2); + } + + { // Check cells + Finite_cells_iterator cit = t.finite_cells_begin(); + Cell_handle ch = cit; + + Simplex s1 = Simplex(cit); + Simplex s2 = ch; + + Simplex s3(cit); + Simplex s4(ch); + + Simplex s5(s1); + + CGAL_assertion(s1.dimension() == 3); + CGAL_assertion(s1 == s2); + CGAL_assertion(s1 == s3); + CGAL_assertion(s1 == s4); + CGAL_assertion(s1 == s5); + Cell_handle ch2 = s1; + CGAL_assertion(ch == ch2); + } +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_remove_cluster.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_remove_cluster.h new file mode 100644 index 00000000000..e8e2edf0b2d --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_remove_cluster.h @@ -0,0 +1,758 @@ +#include + +#include +#include +#include + +template +void _test_rc_random_1() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_random_1" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + CGAL::Random_points_in_cube_3 cube_insert(1.0); + + const int number_of_points = (1<<14); + + for(int i=0; ipoint()) && + s2.has_on_unbounded_side(fit->point())) to_remove.push_back(fit); + } + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_random_2() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_random_2" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + CGAL::Random_points_in_cube_3 cube_insert(1.0); + + const int number_of_points = (1<<14); + + for(int i=0; ipoint())) to_remove.push_back(fit); + if(s2.has_on_bounded_side(fit->point())) to_remove.push_back(fit); + } + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_random_3() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_random_3" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + CGAL::Random random; + CGAL::Random_points_in_cube_3 cube_insert(1.0); + + const int number_of_points = (1<<14); + + for(int i=0; i +void _test_rc_random_4() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_random_4" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + CGAL::Random random; + CGAL::Random_points_in_cube_3 cube_insert(1.0); + + const int number_of_points = (1<<14); + + for(int i=0; i +void _test_rc_trivial() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_trivial" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + Vertex_handle a1, a2, a3, a4, a5; + + a1 = dt.insert(Point(0,0,0)); + a2 = dt.insert(Point(0,0,1)); + a3 = dt.insert(Point(0,1,1)); + a4 = dt.insert(Point(0,1,0)); + a5 = dt.insert(Point(1,0,0)); + + to_remove.push_back(a5); + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_specific_cases_1() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_specific_cases_1" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + Vertex_handle a1, a2, a3, a4, a5, a6, a7, a8; + Vertex_handle b1, b2, b3, b4, b5, b6, b7, b8; + + a1 = dt.insert(Point(0,0,0)); + a2 = dt.insert(Point(0,0,1)); + a3 = dt.insert(Point(0,1,1)); + a4 = dt.insert(Point(0,1,0)); + a5 = dt.insert(Point(1,0,0)); + a6 = dt.insert(Point(1,0,1)); + a7 = dt.insert(Point(1,1,1)); + a8 = dt.insert(Point(1,1,0)); + + b1 = dt.insert(Point(0.25,0.25,0.25)); + b2 = dt.insert(Point(0.25,0.25,0.75)); + b3 = dt.insert(Point(0.25,0.75,0.75)); + b4 = dt.insert(Point(0.25,0.75,0.25)); + b5 = dt.insert(Point(0.75,0.25,0.25)); + b6 = dt.insert(Point(0.75,0.25,0.75)); + b7 = dt.insert(Point(0.75,0.75,0.75)); + b8 = dt.insert(Point(0.75,0.75,0.25)); + + to_remove.push_back(a1); + to_remove.push_back(a2); + to_remove.push_back(a3); + to_remove.push_back(a4); + to_remove.push_back(a5); + to_remove.push_back(a6); + to_remove.push_back(a7); + to_remove.push_back(a8); + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_specific_cases_2() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_specific_cases_2" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + Vertex_handle a1, a2, a3, a4, a5, a6, a7, a8; + Vertex_handle b1, b2, b3, b4, b5, b6, b7, b8; + + a1 = dt.insert(Point(0,0,0)); + a2 = dt.insert(Point(0,0,1)); + a3 = dt.insert(Point(0,1,1)); + a4 = dt.insert(Point(0,1,0)); + a5 = dt.insert(Point(1,0,0)); + a6 = dt.insert(Point(1,0,1)); + a7 = dt.insert(Point(1,1,1)); + a8 = dt.insert(Point(1,1,0)); + + b1 = dt.insert(Point(0.25,0.25,0.25)); + b2 = dt.insert(Point(0.25,0.25,0.75)); + b3 = dt.insert(Point(0.25,0.75,0.75)); + b4 = dt.insert(Point(0.25,0.75,0.25)); + b5 = dt.insert(Point(0.75,0.25,0.25)); + b6 = dt.insert(Point(0.75,0.25,0.75)); + b7 = dt.insert(Point(0.75,0.75,0.75)); + b8 = dt.insert(Point(0.75,0.75,0.25)); + + to_remove.push_back(a1); + to_remove.push_back(a2); + to_remove.push_back(a3); + to_remove.push_back(a4); + to_remove.push_back(a5); + to_remove.push_back(a6); + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_specific_cases_3() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_specific_cases_3" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + Vertex_handle a1, a2, a3, a4, a5, a6, a7, a8; + Vertex_handle b1, b2, b3, b4, b5, b6, b7, b8; + + a1 = dt.insert(Point(0,0,0)); + a2 = dt.insert(Point(0,0,1)); + a3 = dt.insert(Point(0,1,1)); + a4 = dt.insert(Point(0,1,0)); + a5 = dt.insert(Point(1,0,0)); + a6 = dt.insert(Point(1,0,1)); + a7 = dt.insert(Point(1,1,1)); + a8 = dt.insert(Point(1,1,0)); + + b1 = dt.insert(Point(0.25,0.25,0.25)); + b2 = dt.insert(Point(0.25,0.25,0.75)); + b3 = dt.insert(Point(0.25,0.75,0.75)); + b4 = dt.insert(Point(0.25,0.75,0.25)); + b5 = dt.insert(Point(0.75,0.25,0.25)); + b6 = dt.insert(Point(0.75,0.25,0.75)); + b7 = dt.insert(Point(0.75,0.75,0.75)); + b8 = dt.insert(Point(0.75,0.75,0.25)); + + to_remove.push_back(b1); + to_remove.push_back(b2); + to_remove.push_back(b3); + to_remove.push_back(a4); + to_remove.push_back(a5); + to_remove.push_back(a6); + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_specific_cases_4() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_specific_cases_4" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + Vertex_handle a1, a2, a3, a4, a5, a6, a7, a8; + Vertex_handle b1, b2, b3, b4, b5, b6, b7, b8; + + a1 = dt.insert(Point(0,0,0)); + a2 = dt.insert(Point(0,0,1)); + a3 = dt.insert(Point(0,1,1)); + a4 = dt.insert(Point(0,1,0)); + a5 = dt.insert(Point(1,0,0)); + a6 = dt.insert(Point(1,0,1)); + a7 = dt.insert(Point(1,1,1)); + a8 = dt.insert(Point(1,1,0)); + + b1 = dt.insert(Point(0.25,0.25,0.25)); + b2 = dt.insert(Point(0.25,0.25,0.75)); + b3 = dt.insert(Point(0.25,0.75,0.75)); + b4 = dt.insert(Point(0.25,0.75,0.25)); + b5 = dt.insert(Point(0.75,0.25,0.25)); + b6 = dt.insert(Point(0.75,0.25,0.75)); + b7 = dt.insert(Point(0.75,0.75,0.75)); + b8 = dt.insert(Point(0.75,0.75,0.25)); + + to_remove.push_back(b1); + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_specific_cases_5() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_specific_cases_5" << std::endl; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + dt.insert(Point(-1000,-1000,-1000)); + dt.insert(Point(-1000,-1000,1000)); + dt.insert(Point(-1000,1000,1000)); + dt.insert(Point(-1000,1000,-1000)); + dt.insert(Point(1000,-1000,-1000)); + dt.insert(Point(1000,-1000,1000)); + dt.insert(Point(1000,1000,1000)); + dt.insert(Point(1000,1000,-1000)); + + Vertex_handle a1, a2, a3, a4, a5, a6, a7, a8; + Vertex_handle b1, b2, b3, b4, b5, b6, b7, b8; + Vertex_handle c1; + + a1 = dt.insert(Point(0,0,0)); + a2 = dt.insert(Point(0,0,1)); + a3 = dt.insert(Point(0,1,1)); + a4 = dt.insert(Point(0,1,0)); + a5 = dt.insert(Point(1,0,0)); + a6 = dt.insert(Point(1,0,1)); + a7 = dt.insert(Point(1,1,1)); + a8 = dt.insert(Point(1,1,0)); + + b1 = dt.insert(Point(0.25,0.25,0.25)); + b2 = dt.insert(Point(0.25,0.25,0.75)); + b3 = dt.insert(Point(0.25,0.75,0.75)); + b4 = dt.insert(Point(0.25,0.75,0.25)); + b5 = dt.insert(Point(0.75,0.25,0.25)); + b6 = dt.insert(Point(0.75,0.25,0.75)); + b7 = dt.insert(Point(0.75,0.75,0.75)); + b8 = dt.insert(Point(0.75,0.75,0.25)); + + c1 = dt.insert(Point(0.5,0.51,0.52)); + + to_remove.push_back(b1); + to_remove.push_back(b2); + to_remove.push_back(b3); + to_remove.push_back(b4); + to_remove.push_back(b5); + to_remove.push_back(b6); + to_remove.push_back(b7); + to_remove.push_back(b8); + to_remove.push_back(a2); + to_remove.push_back(a4); + to_remove.push_back(a6); + to_remove.push_back(a8); + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_specific_cases_6() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_specific_cases_6" << std::endl; + + std::size_t s1, s2, ns; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + Vertex_handle a1, a2, a3, a4, a5, a6, a7, a8; + Vertex_handle v1, v2; + + dt.insert(Point(-1000,-1000,-1000)); + dt.insert(Point(-1000,-1000,1000)); + dt.insert(Point(-1000,1000,1000)); + dt.insert(Point(-1000,1000,-1000)); + dt.insert(Point(1000,-1000,-1000)); + dt.insert(Point(1000,-1000,1000)); + dt.insert(Point(1000,1000,1000)); + dt.insert(Point(1000,1000,-1000)); + + a1 = dt.insert(Point(0,0,0)); + a2 = dt.insert(Point(0,0,1)); + a3 = dt.insert(Point(0,1,1)); + a4 = dt.insert(Point(0,1,0)); + a5 = dt.insert(Point(1,0,0)); + a6 = dt.insert(Point(1,0,1)); + a7 = dt.insert(Point(2,2,2)); + a8 = dt.insert(Point(1,1,0)); + + v1 = dt.insert(Point(0.25,0.25,0.25)); + v2 = dt.insert(Point(0.75,0.75,0.75)); + + ////////////////////////// + + to_remove.push_back(v1); + s1 = dt.number_of_vertices(); + s2 = to_remove.size(); + ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); + + /////////////////////// + + v1 = dt.insert(Point(0.25,0.25,0.25)); + to_remove.clear(); + to_remove.push_back(v1); + to_remove.push_back(v2); + s1 = dt.number_of_vertices(); + s2 = to_remove.size(); + ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); + + /////////////////////// + + v1 = dt.insert(Point(0.25,0.25,0.25)); + v2 = dt.insert(Point(0.75,0.75,0.75)); + + to_remove.clear(); + to_remove.push_back(a1); + s1 = dt.number_of_vertices(); + s2 = to_remove.size(); + ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); + + /////////////////////// + + a1 = dt.insert(Point(0,0,0)); + + to_remove.clear(); + to_remove.push_back(a1); + to_remove.push_back(a2); + s1 = dt.number_of_vertices(); + s2 = to_remove.size(); + ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); + + /////////////////////// + + a1 = dt.insert(Point(0,0,0)); + a2 = dt.insert(Point(0,0,1)); + + to_remove.clear(); + to_remove.push_back(a1); + to_remove.push_back(a2); + to_remove.push_back(a3); + to_remove.push_back(a4); + to_remove.push_back(a7); + to_remove.push_back(a8); + + s1 = dt.number_of_vertices(); + s2 = to_remove.size(); + ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_grid_1() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_grid_1" << std::endl; + + CGAL::Random random; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + for(int i=1; i<=(1<<10); i<<=1) + for(int j=1; j<=(1<<10); j<<=1) + for(int k=1; k<=(1<<10); k<<=1) + to_insert.push_back(Point_3(i,j,k)); + + dt.insert(to_insert.begin(), to_insert.end()); + + for(Finite_vertices_iterator fit = dt.finite_vertices_begin(); + fit != dt.finite_vertices_end(); fit++) { + if(random.get_double() < 0.9) to_remove.push_back(fit); + } + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_grid_2() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_grid_2" << std::endl; + + CGAL::Random random; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + for(int i=1; i<=(1<<10); i<<=1) + for(int j=1; j<=(1<<10); j<<=1) + for(int k=1; k<=(1<<10); k<<=1) + to_insert.push_back(Point_3(i,j,k)); + + dt.insert(to_insert.begin(), to_insert.end()); + + for(Finite_vertices_iterator fit = dt.finite_vertices_begin(); + fit != dt.finite_vertices_end(); fit++) { + if(random.get_double() < 0.05) to_remove.push_back(fit); + } + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + +template +void _test_rc_grid_3() +{ + typedef T D3; + typedef typename D3::Point Point; + typedef typename D3::Vertex_handle Vertex_handle; + typedef typename D3::Cell_handle Cell_handle; + typedef typename D3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename D3::Locate_type Locate_type; + typedef typename D3::Geom_traits::Sphere_3 Sphere_3; + typedef Point Point_3; + + std::cout << "_test_rc_grid_3" << std::endl; + + CGAL::Random random; + + std::vector to_insert; + std::vector to_remove; + D3 dt; + + for(int i=1; i<=(1<<10); i<<=1) + for(int j=1; j<=(1<<10); j<<=1) + for(int k=1; k<=(1<<10); k<<=1) + to_insert.push_back(Point_3(i,j,k)); + + dt.insert(to_insert.begin(), to_insert.end()); + + for(Finite_vertices_iterator fit = dt.finite_vertices_begin(); + fit != dt.finite_vertices_end(); fit++) { + if(fit->point().x() == (1<<5)) to_remove.push_back(fit); + } + + std::size_t s1 = dt.number_of_vertices(); + std::size_t s2 = to_remove.size(); + std::size_t ns = dt.remove_cluster(to_remove.begin(), to_remove.end()); + assert(dt.is_valid()); + assert(ns == s2); + assert(dt.number_of_vertices() + s2 == s1); +} + + +template +void _test_remove_cluster() { + std::cout << "Removing clusters of points from triangulations..." << std::endl; + + // small cases + { + _test_rc_trivial(); + _test_rc_specific_cases_1(); + _test_rc_specific_cases_2(); + _test_rc_specific_cases_3(); + _test_rc_specific_cases_4(); + _test_rc_specific_cases_5(); + _test_rc_specific_cases_6(); + } + + // big cases + { + // random + _test_rc_random_1(); + _test_rc_random_2(); + _test_rc_random_3(); + _test_rc_random_4(); + + // grid + _test_rc_grid_1(); + _test_rc_grid_2(); + _test_rc_grid_3(); + } +} + + +// Local Variables: +// tab-width: 2 +// End: diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_types.h b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_types.h new file mode 100644 index 00000000000..a533778d0a1 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/include/CGAL/_test_types.h @@ -0,0 +1,33 @@ +// Copyright (c) 1998, 2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Francois Rebufat, Sylvain Pion + +#ifndef CGAL_TEST_TYPES_H +#define CGAL_TEST_TYPES_H + +#include +#include + +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel EPIC; +typedef EPIC K; +typedef CGAL::Exact_predicates_exact_constructions_kernel EPEC; + +#endif diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_3.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_3.cpp new file mode 100644 index 00000000000..5ccf2de42fa --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_3.cpp @@ -0,0 +1,48 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Francois Rebufat + +#include +#include + +bool del=true; + +#include +#include + +// Explicit instantiation of the whole class : +template class CGAL::Delaunay_triangulation_3; + +int main() +{ + typedef CGAL::Delaunay_triangulation_3 Cls; + typedef CGAL::Delaunay_triangulation_3 Cls_with_epec; + + _test_cls_delaunay_3( Cls() ); + _test_cls_delaunay_3( Cls_with_epec() ); + + // Second version for the circumcenter storing cell base class. + typedef CGAL::Triangulation_vertex_base_3 Vb; + typedef CGAL::Triangulation_cell_base_with_circumcenter_3 Cb; + typedef CGAL::Triangulation_data_structure_3 TDS; + typedef CGAL::Delaunay_triangulation_3 Cls_circumcenter; + + _test_cls_delaunay_3( Cls_circumcenter() ); + + return 0; +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_hierarchy_3.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_hierarchy_3.cpp new file mode 100644 index 00000000000..125e74a8540 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_hierarchy_3.cpp @@ -0,0 +1,36 @@ +// Copyright (c) 1998,2001 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Mariette Yvinec, Sylvain Pion + +#include + +bool del=true; + +#include +#include + +int main() +{ + typedef CGAL::Delaunay_triangulation_3 Dh; + typedef CGAL::Delaunay_triangulation_3 Dh_with_epec; + + _test_cls_delaunay_3( Dh() ); + _test_cls_delaunay_3( Dh_with_epec() ); + + return 0; +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_hierarchy_3_old.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_hierarchy_3_old.cpp new file mode 100644 index 00000000000..368bbed225b --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_delaunay_hierarchy_3_old.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 1998,2001 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Mariette Yvinec, Sylvain Pion + +#include +#include + +bool del=true; + +#include +#include + +int main() +{ + typedef CGAL::Triangulation_vertex_base_3 Vbb; + typedef CGAL::Triangulation_hierarchy_vertex_base_3 Vb; + typedef CGAL::Triangulation_data_structure_3 Tds; + typedef CGAL::Delaunay_triangulation_3 Dt; + typedef CGAL::Triangulation_hierarchy_3
Dh; + + _test_cls_delaunay_3( Dh() ); + + return 0; +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_3.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_3.cpp new file mode 100644 index 00000000000..2554466bbd5 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_3.cpp @@ -0,0 +1,441 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Monique Teillaud (Monique.Teillaud@sophia.inria.fr) +// : Mariette Yvinec (Mariette.Yvinec@sophia.inria.fr) + +#include +#include + +#include +#include +#include + +#include +#include + +bool del=true; + +typedef CGAL::Exact_predicates_inexact_constructions_kernel FK; +typedef CGAL::Regular_triangulation_euclidean_traits_3 traits; + +// Explicit instantiation of the whole class : +template class CGAL::Regular_triangulation_3; + +int main() +{ + std::cout << " with CGAL::Regular_triangulation_euclidean_traits_3: " + << std::endl; + + typedef CGAL::Regular_triangulation_3 Cls; + + // _test_cls_regular_3( Cls() ); + typedef traits::Bare_point Point; + typedef traits::Weighted_point Weighted_point; + + typedef Cls::Vertex_handle Vertex_handle; + typedef Cls::Cell_handle Cell_handle; + typedef Cls::Facet Facet; + typedef Cls::Edge Edge; + + typedef std::list list_point; + typedef Cls::Finite_cells_iterator Finite_cells_iterator; + + // temporary version + + int n, m; + int count = 0; + + // For dimension 0, we need to check that the point of highest weight is the + // one that finally ends up in the vertex. + std::cout << " test dimension 0 " << std::endl; + Cls T0; + T0.insert(Weighted_point( Point (0,0,0), 0) ); + T0.insert(Weighted_point( Point (0,0,0), 1) ); + T0.insert(Weighted_point( Point (0,0,0), -1) ); + assert(T0.dimension() == 0); + assert(T0.number_of_vertices() == 1); + assert(T0.finite_vertices_begin()->point().weight() == 1); + + std::cout << " test dimension 1 " << std::endl; + Cls T1; + std::cout << " number of inserted points : " ; + Weighted_point p[5]; + for ( m=0; m<5; m++) { + if ( (m%2)== 0 ) + p[m] = Weighted_point( Point( 2*m,0,0 ), 2 ); + else + p[m] = Weighted_point( Point( -2*m+1,0,0 ), 2 ); + T1.insert( p[m] ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + assert( T1.is_valid() ); + std::cout << std::endl << " number of vertices : " + << T1.number_of_vertices() << std::endl; + + std::cout << " number of inserted points : " ; + Weighted_point q[5]; + for ( m=0; m<5; m++) { + if ( (m%2)== 0 ) + q[m] = Weighted_point( Point( 2*m+1,0,0 ), 5 ); + else + q[m] = Weighted_point( Point( -2*m+1,0,0 ), 5 ); + T1.insert( q[m] ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + assert( T1.is_valid() ); + std::cout << std::endl << " number of vertices : " + << T1.number_of_vertices() << std::endl; + + std::cout << " number of inserted points : " ; + Weighted_point r[10]; + for ( m=0; m<10; m++) { + if ( (m%2)== 0 ) + r[m] = Weighted_point( Point( m,0,0 ), 1 ); + else + r[m] = Weighted_point( Point( -m,0,0 ), 1 ); + T1.insert( r[m] ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + assert( T1.is_valid() ); + std::cout << std::endl << " number of vertices : " + << T1.number_of_vertices() << std::endl; + assert( T1.dimension()==1 ); + + // The following is distilled from a bug report by Wulue Zhao + // (zhao.88@osu.edu), a student of Tamal Dey. + Point pt0(0,0,0); + Point pt1( 1,0,0), pt2(2,0,0), pt3(3,0,0); + Point pt4(-1,0,0), pt5(-2,0,0), pt6(-3,0,0); + + Weighted_point wp0(pt0,10.0); + Weighted_point wp1(pt1,0.0), wp2(pt2,0.0), wp3(pt3,0.0); + Weighted_point wp4(pt4,0.0), wp5(pt5,0.0), wp6(pt6,0.0); + + Cls T11; + + T11.insert(wp0); + T11.insert(wp1); + T11.insert(wp2); + T11.insert(wp3); + T11.insert(wp4); + T11.insert(wp5); + T11.insert(wp6); + + assert(T11.is_valid()); + + // And another distilled bug report from the same guy. + { + Point p1(-0.07, 0.04, 0.04); + Point p2(0.09, 0.04, 0.04); + Point p3(0.09, -0.05, 0.04); + Point p4(0.05, -0.05, 0.04); + Point p5(0.05, 0.0, 0.04); + Point p6(-0.07, 0.0, 0.04); + Point p7(-0.07, 0.04, -0.04); + Point p8(0.09, 0.04, -0.04); + Point p9(0.09, -0.05, -0.04); + Point p10(0.05, -0.05, -0.04); + Point p11(0.05, 0.0, -0.04); + Point p12(-0.07, 0.0, -0.04); + + Weighted_point wp1(p1,0); + Weighted_point wp2(p2,0); + Weighted_point wp3(p3,0); + Weighted_point wp4(p4,0); + Weighted_point wp5(p5,0); + Weighted_point wp6(p6,0); + Weighted_point wp7(p7,0); + Weighted_point wp8(p8,0); + Weighted_point wp9(p9,0); + Weighted_point wp10(p10,0); + Weighted_point wp11(p11,0); + Weighted_point wp12(p12,0); + Weighted_point wp13(p3,0.3); // wp13 has the same coordinates with wp3 + + Cls T111; + + T111.insert(wp1); + T111.insert(wp2); + T111.insert(wp3); + T111.insert(wp13); // it doesnot work inserting wp13 here + T111.insert(wp4); + T111.insert(wp5); + T111.insert(wp6); + T111.insert(wp7); + T111.insert(wp8); + T111.insert(wp9); + T111.insert(wp10); + T111.insert(wp11); + T111.insert(wp12); + + assert(T111.is_valid()); + } + + std::cout << " test dimension 2 " << std::endl; + std::cout << " number of inserted points : " ; + Cls T2; + + count = 0 ; + int px=1, py=1; + int qx=-1, qy=2; + Weighted_point s[400]; + for (m=0; m<10; m++) + for (n=0; n<10; n++) { + s[m+20*n] = Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), 1 ); + T2.insert( s[m+20*n] ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + for (m=10; m<20; m++) + for (n=0; n<10; n++) { + s[m+20*n] = Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), -1 ); + T2.insert( s[m+20*n] ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + for (m=0; m<10; m++) + for (n=10; n<20; n++) { + s[m+20*n] = Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), -2 ); + T2.insert( s[m+20*n] ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + for (m=10; m<20; m++) + for (n=10; n<20; n++) { + s[m+20*n] = Weighted_point( Point(m*px+n*qx, m*py+n*qy, 0), 5 ); + T2.insert( s[m+20*n] ); + count++; + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + std::cout << count << '\b' << '\b' << '\b' ; + std::cout.flush(); + } + + std::cout << std::endl << " number of vertices : " + << T2.number_of_vertices() << std::endl; + assert( T2.dimension()==2 ); + assert( T2.is_valid() ); + + // dimension 3 + std::cout << " test dimension 3" << std::endl; + Cls T; + + list_point lp; + int a, b, d; + for (a=0;a!=10;a++) + // for (b=0;b!=10;b++) + for (b=0;b!=5;b++) + // for (d=0;d!=10;d++) + for (d=0;d!=5;d++) + lp.push_back(Weighted_point( Point(a*b-d*a + (a-b)*10 +a , + a-b+d +5*b, + a*a-d*d+b), + a*b-a*d) ); + list_point::iterator it; + count = 0 ; + std::cout << " number of inserted points : " ; + for (it=lp.begin(); it!=lp.end(); ++it){ + count++; + T.insert(*it); + if (count <10) + std::cout << count << '\b' ; + else + if (count < 100) + std::cout << count << '\b' << '\b' ; + else + if (count < 1000) + std::cout << count << '\b' << '\b' << '\b' ; + else + std::cout << count << std::endl; + std::cout.flush(); + } + std::cout << std::endl; + + std::cout << " number of vertices : " + << T.number_of_vertices() << std::endl; + assert(T.is_valid()); + assert(T.dimension()==3); + + T.clear(); + std::cout << " test iterator range insert" << std::endl; + T.insert (lp.begin(), lp.end()); + + std::cout << " number of vertices : " + << T.number_of_vertices() << std::endl; + assert(T.is_valid()); + assert(T.dimension()==3); + + + //test nearest_power_vertex + std::cout << " test nearest_power_vertex " << std::endl; + Point pp1(0.0, 0.0, 0.0); + Point pp2(1.0, 0.0, 0.0); + Point pp3(0.0, 1.0, 0.0); + Point pp4(0.0, 0.0, 1.0); + Point pp5(1.0, 1.0, 0.0); + Point pp6(0.0, 1.0, 1.0); + Point pp7(1.0, 0.0, 1.0); + Point pp8(1.0, 1.0, 1.0); + + Weighted_point wpp1(pp1, 1.0); + Weighted_point wpp2(pp2, 2.0); + Weighted_point wpp3(pp3, 1.0); + Weighted_point wpp4(pp4, 4.0); + Weighted_point wpp5(pp5, 1.0); + Weighted_point wpp6(pp6, 1.0); + Weighted_point wpp7(pp7, 1.0); + Weighted_point wpp8(pp8, 8.0); + + Cls T3; + + T3.insert(wpp1); + Vertex_handle v2 = T3.insert(wpp2); + assert( T3.nearest_power_vertex(Point(0.5,0.5,0.5)) == v2); + + T3.insert(wpp3); + Vertex_handle v4 = T3.insert(wpp4); + assert( T3.nearest_power_vertex(Point(0.5,0.5,0.5)) == v4); + + T3.insert(wpp5); + T3.insert(wpp6); + T3.insert(wpp7); + // Avoid inserting the same point twice, now that hidden points are handled, + // insert (existing_point) returns Vertex_handle(). + // T3.insert(wpp8); + Vertex_handle v8 = T3.insert(wpp8); + Point query(0.5,0.5,0.5); + assert(T3.nearest_power_vertex(query) == v8); + assert(T3.nearest_power_vertex(Weighted_point(query,1.0)) == v8 ); + assert(T3.nearest_power_vertex_in_cell(query ,v8->cell()) == v8); + + // test dual + std::cout << " test dual member functions" << std::endl; + Finite_cells_iterator fcit = T3.finite_cells_begin(); + for( ; fcit != T3.finite_cells_end(); ++fcit) { + Point cc = T3.dual(fcit); + Vertex_handle ncc = T3.nearest_power_vertex(cc); + assert(fcit->has_vertex(ncc)); + } + + // test Gabriel + std::cout << " test is_Gabriel " << std::endl; + Point q0(0.,0.,0.); + Point q1(2.,0.,0.); + Point q2(0.,2.,0.); + Point q3(0.,0.,2.); + + Weighted_point wq0(q0,0.); + Weighted_point wq1(q1,0.); + Weighted_point wq2(q2,0.); + Weighted_point wq3(q3,0.); + Weighted_point wq01(q0,2.); + + Cls T4; + Vertex_handle v0 = T4.insert(wq0); + Vertex_handle v1 = T4.insert(wq1); + v2 = T4.insert(wq2); + Vertex_handle v3 = T4.insert(wq3); + Cell_handle c; + int i,j,k,l; + assert(T4.is_facet(v0,v1,v2,c,j,k,l)); + i = 6 - (j+k+l); + Facet f = std::make_pair(c,i); + assert(T4.is_Gabriel(c,i)); + assert(T4.is_Gabriel(f)); + assert(T4.is_facet(v1,v2,v3,c,j,k,l)); + i = 6 - (j+k+l); + assert(!T4.is_Gabriel(c,i)); + assert(T4.is_edge(v0,v1,c,i,j)); + assert(T4.is_Gabriel(c,i,j)); + Edge e = make_triple(c,i,j); + assert(T4.is_Gabriel(e)); + assert(T4.is_edge(v2,v3,c,i,j)); + assert(T4.is_Gabriel(c,i,j)); + + Vertex_handle v01 = T4.insert(wq01); + (void) v01; // kill warning + assert(T4.is_edge(v2,v3,c,i,j)); + assert(!T4.is_Gabriel(c,i,j)); + + Weighted_point wwq0(q0,0.); + Weighted_point wwq1(q1,0.); + Weighted_point wwq2(q2,0.); + Weighted_point wwq3(q3,5.); + Cls T5; + v0 = T5.insert(wwq0); + v1 = T5.insert(wwq1); + v2 = T5.insert(wwq2); + v3 = T5.insert(wwq3); + assert(T5.nearest_power_vertex(v3->point().point()) == v3); + assert(T5.nearest_power_vertex(v0->point().point()) == v3); + assert(T5.is_Gabriel(v3)); + assert(!T5.is_Gabriel(v0)); + + std::cout << " quit " << std::endl; + return 0; +} + diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_as_delaunay_3.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_as_delaunay_3.cpp new file mode 100644 index 00000000000..a553cbece05 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_as_delaunay_3.cpp @@ -0,0 +1,42 @@ +// Copyright (c) 2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Sylvain Pion + +#include +#include + + +bool del=true; + +#include +#include + +typedef CGAL::Regular_triangulation_euclidean_traits_3 Traits; + +int main() +{ + typedef CGAL::Regular_triangulation_3 Cls; + + _test_cls_delaunay_3( Cls() ); + + return 0; +} + +// MipsPro prefers this after the other instantiations... +// Explicit instantiation of the whole class : +template class CGAL::Regular_triangulation_3; diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_remove_3.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_remove_3.cpp new file mode 100644 index 00000000000..d62157e2aec --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_remove_3.cpp @@ -0,0 +1,387 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Christophe Delage (Christophe.Delage@sophia.inria.fr) + +#include +#include + +#include +#include +#include +//#include +#include + +#include +#include + +#include +//#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel FK; +typedef CGAL::Regular_triangulation_euclidean_traits_3 bare_traits; + +int degeneracy_counter = 0; + +// This traits class counts the number of times a power_test has returned 0. +// This gives a rough idea of how degenerate a data set is. +struct traits : public bare_traits +{ + struct Power_test_3 : public bare_traits::Power_test_3 + { + typedef bare_traits::Power_test_3 P3; + Oriented_side operator() (const Weighted_point &p0, + const Weighted_point &p) const + { + Oriented_side result = P3::operator()(p0, p); + if (result == 0) ++degeneracy_counter; + return result; + } + Oriented_side operator() (const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p) const + { + Oriented_side result = P3::operator()(p0, p1, p); + if (result == 0) ++degeneracy_counter; + return result; + } + Oriented_side operator() (const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p) const + { + Oriented_side result = P3::operator()(p0, p1, p2, p); + if (result == 0) ++degeneracy_counter; + return result; + } + Oriented_side operator() (const Weighted_point &p0, + const Weighted_point &p1, + const Weighted_point &p2, + const Weighted_point &p3, + const Weighted_point &p) const + { + Oriented_side result = P3::operator()(p0, p1, p2, p3, p); + if (result == 0) ++degeneracy_counter; + return result; + } + }; + + Power_test_3 power_test_3_object() const + { return Power_test_3(); } +}; + + +// Explicit instantiation of the whole class : +template class CGAL::Regular_triangulation_3; + + +typedef CGAL::Regular_triangulation_3 Cls; + +typedef traits::Bare_point Point; +typedef traits::Weighted_point Weighted_point; + +typedef Cls::Vertex_handle Vertex_handle; + +// We don't want to use compare_xyz because it thinks two weighted points +// located at the same place with different weights are identical. +struct less_xyzw +{ + bool operator() (const Weighted_point &p, + const Weighted_point &q) const + { + if (p.x() < q.x()) return true; if (p.x() > q.x()) return false; + if (p.y() < q.y()) return true; if (p.y() > q.y()) return false; + if (p.z() < q.z()) return true; if (p.z() > q.z()) return false; + if (p.weight() < q.weight()) return true; + return false; + } +}; + +typedef std::set point_set; +typedef point_set::iterator set_iterator; + +// Base class for a weighted point generator. +class point_iterator +{ + Weighted_point _wp; + int _i; +public: + point_iterator (int i = 0) : _i (i) {} + + void operator++ () { --_i; } + const Weighted_point &operator* () const { return _wp; } + bool operator== (const point_iterator &i) const { return _i == i._i; } + bool operator!= (const point_iterator &i) const { return ! (*this == i); } + +protected: + void set_point (int x, int y, int z, int w) + { + _wp = Weighted_point (Point (x, y, z), w); + } +}; + +static boost::minstd_rand randgen; + +// point_iterator_x generates points randomly on a grid (thus making lots of +// degenerate cases), staying in dimension x. +struct point_iterator_0 : public point_iterator +{ + point_iterator_0 () {} + point_iterator_0 (int i) : point_iterator(i + 1) { ++*this; } + + void operator++ () + { + int w = randgen() % 10; + set_point (0, 0, 0, w); + point_iterator::operator++(); + } +}; + +struct point_iterator_1 : public point_iterator +{ + point_iterator_1 () {} + point_iterator_1 (int i) : point_iterator(i + 1) { ++*this; } + + void operator++ () + { + int x = randgen() % 10; + int w = randgen() % 10; + set_point (x, 0, 0, w); + point_iterator::operator++(); + } +}; + +struct point_iterator_2 : public point_iterator +{ + point_iterator_2 () {} + point_iterator_2 (int i) : point_iterator(i + 1) { ++*this; } + + void operator++ () + { + int x = randgen() % 10; + int y = randgen() % 10; + int w = randgen() % 10; + set_point (x, y, 0, w); + point_iterator::operator++(); + } +}; + +struct point_iterator_3 : public point_iterator +{ + point_iterator_3 () {} + point_iterator_3 (int i) : point_iterator(i + 1) { ++*this; } + + void operator++ () + { + int x = randgen() % 10; + int y = randgen() % 10; + int z = randgen() % 10; + int w = randgen() % 10; + set_point (x, y, z, w); + point_iterator::operator++(); + } +}; + +class point_reader +{ + std::istream *in; + Weighted_point wp; + int nb; +public: + point_reader () : in (0), wp(), nb(0) {} + point_reader (std::istream &is) : in(&is) + { + if (*in >> nb) { + ++nb; + ++*this; + } else + nb = 0; + } + point_reader &operator++ () + { + if (nb > 0) { + --nb; + if (nb > 0) *in >> wp; + } + return *this; + } + bool operator== (const point_reader& p) const { return nb == p.nb; } + bool operator!= (const point_reader& p) const { return nb != p.nb; } + const Weighted_point &operator*() const { return wp; } +}; + +// Inserts number points in the triangulation and the multiset, using PI as the +// point generator. +template < class PI > +void insert (Cls &T, point_set &points, int number) +{ + int i = 1; + for (PI pi (number), pend; pi != pend; ++pi, ++i) { + points.insert (*pi); + T.insert (*pi); + std::cout << "\r number of inserted points: " << i << std::flush; + } + std::cout << std::endl; + assert(T.is_valid()); + std::cout << " number of vertices: " << T.number_of_vertices() + << std::endl; + + std::cout << " number of degeneracies: " << degeneracy_counter << std::endl; + degeneracy_counter = 0; +} + +// Removes number points from T, and removes each one from points also. +// Checks that each point of T that is removed exists in points. +void remove (Cls &T, point_set &points, int number) +{ + for (int i = 1; !points.empty(); ++i) + { + number--; + assert(T.number_of_vertices() != 0); + Vertex_handle v = T.finite_vertices_begin(); + set_iterator pos = points.find (v->point()); + assert(pos != points.end()); + T.remove (v); + points.erase (pos); + std::cout << "\r number of removed points: " << i << std::flush; + } + std::cout << std::endl; + + assert(number >= 0); + assert(T.number_of_vertices() == 0); + assert(T.is_valid()); + assert(points.empty()); + std::cout << " number of degeneracies: " << degeneracy_counter << std::endl; + degeneracy_counter = 0; +} + +// Adds p which is supposed to increase the dimension of T from dim to dim+1, +// then removes it. +void dim_jump (Cls &T, const Point &p, int dim) +{ + assert(T.dimension() == dim); + + Vertex_handle v = T.insert (Weighted_point (p, 0)); + assert(T.is_valid()); + assert(v != Vertex_handle()); + assert(T.dimension() == dim + 1); + + T.remove (v); + assert(T.is_valid()); + assert(T.dimension() == dim); +} + + +bool test_case (std::istream &is) +{ + point_reader pi (is), pend; + if (pi == pend) return false; + + point_set points; + Cls T; + int number = 0; + + do { + ++number; + points.insert (*pi); + T.insert (*pi); + } while (++pi != pend); + assert(T.is_valid()); + + for (int i = 0; !points.empty(); ++i) { + assert(T.number_of_vertices() != 0); + Vertex_handle v = T.finite_vertices_begin(); + set_iterator pos = points.find (v->point()); + assert(pos != points.end()); + T.remove (v); + points.erase(pos); + } + assert(T.number_of_vertices() == 0); + assert(points.empty()); + + return true; +} + +int main(int argc, char **argv) +{ + std::cout << " with CGAL::Regular_triangulation_euclidean_traits_3: " + << std::endl; + + // Test various data sets that crashed the code at some point in the past. + // File format is: + // number of points of first data set + // point + // ... + // number of points of second data set + // point + // ... + { + std::ifstream fin ("data/regular_remove_3"); + assert(fin); + std:: cout << " test `data/regular_remove_3'" << std::endl; + while (test_case (fin)) + // semicolon + ; + } + + // Hardcoded seeds so that the test-suite is deterministic. + boost::int32_t seed0 = 42, seed1 = 43, seed2 = 42, seed3 = 42; + + // You can also pass seeds on the command line. + if (argc > 1) std::sscanf (argv[1], "%d", &seed0); + if (argc > 2) std::sscanf (argv[2], "%d", &seed1); + if (argc > 3) std::sscanf (argv[3], "%d", &seed2); + if (argc > 4) std::sscanf (argv[4], "%d", &seed3); + + Cls T; + point_set points; + + degeneracy_counter = 0; + + std::cout << " test dimension 0" << std::endl; + randgen.seed(seed0); + + insert (T, points, 10); + dim_jump (T, Point (0, 0, 1), 0); + remove (T, points, 10); + + std::cout << " test dimension 1" << std::endl; + randgen.seed(seed1); + + insert (T, points, 20); + dim_jump (T, Point (0, 0, 1), 1); + remove (T, points, 20); + + std::cout << " test dimension 2" << std::endl; + randgen.seed(seed2); + + insert (T, points, 100); + dim_jump (T, Point (0, 0, 1), 2); + remove (T, points, 100); + + std::cout << " test dimension 3" << std::endl; + randgen.seed(seed3); + + insert (T, points, 500); + assert(T.dimension() == 3); + remove (T, points, 500); + + std::cout << " quit" << std::endl; + + return 0; +} + diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_traits_3.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_traits_3.cpp new file mode 100644 index 00000000000..ae80fcafce0 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_regular_traits_3.cpp @@ -0,0 +1,38 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// $Date$ +// +// +// Author(s) : Mariette Yvinec + +#include +#include +#include + +#include + +//needs exact constructions as well to test the traits class + +typedef CGAL::Exact_predicates_exact_constructions_kernel K; + +// Explicit instantiation of the whole class : +template class CGAL::Regular_triangulation_euclidean_traits_3; + +int main() +{ + typedef CGAL::Regular_triangulation_euclidean_traits_3 Traits; + _test_cls_regular_euclidean_traits_3(Traits() ); +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_simplex_3.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_simplex_3.cpp new file mode 100644 index 00000000000..e7128fedcd7 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_simplex_3.cpp @@ -0,0 +1,39 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Nico Kruithof + +//#define CGAL_TRIANGULATION_DONT_USE_SHORT_NAMES + +#include + +bool del = false; + +#include +#include + +// Explicit instantiation of the whole class : +template class CGAL::Triangulation_3; + +int main() +{ + typedef CGAL::Triangulation_3 Cls3; + + _test_cls_triangulation_simplex_3( Cls3() ); + + return 0; +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_static_filters.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_static_filters.cpp new file mode 100644 index 00000000000..9ed41961da7 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_static_filters.cpp @@ -0,0 +1,250 @@ +#define CGAL_PROFILE +#undef CGAL_NO_STATIC_FILTERS + + +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian Double_kernel; +typedef CGAL::Simple_cartesian > Exact_kernel; +typedef CGAL::Filtered_kernel FK_with_SF; +typedef CGAL::Filtered_kernel FK_without_SF; + +typedef CGAL::Regular_triangulation_euclidean_traits_3 Exact_traits; +typedef CGAL::Regular_triangulation_euclidean_traits_3 FTr_without_SF; +typedef CGAL::Regular_triangulation_euclidean_traits_3 FTr_with_SF; +typedef std::pair NT_pair; + +template < class K1, class K2, class Cmp = CGAL::dont_check_equal > +class Regular_traits_checker : public CGAL::Kernel_checker +{ +public: + + typedef CGAL::Comparison_result Comparison_result; + typedef CGAL::Oriented_side Oriented_side; + + typedef K1 Kernel1; + typedef K2 Kernel2; + typedef Cmp Comparator; + + // Kernel objects are defined as pairs, with primitives run in parallel. +#define CGAL_kc_pair(X) typedef std::pair X; + + CGAL_kc_pair(Weighted_point_3) + +#undef CGAL_kc_pair + +#define CGAL_Kernel_pred(X, Y) \ + typedef CGAL::Primitive_checker X; \ + X Y() const { return X(this->k1.Y(), this->k2.Y(), this->cmp); } + +#define CGAL_Kernel_cons(Y,Z) CGAL_Kernel_pred(Y,Z) + +public: + + CGAL_Kernel_pred(Compare_weighted_squared_radius_3,compare_weighted_squared_radius_3_object) + CGAL_Kernel_pred(Power_test_3,power_test_3_object) +}; + + +typedef Regular_traits_checker< FTr_with_SF, + FTr_without_SF> K3; + +typedef K3::Weighted_point_3 Weighted_point_3; + + +CGAL::Random *r; + +double rand_base() +{ + return r->get_double(0, 1); +} + +// Random double almost in [0;1]. +double my_rand() +{ + // Ensure 53 random bits, not 48. + return rand_base() + rand_base()/1024; +} + +// Random point in unit cube. +Weighted_point_3 my_rand_wp3() +{ + double x = my_rand(), y = my_rand(), z = my_rand(), r=my_rand(); + return Weighted_point_3( FTr_with_SF::Weighted_point_3(FTr_with_SF::Bare_point(x, y, z),r) , FTr_without_SF::Weighted_point_3(FTr_without_SF::Bare_point(x, y, z),r) ); +} + +// Perturbation with given maximum relative epsilon. +void perturb(Weighted_point_3 &p, double rel_eps) +{ + double x = p.first.x()*(1+rand_base()*rel_eps); + double y = p.first.y()*(1+rand_base()*rel_eps); + double z = p.first.z()*(1+rand_base()*rel_eps); + double r= p.first.weight()*(1+rand_base()*rel_eps); + p=Weighted_point_3( FTr_with_SF::Weighted_point_3(FTr_with_SF::Bare_point(x, y, z),r) , FTr_without_SF::Weighted_point_3(FTr_without_SF::Bare_point(x, y, z),r) ); +} + +void toto (int){} + +void test_compare_weighted_squared_radius_3(){ + Weighted_point_3 p=my_rand_wp3(); + Weighted_point_3 q=my_rand_wp3(); + Weighted_point_3 r=my_rand_wp3(); + Weighted_point_3 s=my_rand_wp3(); + double alpha=my_rand(); + + + //test with random points + random alpha + K3().compare_weighted_squared_radius_3_object()(p,q,r,s,NT_pair(alpha,alpha)); + K3().compare_weighted_squared_radius_3_object()(p,q,r, NT_pair(alpha,alpha)); + K3().compare_weighted_squared_radius_3_object()(p,q, NT_pair(alpha,alpha)); + K3().compare_weighted_squared_radius_3_object()(p, NT_pair(alpha,alpha)); + + CGAL::Weighted_converter_3,FTr_with_SF,Exact_traits > convert_to_exact; + Exact_traits::Weighted_point_3 p_e=convert_to_exact(p.first); + Exact_traits::Weighted_point_3 q_e=convert_to_exact(q.first); + Exact_traits::Weighted_point_3 r_e=convert_to_exact(r.first); + Exact_traits::Weighted_point_3 s_e=convert_to_exact(s.first); + + Exact_traits::Compute_squared_radius_smallest_orthogonal_sphere_3 radius=Exact_traits().compute_squared_radius_smallest_orthogonal_sphere_3_object(); + double alpha_pqrs=CGAL::to_double( radius(p_e,q_e,r_e,s_e) ); + double alpha_pqr =CGAL::to_double( radius(p_e,q_e,r_e) ); + double alpha_pq =CGAL::to_double( radius(p_e,q_e) ); + double alpha_p = - p.first.weight(); + + //test with random points + alpha limit + K3().compare_weighted_squared_radius_3_object()(p,q,r,s,NT_pair(alpha_pqrs,alpha_pqrs)); + K3().compare_weighted_squared_radius_3_object()(p,q,r, NT_pair(alpha_pqr,alpha_pqr)); + K3().compare_weighted_squared_radius_3_object()(p,q, NT_pair(alpha_pq,alpha_pq)); + K3().compare_weighted_squared_radius_3_object()(p, NT_pair(alpha_p,alpha_p)); + //test correct result + assert( K3().compare_weighted_squared_radius_3_object()(p,q,r,s,NT_pair(alpha_pqrs-0.1,alpha_pqrs-0.1)) ==CGAL::POSITIVE ); + assert( K3().compare_weighted_squared_radius_3_object()(p,q,r, NT_pair(alpha_pqr-0.1,alpha_pqr-0.1)) ==CGAL::POSITIVE ); + assert( K3().compare_weighted_squared_radius_3_object()(p,q, NT_pair(alpha_pq-0.1,alpha_pq-0.1)) ==CGAL::POSITIVE ); + assert( K3().compare_weighted_squared_radius_3_object()(p, NT_pair(alpha_p-0.1,alpha_p-0.1)) ==CGAL::POSITIVE ); + + // Then with some perturbation on coordinates and weight. + perturb(p, 1.0/(1<<25)/(1<<20)); // 2^-45 + + K3().compare_weighted_squared_radius_3_object()(p,q,r,s,NT_pair(alpha_pqrs,alpha_pqrs)); + K3().compare_weighted_squared_radius_3_object()(p,q,r, NT_pair(alpha_pqr,alpha_pqr)); + K3().compare_weighted_squared_radius_3_object()(p,q, NT_pair(alpha_pq,alpha_pq)); + K3().compare_weighted_squared_radius_3_object()(p, NT_pair(alpha_p,alpha_p)); + +} + +void test_power_test_3(){ + + CGAL::Weighted_converter_3,Exact_traits,FTr_with_SF > convert_to_double; + CGAL::Weighted_converter_3,Exact_traits,FTr_without_SF > convert_to_double_noSF; + CGAL::Weighted_converter_3,FTr_without_SF,Exact_traits > convert_to_exact; + + Weighted_point_3 p=my_rand_wp3(); + Weighted_point_3 q=my_rand_wp3(); + Weighted_point_3 r=my_rand_wp3(); + Weighted_point_3 s=my_rand_wp3(); + Weighted_point_3 query_pt=my_rand_wp3(); + + //test with random points + K3().power_test_3_object()(p,q,r,s,query_pt); + K3().power_test_3_object()(p,q,r,query_pt); + K3().power_test_3_object()(p,q,query_pt); + K3().power_test_3_object()(p,query_pt); + + //test in degenerate case + Exact_traits::Weighted_point_3::Point origin(0,0,0); + Exact_traits::Weighted_point_3 p_e=convert_to_exact(p.second); + Exact_traits::Weighted_point_3 q_e=convert_to_exact(q.second); + Exact_traits::Weighted_point_3 r_e=convert_to_exact(r.second); + Exact_traits::Weighted_point_3 s_e=convert_to_exact(s.second); + + Exact_traits::Weighted_point_3 tmp=Exact_traits::Weighted_point_3( + origin, + CGAL::squared_distance(origin,Exact_traits().construct_weighted_circumcenter_3_object()(p_e,q_e,r_e,s_e))- + Exact_traits().compute_squared_radius_smallest_orthogonal_sphere_3_object()(p_e,q_e,r_e,s_e) + ); + assert(Exact_traits().power_test_3_object()(p_e,q_e,r_e,s_e,tmp)==CGAL::ON_ORIENTED_BOUNDARY); + + Weighted_point_3 ortho_pqrs( convert_to_double(tmp),convert_to_double_noSF(tmp) ); + tmp=Exact_traits::Weighted_point_3( + Exact_traits().construct_weighted_circumcenter_3_object()(p_e,q_e,r_e), + -Exact_traits().compute_squared_radius_smallest_orthogonal_sphere_3_object()(p_e,q_e,r_e) + ); + assert(Exact_traits().power_test_3_object()(p_e,q_e,r_e,tmp)==CGAL::ON_ORIENTED_BOUNDARY); + Weighted_point_3 ortho_pqr( convert_to_double(tmp),convert_to_double_noSF(tmp) ); + tmp=Exact_traits::Weighted_point_3( + Exact_traits().construct_weighted_circumcenter_3_object()(p_e,q_e), + -Exact_traits().compute_squared_radius_smallest_orthogonal_sphere_3_object()(p_e,q_e) + ); + assert(Exact_traits().power_test_3_object()(p_e,q_e,tmp)==CGAL::ON_ORIENTED_BOUNDARY); + Weighted_point_3 ortho_pq( convert_to_double(tmp),convert_to_double_noSF(tmp) ); + + + K3().power_test_3_object()(p,q,r,s,ortho_pqrs); + K3().power_test_3_object()(p,q,r ,ortho_pqr); + K3().power_test_3_object()(p,q ,ortho_pq); + // Then with some perturbation on coordinates and weight. + perturb(p, 1.0/(1<<25)/(1<<20)); // 2^-45 + + K3().power_test_3_object()(p,q,r,s,ortho_pqrs); + K3().power_test_3_object()(p,q,r ,ortho_pqr); + K3().power_test_3_object()(p,q ,ortho_pq); +} + + +int main(int argc, char **argv) +{ + assert(! Exact_traits::Has_filtered_predicates); + assert( FTr_with_SF::Has_filtered_predicates); + assert( FTr_without_SF::Has_filtered_predicates); + + + assert(! FTr_without_SF::Has_static_filters); + assert( FTr_with_SF::Has_static_filters); + + + + int loops = (argc < 2) ? 2000 : std::atoi(argv[1]); + int seed = (argc < 3) ? CGAL::default_random.get_int(0, 1<<30) + : std::atoi(argv[2]); + + std::cout << "Initializing random generator with seed = " << seed + << std::endl + << "#loops = " << loops << " (can be changed on the command line)" + << std::endl; + + CGAL::Random rnd(seed); + r = &rnd; + + std::cout.precision(20); + std::cerr.precision(20); + + std::cout << "ulp(1) = " << CGAL::internal::Static_filter_error::ulp() << std::endl; + + std::cout << "Testing Compare_weighted_squared_radius_3" << std::endl; + for(int i=0; i +#include + +bool del = false; + +#include +#include +#include + +// Explicit instantiation of the whole class : +template class CGAL::Triangulation_3; + +int main() +{ + typedef CGAL::Triangulation_3 Cls3; + + _test_cls_triangulation_3( Cls3() ); + + // Test operator== between triangulations of different Tds types. + + typedef CGAL::Triangulation_3 > > Cls3_2; + + assert(Cls3() == Cls3_2()); + std::cout << "done" << std::endl; + return 0; +} diff --git a/Triangulation_3_copy_tds/test/Triangulation_3/test_triangulation_tds.cpp b/Triangulation_3_copy_tds/test/Triangulation_3/test_triangulation_tds.cpp new file mode 100644 index 00000000000..13cd5d6b8a1 --- /dev/null +++ b/Triangulation_3_copy_tds/test/Triangulation_3/test_triangulation_tds.cpp @@ -0,0 +1,33 @@ +// Copyright (c) 1998 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $URL$ +// $Id$ +// +// +// Author(s) : Francois Rebufat + +#include + +#include + +typedef CGAL::Triangulation_data_structure_3<> Tds; + +// Explicit instantiation : +template class CGAL::Triangulation_data_structure_3<>; + +int main() +{ + _test_cls_tds_3(Tds()); + return 0; +}