From 0a1b5756e5cbfa6beac0ec2f2390308727542d26 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Tue, 6 Jun 2006 13:38:15 +0000 Subject: [PATCH] Copy Mesh_2, Mesh_3 and Surface_mesher, from the branch "cannot_wait_for_CGAL-3.2" to the trunk. My idea: the branch is the real working version, and I want it to be joined back to the trunk: __________________________ cannot_wait_for_CGAL-3.2 branch / \ / \ -------------------------------------------- trunk S M The modification of the trunk between the splitting point S and the merging point M has already been merged into "cannot_wait_for_CGAL-3.2". The trunk versions of these three packages have been removed already. --- .gitattributes | 24 + .gitignore | 65 + Mesh_2/Doxyfile | 220 +++ Mesh_2/GNUmakefile | 56 + Mesh_2/Mesh_2.kdevelop | 170 ++ Mesh_2/Mesh_2.kdevelop.filelist | 30 + Mesh_2/README | 3 + Mesh_2/TODO | 22 + Mesh_2/bench/GNUmakefile | 68 + Mesh_2/bench/bench.C | 137 ++ Mesh_2/bench/data/square-deforme.poly | 16 + Mesh_2/bench/data/square.poly | 16 + Mesh_2/changes.txt | 310 ++++ Mesh_2/demo/Mesh_2/Debug_layer.h | 46 + Mesh_2/demo/Mesh_2/GNUmakefile | 29 + Mesh_2/demo/Mesh_2/Qt_layer_show_circles.h | 159 ++ .../demo/Mesh_2/Qt_layer_show_triangulation.h | 76 + .../Qt_layer_show_triangulation_constraints.h | 83 + .../demo/Mesh_2/Qt_widget_style_editor-aux.h | 144 ++ Mesh_2/demo/Mesh_2/Qt_widget_style_editor.C | 129 ++ Mesh_2/demo/Mesh_2/Qt_widget_style_editor.h | 55 + Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.C | 127 ++ Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.h | 95 ++ Mesh_2/demo/Mesh_2/Show_clusters.h | 213 +++ Mesh_2/demo/Mesh_2/Show_points.C | 72 + Mesh_2/demo/Mesh_2/Show_points.h | 129 ++ Mesh_2/demo/Mesh_2/Show_segments.h | 97 ++ Mesh_2/demo/Mesh_2/Show_segments_base.C | 63 + Mesh_2/demo/Mesh_2/Show_segments_base.h | 53 + Mesh_2/demo/Mesh_2/conform.C | 159 ++ Mesh_2/demo/Mesh_2/contraints.xpm | 37 + Mesh_2/demo/Mesh_2/data/butterfly.edg | 34 + Mesh_2/demo/Mesh_2/data/clusters.edg | 9 + Mesh_2/demo/Mesh_2/data/clusters.poly | 33 + Mesh_2/demo/Mesh_2/data/clusters2.edg | 48 + Mesh_2/demo/Mesh_2/data/fish.edg | 17 + Mesh_2/demo/Mesh_2/data/fish.poly | 40 + Mesh_2/demo/Mesh_2/data/img1.edg | 44 + Mesh_2/demo/Mesh_2/data/img2.edg | 11 + Mesh_2/demo/Mesh_2/data/img3.edg | 4 + Mesh_2/demo/Mesh_2/data/img4.edg | 11 + Mesh_2/demo/Mesh_2/data/img5.edg | 275 +++ Mesh_2/demo/Mesh_2/data/img6.edg | 45 + Mesh_2/demo/Mesh_2/data/img7.edg | 33 + Mesh_2/demo/Mesh_2/data/img8.edg | 7 + Mesh_2/demo/Mesh_2/data/lettre_A.edg | 30 + Mesh_2/demo/Mesh_2/data/lettre_A_2.edg | 19 + Mesh_2/demo/Mesh_2/data/trivial.poly | 17 + Mesh_2/demo/Mesh_2/icons.C | 34 + Mesh_2/demo/Mesh_2/icons.h | 28 + Mesh_2/demo/Mesh_2/makefile | 121 ++ Mesh_2/demo/Mesh_2/marked.xpm | 39 + Mesh_2/demo/Mesh_2/mesh.C | 155 ++ Mesh_2/demo/Mesh_2/mesh_demo.C | 1512 +++++++++++++++++ Mesh_2/demo/Mesh_2/mesh_demo.vcproj | 348 ++++ Mesh_2/demo/Mesh_2/seeds.xpm | 39 + Mesh_2/description.txt | 1 + Mesh_2/doc_tex/GNUmakefile | 9 + Mesh_2/doc_tex/Mesh_2/PkgDescription.tex | 22 + Mesh_2/doc_tex/Mesh_2/domain-mesh.eps | Bin 0 -> 351336 bytes Mesh_2/doc_tex/Mesh_2/domain-mesh.png | Bin 0 -> 27035 bytes Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.eps | Bin 0 -> 291524 bytes Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.png | Bin 0 -> 26218 bytes Mesh_2/doc_tex/Mesh_2/domain-seeds.eps | Bin 0 -> 281875 bytes Mesh_2/doc_tex/Mesh_2/domain-seeds.png | Bin 0 -> 5183 bytes Mesh_2/doc_tex/Mesh_2/domain.eps | Bin 0 -> 353487 bytes Mesh_2/doc_tex/Mesh_2/domain.png | Bin 0 -> 5046 bytes .../Mesh_2/example-conform-Delaunay.eps | Bin 0 -> 42063 bytes .../Mesh_2/example-conform-Delaunay.png | Bin 0 -> 4500 bytes .../Mesh_2/example-conform-Gabriel.eps | Bin 0 -> 53624 bytes .../Mesh_2/example-conform-Gabriel.png | Bin 0 -> 10223 bytes Mesh_2/doc_tex/Mesh_2/example-conform.eps | Bin 0 -> 39479 bytes Mesh_2/doc_tex/Mesh_2/example-conform.png | Bin 0 -> 3893 bytes Mesh_2/doc_tex/Mesh_2/main.tex | 355 ++++ ...onformingDelaunayTriangulationTraits_2.tex | 72 + .../Mesh_2_ref/DelaunayMeshFaceBase_2.tex | 32 + .../Mesh_2_ref/DelaunayMeshTraits_2.tex | 39 + .../Mesh_2_ref/Delaunay_mesh_criteria_2.tex | 34 + .../Mesh_2_ref/Delaunay_mesh_face_base_2.tex | 33 + .../Delaunay_mesh_size_criteria_2.tex | 41 + .../doc_tex/Mesh_2_ref/Delaunay_mesher_2.tex | 154 ++ Mesh_2/doc_tex/Mesh_2_ref/Face_badness.tex | 12 + Mesh_2/doc_tex/Mesh_2_ref/Mesher_level.tex | 302 ++++ .../doc_tex/Mesh_2_ref/MeshingCriteria_2.tex | 79 + .../Mesh_2_ref/Triangulation_conformer_2.tex | 115 ++ Mesh_2/doc_tex/Mesh_2_ref/intro.tex | 32 + Mesh_2/doc_tex/Mesh_2_ref/main.tex | 25 + .../Mesh_2_ref/make_conforming_Delaunay_2.tex | 21 + .../Mesh_2_ref/make_conforming_Gabriel_2.tex | 22 + .../doc_tex/Mesh_2_ref/part_of_a_cluster.eps | 133 ++ .../doc_tex/Mesh_2_ref/part_of_a_cluster.gif | Bin 0 -> 26024 bytes .../Mesh_2_ref/refine_Delaunay_mesh_2.tex | 48 + Mesh_2/dont_submit | 11 + Mesh_2/examples/Mesh_2/GNUmakefile | 34 + Mesh_2/examples/Mesh_2/conforming.C | 52 + Mesh_2/examples/Mesh_2/makefile | 68 + Mesh_2/examples/Mesh_2/mesh_class.C | 55 + Mesh_2/examples/Mesh_2/mesh_global.C | 42 + Mesh_2/examples/Mesh_2/mesh_with_seeds.C | 55 + .../CGAL/Delaunay_mesh_area_criteria_2.h | 134 ++ .../include/CGAL/Delaunay_mesh_criteria_2.h | 113 ++ .../include/CGAL/Delaunay_mesh_face_base_2.h | 79 + .../Delaunay_mesh_local_size_criteria_2.h | 129 ++ .../CGAL/Delaunay_mesh_size_criteria_2.h | 189 +++ Mesh_2/include/CGAL/Delaunay_mesher_2.h | 366 ++++ Mesh_2/include/CGAL/Double_map.h | 218 +++ Mesh_2/include/CGAL/Filter_circulator.h | 98 ++ Mesh_2/include/CGAL/IO/File_poly.h | 164 ++ Mesh_2/include/CGAL/Mesh_2/Clusters.h | 558 ++++++ Mesh_2/include/CGAL/Mesh_2/Face_badness.h | 30 + .../CGAL/Mesh_2/Filtered_queue_container.h | 101 ++ Mesh_2/include/CGAL/Mesh_2/README | 6 + Mesh_2/include/CGAL/Mesh_2/Refine_edges.h | 642 +++++++ .../CGAL/Mesh_2/Refine_edges_visitor.h | 158 ++ .../CGAL/Mesh_2/Refine_edges_with_clusters.h | 308 ++++ Mesh_2/include/CGAL/Mesh_2/Refine_faces.h | 437 +++++ .../Triangulation_mesher_level_traits_2.h | 78 + .../Triangulation_mesher_level_traits_3.h | 109 ++ Mesh_2/include/CGAL/Mesher_level.h | 375 ++++ .../Mesher_level_default_implementations.h | 137 ++ Mesh_2/include/CGAL/Mesher_level_visitors.h | 128 ++ .../include/CGAL/Triangulation_conformer_2.h | 262 +++ Mesh_2/maintainer | 1 + Mesh_2/stylesheet.css | 213 +++ Mesh_2/test/Mesh_2/GNUmakefile | 73 + Mesh_2/test/Mesh_2/fish-and-rectangle.poly | 86 + Mesh_2/test/Mesh_2/fish.edg | 17 + Mesh_2/test/Mesh_2/fish.poly | 40 + Mesh_2/test/Mesh_2/test_conforming.C | 102 ++ Mesh_2/test/Mesh_2/test_double_map.C | 80 + Mesh_2/test/Mesh_2/test_filtred_container.C | 42 + Mesh_2/test/Mesh_2/test_meshing.C | 167 ++ Mesh_2/utils/Mesh_2/polygon2poly.C | 62 + 133 files changed, 13456 insertions(+) create mode 100644 Mesh_2/Doxyfile create mode 100644 Mesh_2/GNUmakefile create mode 100644 Mesh_2/Mesh_2.kdevelop create mode 100644 Mesh_2/Mesh_2.kdevelop.filelist create mode 100644 Mesh_2/README create mode 100644 Mesh_2/TODO create mode 100644 Mesh_2/bench/GNUmakefile create mode 100644 Mesh_2/bench/bench.C create mode 100644 Mesh_2/bench/data/square-deforme.poly create mode 100644 Mesh_2/bench/data/square.poly create mode 100644 Mesh_2/changes.txt create mode 100644 Mesh_2/demo/Mesh_2/Debug_layer.h create mode 100644 Mesh_2/demo/Mesh_2/GNUmakefile create mode 100644 Mesh_2/demo/Mesh_2/Qt_layer_show_circles.h create mode 100644 Mesh_2/demo/Mesh_2/Qt_layer_show_triangulation.h create mode 100644 Mesh_2/demo/Mesh_2/Qt_layer_show_triangulation_constraints.h create mode 100644 Mesh_2/demo/Mesh_2/Qt_widget_style_editor-aux.h create mode 100644 Mesh_2/demo/Mesh_2/Qt_widget_style_editor.C create mode 100644 Mesh_2/demo/Mesh_2/Qt_widget_style_editor.h create mode 100644 Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.C create mode 100644 Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.h create mode 100644 Mesh_2/demo/Mesh_2/Show_clusters.h create mode 100644 Mesh_2/demo/Mesh_2/Show_points.C create mode 100644 Mesh_2/demo/Mesh_2/Show_points.h create mode 100644 Mesh_2/demo/Mesh_2/Show_segments.h create mode 100644 Mesh_2/demo/Mesh_2/Show_segments_base.C create mode 100644 Mesh_2/demo/Mesh_2/Show_segments_base.h create mode 100644 Mesh_2/demo/Mesh_2/conform.C create mode 100644 Mesh_2/demo/Mesh_2/contraints.xpm create mode 100644 Mesh_2/demo/Mesh_2/data/butterfly.edg create mode 100644 Mesh_2/demo/Mesh_2/data/clusters.edg create mode 100644 Mesh_2/demo/Mesh_2/data/clusters.poly create mode 100644 Mesh_2/demo/Mesh_2/data/clusters2.edg create mode 100644 Mesh_2/demo/Mesh_2/data/fish.edg create mode 100644 Mesh_2/demo/Mesh_2/data/fish.poly create mode 100644 Mesh_2/demo/Mesh_2/data/img1.edg create mode 100644 Mesh_2/demo/Mesh_2/data/img2.edg create mode 100644 Mesh_2/demo/Mesh_2/data/img3.edg create mode 100644 Mesh_2/demo/Mesh_2/data/img4.edg create mode 100644 Mesh_2/demo/Mesh_2/data/img5.edg create mode 100644 Mesh_2/demo/Mesh_2/data/img6.edg create mode 100644 Mesh_2/demo/Mesh_2/data/img7.edg create mode 100644 Mesh_2/demo/Mesh_2/data/img8.edg create mode 100644 Mesh_2/demo/Mesh_2/data/lettre_A.edg create mode 100644 Mesh_2/demo/Mesh_2/data/lettre_A_2.edg create mode 100644 Mesh_2/demo/Mesh_2/data/trivial.poly create mode 100644 Mesh_2/demo/Mesh_2/icons.C create mode 100644 Mesh_2/demo/Mesh_2/icons.h create mode 100644 Mesh_2/demo/Mesh_2/makefile create mode 100644 Mesh_2/demo/Mesh_2/marked.xpm create mode 100644 Mesh_2/demo/Mesh_2/mesh.C create mode 100644 Mesh_2/demo/Mesh_2/mesh_demo.C create mode 100644 Mesh_2/demo/Mesh_2/mesh_demo.vcproj create mode 100644 Mesh_2/demo/Mesh_2/seeds.xpm create mode 100644 Mesh_2/description.txt create mode 100644 Mesh_2/doc_tex/GNUmakefile create mode 100644 Mesh_2/doc_tex/Mesh_2/PkgDescription.tex create mode 100644 Mesh_2/doc_tex/Mesh_2/domain-mesh.eps create mode 100644 Mesh_2/doc_tex/Mesh_2/domain-mesh.png create mode 100644 Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.eps create mode 100644 Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.png create mode 100644 Mesh_2/doc_tex/Mesh_2/domain-seeds.eps create mode 100644 Mesh_2/doc_tex/Mesh_2/domain-seeds.png create mode 100644 Mesh_2/doc_tex/Mesh_2/domain.eps create mode 100644 Mesh_2/doc_tex/Mesh_2/domain.png create mode 100644 Mesh_2/doc_tex/Mesh_2/example-conform-Delaunay.eps create mode 100644 Mesh_2/doc_tex/Mesh_2/example-conform-Delaunay.png create mode 100644 Mesh_2/doc_tex/Mesh_2/example-conform-Gabriel.eps create mode 100644 Mesh_2/doc_tex/Mesh_2/example-conform-Gabriel.png create mode 100644 Mesh_2/doc_tex/Mesh_2/example-conform.eps create mode 100644 Mesh_2/doc_tex/Mesh_2/example-conform.png create mode 100644 Mesh_2/doc_tex/Mesh_2/main.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/ConformingDelaunayTriangulationTraits_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/DelaunayMeshFaceBase_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/DelaunayMeshTraits_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_criteria_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_face_base_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_size_criteria_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesher_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/Face_badness.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/Mesher_level.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/MeshingCriteria_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/Triangulation_conformer_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/intro.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/main.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/make_conforming_Delaunay_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/make_conforming_Gabriel_2.tex create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.eps create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.gif create mode 100644 Mesh_2/doc_tex/Mesh_2_ref/refine_Delaunay_mesh_2.tex create mode 100644 Mesh_2/dont_submit create mode 100644 Mesh_2/examples/Mesh_2/GNUmakefile create mode 100644 Mesh_2/examples/Mesh_2/conforming.C create mode 100644 Mesh_2/examples/Mesh_2/makefile create mode 100644 Mesh_2/examples/Mesh_2/mesh_class.C create mode 100644 Mesh_2/examples/Mesh_2/mesh_global.C create mode 100644 Mesh_2/examples/Mesh_2/mesh_with_seeds.C create mode 100644 Mesh_2/include/CGAL/Delaunay_mesh_area_criteria_2.h create mode 100644 Mesh_2/include/CGAL/Delaunay_mesh_criteria_2.h create mode 100644 Mesh_2/include/CGAL/Delaunay_mesh_face_base_2.h create mode 100644 Mesh_2/include/CGAL/Delaunay_mesh_local_size_criteria_2.h create mode 100644 Mesh_2/include/CGAL/Delaunay_mesh_size_criteria_2.h create mode 100644 Mesh_2/include/CGAL/Delaunay_mesher_2.h create mode 100644 Mesh_2/include/CGAL/Double_map.h create mode 100644 Mesh_2/include/CGAL/Filter_circulator.h create mode 100644 Mesh_2/include/CGAL/IO/File_poly.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/Clusters.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/Face_badness.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/Filtered_queue_container.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/README create mode 100644 Mesh_2/include/CGAL/Mesh_2/Refine_edges.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/Refine_edges_visitor.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/Refine_edges_with_clusters.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/Refine_faces.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/Triangulation_mesher_level_traits_2.h create mode 100644 Mesh_2/include/CGAL/Mesh_2/Triangulation_mesher_level_traits_3.h create mode 100644 Mesh_2/include/CGAL/Mesher_level.h create mode 100644 Mesh_2/include/CGAL/Mesher_level_default_implementations.h create mode 100644 Mesh_2/include/CGAL/Mesher_level_visitors.h create mode 100644 Mesh_2/include/CGAL/Triangulation_conformer_2.h create mode 100644 Mesh_2/maintainer create mode 100644 Mesh_2/stylesheet.css create mode 100644 Mesh_2/test/Mesh_2/GNUmakefile create mode 100644 Mesh_2/test/Mesh_2/fish-and-rectangle.poly create mode 100644 Mesh_2/test/Mesh_2/fish.edg create mode 100644 Mesh_2/test/Mesh_2/fish.poly create mode 100644 Mesh_2/test/Mesh_2/test_conforming.C create mode 100644 Mesh_2/test/Mesh_2/test_double_map.C create mode 100644 Mesh_2/test/Mesh_2/test_filtred_container.C create mode 100644 Mesh_2/test/Mesh_2/test_meshing.C create mode 100644 Mesh_2/utils/Mesh_2/polygon2poly.C diff --git a/.gitattributes b/.gitattributes index fe17d311c73..d95f341b3e4 100644 --- a/.gitattributes +++ b/.gitattributes @@ -978,6 +978,30 @@ Matrix_search/doc_tex/Optimisation_ref/MatrixSearch_totmon2.gif -text svneol=uns Matrix_search/doc_tex/Optimisation_ref/MatrixSearch_totmon3.gif -text svneol=unset#unset Matrix_search/doc_tex/Optimisation_ref/MatrixSearch_totmon4.gif -text svneol=unset#unset Matrix_search/doc_tex/Optimisation_ref/MatrixSearch_totmon5.gif -text svneol=unset#unset +Mesh_2/bench/data/square-deforme.poly -text +Mesh_2/bench/data/square.poly -text +Mesh_2/demo/Mesh_2/data/clusters.poly -text +Mesh_2/demo/Mesh_2/data/fish.poly -text +Mesh_2/demo/Mesh_2/data/trivial.poly -text +Mesh_2/doc_tex/Mesh_2/domain-mesh.eps -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/domain-mesh.png -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.eps -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.png -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/domain-seeds.eps -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/domain-seeds.png -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/domain.eps -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/domain.png -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/example-conform-Delaunay.eps -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/example-conform-Delaunay.png -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/example-conform-Gabriel.eps -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/example-conform-Gabriel.png -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/example-conform.eps -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2/example-conform.png -text svneol=unset#unset +Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.eps -text +Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.gif -text svneol=unset#unset +Mesh_2/test/Mesh_2/fish-and-rectangle.poly -text +Mesh_2/test/Mesh_2/fish.edg -text +Mesh_2/test/Mesh_2/fish.poly -text Min_sphere_of_spheres_d/test_extensive/stability/maple/balls-on-boundary-2.mws -text Min_sphere_of_spheres_d/test_extensive/stability/maple/balls-on-boundary-3.mws -text Min_sphere_of_spheres_d/web/figs/heuristic/excess.eps -text diff --git a/.gitignore b/.gitignore index f1d4e08d714..0cf5a823bca 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,71 @@ Maintenance/rpm/SOURCES/Manual_tools Maintenance/rpm/SOURCES/Manual_tools-*.tar.gz Maintenance/rpm/SRPMS/* Maintenance/rpm/my_makefile +Mesh_2/bench/bench +Mesh_2/bench/semantic.cache +Mesh_2/demo/Mesh_2/*.core +Mesh_2/demo/Mesh_2/*.moc +Mesh_2/demo/Mesh_2/conform +Mesh_2/demo/Mesh_2/depends +Mesh_2/demo/Mesh_2/filename.edg +Mesh_2/demo/Mesh_2/last_input.edg +Mesh_2/demo/Mesh_2/mesh +Mesh_2/demo/Mesh_2/mesh_demo +Mesh_2/demo/Mesh_2/semantic.cache +Mesh_2/doc_html +Mesh_2/doc_pdf +Mesh_2/doc_ps +Mesh_2/doc_tex/**.aux +Mesh_2/doc_tex/*.blg +Mesh_2/doc_tex/*.cb +Mesh_2/doc_tex/*.cgallog +Mesh_2/doc_tex/*.hlg +Mesh_2/doc_tex/*.ilg +Mesh_2/doc_tex/*.log +Mesh_2/doc_tex/*.out +Mesh_2/doc_tex/*.pdflg +Mesh_2/doc_tex/*.ref +Mesh_2/doc_tex/*.tmp +Mesh_2/doc_tex/*.tmp.* +Mesh_2/doc_tex/Mesh_2/*.aux +Mesh_2/doc_tex/Mesh_2/*.core +Mesh_2/doc_tex/Mesh_2/*.dvi +Mesh_2/doc_tex/Mesh_2/*.hax +Mesh_2/doc_tex/Mesh_2/*.idx +Mesh_2/doc_tex/Mesh_2/*.log +Mesh_2/doc_tex/Mesh_2/*.mtc* +Mesh_2/doc_tex/Mesh_2/*.pdf +Mesh_2/doc_tex/Mesh_2/*.ps +Mesh_2/doc_tex/Mesh_2/_region* +Mesh_2/doc_tex/Mesh_2/semantic.cache +Mesh_2/doc_tex/Mesh_2_ref/*.aux +Mesh_2/doc_tex/Mesh_2_ref/*.core +Mesh_2/doc_tex/Mesh_2_ref/*.dvi +Mesh_2/doc_tex/Mesh_2_ref/*.hax +Mesh_2/doc_tex/Mesh_2_ref/*.idx +Mesh_2/doc_tex/Mesh_2_ref/*.log +Mesh_2/doc_tex/Mesh_2_ref/*.mtc* +Mesh_2/doc_tex/Mesh_2_ref/*.pdf +Mesh_2/doc_tex/Mesh_2_ref/*.ps +Mesh_2/doc_tex/Mesh_2_ref/_region* +Mesh_2/doc_tex/Mesh_2_ref/semantic.cache +Mesh_2/doxygen +Mesh_2/examples/Mesh_2/*.core +Mesh_2/examples/Mesh_2/conform +Mesh_2/examples/Mesh_2/conforming +Mesh_2/examples/Mesh_2/mesh +Mesh_2/examples/Mesh_2/mesh_class +Mesh_2/examples/Mesh_2/mesh_global +Mesh_2/examples/Mesh_2/mesh_with_seeds +Mesh_2/examples/Mesh_2/my_makefile +Mesh_2/examples/Mesh_2/semantic.cache +Mesh_2/include/CGAL/semantic.cache +Mesh_2/test/Mesh_2/*.core +Mesh_2/test/Mesh_2/semantic.cache +Mesh_2/test/Mesh_2/test_conforming +Mesh_2/test/Mesh_2/test_double_map +Mesh_2/test/Mesh_2/test_filtred_container +Mesh_2/test/Mesh_2/test_meshing Min_annulus_d/*.aux Min_annulus_d/*.bbl Min_annulus_d/*.blg diff --git a/Mesh_2/Doxyfile b/Mesh_2/Doxyfile new file mode 100644 index 00000000000..833084e61f6 --- /dev/null +++ b/Mesh_2/Doxyfile @@ -0,0 +1,220 @@ +# Doxyfile 1.3.8 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +PROJECT_NAME = Mesh_2 +PROJECT_NUMBER = 1.1alpha1 +OUTPUT_DIRECTORY = doxygen/ +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +USE_WINDOWS_ENCODING = NO +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = +ALWAYS_DETAILED_SEC = NO +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = YES +INHERIT_DOCS = YES +DISTRIBUTE_GROUP_DOC = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +SUBGROUPING = YES +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = YES +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = YES +EXTRACT_LOCAL_METHODS = NO +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = YES +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = YES +INLINE_INFO = YES +SORT_MEMBER_DOCS = NO +SORT_BRIEF_DOCS = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = YES +GENERATE_TESTLIST = YES +GENERATE_BUGLIST = YES +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = YES +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = include +FILE_PATTERNS = *.h +RECURSIVE = YES +EXCLUDE = include/boost \ + include/CGAL/Delaunay_mesh_2.h \ + include/CGAL/Conforming_Delaunay_triangulation_2.h +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = YES +REFERENCES_RELATION = YES +VERBATIM_HEADERS = YES +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 5 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +HTML_FOOTER = +HTML_STYLESHEET = stylesheet.css +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NO +TREEVIEW_WIDTH = 250 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = YES +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = NO +USE_PDFLATEX = NO +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = YES +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = NO +SEARCH_INCLUDES = YES +INCLUDE_PATH = /absinthe/CGAL-testsuites/CGAL-I/include/CGAL \ + /0/prisme_util/CGAL/CGAL-I/include/CGAL \ + /home/lrineau/CGAL-3.1-I-49/include +INCLUDE_FILE_PATTERNS = +PREDEFINED = "CGAL_USE_GMP CGAL_USE_QT" \ + "CGAL_BEGIN_NAMESPACE=namespace CGAL {" \ + CGAL_END_NAMESPACE=} \ + CGAL_USE_BOOST +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = YES +PERL_PATH = /usr/bin/perl +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = YES +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +UML_LOOK = YES +TEMPLATE_RELATIONS = YES +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = YES +GRAPHICAL_HIERARCHY = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +MAX_DOT_GRAPH_WIDTH = 1024 +MAX_DOT_GRAPH_HEIGHT = 1024 +MAX_DOT_GRAPH_DEPTH = 0 +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO diff --git a/Mesh_2/GNUmakefile b/Mesh_2/GNUmakefile new file mode 100644 index 00000000000..f0d9eee4f2c --- /dev/null +++ b/Mesh_2/GNUmakefile @@ -0,0 +1,56 @@ +.PHONY: all run test run-test demo examples clean update diff dep + + +all: run-test examples demo + +dep: + $(MAKE) -C demo/Mesh_2 dep + $(MAKE) -C examples/Surface_mesher dep + +run-test: + ${MAKE} -C examples/Mesh_2 run + ${MAKE} -C test/Mesh_2 run + +test: + ${MAKE} -C test/Mesh_2 + +examples: + ${MAKE} -C examples/Mesh_2 + +demo: + ${MAKE} -C demo/Mesh_2 + +run: all + demo/Mesh_2/mesh_demo + +doc: + ${MAKE} -C doc_tex + +ps: + ${MAKE} -C doc_tex ps + +doxygen: + doxygen + +# clean all object files +clean: + ${MAKE} -C demo/Mesh_2 -f makefile clean + ${MAKE} -C test/Mesh_2 clean + ${MAKE} -C examples/Mesh_2 clean + +dist-clean: clean + find . -name '.#*' -exec rm \{\} \; + find . -name '*~' -exec rm \{\} \; + rm -rf doxygen + +dist: dist-clean + tar czfv /tmp/Mesh_2.tar.gz . --exclude=CVS --exclude=TODO \ +--exclude=wrapper.tex --exclude=dont_submit --exclude-from=dont_submit + +# make update: update the working directory +update: + @svn -q update + +# make diff: diff between the cvs repository and the working copy +diff: + @svn diff | less diff --git a/Mesh_2/Mesh_2.kdevelop b/Mesh_2/Mesh_2.kdevelop new file mode 100644 index 00000000000..1e45d0f51d7 --- /dev/null +++ b/Mesh_2/Mesh_2.kdevelop @@ -0,0 +1,170 @@ + + + + Laurent Rineau + Laurent.Rineau@ens.fr + $VERSION$ + KDevCustomProject + C++ + + KDevClearCase + KDevPerforce + + . + false + + + + + + + build + / + + false + true + + + + make + demo/Mesh_2 + + + false + 1 + false + + with_boost + + + + + + + + + + + + + + + + + + + + true + false + false + + + false + true + + + + + ada + ada_bugs_gcc + bash + bash_bugs + clanlib + fortran_bugs_gcc + gnome1 + gnustep + gtk + gtk_bugs + haskell + haskell_bugs_ghc + java_bugs_gcc + java_bugs_sun + kde2book + libstdc++ + opengl + pascal_bugs_fp + php + php_bugs + perl + perl_bugs + python + python_bugs + qt-kdev3 + ruby + ruby_bugs + sdl + stl + sw + w3c-dom-level2-html + w3c-svg + w3c-uaag10 + wxwidgets_bugs + c++_bugs_gcc + libc + kdev3api + + + Guide to the Qt Translation Tools + Qt Assistant Manual + Qt Designer Manual + Qt Reference Documentation + qmake User Guide + + + KDE Libraries (Doxygen) + + + doc_html + doxygen/html/ + + + + + + + + + + + + + + .h + .C + + + + + true + true + true + true + true + true + true + 250 + 400 + 250 + + + + + + + false + false + + + *.o,*.lo,CVS + false + false + + + + true + true + true + true + -C + + diff --git a/Mesh_2/Mesh_2.kdevelop.filelist b/Mesh_2/Mesh_2.kdevelop.filelist new file mode 100644 index 00000000000..5de452eaf42 --- /dev/null +++ b/Mesh_2/Mesh_2.kdevelop.filelist @@ -0,0 +1,30 @@ +# KDevelop Custom Project File List +demo/Mesh_2/conform.C +demo/Mesh_2/icons.C +demo/Mesh_2/icons.h +demo/Mesh_2/mesh.C +demo/Mesh_2/mesh_demo.C +demo/Mesh_2/Qt_layer_show_circles.h +demo/Mesh_2/Qt_layer_show_points.h +demo/Mesh_2/Qt_layer_show_triangulation_constraints.h +demo/Mesh_2/Qt_layer_show_triangulation.h +demo/Mesh_2/Show_clusters.h +examples/Mesh_2/conform.C +examples/Mesh_2/conforming.C +examples/Mesh_2/mesh_class.C +examples/Mesh_2/mesh_global.C +examples/Mesh_2/mesh_with_seeds.C +include/CGAL/Conforming_Delaunay_triangulation_2.h +include/CGAL/Conforming_Delaunay_triangulation_traits_2.h +include/CGAL/Delaunay_mesh_2.h +include/CGAL/Delaunay_mesh_area_traits_2.h +include/CGAL/Delaunay_mesh_face_base_2.h +include/CGAL/Delaunay_mesh_local_size_traits_2.h +include/CGAL/Delaunay_mesh_size_traits_2.h +include/CGAL/Delaunay_mesh_traits_2.h +include/CGAL/Double_map.h +include/CGAL/Filter_circulator.h +include/CGAL/Filtered_container.h +test/Mesh_2/test_filtred_container.C +utils/Mesh_2/polygon2poly.C +bench/bench.C diff --git a/Mesh_2/README b/Mesh_2/README new file mode 100644 index 00000000000..92e4fb21192 --- /dev/null +++ b/Mesh_2/README @@ -0,0 +1,3 @@ + 2d meshing package + Ruppert meshing algorithm + developped by Laurent Rineau diff --git a/Mesh_2/TODO b/Mesh_2/TODO new file mode 100644 index 00000000000..a223ff35fab --- /dev/null +++ b/Mesh_2/TODO @@ -0,0 +1,22 @@ +- Rewrite get_cluster. [done] +- Use Compute_area_2 with three points instead of a triangle. [done] + +- Implement a method to split all clusters at the beginnning. + +- Histograms in the demo + +- do not use default constructor of Geom_traits + +- Rewrite Double_map.h [!] + +- draw() called twice in mesh_demo [!] + +Before CGAL-3.1: + +- Update the hierachy if CDT is a CT_plus_2. [DELAYED] +- [doc] concept CDT. +- [doc] pictures [DONE] +- [doc] document Compute_area_2 in a concept. It is used in + Delaunay_mesh_criteria_2. +- Fix clusters bug: the algorithm should ignore the Shewchuck rule when + inserting point in a *big* triangle. [DONE] diff --git a/Mesh_2/bench/GNUmakefile b/Mesh_2/bench/GNUmakefile new file mode 100644 index 00000000000..392fb927f3e --- /dev/null +++ b/Mesh_2/bench/GNUmakefile @@ -0,0 +1,68 @@ +# Created by the script cgal_create_makefile +# This is the makefile for compiling a CGAL application. + +#---------------------------------------------------------------------# +# include platform specific settings +#---------------------------------------------------------------------# +# Choose the right include file from the /make directory. + +# CGAL_MAKEFILE = ENTER_YOUR_INCLUDE_MAKEFILE_HERE +include $(CGAL_MAKEFILE) + +#---------------------------------------------------------------------# +# compiler flags +#---------------------------------------------------------------------# + +PROF_LD_FLAGS=-pg +PROF_CXX_FLAGS=-pg + +CXXFLAGS = -I../include \ + $(CGAL_CXXFLAGS) \ + $(LONG_NAME_PROBLEM_CXXFLAGS) \ + -DCGAL_IA_DONT_STOP_CONSTANT_PROPAGATION \ + -DCGAL_KERNEL_MEDIUM_INLINE=inline \ + -DCGAL_KERNEL_LARGE_INLINE=inline \ + -fprofile-arcs \ + -DNDEBUG \ + -mcpu=pentiumpro -march=pentiumpro \ + -DCGAL_NO_CONCEPT_CHECKING \ + $(DEBUG_OPT) + +#---------------------------------------------------------------------# +# linker flags +#---------------------------------------------------------------------# + +LIBPATH = \ + $(CGAL_LIBPATH) + +LDFLAGS = $(CGAL_LDFLAGS) + +#---------------------------------------------------------------------# +# target entries +#---------------------------------------------------------------------# + +all: \ + bench$(EXE_EXT) + +bench$(EXE_EXT): bench$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)bench bench$(OBJ_EXT) $(LDFLAGS) + +bench-pg$(OBJ_EXT): bench.C + $(CGAL_CXX) $(CXXFLAGS) $(EXE_OPT)bench-pg$(OBJ_EXT) $(OBJ_OPT) $< $(PROF_CXX_FLAGS) + +bench-pg$(EXE_EXT): bench-pg$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)bench-pg bench-pg$(OBJ_EXT) $(LDFLAGS) $(PROF_LD_FLAGS) + +bench-pg.clean: + rm -f bench-pg$(EXE_OPT) bench-pg$(OBJ_OPT) + +clean: \ + bench.clean bench-pg.clean + rm -f *.bb *.da *.bbg + +#---------------------------------------------------------------------# +# suffix rules +#---------------------------------------------------------------------# + +.C$(OBJ_EXT): + $(CGAL_CXX) $(CXXFLAGS) $(OBJ_OPT) $< diff --git a/Mesh_2/bench/bench.C b/Mesh_2/bench/bench.C new file mode 100644 index 00000000000..56f4363a0f4 --- /dev/null +++ b/Mesh_2/bench/bench.C @@ -0,0 +1,137 @@ +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include + +#include + +typedef CGAL::Simple_cartesian K1; +typedef CGAL::Filtered_kernel K2; + +#ifdef USE_FILTRED +struct K: public K2 {}; +#else +struct K : public K1 {}; +#endif + +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Delaunay_mesh_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2 Tr; +typedef CGAL::Delaunay_mesh_area_criteria_2 Mesh_criteria; + +typedef CGAL::Delaunay_mesher_2 Mesher; + +typedef K::Point_2 Point; + +void usage(char** argv) +{ + std::cerr << "Usage: " << std::endl + << argv[0] << " [-Q] [-a area] input.poly" << std::endl; +} + +int main(int argc, char** argv) +{ + int arg_count = 1; + bool terminal_output = true; + + Tr tr; + + Mesher mesher(tr); + + Mesh_criteria criteria; + + if(argc < 2) + { + usage(argv); + return 1; + } + + while(argv[arg_count][0] == '-' && argv[arg_count] != "--") + { + if(std::string(argv[arg_count]) == "-Q") + terminal_output = false; + else if(std::string(argv[arg_count]) == "-a") + { + double area_bound; + if( (argc > arg_count+1) && + std::istringstream(argv[arg_count+1]) >> area_bound ) + { + criteria.set_area_bound(area_bound); + ++arg_count; + } + else + { + std::cerr << "The area " << argv[arg_count+1] + << " is not a double." << std::endl; + usage(argv); + return 1; + } + } + else + { + std::cerr << "Unknown option " << argv[arg_count] << std::endl; + usage(argv); + return 1; + } + ++arg_count; + } + if(argv[arg_count] == "--") + ++arg_count; + + if(argc < arg_count+1 || argc > arg_count+2) + { + usage(argv); + return 1; + }; + std::ifstream input(argv[arg_count]); + if(input) + { + CGAL::Timer t; + t.start(); + CGAL::read_triangle_poly_file(tr, input); + t.stop(); + if(terminal_output) + std::cout << "Delaunay time: " << t.time() << std::endl; + + mesher.set_criteria(criteria); + + t.reset(); t.start(); + mesher.refine_mesh(); + t.stop(); + if(terminal_output) + std::cout << "Meshing time: " << t.time() << std::endl; + } + else + { + std::cerr << "Bad file: " << argv[arg_count] << std::endl; + usage(argv); + return 1; + } + + if(argc==arg_count+1) + { + } + else + { + std::ofstream output(argv[arg_count+1]); + CGAL::write_triangle_poly_file(tr, output); + } + if(terminal_output) + std::cout + << "Mesh points: " << tr.number_of_vertices() << std::endl + << "Mesh triangles: " << tr.number_of_faces () << std::endl; + + return 0; +}; diff --git a/Mesh_2/bench/data/square-deforme.poly b/Mesh_2/bench/data/square-deforme.poly new file mode 100644 index 00000000000..9d89031fc19 --- /dev/null +++ b/Mesh_2/bench/data/square-deforme.poly @@ -0,0 +1,16 @@ +# Shewchuk Triangle .poly file, produced by the CGAL::Mesh_2 package +# Neither attributes nor boundary markers are used. +4 2 0 0 + +1 2.2 -2.4 +2 2 2 +3 -2 2 +4 -2 -2 + +4 0 +1 2 3 +2 2 1 +3 4 1 +4 4 3 + +0 diff --git a/Mesh_2/bench/data/square.poly b/Mesh_2/bench/data/square.poly new file mode 100644 index 00000000000..0a49b210298 --- /dev/null +++ b/Mesh_2/bench/data/square.poly @@ -0,0 +1,16 @@ +# Shewchuk Triangle .poly file, produced by the CGAL::Mesh_2 package +# Neither attributes nor boundary markers are used. +4 2 0 0 + +1 2 -2 +2 2 2 +3 -2 2 +4 -2 -2 + +4 0 +1 2 3 +2 2 1 +3 4 1 +4 4 3 + +0 diff --git a/Mesh_2/changes.txt b/Mesh_2/changes.txt new file mode 100644 index 00000000000..e75d8103f02 --- /dev/null +++ b/Mesh_2/changes.txt @@ -0,0 +1,310 @@ +6 June 2006 Laurent Rineau +- merge trunk modifications into the branch "cannot_wait_for_CGAL-3.2" + I will copy the branch into the trunk. + + Here are the changes: + 20 April 2006 Laurent Rineau + - small changes in the user manual: + - change captions location + - fix typos and bad english + (thanks to Pierre Alliez) + - fix a typo in doc_tex/Mesh_2_ref/Delaunay_mesh_*criteria_2.tex : + (1/2B instead of 1/4B^2) + + 13 April 2006 Laurent Rineau + - added test_conforming and test_meshing in test/ with test files. + - rename test/Mesh_2/makefile to GNUmakefile, not submitted: + makefiles in the testsuite are generated. + - fix a BUG in Mesher_level: one_step() and try_to_insert_one_point(), in + Null_mesher_level must return false! This fix solves the "follow under + mouse" bug of mesh_demo.C! + - change some DEBUG macro names to: + CGAL_MESH_2_DEBUG_BAD_FACES + CGAL_MESH_2_DEBUG_CLUSTERS + CGAL_MESH_2_DEBUG_CONFLICTS_ZONE + CGAL_MESH_2_DEBUG_DRAW + CGAL_MESH_2_DEBUG_INSERTIONS + CGAL_MESH_2_VERBOSE + to please CGAL developer manual. + - add a seed in fish.poly + +30 April 2006 Laurent Rineau + (fix only in the branch "cannot_wait_for_CGAL-3.2") +- Fix for a bug leading to a crash, if the mesh criteria are too strong. + The algorithm will now inter into an infinite loop, instead of crashing + Delaunay_triangulation_2. It seems safer in a way. +- CGAL-3.2 is too close: it will be submitted to CGAL-3.2.1 only. + +20 March 2006 Laurent Rineau +- fix a desynch between the doc and code: is_marked->is_in_domain, in the + face base type + +26 Febraury 2006 Laurent Rineau +- Move the internal header +include/CGAL/Mesh_3/Triangulation_mesher_level_traits_3.h to Mesh_2. + + +16 November 2005 Laurent Rineau +- added copy constructor and operator= in CGAL::Double_map +- check them in test/Mesh_2/test_double_map.C + +9 May 2005 Laurent Rineau +- new (and last) optimization (for the moment) of Double_map +- added a test for Double_map! +- include/CGAL/Mesher_level.h splitted into: + include/CGAL/Mesher_level.h + include/CGAL/Mesher_level_default_implementations.h + include/CGAL/Mesher_level_visitors.h +- new class Combine_mesh_visitor in include/CGAL/Mesher_level_visitors.h +- fixed a stupid bug introduced 09-Feb-2005 in + include/CGAL/Mesh_2/Refine_edges_with_clusters.h + + +23 March 2005 Laurent Rineau +- conflicts_zone_impl requirements have changed + +8 March 2005 Laurent Rineau +- new Double_map.h + +28 February 2005 Laurent Rineau +- Added macro CGAL_MESH_2_DEBUG_DRAW and Debug_layer.h in mesh_demo, to debug +calls to widget->redraw(). Not activated by default. + +8 February 2005 Laurent Rineau +- CHANGES to Mesher_level: + - enum Mesher_level_conflict_status instead of std::map. + - new template parameters for Mesher_level + - new Mesher_level function names: + - Tr& triangulation_ref_impl() + - Vertex_handle insert_impl(p, z) + - Zone conflicts_zone_impl(p) + - void scan_triangulation_impl() + - bool no_longer_element_to_refine_impl() + - Element get_next_element_impl() + - void pop_next_element_impl() + - Point refinement_point_impl(e) + - void before_conflicts_impl(e, p) + - Mesher_level_conflict_status private_test_point_conflict_impl(p, zone) + - Mesher_level_conflict_status + test_point_conflict_from_superior_impl(p, zone) + - void before_insertion_impl(e, p, zone) + - void after_insertion_impl(vh) + - void after_no_insertion_impl(e, p, zone) + - new class in Mesher_level.h for default implementations: + - class Triangulation_ref_impl + - No_private_test_point_conflict + - No_test_point_conflict_from_superior + - No_test_point_conflict : + - No_before_insertion + - No_after_insertion + - No_after_no_insertion + - No_before_after_insertion + +18 January 2005 Laurent Rineau +- new Qt_widget_style_editor implementation +- demoicon.xpm in the demo +- remove some cerr outputs + +11 December 2004 Laurent Rineau +- new dialog in mesh_demo, to set up layer properties +- fix documentation +- NEW: pictures in the documentation + +17 November 2004 Laurent Rineau +- fix for g++-3.4 +- fix Delaunay_mesh_area_2 which was broken +- fix warnings in demo/Mesh_2/ layers + +16 November 2004 Laurent Rineau +- fix documentation +- enum Face_badness { NOT_BAD, BAD, IMPERATIVELY_BAD }; and modified +specifications for MeshingCriteria_2, to refines too small faces near +clusters. + +22 October 2004 Laurent Rineau +- fix two typo bugs in the testsuite + +21 October 2004 Laurent Rineau +- Yet another killed bug!! :-) The minimum sine of triangle was badly + computed. +- Refine_faces forgot to scan for bad faces the star of the new vertex. + +20 October 2004 Laurent Rineau +- fixed details in Delaunay_mesh_size_criteria_2.h + and marked todo and warning + +19 October 2004 Laurent Rineau +- Revert changes from 2004/10/17. Refine_edges_for_refine_faces no + longer exists. The conflicts zone of a point is calculated by using + propagate_conflicts(), from the CDT. For that, Refine_edges uses a + special Triangulation_mesher_level_traits_2. +- Special_zone is now useless. +- That's it: the bug is over!! +- Mesh_level no wants a function get_triangulation_traits() that + returns a reference to the Triangulation_mesher_level_traits. THAT +BREAKS COMPATIBILTY with previous codes. +- The special traits class + Refine_edges_triangulation_mesher_level_traits_2 has a function to + set the current edge. This function is used to pass the edge to it, + so that get_conflicts_zone() can work. + +18 October 2004 Laurent Rineau +- Conforming_Delaunay_triangulation_maker_2 renamed to + Triangulation_conformer_2. +- Update of the documentation. Thanks to Michel Hoffman for his review of + the specifications + +17 October 2004 Laurent Rineau +- Attempt to fix remaining bug: the list of faces modified by the insertion +of a point on a segment is not the conflicts zone of the +point. remove_constrained_edge() and insert_constraint() flip some faces. I +have added a class Refine_edges_for_refine_faces that handles a special +member special_zone (bad name) which is a set of +faces. do_before_conflict() and do_after_insertion() deal with functions +remove_constrained_edge() and insert_contraint() and fill the set +special_zone. The visitor Refine_edges_visitor uses this set to remove +those faces from bad_faces in after_insertion() (before the two +sub-segments are added back by Refine_edges::do_after_insertion(). +- However, this attempt fails! Seems that adding back the two +subconstraints intersects some other constrained edges already in the +triangulation. + +12 October 2004 Laurent Rineau +- Added parents and names to every layers, so that Qt releases the memory. +- Added debugging functions in Delaunay_mesher_2, and new debugging + layers and buttons tools into demo/Mesh_2/mesh_demo. These functions are + not documented. +- CGAL::Mesh_2::Refine_edges now has Tr::Edge has Element type. It + decreases number of calls to Tr::is_edge(). +- Removed debugging outputs to std::cerr. +- The step by step demo now display the edge of the face that will be refined. +- Modified Mesh_2::Clusters::get_cluster and Mesh_2::Clusters::update_clusters + to fix a bug in debugging functions (can we call that a "meta-bug"?). +- Added a function check_bad_faces() in Refine_faces. For the moment, it + checks that no bad face has three collinear vertices. It is used in a + CGAL_expensive_assertion. + +6 October 2004 Laurent Rineau +- Patch for gcc-3.4 + +29 September 2004 Laurent Rineau +- New code +- New layers in mesh_demo + +30 August 2004 Laurent Rineau +- New specifications. + +17 August 2004 Laurent Rineau +- Use namespace CGAL instead of CGAL_NAMESPACE_BEGIN/END. +- Insertion in an edge now reinstert the two sub-constraints, instead of + using insert with Locate_type==EDGE. +- Boost iterators have changed. + +09 August 2004 Andreas Fabri +Removed semicolons after closing parenthesis of functions, as they make problems for SunProCC + +22 July 2004 Laurent Rineau +- patch a bug in Delaunay_mesh_2: virtual_insert_in_the_edge was + forcing the insertion of a point on a EDGE. + +4 July 2004 Andreas Fabri +- In Delaunay_mesh_2: Removed const& on an object in a stack that gets popped before it gets used + +1 July 2004 Laurent Rineau +- Added Extras in Delaunay_mesh_2 too. + +28 June 2004 Laurent Rineau +- Move mark_facets functions from Delaunay_mesh_2 to + Conforming_Delaunay_triangulation_2. +- Added a sort of hooks, through a template parameter "Extras", in + Conforming_Delaunay_triangulation_2. There is a default + template argument that does nothing. + These hooks help doing actions when points are inserted. Used in the + package Mesh_3. + +17 May 2004 Menelaos Karavelas +- replaced Point by Point_2 in the demo in order to resolve clash with + the Mac version of Qt + +6 May 2000 Laurent Rineau +- workaround for CC-5.xx, in include/CGAL/Delaunay_mesh_2.h + +3 April 2004 Sylvain Pion +- Regenerate demo/example makefiles to remove debug options, + which makes PGCC pass. + +Version 1.0.2 (10 February 2004) [rursu] +- Updated headers in examples + +version 1.0.1 (2003/12/07) [Laurent] +-------------------------- +Submit the documentation too. + +version 1.0.0 (2003/12/07) [Laurent] +-------------------------- +o Bix Conforming_Delaunay_triangulation_2 where a typename was missing. +o bench/bench.C now compile again. +o I think this version can be named 1.0.0 now. + +version 0.9.5 (2003/11/28) [Laurent] +-------------------------- +o Fix the deprecated use of RIGHTTURN in conforming. + +version 0.9.4 (2003/11/5) [Laurent] +-------------------------- +o submitted to the testsuite + +version 0.9.4 (2003/10/9) [af] +-------------------------- +o Bug fix in Is_locally_conforming_Gabriel and in Is_locally_conforming_Delaunay +o Removed redundant tests + +version 0.9.4 +-------------------------- +o All names have changed. +o new concepts ConformingDelaunayTriangulationTraits_2 and + ConformingDelaunayTriangulationTraits_2 +o New internals and interface for Delaunay_mesh_2 and + Conforming_Delaunay_triangulation_2 +o updated documentation +o various changes in examples/ and demo/ + +version 0.9.3 (2003/05/10) +-------------------------- +o internal release +o split of the code into Mesh_2 and Conform_2 +o the demo mesh_demo can now displays clusters +o updated documentation (which is not really sync with the code) +o the interface of the demo has been improved + +version 0.9.2 (2003/03/12) +-------------------------- +o added a bench sub-directory +o fixed some gcc-3.2.1 compilation errors +o changes in the demo: + - added a panel next to the widget, that shows currently the number of points + - added a step actions'toolbar, improved with new buttons + - fix some bugs +o changes in the example: + - added some "Triangle-like" options +o changes in Mesh_2.h: + - fix compilation errors with gcc-3.2.1 + - fix compilation errors when the number type is not double + - the bound on size is no longer a squared distance + +version 0.9.1 (2002/08/26) +-------------------------- +o some code cleaning +o some bug fixes in the demo +o changes from Andreas Fabri, so that it works with VC++, and BCC: + - Added many const& + - insert(Point, Point) -> insert_constraint to make it work + with the Triangulation_hierarchy + - Added some typename + - std::queue only works with std::list not with std::deque on VC++6 +o added this file +o move Double_map.h in this package to remove dependency to Mesh_3 + +version 0.9 (2002/07/?) +----------------------- + first release diff --git a/Mesh_2/demo/Mesh_2/Debug_layer.h b/Mesh_2/demo/Mesh_2/Debug_layer.h new file mode 100644 index 00000000000..4953b6c31bc --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Debug_layer.h @@ -0,0 +1,46 @@ +// 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) : Laurent RINEAU + +#ifndef CGAL_DEBUG_LAYER_H +#define CGAL_DEBUG_LAYER_H + +#include +#include + +namespace CGAL { + +class Debug_layer : public Qt_widget_layer +{ + std::ostream& stream; + +public: + + Debug_layer(std::ostream& s = std::cerr) : stream(s) + { + } + + void draw() + { + stream << "redraw()" << std::endl; + } +}; // end class Debug_layer + +} // end namespace CGAL + +#endif // CGAL_DEBUG_LAYER_H diff --git a/Mesh_2/demo/Mesh_2/GNUmakefile b/Mesh_2/demo/Mesh_2/GNUmakefile new file mode 100644 index 00000000000..293af396b8f --- /dev/null +++ b/Mesh_2/demo/Mesh_2/GNUmakefile @@ -0,0 +1,29 @@ +include makefile + +#---------------------------------------------------------------------# +# +# dependencies +# +# if you want deps, create a file my_makefile that contains +# -include depends +# +#---------------------------------------------------------------------# + +-include my_makefile + +dep: + rm depends; $(MAKE) depends + +.PHONY: dep + + +depends: *.C + cat /dev/null > depends + for f in *.C; do \ + echo >> depends; \ + echo >> depends; \ + echo "$${f%.C}$(OBJ_EXT): \\" >> depends; \ + $(CGAL_CXX) $(CXXFLAGS) -M -MG $$f \ + | grep '\.\./\.\..*/include/CGAL' >> depends; \ + done + test -f depends diff --git a/Mesh_2/demo/Mesh_2/Qt_layer_show_circles.h b/Mesh_2/demo/Mesh_2/Qt_layer_show_circles.h new file mode 100644 index 00000000000..e788b7439f5 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Qt_layer_show_circles.h @@ -0,0 +1,159 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef CGAL_QT_LAYER_SHOW_CIRCLES_H +#define CGAL_QT_LAYER_SHOW_CIRCLES_H + +#include +#include +#include +#include +#include +#include + + +namespace CGAL { + +// T::Geom_traits has to be a CGAL kernel! +template +class Qt_layer_show_circles : public Qt_widget_layer { +public: + typedef typename T::Point Point; + typedef typename T::Segment Segment; + typedef typename T::Finite_faces_iterator Finite_faces_iterator; + typedef typename T::Locate_type Locate_type; + typedef typename T::Face_handle Face_handle; + typedef typename T::Geom_traits GT; + typedef typename GT::Circle_2 Circle; + typedef typename GT::FT FT; + + Qt_layer_show_circles(T* t, + CGAL::Color c = CGAL::GRAY, + int linewidth = 1, + CGAL::Color fill_color = CGAL::WHITE, + bool filled = false, + QObject* parent = 0, const char* name = 0) : + Qt_widget_layer(parent, name), + tr(t), do_erase(false), color(c), width(linewidth), + fillcolor(fill_color), fill(filled) {}; + + void draw() + { + Qt_widget_layer::draw(); + do_erase = false; + }; + + void mousePressEvent(QMouseEvent* e) + { + if (tr->dimension()<1) return; + FT + x=static_cast(widget->x_real(e->x())), + y=static_cast(widget->y_real(e->y())); + + Point p(x,y); + + int li; + Locate_type lt; + Face_handle fh = tr->locate(p,lt,li); + if(lt == T::FACE) + draw_circle(fh); + }; + + void mouseMoveEvent(QMouseEvent *e) + { + if (tr->dimension()<1) return; + FT + x=static_cast(widget->x_real(e->x())), + y=static_cast(widget->y_real(e->y())); + + Point p(x,y); + + int li; + Locate_type lt; + Face_handle fh = tr->locate(p,lt,li); + if(lt == T::FACE) + { + if(fh!=old_face) + { + widget->lock(); + + if(do_erase) draw_circle(old_face); + draw_circle(fh); + old_face=fh; + + widget->unlock(); + do_erase=true; + } + } + else + { + if(do_erase) + draw_circle(old_face); + do_erase=false; + } + }; + + void leaveEvent(QEvent* e) + { + Qt_widget_layer::leaveEvent(e); + if (tr->dimension()<1) return; + if(do_erase) + draw_circle(old_face); + }; + +private: + void draw_circle(const Face_handle& fh) const + { + RasterOp oldRaster = widget->rasterOp(); + QColor oldcolor = widget->color(); + QColor oldFillColor = widget->fillColor(); + int oldwidth = widget->lineWidth(); + bool oldFilled = widget->isFilled(); + + *widget << color; + *widget << LineWidth(width) << FillColor(fillcolor); + widget->setFilled(fill); + widget->get_painter().setRasterOp(NotROP); + + Point v=((*fh).vertex(0))->point(); + Point c=tr->circumcenter(fh); + + *widget << Circle(c,squared_distance(v,c)); + widget->setColor(oldcolor); + widget->setLineWidth(oldwidth); + widget->setFillColor(oldFillColor); + widget->setFilled(oldFilled); + widget->setRasterOp(oldRaster); + widget->do_paint(); + } + + T* tr; + Face_handle old_face; + bool do_erase; + + CGAL::Color color; + int width; + CGAL::Color fillcolor; + bool fill; +};//end class + +} // namespace CGAL + +#endif // CGAL_QT_LAYER_SHOW_CIRCLES_H diff --git a/Mesh_2/demo/Mesh_2/Qt_layer_show_triangulation.h b/Mesh_2/demo/Mesh_2/Qt_layer_show_triangulation.h new file mode 100644 index 00000000000..35e688d8b69 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Qt_layer_show_triangulation.h @@ -0,0 +1,76 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef CGAL_QT_LAYER_SHOW_TRIANGULATION_H +#define CGAL_QT_LAYER_SHOW_TRIANGULATION_H + +#include "Qt_widget_styled_layer.h" +#include + +namespace CGAL { + +template +class Qt_layer_show_triangulation : public Qt_widget_styled_layer +{ +public: + + Qt_layer_show_triangulation(T *t, + CGAL::Color lc = CGAL::BLUE, + int linewidth = 1, + QObject* parent = 0, const char* name = 0) + : Qt_widget_styled_layer(0, parent, name), + tr(t) + { + color="Color"; + width="Line width"; + + setColor(QColor(lc.red(), lc.green(), lc.blue())); + setLineWidth(linewidth); + }; + + void setColor(QColor c) + { style()->setColor(color, c); } + + void setLineWidth(int line_width) + { style()->setInt(width, line_width); } + + void draw() + { + QColor old_color = widget->color(); + int old_width = widget->lineWidth(); + + widget->setColor(style()->getColor(color)); + widget->setLineWidth(style()->getInt(width)); + + *widget << *tr; + + widget->setLineWidth(old_width); + widget->setColor(old_color); + }; + +private: + T *tr; + QString color; + QString width; +};//end class + +} // namespace CGAL + +#endif // CGAL_QT_LAYER_SHOW_TRIANGULATION_H diff --git a/Mesh_2/demo/Mesh_2/Qt_layer_show_triangulation_constraints.h b/Mesh_2/demo/Mesh_2/Qt_layer_show_triangulation_constraints.h new file mode 100644 index 00000000000..886fb6b399f --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Qt_layer_show_triangulation_constraints.h @@ -0,0 +1,83 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef CGAL_QT_LAYER_SHOW_TRIANGULATION_CONSTRAINTS_H +#define CGAL_QT_LAYER_SHOW_TRIANGULATION_CONSTRAINTS_H + +#include "Qt_widget_styled_layer.h" + +namespace CGAL { + +template +class Qt_layer_show_triangulation_constraints + : public Qt_widget_styled_layer +{ +public: + + Qt_layer_show_triangulation_constraints(T *t, + CGAL::Color lc = CGAL::RED, + int linewidth = 1, + QObject* parent = 0, + const char* name = 0) + : Qt_widget_styled_layer(0, parent, name), tr(t) + { + color="Color"; + width="Line width"; + + setColor(QColor(lc.red(), lc.green(), lc.blue())); + setLineWidth(linewidth); + }; + + void setColor(QColor c) + { style()->setColor(color, c); } + + void setLineWidth(int line_width) + { style()->setInt(width, line_width); } + + void draw() + { + widget->lock(); + + QColor old_color = widget->color(); + int old_width = widget->lineWidth(); + + widget->setColor(style()->getColor(color)); + widget->setLineWidth(style()->getInt(width)); + + for(typename T::Edge_iterator it=tr->edges_begin(); + it!=tr->edges_end(); + it++) + if(tr->is_constrained(*it)) + *widget << tr->segment(*it); + + widget->setLineWidth(old_width); + widget->setColor(old_color); + widget->unlock(); + }; + +private: + T *tr; + QString color; + QString width; +};//end class + +} // namespace CGAL + +#endif // CGAL_QT_LAYER_SHOW_TRIANGULATION_CONSTRAINTS_H diff --git a/Mesh_2/demo/Mesh_2/Qt_widget_style_editor-aux.h b/Mesh_2/demo/Mesh_2/Qt_widget_style_editor-aux.h new file mode 100644 index 00000000000..a7ba30b6fe5 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Qt_widget_style_editor-aux.h @@ -0,0 +1,144 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef CGAL_QT_WIDGET_STYLE_EDITOR_AUX_H +#define CGAL_QT_WIDGET_STYLE_EDITOR_AUX_H + +#include +#include +#include +#include +#include +#include +#include + +class Color_selector : public QPushButton +{ + Q_OBJECT +public: + Color_selector(QColor c = Qt::black, + QWidget* parent = 0, const char* name = 0) + : QPushButton(parent, name) + { + setColor(c); + connect(this, SIGNAL(clicked()), + this, SLOT(color_dialog()) ); + } + + virtual ~Color_selector() {}; + + QColor value() const + { + return color; + } + +public slots: + void setColor(QColor c) + { + color = c; + + QPixmap pix(24,20); + pix.fill(c); + setPixmap(pix); + + emit newColor(c); + } + +signals: + void newColor(QColor); + +private slots: + void color_dialog() + { + QColor c = QColorDialog::getColor(value()); + if( c.isValid() ) + setColor(c); + } + +private: + QColor color; +}; + +class Int_selector : public QSpinBox +{ + Q_OBJECT +public: + Int_selector(int i, QWidget *parent = 0, const char *name = 0) + : QSpinBox(-INT_MAX, INT_MAX, 1, parent, name) + { + setValue(i); + } + + virtual ~Int_selector() {}; +}; + +class Bool_selector : public QComboBox +{ + Q_OBJECT +public: + Bool_selector(bool b_, QWidget *parent = 0, const char *name = 0) + : QComboBox(false, parent, name) + { + insertItem("False"); + insertItem("True"); + + if(b_) + setCurrentItem(1); + else + setCurrentItem(0); + } + + virtual ~Bool_selector() {}; + + bool value() const + { + return currentItem() == 1; + } +}; + +class Point_style_selector : public QComboBox +{ + Q_OBJECT +public: + typedef ::CGAL::PointStyle PointStyle; + Point_style_selector(PointStyle s, + QWidget *parent = 0, const char *name = 0) + : QComboBox(false, parent, name) + { + insertItem("Pixel"); + insertItem("Cross"); + insertItem("Plus"); + insertItem("Circle"); + insertItem("Disc"); + insertItem("Rect"); + insertItem("Box"); + + setCurrentItem(static_cast(s)); + } + + virtual ~Point_style_selector() {}; + + PointStyle value() const + { + return PointStyle(currentItem()); + } +}; + +#endif // CGAL_QT_WIDGET_STYLE_EDITOR_AUX_H diff --git a/Mesh_2/demo/Mesh_2/Qt_widget_style_editor.C b/Mesh_2/demo/Mesh_2/Qt_widget_style_editor.C new file mode 100644 index 00000000000..1e116284026 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Qt_widget_style_editor.C @@ -0,0 +1,129 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#include + +#ifdef CGAL_USE_QT + +#include "Qt_widget_style_editor.h" +#include "Qt_widget_style_editor-aux.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +Qt_widget_style_editor::Qt_widget_style_editor(Style* style, + QWidget *parent, + const char *name) + : QFrame(parent, name), style(style) +{ + typedef Style::const_iterator iterator; + + QGridLayout* layout = new QGridLayout(this); + layout->addColSpacing(1,5); + + const int labels_col = 0; // column number of labels + const int selectors_col = 2; // column number of selectors + + int row = 0; + for(iterator it=style->begin(); + it != style->end(); + ++it) + { + QLabel* label = new QLabel( it.key(), this); + layout->addWidget(label, row, labels_col); + + QWidget* selector = 0; + switch( it.data().type() ) { + case QVariant::Color: + selector = new Color_selector(it.data().toColor(), this); + connect(selector, SIGNAL(newColor(QColor)), + this, SLOT(map(QColor))); + break; + case QVariant::Int: + selector = new Int_selector(it.data().toInt(), this); + connect(selector, SIGNAL(valueChanged(int)), + this, SLOT(map(int))); + break; + case QVariant::Bool: + selector = new Bool_selector(it.data().toBool(), + this); + connect(selector, SIGNAL(toggled(bool)), + this, SLOT(map(bool))); + break; + case QVariant::UInt: + selector = + new Point_style_selector(PointStyle(it.data().toUInt()), + this); + connect(selector, SIGNAL(activated(int)), + this, SLOT(pointstyle(int))); + break; + default: + CGAL_assertion(false); + break; + } + + mapper[selector]=it.key(); + + layout->addWidget(selector, row, selectors_col); + + ++row; + } +} + +void Qt_widget_style_editor::map(QColor c) +{ + const QObject* s = sender(); + if( mapper.contains(s) ) + style->setColor(mapper[s], c); + emit styleChanged(); +} + +void Qt_widget_style_editor::map(int i) +{ + const QObject* s = sender(); + if( mapper.contains(s) ) + style->setInt(mapper[s], i); + emit styleChanged(); +} + +void Qt_widget_style_editor::map(bool b) +{ + const QObject* s = sender(); + if( mapper.contains(s) ) + style->setBool(mapper[s], b); + emit styleChanged(); +} + +} // end namespace CGAL + +// moc_source_file: Qt_widget_style_editor.h +#include "Qt_widget_style_editor.moc" + +// moc_source_file: Qt_widget_style_editor-aux.h +#include "Qt_widget_style_editor-aux.moc" + +#endif // CGAL_USE_QT diff --git a/Mesh_2/demo/Mesh_2/Qt_widget_style_editor.h b/Mesh_2/demo/Mesh_2/Qt_widget_style_editor.h new file mode 100644 index 00000000000..7763f4771de --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Qt_widget_style_editor.h @@ -0,0 +1,55 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef QT_WIDGET_STYLE_EDITOR_H +#define QT_WIDGET_STYLE_EDITOR_H + +#include +#include "Qt_widget_styled_layer.h" + +namespace CGAL { + +class Qt_widget_style_editor : public QFrame { + Q_OBJECT +public: + + typedef Qt_widget_styled_layer::Style Style; + + Qt_widget_style_editor(Style* style, + QWidget *parent = 0 , const char *name = 0); + + virtual ~Qt_widget_style_editor() {} + +signals: + void styleChanged(); + +private slots: + void map(QColor); + void map(int); + void map(bool); + +private: + Style* style; + QMap mapper; +}; // end of class Qt_widget_style_editor + +} // end namespace CGAL + +#endif // QT_WIDGET_STYLE_EDITOR_H diff --git a/Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.C b/Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.C new file mode 100644 index 00000000000..1499999ef81 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.C @@ -0,0 +1,127 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#include + +#ifdef CGAL_USE_QT + +#include "Qt_widget_styled_layer.h" + +namespace CGAL { + + Qt_widget_styled_layer::Qt_widget_styled_layer( + Qt_widget_styled_layer::Style* style, + QObject * parent, + const char * name) + : Qt_widget_layer(parent, name), + style_(style), private_style(false) + { + if( style == 0 ) + { + this->style_ = new Style(); + private_style = true; + } + } + + Qt_widget_styled_layer::~Qt_widget_styled_layer() + { + if( private_style ) + delete style_; + } + + void Qt_widget_styled_layer::setStyle(Qt_widget_styled_layer::Style* s) + { + if( private_style ) + delete style_; + private_style = false; + style_ = s; + } + + void Qt_widget_style::setBool(QString name, bool b) + { + map[name] = b; + } + + void Qt_widget_style::setInt(QString name, int i) + { + map[name] = i; + } + + void Qt_widget_style::setColor(QString name, QColor c) + { + map[name] = c; + } + + void Qt_widget_style::setPointStyle(QString name, PointStyle s) + { + map[name] = static_cast(s); + map[name].cast(QVariant::UInt); + } + + bool Qt_widget_style::getBool(QString name) + { + if( ! map.contains(name) ) + return false; + else + { + CGAL_assertion( map[name].type() == QVariant::Bool ); + return map[name].asBool(); + } + } + + int Qt_widget_style::getInt(QString name) + { + if( ! map.contains(name) ) + return 0; + else + { + CGAL_assertion( map[name].type() == QVariant::Int ); + return map[name].asInt(); + } + } + + QColor Qt_widget_style::getColor(QString name) + { + if( ! map.contains(name) ) + return QColor(); + else + { + CGAL_assertion( map[name].type() == QVariant::Color ); + return map[name].asColor(); + } + } + + ::CGAL::PointStyle Qt_widget_style::getPointStyle(QString name) + { + if( ! map.contains(name) ) + return PointStyle(); + else + { + CGAL_assertion( map[name].type() == QVariant::UInt ); + return PointStyle(map[name].asUInt()); + } + } + +} // namespace CGAL + +// moc_source_file: Qt_widget_styled_layer.h +#include "Qt_widget_styled_layer.moc" + +#endif // CGAL_USE_QT diff --git a/Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.h b/Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.h new file mode 100644 index 00000000000..92f64088f49 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Qt_widget_styled_layer.h @@ -0,0 +1,95 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef QT_WIDGET_STYLED_LAYER_H +#define QT_WIDGET_STYLED_LAYER_H + +#include +#include +#include + +#include +#include + +namespace CGAL { + +class Qt_widget_style : public QObject { + Q_OBJECT + + typedef QMap Map; +public: + + typedef Map::const_iterator const_iterator; + typedef Map::size_type size_type; + + Qt_widget_style() + : map() {}; + +public slots: + void setBool(QString name, bool b); + void setInt(QString name, int i); + void setColor(QString name, QColor c); + void setPointStyle(QString name, PointStyle s); + +public: + bool getBool(QString name); + int getInt(QString name); + QColor getColor(QString name); + PointStyle getPointStyle(QString name); + + const_iterator begin() const + { + return map.begin(); + } + + const_iterator end() const + { + return map.end(); + } + + size_type size() const + { + return map.size(); + } + +private: + Map map; +}; + +class Qt_widget_styled_layer : public Qt_widget_layer { + Q_OBJECT +public: + typedef Qt_widget_style Style; + + Qt_widget_styled_layer(Style* style = 0, + QObject * parent=0, const char * name=0); + + ~Qt_widget_styled_layer(); + + void setStyle(Style* style); + Style * style() { return style_; } +private: + Style* style_; + bool private_style; +}; + +} // namespace CGAL + +#endif // QT_WIDGET_STYLED_LAYER_H diff --git a/Mesh_2/demo/Mesh_2/Show_clusters.h b/Mesh_2/demo/Mesh_2/Show_clusters.h new file mode 100644 index 00000000000..a3b8af79e2f --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Show_clusters.h @@ -0,0 +1,213 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef MESH_2_SHOW_CLUSTERS_H +#define MESH_2_SHOW_CLUSTERS_H + +#include +#include + +#include + +#include + +class Show_clusters_aux : public CGAL::Qt_widget_layer +{ + Q_OBJECT +private: + virtual void reinit_clusters() {} + +public slots: + void reinitClusters() + { + reinit_clusters(); + } +public: + Show_clusters_aux(QObject* parent, const char* name) + : Qt_widget_layer(parent, name) + { + } +}; + +template +class Show_clusters : public Show_clusters_aux +{ +public: + typedef typename Mesher::Triangulation Tr; + typedef typename Tr::Point Point; + typedef typename Tr::Geom_traits Geom_traits; + typedef CGAL::Delaunay_triangulation_2 DT; + typedef typename DT::Finite_vertices_iterator Vertices_iterator; + typedef typename DT::Vertex_handle DT_vertex_handle; + typedef typename Tr::Segment Segment; + typedef typename Tr::Face_handle Face_handle; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Geom_traits::FT FT; + typedef typename Mesher::Clusters Clusters; + typedef typename Clusters::Cluster Cluster; + typedef typename Clusters::Cluster_vertices_iterator CVIt; + typedef typename Clusters::Vertices_in_cluster_iterator ViCIt; + typedef typename Clusters::const_iterator Clusters_const_iterator; + typedef std::list List_of_points; + typedef typename List_of_points::const_iterator Point_iterator; + + Show_clusters(Mesher* m, + CGAL::Color color_ = CGAL::GREEN, + int pointsize = 3, + CGAL::PointStyle pointstyle = CGAL::DISC, + CGAL::Color lc = CGAL::RED, + CGAL::Color reduced_line_color_ = CGAL::BLUE, + int linewidth = 2, + QObject* parent = 0, const char* name = 0) + : Show_clusters_aux(parent, name), + mesher(m), dt(), color(color_), + size(pointsize), style(pointstyle), line_color(lc), + reduced_line_color(reduced_line_color_), + width(linewidth) + { + reinit_clusters(); + } + + void activating() + { + reinit_clusters(); + } + + void change_mesher(Mesher* m) + { + mesher = m; + reinit_clusters(); + } + + void reinit_clusters() + { + if(!is_active()) return; + + dt.clear(); + + if( mesher != 0 ) + for(CVIt it = mesher->clusters().clusters_vertices_begin(); + it != mesher->clusters().clusters_vertices_end(); + ++it) + dt.push_back( (*it)->point() ); + } + + void draw() + { + widget->lock(); + + QColor oldColor = widget->color(); + int oldPointSize = widget->pointSize(); + CGAL::PointStyle oldStyle = widget->pointStyle(); + + *widget << color << CGAL::PointStyle(style) + << CGAL::PointSize(size); + + for(Vertices_iterator it = dt.finite_vertices_begin(); + it != dt.finite_vertices_end(); + ++it) + *widget << it->point(); + + widget->setPointStyle(oldStyle); + widget->setPointSize(oldPointSize); + widget->setColor(oldColor); + + widget->unlock(); + oldPixmap = widget->get_pixmap(); + } + + void mouseMoveEvent(QMouseEvent *e) + { + if( mesher == 0 ) return; + + FT x, y; + widget->x_real(e->x(), x); + widget->y_real(e->y(), y); + Point p(x, y); + + DT_vertex_handle v = dt.nearest_vertex(p); + + if(v == NULL) return; + if(v == oldVertex) return; + + oldVertex = v; + + QColor oldColor = widget->color(); + int oldWidth = widget->lineWidth(); + + widget->lock(); + + widget->get_painter().drawPixmap(0, 0, oldPixmap); + + *widget << CGAL::LineWidth(width); + + typename Tr::Locate_type lt; + int i; + Face_handle fh = mesher->triangulation().locate(v->point(), lt, i); + CGAL_assertion( lt == Tr::VERTEX ); + + Vertex_handle v2 = fh->vertex(i); + + int n = mesher->clusters().number_of_clusters_at_vertex(v2); + + for(int j = 0; j < n; ++j) + { + std::pair seq = + mesher->clusters().vertices_in_cluster_sequence(v2, j); + Cluster c; + Clusters_const_iterator dummy_c_it; + mesher->clusters().get_cluster(v2, *(seq.first), c, dummy_c_it); + if( c.is_reduced() ) + *widget << reduced_line_color; + else + *widget << line_color; + for(ViCIt it = seq.first; + it != seq.second; + ++it) + *widget << Segment(v2->point(), (*it)->point()); + } + + widget->setLineWidth(oldWidth); + widget->setColor(oldColor); + + widget->unlock(); + } + + void leaveEvent(QEvent *) + { + widget->get_painter().drawPixmap(0, 0, oldPixmap); + widget->update(); + } + +private: + Mesher* mesher; + DT dt; + DT_vertex_handle oldVertex; + QPixmap oldPixmap; + bool should_restore_pixmap; + CGAL::Color color; + int size; + CGAL::PointStyle style; + CGAL::Color line_color; + CGAL::Color reduced_line_color; + int width; +}; + +#endif diff --git a/Mesh_2/demo/Mesh_2/Show_points.C b/Mesh_2/demo/Mesh_2/Show_points.C new file mode 100644 index 00000000000..5dc87b352c0 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Show_points.C @@ -0,0 +1,72 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#include + +#ifdef CGAL_USE_QT + +#include "Show_points.h" + +namespace CGAL { + + Show_points_base::Show_points_base(Color c, + int pointsize, + PointStyle pointstyle, + QObject * parent, + const char * name) + : Qt_widget_styled_layer(0, parent, name) + { + color=tr("Color"); + size=tr("Point size"); + style_name=tr("Point style"); + + setColor(QColor(c.red(), c.green(), c.blue())); + setPointSize(pointsize); + setPointStyle(pointstyle); + } + + Show_points_base::Show_points_base(Style* style, + QString points_color_name, + QString points_size_name, + QString points_style_name, + QObject * parent, + const char * name) + : Qt_widget_styled_layer(style, parent, name), + color(points_color_name), + size(points_size_name), + style_name(points_style_name) + {} + + void Show_points_base::setColor(QColor c) + { style()->setColor(color, c); } + + void Show_points_base::setPointSize(int pointsize) + { style()->setInt(size, pointsize); } + + void Show_points_base::setPointStyle(PointStyle pointstyle) + { style()->setInt(style_name, static_cast(pointstyle)); } + +} // namespace CGAL + +// moc_source_file: Show_points.h +#include "Show_points.moc" + +#endif // CGAL_USE_QT + diff --git a/Mesh_2/demo/Mesh_2/Show_points.h b/Mesh_2/demo/Mesh_2/Show_points.h new file mode 100644 index 00000000000..491bbecf836 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Show_points.h @@ -0,0 +1,129 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef SHOW_POINTS_H +#define SHOW_POINTS_H + +#include +#include +#include +#include + +#include "Qt_widget_styled_layer.h" +#include + +namespace CGAL { + +class Show_points_base: public Qt_widget_styled_layer { + Q_OBJECT +public: + typedef Qt_widget_styled_layer::Style Style; + + Show_points_base(Color c, + int pointsize, + PointStyle pointstyle, + QObject * parent=0, const char * name=0); + + Show_points_base(Style* style, + QString points_color_name, + QString points_size_name, + QString points_style_name, + QObject * parent=0, const char * name=0); + +public slots: + void setColor(QColor); + void setPointSize(int); + void setPointStyle(PointStyle); + +protected: + QString color; + QString size; + QString style_name; +}; // end Show_points_base + +template > +class Show_points : public Show_points_base { +public: + typedef Qt_widget_styled_layer::Style Style; + + typedef It iterator; + typedef iterator (C::* iterator_function)() const; + + Show_points(C *container, + iterator_function begin, + iterator_function end, + Color c = CGAL::GREEN, + int pointsize = 3, + PointStyle pointstyle = CGAL::DISC, + QObject * parent=0, const char * name=0) + : Show_points_base(c, pointsize, pointstyle, + parent, name), + cont(container), _begin(begin), _end(end) {}; + + Show_points(C *container, + iterator_function begin, + iterator_function end, + Style* style, + QString points_color_name, + QString points_size_name, + QString points_style_name, + QObject * parent=0, const char * name=0) + : Show_points_base(style, + points_color_name, + points_size_name, + points_style_name, + parent, name), + cont(container), _begin(begin), _end(end) {}; + + void draw() + { + widget->lock(); + { + QColor old_color = widget->color(); + int old_size = widget->pointSize(); + PointStyle old_point_style = widget->pointStyle(); + + widget->setColor(style()->getColor(color)); + widget->setPointSize(style()->getInt(size)); + widget->setPointStyle(static_cast(style()-> + getInt(style_name))); + + for(iterator it = (cont->*_begin)(); + it!=(cont->*_end)(); + ++it) + *widget << Transform()(*it); + + widget->setColor(old_color); + widget->setPointSize(old_size); + widget->setPointStyle(old_point_style); + } + widget->unlock(); + }; + +private: + C *cont; + iterator_function _begin; + iterator_function _end; +};//end class + +} // namespace CGAL + +#endif // SHOW_POINTS_H diff --git a/Mesh_2/demo/Mesh_2/Show_segments.h b/Mesh_2/demo/Mesh_2/Show_segments.h new file mode 100644 index 00000000000..44c86e45ccc --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Show_segments.h @@ -0,0 +1,97 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef SHOW_SEGMENTS_H +#define SHOW_SEGMENTS_H + +#include "Show_segments_base.h" + +namespace CGAL { + +template > +class Show_segments : public Show_segments_base { +public: + typedef Qt_widget_styled_layer::Style Style; + + typedef It iterator; + typedef iterator (C::* iterator_function)() const; + + Show_segments(C *container, + iterator_function begin, + iterator_function end, + Color c=CGAL::GREEN, + int linewidth=3, + QObject* parent = 0, const char* name = 0) + : Show_segments_base(c, linewidth, + parent, name), + cont(container), _begin(begin), _end(end) {}; + + Show_segments(C *container, + iterator_function begin, + iterator_function end, + Style* style, + QString line_color_name, + QString line_width_name, + QObject* parent = 0, const char* name = 0) + : Show_segments_base(style, line_color_name, line_width_name, + parent, name), + cont(container), _begin(begin), _end(end) {}; + + void set_container(C* container) + { + cont = container; + } + + void draw() + { + if( cont != 0 ) + { + widget->lock(); + { + QColor old_color = widget->color(); + int old_width = widget->lineWidth(); + + widget->setColor(style()->getColor(color)); + widget->setLineWidth(style()->getInt(width)); + + for(iterator it = (cont->*_begin)(); + it!=(cont->*_end)(); + ++it) + { + *widget << Transform()(*it); + } + + widget->setColor(old_color); + widget->setLineWidth(old_width); + } + widget->unlock(); + } + }; + +private: + C *cont; + iterator_function _begin; + iterator_function _end; +};//end class + +} // namespace CGAL + +#endif // SHOW_SEGMENTS_H diff --git a/Mesh_2/demo/Mesh_2/Show_segments_base.C b/Mesh_2/demo/Mesh_2/Show_segments_base.C new file mode 100644 index 00000000000..bf09a5397ea --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Show_segments_base.C @@ -0,0 +1,63 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#include + +#ifdef CGAL_USE_QT + +#include "Show_segments_base.h" + +namespace CGAL { + + Show_segments_base::Show_segments_base(Color c, + int linewidth, + QObject* parent, + const char* name) + : Qt_widget_styled_layer(0, parent, name) + { + color=tr("Color"); + width=tr("Line width"); + + setColor(QColor(c.red(), c.green(), c.blue())); + setLineWidth(linewidth); + } + + Show_segments_base::Show_segments_base(Style* style, + QString line_color_name, + QString line_width_name, + QObject* parent, + const char* name) + : Qt_widget_styled_layer(style, parent, name), + color(line_color_name), + width(line_width_name) + {} + + void Show_segments_base::setColor(QColor c) + { style()->setColor(color, c); } + + void Show_segments_base::setLineWidth(int line_width) + { style()->setInt(width, line_width); } + +} // namespace CGAL + +// moc_source_file: Show_segments_base.h +#include "Show_segments_base.moc" + +#endif // CGAL_USE_QT diff --git a/Mesh_2/demo/Mesh_2/Show_segments_base.h b/Mesh_2/demo/Mesh_2/Show_segments_base.h new file mode 100644 index 00000000000..04bf556365c --- /dev/null +++ b/Mesh_2/demo/Mesh_2/Show_segments_base.h @@ -0,0 +1,53 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#ifndef SHOW_SEGMENTS_BASE_H +#define SHOW_SEGMENTS_BASE_H + +#include "Qt_widget_styled_layer.h" + +namespace CGAL { + +class Show_segments_base: public Qt_widget_styled_layer { + Q_OBJECT +public: + typedef Qt_widget_styled_layer::Style Style; + + Show_segments_base(Color c, + int linewidth, + QObject* parent = 0, const char* name = 0); + + Show_segments_base(Style* style, + QString line_color_name, + QString line_width_name, + QObject* parent = 0, const char* name = 0); + +public slots: + void setColor(QColor); + void setLineWidth(int); + +protected: + QString color; + QString width; +}; //end Show_segments_base + +} // namespace CGAL + +#endif // SHOW_SEGMENTS_BASE_H diff --git a/Mesh_2/demo/Mesh_2/conform.C b/Mesh_2/demo/Mesh_2/conform.C new file mode 100644 index 00000000000..c27aedd3d31 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/conform.C @@ -0,0 +1,159 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#include + + // if QT is not installed, a message will be issued in runtime. +#ifndef CGAL_USE_QT +#include + +int main(int, char*) +{ + + std::cout << "Sorry, this demo needs QT..."; + std::cout << std::endl; + + return 0; +} + +#else + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +typedef CGAL::Simple_cartesian K1; +typedef CGAL::Filtered_kernel K2; +struct K : public K2 {}; + +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds1; + +struct Tds : public Tds1 {}; + +typedef CGAL::Constrained_Delaunay_triangulation_2 Tr; + +typedef K::Point_2 Point; + +void usage(char** argv) +{ + std::cerr << "Usage: " << argv[0] + << " [-Q] [-D] [-v] input.poly [output.poly]" << std::endl + << "Read a Shewchuk .poly file and output a conforming PSLG." + << std::endl + << " -Q Quiet" << std::endl + << " -D Make conforming Delaunay, instead of" + " conforming Gabriel." << std::endl + << " -v Verbose" << std::endl; +} + +int main(int argc, char** argv) +{ + int arg_count = 1; + bool terminal_output = true; + bool delaunay = false; + bool verbose = false; + + if(argc < 2) + { + usage(argv); + return 1; + } + + while(argv[arg_count][0] == '-' && argv[arg_count] != "--") + { + if(std::string(argv[arg_count]) == "-Q") + terminal_output = false; + else if(std::string(argv[arg_count]) == "-D") + delaunay = true; + else if(std::string(argv[arg_count]) == "-v") + verbose = true; + else + { + std::cerr << "Unknown option " << argv[arg_count] << std::endl; + usage(argv); + return 1; + } + ++arg_count; + } + if(argv[arg_count] == "--") + ++arg_count; + + if(argc < arg_count+1 || argc > arg_count+2) + { + usage(argv); + return 1; + }; + std::ifstream input(argv[arg_count]); + if(input) + { + Tr t; + CGAL::read_triangle_poly_file(t, input); + if(delaunay) + { + if(verbose) + std::cerr << "Make conforming Delaunay..." << std::endl; + CGAL::make_conforming_Delaunay_2(t); + } + else + { + if(verbose) + std::cerr << "Make conforming Gabriel..." << std::endl; + CGAL::make_conforming_Gabriel_2(t); + } + + if(argc==arg_count+1) + { + if(terminal_output) + CGAL::write_triangle_poly_file(t, std::cout); + } + else + { + std::ofstream output(argv[arg_count+1]); + CGAL::write_triangle_poly_file(t, output); + } + + if(terminal_output) + std::cerr + << "Number of points: " << t.number_of_vertices() << std::endl + << "Number of triangles: " << t.number_of_faces () << std::endl; + + } + else + { + std::cerr << "Bad file: " << argv[arg_count] << std::endl; + usage(argv); + return 1; + } + return 0; +}; + +#endif // CGAL_USE_QT diff --git a/Mesh_2/demo/Mesh_2/contraints.xpm b/Mesh_2/demo/Mesh_2/contraints.xpm new file mode 100644 index 00000000000..90533a05d14 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/contraints.xpm @@ -0,0 +1,37 @@ +/* XPM */ +const char * contraints_xpm[] = { +"32 32 2 1", +" c None", +". c #FF0000", +" ", +" ", +" ", +" ............. ", +" .. .. ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . . ", +" . ... . ", +" . ... .... . ", +" . . . . . ", +" . . . . . ", +" . . . . . ", +" . . . . . ", +" .. . . . . ", +" .. . . . . ", +" . .. .. . ", +" . ..... .. ... ", +" . .... . ", +" . . ", +" . . ", +" . . ", +" . . ", +" ..... . ", +" ........ .. ", +" .... ", +" ", +" ", +" "}; diff --git a/Mesh_2/demo/Mesh_2/data/butterfly.edg b/Mesh_2/demo/Mesh_2/data/butterfly.edg new file mode 100644 index 00000000000..204649444d0 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/butterfly.edg @@ -0,0 +1,34 @@ +26 +0 0 0.7 1 +0 0 0.7 -1 +0 0 -0.7 -1 +0 0 -0.7 1 + +0.7 1 1 0.8 +1 0.8 1 0.3 +1 0.3 0.7 0.2 +0.7 0.2 1 0 +1 0 0.7 -0.2 +0.7 -0.2 1 -0.3 +1 -0.3 0.7 -0.6 +0.7 -0.6 1 -0.8 +1 -0.8 0.7 -1 + +-0.7 1 -1 0.8 +-1 0.8 -1 0.3 +-1 0.3 -0.7 0.2 +-0.7 0.2 -1 0 +-1 0 -0.7 -0.2 +-0.7 -0.2 -1 -0.3 +-1 -0.3 -0.7 -0.6 +-0.7 -0.6 -1 -0.8 +-1 -0.8 -0.7 -1 + + +0 0 0.7 0.2 +0 0 0.7 -0.2 +0 0 -0.7 0.2 +0 0 -0.7 -0.2 + + + diff --git a/Mesh_2/demo/Mesh_2/data/clusters.edg b/Mesh_2/demo/Mesh_2/data/clusters.edg new file mode 100644 index 00000000000..b72dca4d9c7 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/clusters.edg @@ -0,0 +1,9 @@ +8 +812.183 152.284 -20.3046 30.4569 +-20.3046 30.4569 662.437 365.482 +824.873 53.2995 -20.3046 30.4569 +819.797 -119.289 -20.3046 30.4569 +-116.751 -441.624 -20.3046 30.4569 +-279.188 -418.782 -20.3046 30.4569 +-784.264 109.137 -20.3046 30.4569 +-20.3046 30.4569 -710.66 225.888 diff --git a/Mesh_2/demo/Mesh_2/data/clusters.poly b/Mesh_2/demo/Mesh_2/data/clusters.poly new file mode 100644 index 00000000000..9f00ee2d569 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/clusters.poly @@ -0,0 +1,33 @@ +# Shewchuk Triangle .poly file, produced by the CGAL::Mesh_2 package +# Neither attributes nor boundary markers are used. +13 2 0 0 + +1 812.183 152.284 +2 -20.3046 30.4569 +3 662.437 365.482 +4 824.873 53.2995 +5 819.797 -119.289 +6 -116.751 -441.624 +7 -279.188 -418.782 +8 -784.264 109.137 +9 -710.66 225.888 +10 -1186.55 -643.401 +11 1227.16 -643.401 +12 1227.16 567.259 +13 -1186.55 567.259 + +12 0 +1 2 8 +2 9 2 +3 2 3 +4 1 2 +5 4 2 +6 13 10 +7 12 11 +8 5 2 +9 6 2 +10 7 2 +11 13 12 +12 10 11 + +0 diff --git a/Mesh_2/demo/Mesh_2/data/clusters2.edg b/Mesh_2/demo/Mesh_2/data/clusters2.edg new file mode 100644 index 00000000000..a63a5756686 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/clusters2.edg @@ -0,0 +1,48 @@ +47 +-20.3046 30.4569 -784.264 109.137 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 662.437 365.482 +812.183 152.284 -20.3046 30.4569 +824.873 53.2995 -20.3046 30.4569 +819.797 -119.289 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -116.751 -441.624 +-20.3046 30.4569 -81.2183 116.751 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -279.188 -418.782 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-710.66 225.888 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 +-20.3046 30.4569 -20.3046 30.4569 diff --git a/Mesh_2/demo/Mesh_2/data/fish.edg b/Mesh_2/demo/Mesh_2/data/fish.edg new file mode 100644 index 00000000000..b87d3bff6f2 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/fish.edg @@ -0,0 +1,17 @@ +16 +-0.25 0.0 -0.5 1.0 +-0.25 0.0 -0.5 -1.0 +-0.5 1.0 0.0 0.5 +-0.5 -1.0 0.0 -0.5 + 0.0 0.5 0.5 1.0 + 0.0 -0.5 0.5 -1.0 + 0.5 1.0 1.0 0.0 + 0.5 -1.0 1.0 0.0 + 0.25 0.0 0.5 0.5 +0.25 0.0 0.5 -0.5 +0.5 0.5 0.75 0.0 +0.5 -0.5 0.75 0.0 +-0.25 0.0 -0.5 0.5 +-0.25 0.0 -0.5 -0.5 +-0.5 0.5 -0.75 0.0 +-0.5 -0.5 -0.75 0.0 \ No newline at end of file diff --git a/Mesh_2/demo/Mesh_2/data/fish.poly b/Mesh_2/demo/Mesh_2/data/fish.poly new file mode 100644 index 00000000000..5c1f291f094 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/fish.poly @@ -0,0 +1,40 @@ +# Shewchuk Triangle .poly file, produced by the CGAL::Mesh_2 package +# Neither attributes nor boundary markers are used. +15 2 0 0 + +1 -0.25 0 +2 -0.5 1 +3 -0.5 -1 +4 0 0.5 +5 0 -0.5 +6 0.5 1 +7 0.5 -1 +8 1 0 +9 0.25 0 +10 0.5 0.5 +11 0.5 -0.5 +12 0.75 0 +13 -0.5 0.5 +14 -0.5 -0.5 +15 -0.75 0 + +16 0 +1 15 14 +2 5 3 +3 3 1 +4 6 4 +5 4 2 +6 12 10 +7 5 7 +8 10 9 +9 7 8 +10 8 6 +11 9 11 +12 12 11 +13 13 15 +14 14 1 +15 13 1 +16 2 1 + +1 +1 0.505223 0.0994429 diff --git a/Mesh_2/demo/Mesh_2/data/img1.edg b/Mesh_2/demo/Mesh_2/data/img1.edg new file mode 100644 index 00000000000..24d96340703 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/img1.edg @@ -0,0 +1,44 @@ +43 +435.625 74.625 401.25 79.25 +206.5 24 159 28 +406.5 55.5 435.375 51.625 +464.25 47.75 522 40 +206.5 24 254 20 +438 24 373 20 +319 33 289 54 +377.625 59.375 348.75 63.25 +406.5 55.5 377.625 59.375 +366.875 83.875 401.25 79.25 +464.25 47.75 435.375 51.625 +332.5 88.5 298.125 93.125 +263.75 97.75 298.125 93.125 +319.875 67.125 348.75 63.25 +319.875 67.125 291 71 +190.5 60 150.75 66 +230.25 54 270 48 +431.5 294.5 487 230 +376 359 431.5 294.5 +265 252 278 221.5 +258.253 196.183 221.5 202 +291 191 258.253 196.183 +278 221.5 291 191 +186.75 207.5 221.5 202 +194.625 177.125 252.25 166.25 +309.875 155.375 252.25 166.25 +94 221 109 306 +79 136 94 221 +598 182 555 263 +555 263 512 344 +230.25 54 190.5 60 +367.5 144.5 440.942 130.64 +514.385 116.78 440.942 130.64 +366.875 83.875 332.5 88.5 +150.75 66 111 72 +309.875 155.375 367.5 144.5 +263.75 97.75 195 107 +137 188 194.625 177.125 +598 101 514.385 116.78 +542.5 165.5 598 101 +470 70 435.625 74.625 +152 213 186.75 207.5 +542.5 165.5 487 230 diff --git a/Mesh_2/demo/Mesh_2/data/img2.edg b/Mesh_2/demo/Mesh_2/data/img2.edg new file mode 100644 index 00000000000..10ee1b9fbca --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/img2.edg @@ -0,0 +1,11 @@ +10 +371.146 65.1014 311.573 64.3007 +375.5 89.75 438 66 +313 113.5 375.5 89.75 +252 63.5 311.573 64.3007 +188 161 313 113.5 +371.146 65.1014 438 66 +420.5 170.5 321.609 166.459 +653 180 420.5 170.5 +66 61 252 63.5 +321.609 166.459 188 161 diff --git a/Mesh_2/demo/Mesh_2/data/img3.edg b/Mesh_2/demo/Mesh_2/data/img3.edg new file mode 100644 index 00000000000..5f56b41f4c5 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/img3.edg @@ -0,0 +1,4 @@ +3 +622 53 185 145 +125 53 622 53 +710 145 185 145 diff --git a/Mesh_2/demo/Mesh_2/data/img4.edg b/Mesh_2/demo/Mesh_2/data/img4.edg new file mode 100644 index 00000000000..8b429e52147 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/img4.edg @@ -0,0 +1,11 @@ +10 +619 81 499.25 81 +259.75 81 379.5 81 +302 192 387 192 +499.25 81 379.5 81 +383 143 462 143 +383 143 304 143 +462 143 541 143 +387 192 472 192 +304 143 225 143 +140 81 259.75 81 diff --git a/Mesh_2/demo/Mesh_2/data/img5.edg b/Mesh_2/demo/Mesh_2/data/img5.edg new file mode 100644 index 00000000000..a6737dbf522 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/img5.edg @@ -0,0 +1,275 @@ +274 +529.987 14.0048 529.99 14.0036 +93.01 171.996 93.0133 171.995 +93.0067 171.998 93.01 171.996 +93.0067 171.998 93 172 +688.982 49.0038 688.986 49.0028 +688.995 49.0021 689 49 +93.02 171.993 93.0167 171.994 +93.0133 171.995 93.0167 171.994 +93.0182 171.996 93.0227 171.995 +93.0136 171.997 93.0091 171.998 +688.973 49.0056 688.977 49.0047 +688.975 49.0103 688.98 49.0082 +688.986 49.0028 688.991 49.0019 +688.98 49.0082 688.985 49.0062 +529.973 14.0096 529.967 14.0121 +529.965 14.0052 529.971 14.0043 +529.988 14.0017 529.982 14.0026 +529.98 14.0072 529.973 14.0096 +93.02 171.993 93.0267 171.99 +93.0091 171.998 93.0045 171.999 +688.973 49.0056 688.964 49.0075 +529.953 14.007 529.965 14.0052 +530 14 529.993 14.0024 +529.982 14.0026 529.977 14.0035 +688.961 49.0164 688.951 49.0205 +688.97 49.0123 688.961 49.0164 +529.947 14.0193 529.933 14.0241 +529.977 14.0035 529.971 14.0043 +529.96 14.0145 529.947 14.0193 +93.0333 171.988 93.04 171.986 +93.0333 171.988 93.0267 171.99 +93.0182 171.996 93.0136 171.997 +688.945 49.0113 688.927 49.015 +688.995 49.0021 688.99 49.0041 +688.982 49.0038 688.977 49.0047 +529.941 14.0087 529.93 14.0104 +529.993 14.0024 529.99 14.0036 +93.0227 171.995 93.0273 171.994 +93.0533 171.981 93.04 171.986 +93.0455 171.991 93.0364 171.992 +688.901 49.041 688.921 49.0328 +688.955 49.0094 688.945 49.0113 +688.941 49.0246 688.921 49.0328 +529.867 14.0482 529.893 14.0386 +529.953 14.007 529.941 14.0087 +529.92 14.0289 529.893 14.0386 +93.0667 171.976 93.08 171.971 +93.0667 171.976 93.0533 171.981 +93.0364 171.992 93.0273 171.994 +688.891 49.0225 688.854 49.03 +688.99 49.0041 688.985 49.0062 +688.964 49.0075 688.955 49.0094 +529.883 14.0174 529.859 14.0209 +529.987 14.0048 529.98 14.0072 +529.93 14.0104 529.906 14.0139 +93.0455 171.991 93.0546 171.989 +93.1067 171.961 93.08 171.971 +93.0909 171.981 93.0728 171.985 +688.803 49.0821 688.842 49.0657 +688.909 49.0188 688.891 49.0225 +688.882 49.0493 688.842 49.0657 +529.733 14.0964 529.787 14.0771 +529.906 14.0139 529.883 14.0174 +529.84 14.0579 529.787 14.0771 +93.1334 171.952 93.16 171.942 +93.1334 171.952 93.1067 171.961 +93.0728 171.985 93.0546 171.989 +688.782 49.045 688.709 49.0601 +688.975 49.0103 688.97 49.0123 +688.927 49.015 688.909 49.0188 +529.766 14.0348 529.719 14.0417 +529.967 14.0121 529.96 14.0145 +529.859 14.0209 529.812 14.0278 +93.0909 171.981 93.1091 171.977 +93.2134 171.923 93.16 171.942 +93.1819 171.962 93.1455 171.97 +688.606 49.1642 688.685 49.1313 +688.818 49.0375 688.782 49.045 +688.763 49.0985 688.685 49.1313 +529.467 14.1929 529.573 14.1543 +529.812 14.0278 529.766 14.0348 +529.68 14.1157 529.573 14.1543 +93.2667 171.904 93.3201 171.884 +93.2667 171.904 93.2134 171.923 +93.1455 171.97 93.1091 171.977 +688.563 49.0901 688.418 49.1201 +688.951 49.0205 688.941 49.0246 +688.854 49.03 688.818 49.0375 +529.531 14.0696 529.438 14.0835 +529.933 14.0241 529.92 14.0289 +529.719 14.0417 529.625 14.0557 +93.1819 171.962 93.2183 171.955 +93.4268 171.846 93.3201 171.884 +93.3638 171.925 93.291 171.94 +688.211 49.3284 688.369 49.2627 +688.636 49.0751 688.563 49.0901 +688.527 49.197 688.369 49.2627 +528.933 14.3857 529.146 14.3086 +529.625 14.0557 529.531 14.0696 +529.36 14.2314 529.146 14.3086 +93.5334 171.807 93.6401 171.769 +93.5334 171.807 93.4268 171.846 +93.291 171.94 93.2183 171.955 +688.127 49.1802 687.836 49.2402 +688.901 49.041 688.882 49.0493 +688.709 49.0601 688.636 49.0751 +529.062 14.1392 528.875 14.167 +529.867 14.0482 529.84 14.0579 +529.438 14.0835 529.25 14.1113 +93.3638 171.925 93.4365 171.91 +93.8535 171.691 93.6401 171.769 +93.7275 171.85 93.582 171.88 +687.423 49.6567 687.738 49.5254 +688.272 49.1501 688.127 49.1802 +688.054 49.394 687.738 49.5254 +527.866 14.7715 528.293 14.6172 +529.25 14.1113 529.062 14.1392 +528.72 14.4629 528.293 14.6172 +94.0669 171.614 94.2803 171.537 +94.0669 171.614 93.8535 171.691 +93.582 171.88 93.4365 171.91 +687.254 49.3604 686.672 49.4805 +688.803 49.0821 688.763 49.0985 +688.418 49.1201 688.272 49.1501 +528.125 14.2783 527.75 14.334 +529.733 14.0964 529.68 14.1157 +528.875 14.167 528.5 14.2227 +93.7275 171.85 93.873 171.82 +94.707 171.383 94.2803 171.537 +94.4551 171.7 94.1641 171.76 +685.846 50.3135 686.477 50.0508 +687.545 49.3003 687.254 49.3604 +687.107 49.7881 686.477 50.0508 +525.732 15.543 526.586 15.2344 +528.5 14.2227 528.125 14.2783 +527.439 14.9258 526.586 15.2344 +95.1338 171.229 95.5605 171.074 +95.1338 171.229 94.707 171.383 +94.1641 171.76 93.873 171.82 +685.508 49.7207 684.344 49.9609 +688.606 49.1642 688.527 49.197 +687.836 49.2402 687.545 49.3003 +526.25 14.5566 525.5 14.668 +529.467 14.1929 529.36 14.2314 +527.75 14.334 527 14.4453 +94.4551 171.7 94.7461 171.64 +96.4141 170.766 95.5605 171.074 +95.9102 171.399 95.3281 171.52 +682.691 51.627 683.953 51.1016 +686.09 49.6006 685.508 49.7207 +685.215 50.5762 683.953 51.1016 +521.465 17.0859 523.172 16.4688 +527 14.4453 526.25 14.5566 +524.879 15.8516 523.172 16.4688 +97.2676 170.457 98.1211 170.148 +97.2676 170.457 96.4141 170.766 +95.3281 171.52 94.7461 171.64 +682.016 50.4414 679.688 50.9219 +688.211 49.3284 688.054 49.394 +686.672 49.4805 686.09 49.6006 +522.5 15.1133 521 15.3359 +528.933 14.3857 528.72 14.4629 +525.5 14.668 524 14.8906 +95.9102 171.399 96.4922 171.279 +99.8281 169.531 98.1211 170.148 +98.8203 170.799 97.6562 171.039 +676.383 54.2539 678.906 53.2031 +683.18 50.2012 682.016 50.4414 +681.43 52.1523 678.906 53.2031 +512.93 20.1719 516.344 18.9375 +524 14.8906 522.5 15.1133 +519.758 17.7031 516.344 18.9375 +101.535 168.914 103.242 168.297 +101.535 168.914 99.8281 169.531 +97.6562 171.039 96.4922 171.279 +675.031 51.8828 670.375 52.8438 +687.423 49.6567 687.107 49.7881 +684.344 49.9609 683.18 50.2012 +515 16.2266 512 16.6719 +527.866 14.7715 527.439 14.9258 +521 15.3359 518 15.7812 +98.8203 170.799 99.9844 170.559 +106.656 167.062 103.242 168.297 +104.641 169.598 102.312 170.078 +663.766 59.5078 668.812 57.4062 +677.359 51.4023 675.031 51.8828 +673.859 55.3047 668.812 57.4062 +495.859 26.3438 502.688 23.875 +518 15.7812 515 16.2266 +509.516 21.4062 502.688 23.875 +113.484 164.594 120.312 162.125 +110.07 165.828 113.484 164.594 +110.07 165.828 106.656 167.062 +102.312 170.078 99.9844 170.559 +661.062 54.7656 651.75 56.6875 +685.846 50.3135 685.215 50.5762 +679.688 50.9219 677.359 51.4023 +500 18.4531 494 19.3438 +525.732 15.543 524.879 15.8516 +512 16.6719 506 17.5625 +104.641 169.598 106.969 169.117 +116.281 167.195 111.625 168.156 +638.531 70.0156 648.625 65.8125 +665.719 53.8047 661.062 54.7656 +658.719 61.6094 648.625 65.8125 +461.719 38.6875 475.375 33.75 +506 17.5625 500 18.4531 +489.031 28.8125 475.375 33.75 +127.141 159.656 133.969 157.188 +127.141 159.656 120.312 162.125 +111.625 168.156 106.969 169.117 +633.125 60.5312 614.5 64.375 +682.691 51.627 681.43 52.1523 +670.375 52.8438 665.719 53.8047 +470 22.9062 458 24.6875 +521.465 17.0859 519.758 17.7031 +494 19.3438 482 21.125 +116.281 167.195 120.938 166.234 +147.625 152.25 133.969 157.188 +139.562 162.391 130.25 164.312 +642.438 58.6094 633.125 60.5312 +628.438 74.2188 608.25 82.625 +393.438 63.375 420.75 53.5 +482 21.125 470 22.9062 +461.719 38.6875 448.062 43.625 +161.281 147.312 174.938 142.375 +161.281 147.312 147.625 152.25 +130.25 164.312 120.938 166.234 +588.062 91.0312 608.25 82.625 +676.383 54.2539 673.859 55.3047 +651.75 56.6875 642.438 58.6094 +410 31.8125 386 35.375 +512.93 20.1719 509.516 21.4062 +458 24.6875 434 28.25 +311.5 93 256.875 112.75 +139.562 162.391 148.875 160.469 +202.25 132.5 174.938 142.375 +186.125 152.781 167.5 156.625 +420.75 53.5 448.062 43.625 +595.875 68.2188 614.5 64.375 +595.875 68.2188 577.25 72.0625 +567.875 99.4375 527.5 116.25 +229.562 122.625 256.875 112.75 +434 28.25 410 31.8125 +242 56.75 146 71 +229.562 122.625 202.25 132.5 +167.5 156.625 148.875 160.469 +465.5 95.125 391 110.5 +487.125 133.062 446.75 149.875 +540 79.75 577.25 72.0625 +588.062 91.0312 567.875 99.4375 +285.25 217.125 204.5 250.75 +366.125 73.25 311.5 93 +290 49.625 338 42.5 +386 35.375 338 42.5 +204.75 148.938 242 141.25 +186.125 152.781 204.75 148.938 +290 49.625 242 56.75 +393.438 63.375 366.125 73.25 +663.766 59.5078 658.719 61.6094 +279.25 133.562 242 141.25 +93.0045 171.999 93 172 +688.991 49.0019 689 49 +465.5 95.125 502.75 87.4375 +495.859 26.3438 489.031 28.8125 +279.25 133.562 316.5 125.875 +446.75 149.875 366 183.5 +527.5 116.25 487.125 133.062 +391 110.5 316.5 125.875 +204.5 250.75 43 318 +366 183.5 285.25 217.125 +638.531 70.0156 628.438 74.2188 +529.988 14.0017 530 14 +502.75 87.4375 540 79.75 diff --git a/Mesh_2/demo/Mesh_2/data/img6.edg b/Mesh_2/demo/Mesh_2/data/img6.edg new file mode 100644 index 00000000000..828f4ca3d2f --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/img6.edg @@ -0,0 +1,45 @@ +44 +350 158.5 392.25 148.125 +408.5 180 356.75 198.5 +350 158.5 265.5 179.25 +305 217 356.75 198.5 +434.5 137.75 476.75 127.375 +432.75 98 494.5 87 +556.25 76 494.5 87 +486.125 152.25 512 143 +460.25 161.5 486.125 152.25 +378 270.25 303 262.5 +300 27.25 245 27 +311 53 340 51.625 +434.5 137.75 392.25 148.125 +408.5 180 460.25 161.5 +519 117 476.75 127.375 +355 27.5 382.5 27.625 +369 50.25 398 48.875 +437.5 27.875 410 27.75 +327.5 27.375 300 27.25 +427 47.5 456 46.125 +300.25 90.25 276.875 94.875 +378 270.25 453 278 +398 48.875 427 47.5 +371 109 432.75 98 +340 51.625 369 50.25 +456 46.125 485 44.75 +96 251.5 135 285.75 +303 262.5 228 254.75 +265.5 179.25 181 200 +556.25 76 618 65 +83 51 100 116.5 +263 82 215 53 +253.5 99.5 276.875 94.875 +253.5 99.5 160 118 +485 44.75 543 42 +410 27.75 382.5 27.625 +327.5 27.375 355 27.5 +167 24 215 53 +18 183 96 251.5 +153 247 228 254.75 +174 320 135 285.75 +465 28 437.5 27.875 +347 81 300.25 90.25 +117 182 100 116.5 diff --git a/Mesh_2/demo/Mesh_2/data/img7.edg b/Mesh_2/demo/Mesh_2/data/img7.edg new file mode 100644 index 00000000000..c8fd3429a08 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/img7.edg @@ -0,0 +1,33 @@ +32 +-2622.44 97.8238 -2622.44 -2962.18 +437.56 3157.82 -2622.44 3157.82 +3497.56 97.8238 3497.56 3157.82 +-2622.44 97.8238 -2622.44 3157.82 +-583 97.25 -583 -922.75 +500.981 34.6916 591.49 34.8458 +516.76 78.8601 594.52 58.2201 +361.24 120.14 283.48 140.78 +283.48 140.78 196 164 +286.501 162.75 377.002 161.499 +95 34 276.019 34.3084 +361.24 120.14 439 99.5 +388.5 34.5 500.981 34.6916 +485.5 160 593.998 158.501 +439 99.5 516.76 78.8601 +276.019 34.3084 388.5 34.5 +485.5 160 377.002 161.499 +591.49 34.8458 682 35 +1457 1117.25 1457 97.25 +-583 1117.25 437 1117.25 +3497.56 3157.82 437.56 3157.82 +286.501 162.75 196 164 +437 -922.75 1457 -922.75 +437 1117.25 1457 1117.25 +437.56 -2962.18 -2622.44 -2962.18 +1457 97.25 1457 -922.75 +437 -922.75 -583 -922.75 +3497.56 -2962.18 3497.56 97.8238 +775 156 593.998 158.501 +-583 97.25 -583 1117.25 +594.52 58.2201 682 35 +437.56 -2962.18 3497.56 -2962.18 diff --git a/Mesh_2/demo/Mesh_2/data/img8.edg b/Mesh_2/demo/Mesh_2/data/img8.edg new file mode 100644 index 00000000000..72fba8977d2 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/img8.edg @@ -0,0 +1,7 @@ +6 +419 132 699 200 +626 111 419 132 +213 166 699 200 +626 111 273 89 +273 89 431 41 +431 41 76 58 diff --git a/Mesh_2/demo/Mesh_2/data/lettre_A.edg b/Mesh_2/demo/Mesh_2/data/lettre_A.edg new file mode 100644 index 00000000000..e40114a33d8 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/lettre_A.edg @@ -0,0 +1,30 @@ +29 +120 465.84 120 475.44 +480 465.84 464.64 463.44 +480 475.44 480 465.84 +453.6 456.72 464.64 463.44 +444.48 443.76 453.6 456.72 +480 475.44 347.52 475.44 +293.28 124.56 166.56 421.2 +147.36 453.84 166.56 421.2 +120 475.44 222.72 475.44 +187.2 443.76 191.52 424.08 +444.48 443.76 302.88 124.56 +372.96 462.96 347.52 465.84 +347.52 475.44 347.52 465.84 +352.32 362.64 372.48 410.64 +372.48 410.64 383.52 446.64 +120 465.84 132 463.92 +132 463.92 147.36 453.84 +216.48 362.64 191.52 424.08 +380.16 457.68 383.52 446.64 +372.96 462.96 380.16 457.68 +222.72 465.84 200.64 462.96 +222.72 475.44 222.72 465.84 +187.2 443.76 191.04 456.72 +191.04 456.72 200.64 462.96 +293.28 124.56 302.88 124.56 +224.64 342 284.16 198.48 +216.48 362.64 352.32 362.64 +284.16 198.48 344.64 342 +224.64 342 344.64 342 diff --git a/Mesh_2/demo/Mesh_2/data/lettre_A_2.edg b/Mesh_2/demo/Mesh_2/data/lettre_A_2.edg new file mode 100644 index 00000000000..3e9fe4876f7 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/lettre_A_2.edg @@ -0,0 +1,19 @@ +18 +-401.015 -355.33 -370.558 -368.02 +-456.853 -335.025 -477.157 -355.33 +-477.157 -355.33 -510.152 -365.482 +-238.579 324.873 -456.853 -335.025 +-510.152 -365.482 -370.558 -368.02 +-149.746 -119.289 -81.2183 -342.64 +-418.782 -337.563 -350.254 -119.289 +-12.6904 -360.406 -40.6091 -342.64 +27.9188 -365.482 -12.6904 -360.406 +-40.6091 -342.64 -238.579 324.873 +-91.3706 -357.868 -124.365 -368.02 +-81.2183 -342.64 -91.3706 -357.868 +-124.365 -368.02 27.9188 -365.482 +-350.254 -119.289 -149.746 -119.289 +-342.64 -78.6802 -157.36 -78.6802 +-401.015 -355.33 -418.782 -337.563 +-241.117 218.274 -342.64 -78.6802 +-157.36 -78.6802 -241.117 218.274 diff --git a/Mesh_2/demo/Mesh_2/data/trivial.poly b/Mesh_2/demo/Mesh_2/data/trivial.poly new file mode 100644 index 00000000000..ba65151238c --- /dev/null +++ b/Mesh_2/demo/Mesh_2/data/trivial.poly @@ -0,0 +1,17 @@ +# Shewchuk Triangle .poly file, produced by the CGAL::Mesh_2 package +# Neither attributes nor boundary markers are used. +5 2 0 0 + +1 -4.0 0.0 +2 0.0 -1.0 +3 4.0 0.0 +4 0.0 1.0 +5 2.0 0.6 + +4 0 +1 1 2 +2 2 3 +3 3 4 +4 4 1 + +0 diff --git a/Mesh_2/demo/Mesh_2/icons.C b/Mesh_2/demo/Mesh_2/icons.C new file mode 100644 index 00000000000..2332d17f1b1 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/icons.C @@ -0,0 +1,34 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#include + +#ifdef CGAL_USE_QT + +#include +#include +#include +#include "contraints.xpm" +#include "marked.xpm" +#include "seeds.xpm" +#include +#include + +#endif diff --git a/Mesh_2/demo/Mesh_2/icons.h b/Mesh_2/demo/Mesh_2/icons.h new file mode 100644 index 00000000000..76d1a86ea5f --- /dev/null +++ b/Mesh_2/demo/Mesh_2/icons.h @@ -0,0 +1,28 @@ +// Copyright (c) 2003-2004 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +extern const char *polygon_xpm[], + *point_xpm[], + *points_xpm[], + *contraints_xpm[], + *marked_xpm[], + *seeds_xpm[], + *circle_xpm[], + *triangulation_xpm[]; diff --git a/Mesh_2/demo/Mesh_2/makefile b/Mesh_2/demo/Mesh_2/makefile new file mode 100644 index 00000000000..93a405a66ad --- /dev/null +++ b/Mesh_2/demo/Mesh_2/makefile @@ -0,0 +1,121 @@ +# Created by the script cgal_create_makefile +# This is the makefile for compiling a CGAL application. + +#---------------------------------------------------------------------# +# include platform specific settings +#---------------------------------------------------------------------# +# Choose the right include file from the /make directory. + +# CGAL_MAKEFILE = ENTER_YOUR_INCLUDE_MAKEFILE_HERE +include $(CGAL_MAKEFILE) + +#---------------------------------------------------------------------# +# compiler flags +#---------------------------------------------------------------------# + +OTHER_CXXFLAGS= + +CXXFLAGS = \ + -I../../include \ + -I../../../Triangulation_2/include \ + $(CGAL_CXXFLAGS) \ + $(LONG_NAME_PROBLEM_CXXFLAGS) \ + $(OTHER_CXXFLAGS) + +#---------------------------------------------------------------------# +# linker flags +#---------------------------------------------------------------------# + +LIBPATH = \ + $(CGAL_LIBPATH) + +LDFLAGS = \ + $(LONG_NAME_PROBLEM_LDFLAGS) \ + $(CGAL_QT_LDFLAGS) + +#---------------------------------------------------------------------# +# target entries +#---------------------------------------------------------------------# + +all: \ + mesh_demo$(EXE_EXT) \ + mesh$(EXE_EXT) \ + conform$(EXE_EXT) + +Qt_widget_styled_layer.moc: Qt_widget_styled_layer.h + $(QT_MOC) -o Qt_widget_styled_layer.moc Qt_widget_styled_layer.h + +Qt_widget_styled_layer$(OBJ_EXT): Qt_widget_styled_layer.moc + +Qt_widget_style_editor.moc: Qt_widget_style_editor.h + $(QT_MOC) -o Qt_widget_style_editor.moc Qt_widget_style_editor.h + +Qt_widget_style_editor-aux.moc: Qt_widget_style_editor-aux.h + $(QT_MOC) -o Qt_widget_style_editor-aux.moc Qt_widget_style_editor-aux.h + +Qt_widget_style_editor$(OBJ_EXT): Qt_widget_style_editor-aux.moc Qt_widget_style_editor.moc + + +Show_points.moc: Show_points.h + $(QT_MOC) -o Show_points.moc Show_points.h + +Show_points$(OBJ_EXT): Show_points.moc Show_points.C + +Show_segments_base.moc: Show_segments_base.h + $(QT_MOC) -o Show_segments_base.moc Show_segments_base.h + +Show_segments_base$(OBJ_EXT): Show_segments_base.moc Show_segments_base.C + +icons$(OBJ_EXT): seeds.xpm marked.xpm contraints.xpm + +mesh_demo.moc: mesh_demo.C + $(QT_MOC) -o mesh_demo.moc $< + +Show_clusters.moc: Show_clusters.h + $(QT_MOC) -o Show_clusters.moc $< + +mesh_demo$(OBJ_EXT): mesh_demo.moc Show_clusters.moc Show_segments_base.moc\ + Show_points.h \ + Qt_widget_style_editor.h + +mesh_demo$(EXE_EXT): mesh_demo$(OBJ_EXT) icons$(OBJ_EXT) \ + Show_points$(OBJ_EXT) \ + Show_segments_base$(OBJ_EXT) \ + Qt_widget_styled_layer$(OBJ_EXT) \ + Qt_widget_style_editor$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)mesh_demo \ + mesh_demo$(OBJ_EXT) \ + icons$(OBJ_EXT) \ + Show_points$(OBJ_EXT) \ + Show_segments_base$(OBJ_EXT) \ + Qt_widget_styled_layer$(OBJ_EXT) \ + Qt_widget_style_editor$(OBJ_EXT) \ + $(LDFLAGS) + +run_mesh_demo: mesh_demo$(EXE_EXT) + ./mesh_demo$(EXE_EXT) + +conform$(EXE_EXT): conform$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)conform conform$(OBJ_EXT) $(LDFLAGS) + +mesh$(EXE_EXT): mesh$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)mesh mesh$(OBJ_EXT) $(LDFLAGS) + +clean: \ + icons.clean \ + mesh_demo.clean \ + mesh.clean \ + conform.clean \ + Show_points.clean \ + Show_segments_base.clean \ + Qt_widget_styled_layer.clean \ + Qt_widget_style_editor.clean + rm -f Show_clusters.moc Qt_widget_style_editor-aux.moc + +#---------------------------------------------------------------------# +# suffix rules +#---------------------------------------------------------------------# + +.C$(OBJ_EXT): + $(CGAL_CXX) $(CXXFLAGS) $(OBJ_OPT) $< + diff --git a/Mesh_2/demo/Mesh_2/marked.xpm b/Mesh_2/demo/Mesh_2/marked.xpm new file mode 100644 index 00000000000..5a1c8d26513 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/marked.xpm @@ -0,0 +1,39 @@ +/* XPM */ +const char * marked_xpm[] = { +"32 32 4 1", +" c None", +". c #000080", +"+ c #0CFF00", +"@ c #FFFFFF", +" ", +" ", +" ", +" ............. ", +" ..++++++++++... ", +" .+.++++++++.@.+. ", +" .++.+++++++.+.++. ", +" .+++.+++++.++.+++. ", +" .+++.++++.+++.++++. ", +" .+++++.++.++++.+++++. ", +" .++++++..++++.++++... ", +" .+++++++...+++.++..@.. ", +" .+++++....@......++.+. ", +" .++++.+.@.@@@@.++++.+. ", +" .+++..++.@@.@@@.+++.++. ", +" .++.++++.@@.@@@.+++.+++. ", +" ...+++++.@@@.@@.++.++++. ", +" ..++++++.@@@@@.@.++.++++. ", +" ...+++++.@@@@@.@.+.+++++. ", +" .++......@@@@@@..+.+++++. ", +" .+++++++.....@@.......... ", +" .+++++..+.+++.....++++. ", +" .++++.++++.++++++.+++. ", +" .+++.++++++.+++++.++. ", +" .+..++++++++.+++.++. ", +" ..+++++++++++.++.++. ", +" .....+++++++++.+.+. ", +" ........++... ", +" .... ", +" ", +" ", +" "}; diff --git a/Mesh_2/demo/Mesh_2/mesh.C b/Mesh_2/demo/Mesh_2/mesh.C new file mode 100644 index 00000000000..77dd85464a3 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/mesh.C @@ -0,0 +1,155 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#include + + // if QT is not installed, a message will be issued in runtime. +#ifndef CGAL_USE_QT +#include + +int main(int, char*) +{ + + std::cout << "Sorry, this demo needs QT..."; + std::cout << std::endl; + + return 0; +} + +#else + +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian K1; +typedef CGAL::Filtered_kernel K2; +struct K : public K2 {}; + +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Delaunay_mesh_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2 Tr; +typedef CGAL::Delaunay_mesh_area_criteria_2 Meshcriteria; + +typedef K::Point_2 Point; + +void usage(char** argv) +{ + std::cerr << "Usage: " << std::endl + << argv[0] << " [-Q] [-a area] input.poly [output.poly]" << std::endl; +} + +int main(int argc, char** argv) +{ + int arg_count = 1; + bool terminal_output = true; + Meshcriteria criteria; + Tr t; + + if(argc < 2) + { + usage(argv); + return 1; + } + + while(argv[arg_count][0] == '-' && argv[arg_count] != "--") + { + if(std::string(argv[arg_count]) == "-Q") + terminal_output = false; + else if(std::string(argv[arg_count]) == "-a") + { + double area_bound; + if( (argc > arg_count+1) && + std::istringstream(argv[arg_count+1]) >> area_bound ) + { + criteria.set_area_bound(area_bound); + ++arg_count; + } + else + { + std::cerr << "The area " << argv[arg_count+1] + << " is not a double." << std::endl; + usage(argv); + return 1; + } + } + else + { + std::cerr << "Unknown option " << argv[arg_count] << std::endl; + usage(argv); + return 1; + } + ++arg_count; + } + if(argv[arg_count] == "--") + ++arg_count; + + if(argc < arg_count+1 || argc > arg_count+2) + { + usage(argv); + return 1; + }; + + std::ifstream input(argv[arg_count]); + if(input) + { + CGAL::read_triangle_poly_file(t, input); + CGAL::refine_Delaunay_mesh_2(t, criteria); + + if(argc==arg_count+1) + { + if(terminal_output) + CGAL::write_triangle_poly_file(t, std::cout); + } + else + { + std::ofstream output(argv[arg_count+1]); + CGAL::write_triangle_poly_file(t, output); + } + if(terminal_output) + std::cerr + << "Mesh points: " << t.number_of_vertices() << std::endl + << "Mesh triangles: " << t.number_of_faces () << std::endl; + + } + else + { + std::cerr << "Bad file: " << argv[arg_count] << std::endl; + usage(argv); + return 1; + } + + return 0; +}; + +#endif // CGAL_USE_QT diff --git a/Mesh_2/demo/Mesh_2/mesh_demo.C b/Mesh_2/demo/Mesh_2/mesh_demo.C new file mode 100644 index 00000000000..45836ace7c2 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/mesh_demo.C @@ -0,0 +1,1512 @@ +// Copyright (c) 2003-2006 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public License as +// published by the Free Software Foundation; version 2.1 of the License. +// See the file LICENSE.LGPL 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) : Laurent Rineau + +#include + + // if QT is not installed, a message will be issued in runtime. +#ifndef CGAL_USE_QT +#include + +int main(int, char*) +{ + + std::cout << "Sorry, this demo needs QT..."; + std::cout << std::endl; + + return 0; +} + +#else + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#define CGAL_MESH_2_USE_TIMERS +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "icons.h" + +#include "Show_points.h" +#include "Show_segments.h" +#include "Qt_layer_show_triangulation.h" +#include "Qt_layer_show_triangulation_constraints.h" +#include "Qt_layer_show_circles.h" +#include "Show_clusters.h" +#include + +#ifdef CGAL_MESH_2_DEBUG_DRAW +#include "Debug_layer.h" +#endif + +#include "Qt_widget_style_editor.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef TESTING +# include + typedef CGAL::Simple_cartesian Kernel; +#else // !TESTING +# include + typedef CGAL::Simple_cartesian K1; + typedef CGAL::Filtered_kernel Kernel; +#endif // #ifdef TESTING + +struct K : public Kernel {}; +typedef K::FT FT; + +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Delaunay_mesh_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2 Tr; +typedef CGAL::Delaunay_mesh_local_size_criteria_2 Criteria; + +typedef K::Point_2 Point_2; +typedef K::Segment_2 Segment_2; +typedef K::Triangle_2 Triangle_2; +typedef K::Circle_2 Circle; +typedef CGAL::Polygon_2 CGALPolygon; + +typedef CGAL::Delaunay_mesher_2 Mesher; +typedef Tr::Vertex Vertex; +typedef Tr::Edge Edge; + +template +void +read_constraints(CDT& t, std::istream &f) +{ + typedef typename CDT::Point Point; + + t.clear(); + + int nedges = 0; + f>>nedges; + + for(int n = 0; n> p1 >> p2; + t.insert_constraint(p1, p2); + } +} + +template +void +write_constraints(const CDT& t, std::ostream &f) +{ + typedef typename CDT::Finite_edges_iterator Finite_edges_iterator; + + int number_of_constrained_edges = 0; + for(Finite_edges_iterator it = t.finite_edges_begin(); + it != t.finite_edges_end(); + ++it) + if((*it).first->is_constrained((*it).second)) + ++number_of_constrained_edges; + + f << number_of_constrained_edges << std::endl; + for(Finite_edges_iterator eit = t.finite_edges_begin(); + eit!=t.finite_edges_end(); + ++eit) + if((*eit).first->is_constrained((*eit).second)) + { + f << (*eit).first->vertex(t.cw((*eit).second))->point() << " " + << (*eit).first->vertex(t.ccw((*eit).second))->point() <vertex(Tr::cw (e.second))->point(), + e.first->vertex(Tr::ccw(e.second))->point()); + } +}; + +template +class Show_in_domain_faces : public CGAL::Qt_widget_layer +{ + Tr *cdt; + CGAL::Color color; +public: + Show_in_domain_faces(Tr *t, CGAL::Color c=CGAL::GREEN, + QObject* parent = 0, const char* name = 0) + : Qt_widget_layer(parent, name), + cdt(t), + color(c) + { + } + + typedef typename Tr::Finite_faces_iterator Face_iterator; + + void draw() + { + QColor old_fill_color = widget->fillColor(); + int old_line_width = widget->lineWidth(); + *widget << CGAL::FillColor(CGAL::GREEN) << CGAL::LineWidth(0); + for(Face_iterator fit=cdt->finite_faces_begin(); + fit!=cdt->finite_faces_end(); + ++fit) + if(fit->is_in_domain()) + *widget << cdt->triangle(fit); + widget->setFillColor(old_fill_color); + widget->setLineWidth(old_line_width); + } +}; + +template +class Show_bad_faces : public CGAL::Qt_widget_layer +{ + Mesher *m; + CGAL::Color color; +public: + Show_bad_faces(Mesher *mesher, + CGAL::Color c=CGAL::Color(127,0,0), + QObject* parent = 0, const char* name = 0) + : Qt_widget_layer(parent, name), + m(mesher), + color(c) + {} + + void set_container(Mesher* mesher) + { + m = mesher; + } + + typedef typename Mesher::Bad_faces_const_iterator Bad_faces_iterator; + + void draw() + { + if( m != 0 ) + { + widget->lock(); + { + QColor old_fill_color = widget->fillColor(); + int old_line_width = widget->lineWidth(); + + *widget << CGAL::FillColor(color) + << CGAL::LineWidth(0); + + for(Bad_faces_iterator fit=m->bad_faces_begin(); + fit!=m->bad_faces_end(); + ++fit) + *widget << Triangle_2((*fit)->vertex(0)->point(), + (*fit)->vertex(1)->point(), + (*fit)->vertex(2)->point()); + widget->setFillColor(old_fill_color); + widget->setLineWidth(old_line_width); + } + widget->unlock(); + } + } +}; + +class Meshing_debugging_layer : public CGAL::Qt_widget_layer +{ + Q_OBJECT + Mesher* m; + bool point_on; +public: + Meshing_debugging_layer(QObject* parent = 0, const char* name = 0) + : Qt_widget_layer(parent, name), m(0), point_on(false) + { + } + + void set_container(Mesher* mesher) + { + m = mesher; + } + + void draw() + { + if( m != 0 ) + { + if( m->is_refinement_done() ) return; + + widget->lock(); + { + QColor old_color = widget->color(); + int old_line_width = widget->lineWidth(); + CGAL::PointStyle old_point_style = widget->pointStyle(); + int old_point_size = widget->pointSize(); + + if( m->is_edges_refinement_done() ) + { + QColor old_fill_color = widget->fillColor(); + + const Tr::Face_handle fh = m->next_bad_face(); + + *widget << CGAL::FillColor(CGAL::RED) + << CGAL::LineWidth(0) + << Triangle_2(fh->vertex(0)->point(), + fh->vertex(1)->point(), + fh->vertex(2)->point()); + + widget->setFillColor(old_fill_color); + } + else + { + Edge_to_segment edge_to_segment; + + *widget << CGAL::PURPLE + << CGAL::LineWidth(2) + << edge_to_segment(m->next_encroached_edge()); + } + + *widget << CGAL::BLACK + << CGAL::PointStyle(CGAL::PLUS) + << CGAL::PointSize(3) + << m->next_refinement_point() + << CGAL::PointSize(old_point_size) + << CGAL::PointStyle(old_point_style); + + widget->setLineWidth(old_line_width); + widget->setColor(old_color); + } + widget->unlock(); + } + } +}; + + +class Follow_mouse : public CGAL::Qt_widget_layer +{ + QCursor oldcursor; +public: + Follow_mouse(QObject* parent = 0, const char* name = 0) + : Qt_widget_layer(parent, name) + { + } + + void mouseMoveEvent(QMouseEvent *e) + { + FT x=static_cast(widget->x_real(e->x())); + FT y=static_cast(widget->y_real(e->y())); + + widget->new_object(CGAL::make_object(Point_2(x, y))); + } + + void activating() + { + oldcursor = widget->cursor(); + widget->setCursor(crossCursor); + }; + + void deactivating() + { + widget->setCursor(oldcursor); + }; +}; + +class Preferences : public QWidget +{ + Q_OBJECT +private: + QGridLayout* layout; + QTabWidget* tab; + +public: + Preferences(QWidget* parent = 0, const char* name = 0, bool modal = false) + : QWidget(parent, name, modal) + { + layout = new QGridLayout(this, 1,1, 11, 6, "pref_layout"); + tab = new QTabWidget(this); + layout->addWidget(tab, 0, 0); + } + + template + void setLayers(LayersIterator begin, LayersIterator end) + { + QWidget* w; + while( (w = tab->currentPage()) != 0) + { + tab->removePage(w); + delete w; + } + + for(LayersIterator it = begin; it!=end; ++it) + { + QFrame* box = new QFrame(this); + QHBoxLayout* hor = new QHBoxLayout(box, 5, 0); + QVBoxLayout* layout = new QVBoxLayout(hor, 5); + + QCheckBox* check = new QCheckBox("&Activated", box); + layout->addWidget(check); + + check->setChecked((*it)->is_active()); + + connect(check, SIGNAL(stateChanged(int)), + *it, SLOT(stateChanged(int))); + connect(check, SIGNAL(stateChanged(int)), + this, SLOT(is_changed())); + + // QGroupBox* group = new QGroupBox("&Properties", box); + CGAL::Qt_widget_style_editor* editor = + new CGAL::Qt_widget_style_editor((*it)->style(), box); + editor->show(); + + layout->addWidget(editor); + layout->addItem(new QSpacerItem(0, 0, + QSizePolicy::Minimum, + QSizePolicy::Expanding)); + hor->addItem(new QSpacerItem(0, 0, + QSizePolicy::Expanding, + QSizePolicy::Minimum)); + + connect(editor, SIGNAL(styleChanged()), + this, SLOT(is_changed())); + + tab->addTab(box, (*it)->name()); + } + } + +private slots: + void is_changed() { emit changed(); } + +signals: + void changed(); +}; // end of class Preferences + +class MyWindow : public QMainWindow +{ + Q_OBJECT + + typedef std::list Seeds; +public: + MyWindow() : criteria(), mesher(0) + { + // --- DEMO WINDOW'S LAYOUT --- + // a main frame, with a QHBoxLayout (border=0, space=0) + QFrame* mainframe = new QFrame(this, "mainframe"); + QHBoxLayout *mainlayout = new QHBoxLayout(mainframe, 0, 0, + "mainlayout"); + + // a Qt_widget at the left of the main frame + widget = new CGAL::Qt_widget(mainframe, "Main widget"); + widget->setSizePolicy(QSizePolicy( QSizePolicy::Expanding, + QSizePolicy::Expanding )); + mainlayout->addWidget(widget); + + // an other frame "infoframe" at the right of the main frame + // with a QVBoxLayout (border=10, space=5) + QFrame* infoframe = new QFrame(mainframe, "infoframe"); + infoframe->setFrameStyle( QFrame::Box | QFrame::Raised ); + infoframe->setLineWidth(2); + QVBoxLayout *infoframelayout = new QVBoxLayout(infoframe, 10, 5, + "infoframelayout"); + mainlayout->addWidget(infoframe); + + // a 3x2 QGridLayout in the info frame (space=5) + QGridLayout *numbers_layout = new QGridLayout(infoframelayout, + 3, 2, + 5, // space + "infolayout"); + // number of points + numbers_layout->addWidget(new QLabel("Number of points: ", + infoframe), + 0, 0, + AlignRight | AlignTop ); + + nb_of_points = new QLabel("0", infoframe); + numbers_layout->addWidget(nb_of_points, 0, 1, + AlignLeft | AlignTop ); + + // number of clusters + numbers_layout->addWidget(new QLabel("Number of clusters: ", + infoframe), + 1, 0, + AlignRight | AlignTop ); + + nb_of_clusters = new QLabel("", infoframe); + numbers_layout->addWidget(nb_of_clusters, 1, 1, + AlignLeft | AlignTop ); + + // initialization status + numbers_layout->addWidget(new QLabel("init status: ", infoframe), + 2, 0, + AlignRight | AlignTop ); + + init_status = new QLabel("no", infoframe); + numbers_layout->addWidget(init_status, 2, 1, + AlignLeft | AlignTop ); + + // a vertical spacer in the info frame + infoframelayout->addItem(new + QSpacerItem( 0, 0, + QSizePolicy::Minimum, + QSizePolicy::Expanding )); + + // another grid: a 2x3 QGridLayout (space=5) + QGridLayout *criteria_layout = + new QGridLayout(infoframelayout, 2, 3, + 5, // space + "criteria_layout"); + + // angle bound + criteria_layout->addWidget(new QLabel("Angle bound: ", + infoframe), + 0, 0, + AlignRight | AlignTop); + angle_bound = new QLineEdit("0.125", infoframe, + "angle_bound"); + angle_bound->setValidator(new QDoubleValidator(angle_bound)); + criteria_layout->addWidget(angle_bound, 0, 1, + AlignLeft | AlignTop ); + connect(angle_bound, SIGNAL(textChanged(const QString&)), + this, SLOT(setBound(const QString&))); + + + // size bound + criteria_layout->addWidget(new QLabel("Size bound: ", + infoframe), + 1, 0, + AlignRight | AlignTop); + size_bound = new QLineEdit("0", infoframe, + "size_bound"); + size_bound->setValidator(new QDoubleValidator(size_bound)); + criteria_layout->addWidget(size_bound, 1, 1, + AlignLeft | AlignTop ); + connect(size_bound, SIGNAL(textChanged(const QString&)), + this, SLOT(setSizeBound(const QString&))); + + // under mouse + under_mouse = new QCheckBox("Under mouse only", infoframe, + "under_mouse"); + criteria_layout->addMultiCellWidget(under_mouse, + 3, 3, 0, 1); + connect(under_mouse, SIGNAL(toggled(bool)), + this, SLOT(setLocal(bool))); + + setCentralWidget(mainframe); + resize(700,500); + mainframe->show(); + + // --- STATUSBAR --- + statusBar(); + + // --- LAYERS --- + + show_points = + new Show_points_from_triangulation(&cdt, + &Tr::finite_vertices_begin, + &Tr::finite_vertices_end, + CGAL::BLACK, 2, + CGAL::DISC, + this, "Show points"); + + show_seeds = new Show_seeds(&seeds, + &Seeds::begin, + &Seeds::end, + CGAL::BLUE, + 5, + CGAL::CROSS, + this, "Show seeds"); + show_triangulation = + new CGAL::Qt_layer_show_triangulation(&cdt, + CGAL::BLUE,1, + this, + "Show triangulation edges"); + show_in_domain = + new Show_in_domain_faces(&cdt, CGAL::GREEN, + this, "Show in_domain faces"); + + show_constraints = + new CGAL::Qt_layer_show_triangulation_constraints + (&cdt, CGAL::RED, 1, + this, "Show constrained edges"); + + show_encroached_edges = + new Show_encroached_edges(0, + &Mesher::encroached_edges_begin, + &Mesher::encroached_edges_end, + CGAL::RED, 2, + this, "Encroached edges layer"); + + show_bad_faces = + new Show_bad_faces(0, CGAL::Color(0,160,0), + this, "Show bad faces"); + + debug_layer = new Meshing_debugging_layer(this, + "Debug layer"); + + show_circles = + new CGAL::Qt_layer_show_circles(&cdt, CGAL::GRAY, 1, + CGAL::WHITE, false, + this, "Show circles"); + + show_coordinates = + new CGAL::Qt_widget_show_mouse_coordinates(*this, + this, + "Follow mouse coordinates"); + + show_clusters = new Show_clusters(mesher, + CGAL::BLACK,3,CGAL::RECT, + CGAL::BLACK,CGAL::BLUE,2, + this, + "Show clusters"); + + // layers order, first attached are "under" last attached +#ifdef CGAL_MESH_2_DEBUG_DRAW + widget->attach(new CGAL::Debug_layer()); +#endif + widget->attach(show_in_domain); + widget->attach(show_bad_faces); + widget->attach(show_triangulation); + widget->attach(show_constraints); + widget->attach(show_circles); + widget->attach(show_encroached_edges); + widget->attach(show_points); + widget->attach(show_seeds); + widget->attach(show_coordinates); + widget->attach(debug_layer); + widget->attach(show_clusters); // should be last + + show_circles->deactivate(); + show_encroached_edges->deactivate(); + show_bad_faces->deactivate(); + show_clusters->deactivate(); + + get_point = new CGAL::Qt_widget_get_point(); + widget->attach(get_point); + get_point->deactivate(); + + get_polygon = new CGAL::Qt_widget_get_polygon(); + widget->attach(get_polygon); + get_polygon->deactivate(); + + get_seed = new CGAL::Qt_widget_get_point(); + widget->attach(get_seed); + get_seed->deactivate(); + + follow_mouse = new Follow_mouse(); + widget->attach(follow_mouse); + follow_mouse->deactivate(); + + connect(widget, SIGNAL(new_cgal_object(CGAL::Object)), + this, SLOT(get_cgal_object(CGAL::Object))); + + const int number_of_styled_layers = 4; + CGAL::Qt_widget_styled_layer* styled_layers[number_of_styled_layers] = + { show_points, + show_seeds, + show_constraints, + show_triangulation}; + + prefs = new Preferences(0, "Preferences", false); + prefs->setCaption("Layers properties"); + prefs->setLayers(styled_layers, styled_layers + number_of_styled_layers); + prefs->resize(300, 200); + + connect(prefs, SIGNAL(changed()), + widget, SLOT(redraw())); + + // --- TOOLBARS --- + + // Actions: bouding box and mesh + QToolBar *toolBarActions = new QToolBar("Actions", this); + QPushButton *pbBounding = + new QPushButton("Insert bounding box", toolBarActions); + connect(pbBounding, SIGNAL(clicked()), this, + SLOT(insert_bounding_box())); + + QPushButton *pbMesh = + new QPushButton("Mesh", toolBarActions); + connect(pbMesh, SIGNAL(clicked()), this, SLOT(refineMesh())); + + QPushButton *pbConform = + new QPushButton("Conform", toolBarActions); + connect(pbConform, SIGNAL(clicked()), this, + SLOT(conformMesh())); + + QPushButton *pbAdvanced = + new QPushButton("Advanced", toolBarActions); + pbAdvanced->setToggleButton(true); + pbAdvanced->setOn(false); + connect(pbAdvanced, SIGNAL(stateChanged(int)), + this, SLOT(advanced(int))); + + // Inputs: polygons or points + QToolBar *toolbarInputs = new QToolBar("Inputs",this); + QButtonGroup *bgChooseInputs = + new QButtonGroup("Choose inputs type", 0, + "InputType"); + bgChooseInputs->setExclusive(true); + QToolButton *pbPolygon = + new QToolButton(QPixmap( (const char**)polygon_xpm ), + "Polygon", "Insert polygonal constraints", + this, SLOT(fake_slot()), + toolbarInputs, "polygon"); + QToolButton *pbPoint = + new QToolButton(QPixmap( (const char**)point_xpm ), + "Point", "Insert points", + this, SLOT(fake_slot()), + toolbarInputs, "point"); + QToolButton *pbSeed = + new QToolButton(QPixmap( (const char**)marked_xpm ), + "Seed", "Insert a seed to define a region to mesh", + this, SLOT(fake_slot()), + toolbarInputs, "seed"); + + pbPoint->setToggleButton(true); + pbPolygon->setToggleButton(true); + pbSeed->setToggleButton(true); + bgChooseInputs->insert(pbPoint); + bgChooseInputs->insert(pbPolygon); + bgChooseInputs->insert(pbSeed); + + connect(pbPoint, SIGNAL(stateChanged(int)), + get_point, SLOT(stateChanged(int))); + connect(pbPolygon, SIGNAL(stateChanged(int)), + get_polygon, SLOT(stateChanged(int))); + connect(pbSeed, SIGNAL(stateChanged(int)), + get_seed, SLOT(stateChanged(int))); + + pbPolygon->setOn(true); + + // Layers: points, edges, constrained edges + QToolBar *toolbarLayers = new QToolBar("Layers",this); + + QToolButton *pbShowPoints + = new QToolButton(QPixmap( (const char**)points_xpm ), + "Show points", "Display mesh vertices", + this, SLOT(fake_slot()), + toolbarLayers, "show points"); + pbShowPoints->setToggleButton(true); + pbShowPoints->setOn(true); + connect(pbShowPoints, SIGNAL(stateChanged(int)), + show_points, SLOT(stateChanged(int))); + + QToolButton *pbShowSeeds + = new QToolButton(QPixmap( (const char**)seeds_xpm ), + "Show seeds", "Display seeds that define the " + "region not to mesh", + this, SLOT(fake_slot()), + toolbarLayers, "show points"); + pbShowSeeds->setToggleButton(true); + pbShowSeeds->setOn(true); + connect(pbShowSeeds, SIGNAL(stateChanged(int)), + show_seeds, SLOT(stateChanged(int))); + + QToolButton *pbShowTriangulation + = new QToolButton(QPixmap( (const char**)triangulation_xpm ), + "Show triangulation", "Display mesh edges", + this, SLOT(fake_slot()), + toolbarLayers, + "show triangulation"); + pbShowTriangulation->setToggleButton(true); + pbShowTriangulation->setOn(true); + connect(pbShowTriangulation, SIGNAL(stateChanged(int)), + show_triangulation, SLOT(stateChanged(int))); + + QToolButton *pbShowConstraints + = new QToolButton(QPixmap( (const char**)contraints_xpm ), + "Show constraints", "Display mesh constraints edges", + this, SLOT(fake_slot()), + toolbarLayers, + "show constraints"); + pbShowConstraints->setToggleButton(true); + pbShowConstraints->setOn(true); + connect(pbShowConstraints, SIGNAL(stateChanged(int)), + show_constraints, SLOT(stateChanged(int))); + + QToolButton *pbShowInDomain + = new QToolButton(QPixmap( (const char**)marked_xpm ), + "Show faces in domain", + "Display faces that will be refined", + this, SLOT(fake_slot()), + toolbarLayers, + "show in domain"); + pbShowInDomain->setToggleButton(true); + pbShowInDomain->setOn(true); + connect(pbShowInDomain, SIGNAL(stateChanged(int)), + show_in_domain, SLOT(stateChanged(int))); + + QToolButton *pbShowCircles + = new QToolButton(QPixmap( (const char**)circle_xpm ), + "Show circles", "Display circumcircles of faces", + this, SLOT(fake_slot()), + toolbarLayers, + "show circles"); + pbShowCircles->setToggleButton(true); + connect(pbShowCircles, SIGNAL(stateChanged(int)), + show_circles, SLOT(stateChanged(int))); + + bgChooseInputs->insert(pbShowCircles); + + // button group trick to connect to widget->redraw() slot + QButtonGroup *bgLayers = + new QButtonGroup("Layers", 0, "layers"); + bgLayers->insert(pbShowPoints); + bgLayers->insert(pbShowInDomain); + bgLayers->insert(pbShowTriangulation); + bgLayers->insert(pbShowConstraints); + bgLayers->insert(pbShowSeeds); + // bgLayers->insert(pbShowCircles); + connect(bgLayers, SIGNAL(clicked(int)), + widget, SLOT(redraw())); + + // the standard toolbar + CGAL::Qt_widget_standard_toolbar *std_toolbar = + new CGAL::Qt_widget_standard_toolbar(widget, this); + this->addToolBar(std_toolbar->toolbar(), Top, FALSE); + + // Steps actions: step by step meshing operations + toolBarAdvanced = new QToolBar("Advanced operations",this); + toolBarAdvanced->hide(); + + pbMeshStep = + new QPushButton("Mesh 1 step", toolBarAdvanced); + connect(pbMeshStep, SIGNAL(clicked()), this, + SLOT(refineMeshStep())); + + QSpinBox *sbStepLenght = + new QSpinBox(1, INT_MAX, 1, toolBarAdvanced); + sbStepLenght->setValue(1); + step_lenght = 1; + connect(sbStepLenght, SIGNAL(valueChanged(int)), + this, SLOT(updateStepLenght(int))); + + timer = new QTimer(this); + connect(timer, SIGNAL(timeout()), + this, SLOT(refineMeshStep())); + + pbMeshTimer = new QPushButton("Auto step", toolBarAdvanced); + pbMeshTimer->setToggleButton(true); + connect(pbMeshTimer, SIGNAL(stateChanged(int)), + this, SLOT(updateTimer(int))); + + QSpinBox *sbTimerInterval = + new QSpinBox(0, INT_MAX, 10, toolBarAdvanced); + sbTimerInterval->setValue(1000); + sbTimerInterval->setSuffix("ms"); + timer_interval=1000; + connect(sbTimerInterval, SIGNAL(valueChanged(int)), + this, SLOT(updateTimerInterval(int))); + + pbShowCluster = new QPushButton("Show clusters", toolBarAdvanced); + pbShowCluster->setToggleButton(true); + pbShowCluster->setEnabled(false); + connect(pbShowCluster, SIGNAL(stateChanged(int)), + show_clusters, SLOT(stateChanged(int))); + connect(pbShowCluster, SIGNAL(stateChanged(int)), + widget, SLOT(redraw())); + + pbShowEncroachedEdges = new QPushButton("Show encroached edges", + toolBarAdvanced); + pbShowEncroachedEdges->setToggleButton(true); + pbShowEncroachedEdges->setEnabled(false); + connect(pbShowEncroachedEdges, SIGNAL(stateChanged(int)), + show_encroached_edges, SLOT(stateChanged(int))); + connect(pbShowEncroachedEdges, SIGNAL(stateChanged(int)), + widget, SLOT(redraw())); + + pbShowBadFaces = new QPushButton("Show bad faces", + toolBarAdvanced); + pbShowBadFaces->setToggleButton(true); + pbShowBadFaces->setEnabled(false); + connect(pbShowBadFaces, SIGNAL(stateChanged(int)), + show_bad_faces, SLOT(stateChanged(int))); + connect(pbShowBadFaces, SIGNAL(stateChanged(int)), + widget, SLOT(redraw())); + + setUsesBigPixmaps(true); + + // --- MENUS --- + QPopupMenu *pmMesh = new QPopupMenu(this); + menuBar()->insertItem("&File", pmMesh); + pmMesh->insertItem("&Refine mesh", this, SLOT(refineMesh()), + CTRL+Key_R ); + pmMesh->insertItem("&Clear mesh", this, SLOT(clearMesh()), + CTRL+Key_C ); + pmMesh->insertItem("Clear seeds", this, SLOT(clearSeeds())); + pmMesh->insertItem("&Open constrained triangulation...", this, + SLOT(openTriangulation()), + CTRL+Key_O ); + pmMesh->insertItem("&Save constrained edges...", this, + SLOT(saveTriangulation()), + CTRL+Key_S ); + pmMesh->insertItem("&Quit", qApp, SLOT(closeAllWindows()), + CTRL+Key_Q ); + + connect(this, SIGNAL(insertedInput()), + this, SLOT(after_inserted_input())); + connect(this, SIGNAL(initializedMesher()), + this, SLOT(after_initialized_mesher())); + + QPopupMenu *pmOptions = new QPopupMenu(this); + menuBar()->insertItem("&Options", pmOptions); + pmOptions->insertItem("Set &layer properties...", this, + SLOT(displayPreferences())); + pmOptions->setCheckable(true); + + widget->set_window(-1.,1.,-1.,1.); + widget->setMouseTracking(TRUE); + }; + + // compute bounds of the mesh + void bounds(FT &xmin, FT &ymin, + FT &xmax, FT &ymax) + { + Tr::Finite_vertices_iterator vi=cdt.finite_vertices_begin(); + xmin=xmax=vi->point().x(); + ymin=ymax=vi->point().y(); + vi++; + while(vi != cdt.finite_vertices_end()) + { + if(vi->point().x() < xmin) xmin=vi->point().x(); + if(vi->point().x() > xmax) xmax=vi->point().x(); + if(vi->point().y() < ymin) ymin=vi->point().y(); + if(vi->point().y() > ymax) ymax=vi->point().y(); + vi++; + } + } + +signals: + void insertedInput(); + void initializedMesher(); + +private slots: + void after_initialized_mesher() + { + updatePointCounter(); + if( mesher !=0 ) + { + init_status->setText("yes"); + pbShowCluster->setEnabled(true); + pbShowEncroachedEdges->setEnabled(true); + pbShowBadFaces->setEnabled(true); + } + else + { + init_status->setText("no"); + pbShowCluster->setOn(false); + pbShowCluster->setEnabled(false); + pbShowEncroachedEdges->setOn(false); + pbShowEncroachedEdges->setEnabled(false); + pbShowBadFaces->setOn(false); + pbShowBadFaces->setEnabled(false); + } + show_clusters->change_mesher(mesher); + show_encroached_edges->set_container(mesher); + show_bad_faces->set_container(mesher); + debug_layer->set_container(mesher); + } + + void after_inserted_input() + { + delete mesher; + mesher = 0; + emit initializedMesher(); + mark_facets(); + nb_of_clusters_has_to_be_updated = true; + } + + void mark_facets() + { + Mesher::mark_facets(cdt, seeds.begin(), seeds.end()); + } + + void displayPreferences() + { + prefs->show(); + } + + +public slots: + + void get_cgal_object(CGAL::Object obj) + { + Point_2 p; + CGALPolygon poly; + + if(CGAL::assign(p,obj)) + if(follow_mouse->is_active()) + { + typedef Tr::Face_handle Face_handle; + Face_handle fh = cdt.locate(p); + if( (fh!=NULL) && (!cdt.is_infinite(fh)) && fh->is_in_domain() ) + { + criteria.set_local_size(true); + criteria.set_point(p); + + std::list l; + + Criteria::Quality q; + if(criteria.is_bad_object().operator()(fh, q) != + CGAL::Mesh_2::NOT_BAD) + l.push_back(fh); + + if( mesher!=0 ) + { + mesher->set_criteria(criteria, false); + mesher->set_bad_faces(l.begin(), l.end()); + while( mesher->step_by_step_refine_mesh() ); + } + } + } + else + if(get_seed->is_active()) + { + seeds.push_back(p); + mark_facets(); + } + else // get_point is active + { + cdt.insert(p); + emit( insertedInput() ); + } + else + if (CGAL::assign(poly,obj)) + { + for(CGALPolygon::Edge_const_iterator it=poly.edges_begin(); + it!=poly.edges_end(); + it++) + cdt.insert((*it).source(),(*it).target()); + emit( insertedInput() ); + } + else // obj should be a polygon or a point! + CGAL_assertion(false); + updatePointCounter(); + widget->redraw(); + } + + //insert a bounding box around the mesh + void insert_bounding_box() + { + FT xmin, xmax, ymin, ymax; + bounds(xmin, ymin, xmax, ymax); + + FT xcenter=(xmin+xmax)/2, + ycenter=(ymin+ymax)/2; + FT xspan = (xmax-xmin)/2, + yspan = (ymax-ymin)/2; + + Point_2 bb1(xcenter - FT(1.5)*xspan, ycenter - FT(1.5)*yspan); + Point_2 bb2(xcenter + FT(1.5)*xspan, ycenter - FT(1.5)*yspan); + Point_2 bb3(xcenter + FT(1.5)*xspan, ycenter + FT(1.5)*yspan); + Point_2 bb4(xcenter - FT(1.5)*xspan, ycenter + FT(1.5)*yspan); + cdt.insert(bb1); + cdt.insert(bb2); + cdt.insert(bb3); + cdt.insert(bb4); + cdt.insert(bb1, bb2); + cdt.insert(bb2, bb3); + cdt.insert(bb3, bb4); + cdt.insert(bb4, bb1); + emit( insertedInput() ); + widget->redraw(); + } + + void updatePointCounter() + { + nb_of_points->setNum(static_cast(cdt.number_of_vertices())); + if(nb_of_clusters_has_to_be_updated && + mesher != 0) + { + nb_of_clusters_has_to_be_updated = false; + nb_of_clusters->setNum(mesher->clusters().size()); + } + } + + void refineMesh() + { + dumpTriangulation("last_input.edg"); + if( mesher == 0 ) + mesher = create_mesher(); + mesher->refine_mesh(); + emit initializedMesher(); + widget->redraw(); + } + + void conformMesh() + { + dumpTriangulation("last_input.edg"); + CGAL::make_conforming_Gabriel_2(cdt); + mark_facets(); + delete mesher; + mesher = 0; + emit initializedMesher(); + updatePointCounter(); + widget->redraw(); + } + + void refineMeshStep() + { + int counter = step_lenght; + if(mesher == 0) + { + mesher = create_mesher(); + mesher->init(); + emit initializedMesher(); + dumpTriangulation("last_input.edg"); + } + while(counter>0) + { + --counter; + if(!mesher->try_one_step_refine_mesh()) + { + pbMeshTimer->setOn(false); + counter = 0; + } + } + updatePointCounter(); + widget->redraw(); + } + + void updateTimer(int i) + { + if(i==0) + timer->stop(); + else + timer->start(timer_interval); + } + + void updateStepLenght(int i) + { + step_lenght = i; + QString s; + s = "Mesh " + QString::number(i) + " step"; + if(i > 1) + s+="s"; + pbMeshStep->setText(s); + } + + void updateTimerInterval(int i) + { + timer_interval=i; + if(timer->isActive()) + timer->changeInterval(timer_interval); + } + + void clearMesh() + { + cdt.clear(); + emit( insertedInput() ); + updatePointCounter(); + widget->clear_history(); + widget->redraw(); + } + + void clearSeeds_without_redraw() + { + seeds.clear(); + delete mesher; + mesher = 0; + emit initializedMesher(); + mark_facets(); + } + + void clearSeeds() + { + clearSeeds_without_redraw(); + widget->redraw(); + } + + void openTriangulation() { openTriangulation(QString()); } + + void openTriangulation(QString filename) + { + QString s; + if( filename.isEmpty() ) + s = QFileDialog::getOpenFileName( QString::null, + my_filters, this ); + else + s = filename; + + if ( s.isEmpty() ) + return; + std::ifstream f(s); + if (!f) return; + + if(s.right(5) == ".poly") + { + clearSeeds_without_redraw(); + CGAL::read_triangle_poly_file(cdt, f, std::back_inserter(seeds)); + } + else if(s.right(5) == ".data") + { + int nx, ny, niso, use_threshold; + float threshold; + + std::ifstream ins(s); + ins >> nx >> ny >> niso >> use_threshold >> threshold; + for(int c = 0; c < niso; c++) { + float f; + ins >> f; + } + + std::vector points(nx * ny); + double xmin,xmax,ymin,ymax; + ins >> xmin >> xmax >> ymin >> ymax; + + double dx = (xmax-xmin)/(nx-1); + double dy = (ymax-ymin)/(ny-1); + + int k2=0; + for (int i2=0; i2> num_lines; + std::vector num_vertex_per_line(num_lines); + for(int n = 0; n < num_lines; n++){ + ins2 >> num_vertex_per_line[n]; + } + + CGAL::Bbox_2 b; + for(int i = 0; i < num_lines; i++){ + Point_2 p, q; + ins2 >> p; + if(i == 0){ + b = p.bbox(); + } else { + b = b + p.bbox(); + } + for(int j = 1; j < num_vertex_per_line[i]; j++){ + ins2 >> q; + cdt.insert_constraint(p, q); + p = q; + b = b + p.bbox(); + } + } + + for(unsigned int k = 0; k < points.size(); k++) + if (CGAL::do_overlap(b,points[k].bbox())) + cdt.insert(points[k]); + + xmax = b.xmax(); + xmin = b.xmin(); + ymax = b.ymax(); + ymin = b.ymin(); + + dx = (xmax - xmin)/20.0; + dy = (ymax - ymin)/20.0; + xmin -= dx; + ymin -= dy; + xmax += dx; + ymax += dy; + Point_2 bl(xmin, ymin); + Point_2 br(xmax, ymin); + Point_2 tl(xmin, ymax); + Point_2 tr(xmax, ymax); + cdt.insert_constraint(bl, br); + cdt.insert_constraint(br, tr); + cdt.insert_constraint(tr, tl); + cdt.insert_constraint(tl, bl); + + clearSeeds_without_redraw(); + } + else + { + read_constraints(cdt, f); + clearSeeds_without_redraw(); + } + + // compute bounds + FT xmin, xmax, ymin, ymax; + bounds(xmin, ymin, xmax, ymax); + + FT xspan = (xmax-xmin)/2, + yspan = (ymax-ymin)/2; + + widget->set_window(CGAL::to_double(xmin-FT(1.1)*xspan), + CGAL::to_double(xmax+FT(1.1)*xspan), + CGAL::to_double(ymin-FT(1.1)*yspan), + CGAL::to_double(ymax+FT(1.1)*yspan)); + widget->clear_history(); + + emit( insertedInput() ); + updatePointCounter(); + // widget->set_window() calls widget->redraw() + // widget->redraw(); + } + + void saveTriangulation() + { + QString s( QFileDialog::getSaveFileName( "filename.edg", + my_filters, this ) ); + if ( s.isEmpty() ) + return; + std::ofstream of(s); + if(s.right(5) == ".poly") + CGAL::write_triangle_poly_file(cdt, of, seeds.begin(), seeds.end()); + else + write_constraints(cdt, of); + } + + void dumpTriangulation(QString s=QString("dump.edg")) + { + std::ofstream of(s); + write_constraints(cdt, of); + } + + inline + void fake_slot() + { + } + + void setBound(const QString& bound) + { + criteria.set_bound(bound.toDouble()); + if( mesher != 0 ) + mesher->set_criteria(criteria); + } + + void setSizeBound(const QString& size_bound) + { + criteria.set_size_bound(size_bound.toDouble()); + if ( mesher != 0 ) + mesher->set_criteria(criteria); + } + + void setLocal(bool checked) + { + if( mesher == 0 ) + { + mesher = create_mesher(); + mesher->init(); + emit initializedMesher(); + } + if(checked == false) + { + criteria.set_local_size(false); + mesher->set_criteria(criteria); + } + if(checked) + follow_mouse->activate(); + else + follow_mouse->deactivate(); + } + + void advanced(int state) + { + if( state == 0 ) + toolBarAdvanced->hide(); + else + toolBarAdvanced->show(); + } + +private: + Mesher* create_mesher() + { + Mesher* m = new Mesher(cdt, criteria); + m->set_seeds(seeds.begin(), seeds.end()); + return m; + } + +private: + static const QString my_filters; + Criteria criteria; + Tr cdt; + Mesher* mesher; + Seeds seeds; + + Preferences* prefs; + QPopupMenu *pmCriteria; + int menu_id; + + CGAL::Qt_widget* widget; + QColor background_color; + CGAL::Qt_widget_get_point* get_point; + CGAL::Qt_widget_get_point* get_seed; + CGAL::Qt_widget_get_polygon* get_polygon; + Follow_mouse* follow_mouse; + + typedef CGAL::Show_points + Show_points_from_triangulation; + + typedef CGAL::Show_points + Show_seeds; + + typedef CGAL::Show_segments + Show_encroached_edges; + + Show_points_from_triangulation* show_points; + Show_seeds* show_seeds; + Show_encroached_edges* show_encroached_edges; + Meshing_debugging_layer* debug_layer; + Show_bad_faces* show_bad_faces; + CGAL::Qt_layer_show_triangulation* show_triangulation; + CGAL::Qt_layer_show_triangulation_constraints* show_constraints; + CGAL::Qt_layer_show_circles* show_circles; + CGAL::Qt_widget_show_mouse_coordinates* show_coordinates; + Show_in_domain_faces* show_in_domain; + + bool nb_of_clusters_has_to_be_updated; + QLabel *nb_of_clusters; + Show_clusters* show_clusters; + + QLabel *nb_of_points; + QLabel *init_status; + QLineEdit* angle_bound; + QLineEdit* size_bound; + QCheckBox* under_mouse; + QTimer* timer; + QPushButton *pbMeshTimer; + QPushButton *pbMeshStep; + QPushButton* pbShowCluster; + QPushButton* pbShowEncroachedEdges; + QPushButton* pbShowBadFaces; + QToolBar *toolBarAdvanced; + int timer_interval; + int step_lenght; +}; + +const QString MyWindow::my_filters = +"Constrained edges (*.edg);;" +"Shewchuk Triangle .poly files (*.poly);;" +"All files (*)"; + + +#include +#include + +CGAL::Failure_function my_previous_failure_function; + +class Cgal_exception : public std::exception { +public: + Cgal_exception(const char *t, + const char *e, + const char* f, + int l, + const char* m) + : type(t), expr(e), file(f), line(l), msg(m) {}; + + const char *type; + const char *expr; + const char* file; + int line; + const char* msg; +}; + +void cgal_with_exceptions_failure_handler( + const char *type, + const char *expr, + const char* file, + int line, + const char* msg) +{ + throw Cgal_exception(type,expr,file,line,msg); +} + +int main(int argc, char** argv) +{ + QApplication app( argc, argv ); + MyWindow* W = new MyWindow(); + app.setMainWidget(W); +#if !defined (__POWERPC__) + QPixmap cgal_icon = QPixmap((const char**)demoicon_xpm); + W->setIcon(cgal_icon); +#endif + W->show(); + + if( argc == 2 ) + W->openTriangulation(QString(argv[1])); + + // my_previous_failure_function = + //CGAL::set_error_handler(cgal_with_exceptions_failure_handler); + + try { + return app.exec(); + } + catch(Cgal_exception e) { + std::cerr << "catch(Cgal_exception e)" << std::endl; + try { + W->dumpTriangulation(); + } + catch(...) { + std::cerr << "PANIC !!" << std::endl; + } + my_previous_failure_function(e.type, e.expr, e.file, e. line, e.msg); + } + + return 0; +} + +// moc_source_file: mesh_demo.C +#include "mesh_demo.moc" + +// moc_source_file: Show_clusters.h +#include "Show_clusters.moc" + +#endif // CGAL_USE_QT diff --git a/Mesh_2/demo/Mesh_2/mesh_demo.vcproj b/Mesh_2/demo/Mesh_2/mesh_demo.vcproj new file mode 100644 index 00000000000..2b4ba41fd10 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/mesh_demo.vcproj @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Mesh_2/demo/Mesh_2/seeds.xpm b/Mesh_2/demo/Mesh_2/seeds.xpm new file mode 100644 index 00000000000..36601fe36d4 --- /dev/null +++ b/Mesh_2/demo/Mesh_2/seeds.xpm @@ -0,0 +1,39 @@ +/* XPM */ +const char * seeds_xpm[] = { +"32 32 4 1", +" c None", +". c #FF0000", +"+ c #00FF00", +"@ c #000000", +" ..++++++++++++++", +" ..+++++++++++++++", +" ..++++++++++++++++", +" ..++++++++++++++++++", +" ..+++++++++++++++++++", +" ..++++++++++++++++++++", +" ..++++++++++++@++++++++", +" @ ..++++++++++++@+++++++++", +" ..++++++++++++@@++++++++++", +" ..@@++++++++++@@+++++++++++", +" ..+++@+++++++++@++++++++++++", +" ..+++++@@+++++@@+++++++++++++", +" ..++++++++@@+++@@++++++++++++++", +"..++++++++++@@+@@+++++++++++++++", +".++++++++++++@@@++++++++++++++++", +"+++++++++++++@@@++++++++++++++++", +"++++++++++++@@+@@+++++++++++++++", +"+++++++++++@@+++@@@+++++++++++++", +"++++++++++@@++++++@@++++++++++++", +"+++++++++@@++++++++@@+++++++++++", +"++++++++@@++++++++++@@++++++++++", +"+++++++@@++++++++++++@@+++++++++", +"++++++@@++++++++++++++@@++++++++", +"..+++++++++++++++++++++@@+++++++", +" .....++++++++++++++++++++++++++", +" ....+++++++++++++++++++++++", +" ....++++++++++++++++++++", +" ...+++++++++++++++++", +" ....+++++++++++++", +" ....++++++++++", +" ....+++++++", +" ....+++"}; diff --git a/Mesh_2/description.txt b/Mesh_2/description.txt new file mode 100644 index 00000000000..10d31ee60af --- /dev/null +++ b/Mesh_2/description.txt @@ -0,0 +1 @@ +2d meshing package diff --git a/Mesh_2/doc_tex/GNUmakefile b/Mesh_2/doc_tex/GNUmakefile new file mode 100644 index 00000000000..3c42dd78c94 --- /dev/null +++ b/Mesh_2/doc_tex/GNUmakefile @@ -0,0 +1,9 @@ +all: + cgal_manual Mesh_2 Mesh_2_ref + +ps: + cgal_manual -ps Mesh_2 Mesh_2_ref + +html: + cgal_manual -html Mesh_2 Mesh_2_ref + diff --git a/Mesh_2/doc_tex/Mesh_2/PkgDescription.tex b/Mesh_2/doc_tex/Mesh_2/PkgDescription.tex new file mode 100644 index 00000000000..10657b78547 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2/PkgDescription.tex @@ -0,0 +1,22 @@ + +\begin{ccPkgDescription}{2D Conforming Triangulations and Meshes\label{Pkg:Mesh2}} +\ccPkgSummary{ +This package implements a Delaunay refinement algorithm to construct +conforming triangulations and 2D meshes. + +Conforming Delaunay triangulations are obtained from constrained +Delaunay triangulations by refining constrained edges until they are +Delaunay edges. Conforming Gabriel triangulations are obtained by further +refining constrained edges until they become Gabriel edges. + +The package provides also a 2D mesher that refines triangles +and constrained edges until user defined size and shape criteria on triangles +are satisfied. +The package can handle intersecting input constraints +and set no restriction on the angle formed + by two constraints sharing an endpoint.} + +\ccPkgDependsOn{\ccRef[2D Delaunay Triangulation]{Pkg:Triangulation2}} +\ccPkgIntroducedInCGAL{3.1} +\ccPkgLicense{\ccLicenseQPL} +\end{ccPkgDescription} diff --git a/Mesh_2/doc_tex/Mesh_2/domain-mesh.eps b/Mesh_2/doc_tex/Mesh_2/domain-mesh.eps new file mode 100644 index 0000000000000000000000000000000000000000..58a95e7e8c8de35c39206e82c1076e0f8a8e319c GIT binary patch literal 351336 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

?Z`jc>gv8J|UOoVWADSm3N#*)a$J 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 literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/domain-mesh.png b/Mesh_2/doc_tex/Mesh_2/domain-mesh.png new file mode 100644 index 0000000000000000000000000000000000000000..08e52eb3da0dc426df33893af079c2080c4fef0b GIT binary patch literal 27035 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 CGqzs< literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.eps b/Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.eps new file mode 100644 index 0000000000000000000000000000000000000000..fc531560716ec09245bfafa606442d4d912ed2b7 GIT binary patch literal 291524 zcmdqKeb8>nQ6KiehBdnu$R=?@g$g+&$R8B?mOuy>RUlz-8B!`xRmz23sjJ;r(k)iI z%HF#mg(82f1I34dQi6jc3?&T41r8;`SFmxgWy{DG7GAMrVabYxg%wv^yy%L%`(C~B z-ZwqnGd(>$-93GtyXCkd-F@EkoHNtYAHV*XIdjhQg3o!~*S_#e@4oL1Cog>Yi(ayQ z`Rl&+FO`EkU+{w0+<$W6@_qNedi(Q#`7IaTbn?{~-gNPM7cVBwpTTU*$`9&vhy;K@t&x`ln``QbaOS{*<`GM`VCwFbz7i}+n<*Q%u zvRA+2mD|f+@{(7SreAj71NYv2@!mIm*?n(&_4X3@|4U!>%I&2ue0*cUV7_27v8>I*zSUJ_iq=A241vnuYdCi z9d8#eZFf_nle@Qz_ttjz-3y&xci*MUm+rd%;#)6o-*EBd8&B@Pv;m2?-hc7l%jNj; zn=f46E8tDf1nkP`1-fM^#rtBy1}Xc_Tt@_-&`bl;4SxFYA3() zv&e0jV7zHj7HUv}~GrPrO@4`zAmefNT4wpX>rfR6j_KH0tw%wHf-{`>3gS_R+b z`!Bw2`?@*^G6D-*oxSm5(=Gyaz0`ee*4J-7dcI%oWN-vF+w2j`IS6%d{NyMN<=4OdFI{-s5aH^0 z-`pIe5HN#P!_)|R0egV;s{y@te?Fk?o`4S$A#kBn zbCH*CZ+YOJ4dOAB0_dQnt;8sIC@%8mleg8T#W%=T#^$y^ZQIvD0=xI_lea<67WuBa z(MusKzk%I!`|JPSFm2?)m%Z|p{~+xBO-w{Ms4 zzi{uRdoEmtx&R|E0E{lw!ivy*&xJRf+yjt;TJ6%s{{iYPI(@O!e;ZyLPXTmF)dM4x zN~c}BtJG#t&%RJrVZioFUnm&o#-+ls=BUSIr`C-;2A$>oc8UD)0Tb;TR+gNn8{MpWTBsHV$b zkfun7=l4q1P}b7_sKtUj&D<^#5w5pJfiZlGWIC#wtQ8r=V=3sjZ<6j$WzILlN#Sel zBp2b3l`g?t_T)|xb#M~c=6pDHeDwxZaG5-od89k@eBjc_{dZry>+<%7GN){l$CB!y zKmPA!ulmAQeBl>vUv}}{3-`Z$`?9xRKDl(~5aD3@a_385^@{rt+|&s4c&OE?y$+3NvH zgw5lJN4$B^);~({%s_vdtuIE;bW}pQO1^oxtqk#p3clZQ{`-f_FcN2Zbb?gciZ>7c z`Fv8yY<7VWfsiJ}z4&1Chj^g>#H4w%Xk#(f9nq!_h2@ctb@KN^NxtQ4dS z4(_{P7p|l8+06pKym{~h+f0Gk3^=0V6M*S40Cuu3A)VNYCR}E(Rm|uHIs*L+#GmI4 zCLNI#c$p@RfEq{@VaI1O)xYCLjok~Jx&sFHQ8E5j_|`ytDIW*er_=F!rH>#`(aCt0?XN?JCi7{PoOK^kUhNdPXn z(g`tVYXlH@l||7yHw}&YEG&&BC*=*z>exm~TE`OB0se>Xxytl#{^0=(KTQ+Hff6f; z55%y6k|1QQRdVx?OuC$(%%s3+kA~FaT7hwEjoROdTXZluTO0Vf6O_;zX(LdKrQ`=-L!k*lLJJ4<@}R@ovYKL7=Z}{zJbZ;d#ofw5cyYX%X2x?^!yhpM7@W5P zXa{>BO=*bXh)fIan1F zT5W}x^KbucA_&7oi`ZjxQGnzu+FFg{?jOzsZ=5LX5HhZ|nk9f~Eb=NX&I-k(jq)i` z_Kx%4N-ZBJC778~ITG}w+b|F?ufXNr;O1coOtv3ZF$99&gNO7@fQ|pRu*u4&<1pODskOR4zy>R5#8+~UR}1C zctZ=DFYn)`bq0hU;kB}MIJ0jrF{@hwLSBTEP*gkA_Y!}I{4kL4Uw}uCj(>3`W@%r1xp5> z)tIytF_uQlvMR6>*s|zO#4ImDnZC{4`)WrkJ|q4`tWlm8uuAcFO}5=}VNAe`kCiA6 z`P}MY(so3|S*eJ+0C$On7m3=q-Xl;-senE#ywI8US6=szb8F?ZV{A(YZmV%Hwpbzi zyHItfyu}J<0eIrnP9sV!7+MO~F>Yo3RYt~`&t1_<-hME|={_OlwvHzZ2?8!RSX z4i~DI1AV2le-&98Xw8h|b`sx=ges23c4QCjoX8;4%lMxG*SM`T!T??L*iu~YDS4%1 zXFG~l_-sq_V0enGn22BWyhB7p2_kY5aJcB0zD4%clj5cmFjV@V6^0<1tSL+ejRf=! zN+S)!?JR1jNUU_)<2D9aQzsI&p#yWxNae-AFi>ubP_`0G@q4-SuVGR!EN^pF!lT9s z({l{d(PPi%p^wf*Y>%R&b_av(5m}|p+LFn0S%FizK|II=^~Gp9Z9fwn^GVBFwxzeA z`L*nbHhq#toB}pk9~v8Mrvryn$UMK3ivz|etO^m-0)#Mb&BDr-S_~0Ew7bo3L2hw( z#xn=f_Q0{H#6Xx?2G8FJ`c-|+z=k%%NF(j!4Magm!l8`PW-hjjtY13t7c$J`uF3`rz3*A zU+~8;Z;2U_xSU2#(^DA&^Z!1auwu$!;`x#S~H)0|k~_N37G^QAcAxmr)~ zSpO1RLHHxP7yid&9%&;CaHhLTbS>9|m_pZTbC_ja!0QNEo3?Pdq%1`!9^Nw5w;Kyu@=srEL&xG1kr`ZmON?92iNDHC2|$sUC%DA_vN!gPdHek)vt` zluGBXt4e@4sbrNn&Eb9!9L{*Owd%uU(n<^ zw~9kEKalBN;_Fpeq09?fi|Op{JiMVwicW=#9SC=0c> zU?cNA1ZM8m53weI^W{upy_bme?oBArr#{(78!zpthdIjbeR9{!LZ&_!@H=DIJWD*4 zK0Ew;2DqpyXClCEP-16Wns>#&!gaEOO6L2$&rZkH`>tT) zImD6(L)(KY)%L~W&6|_j@CfFo6`T`z$;Ad9z;6oe`O?Jn#UN7!mu@Q%|3vlEA3r}s z#+D{98Bjnq+hp8<^Z%EtKW?kD z=Ve~WgGbW6xAg*kdP*?FlkWhg8+I>ow9&SDR zE>)!R*AoBUK)w8E_3uwYUcH^=2wXh4#6A?X2`+J>%h+vKV}egJQ;Df^$=fx)L<${S z!7`9&X&+gJ2Xt=z`8I{q7}T=5iIn3lckI-XRKn67mnsd^IF~WuHpifTaLeDs?1RA*gCCOtwX{y|b-Zr81VQ{Q6JMpDDL>2W44K z6;}r!8&FXH^odEWp7A{3dhMa^&|_&{uz|QAOSOhK5DBY@)*<%5C;-Q7Br^xWe!G-t zv%J5TSm~Fz@RU0<8c3xgPz;(GcDoE&^pdCp;*cr5ZPy(jS*Y!{(Buiy5dFB-!2b+t zU|e* zF)PAX4^M+tKdWn9s)~-SFgy>gTy9xHutql=J7z$dV((Oj=-XIm0z#XJ0ca*-b~1r} z=|pilu^v=uRk}+*Zq@F;)N@pFwmR(SPNvULBK8?pa@f+~Gi2hBxFo39==#92 zH>>QiMqc#tr~RJmDg*9_?N<+f2(uUW0fXd#QY(P+Zd-!B`V_TtKG4NAjC^iT;eDy> zJP(B2POv3pHDVWE_%jFU-d(9heH}eXS$O!`GUqRYXMTo3Ug%pIYM{}k=ACz9CtSm) zTAigghL$o-b->d1V%MErT}hM-p@ghmnPMI~C=;d5w`B^rdiW4Hq;1CJAacN@4uZPJ z+w{t2pAT#x;Ia`kwy!q0?TB6DV~`8VK)+2frGCKqiJ|t_VGq5r4lw~)!=X9k2cysm zfGhL_Q%s&_67_5455D0)j5!grJ5vqgK8X}BBP6TGrO&fkq?MqTt&OG=ZGkXsNy@HE zT|Imd!s+w1rd!C@=h;dlP$;%+G3cSM^FE4ZbVqve7A%(^W{eI*E{LOR5)Pc!BKt@l zL`pOv1G*xq+h3^zJZ>HXHiz%M**t@2CF`%lvJd%GZ$0t^kRVFzj~kznE#+}yCrYIW zy&7(q-$uTjXi`x?(pTlUbUaIom ze-OoTb`RgjIbb!=)x$r8n&pn}1$%bW%ODDXWYyBabfSork9NRdQHjW3Nz6+Vc}7@z zoB|ZXd0CjKj$0yvQMfI_k_ub2(J|74fAhN!K?E%dTM7p&dTlJ!@$gMv5yuuH&DEZb z_u7@Ft^AS{g#RnrU)Kt%*G6j6g;mSeggdMwj%2uPdm^Si{t)%N;_hVvJ2u7xcE;U|Lp)!EUN{xU~4qd zoq}UwpcNwq`mP*qp8tuao3ryj-ws{ATZ0eOLS+Uo#W_R##>R6#_fqiiSTbbt%CX6% zW}301&+Sd;Gc2<=*s6~Z}i3@oK_zE^qLP?iXdk%&^wRf zR!Xfb{UZpi&z}_&`=l(;mXpW5m66NxQ6N%E3W$T^o8F9resSE2-Op2}J(D!7Ge2_p zqx1g=`(EkE@fXiOUGeZtd7ZKzOtpcpQ!d$-y+)|#Ge_W(z-VW66=h}Vz!4YN9*9_y z#u#N%fyrT%&gVP?>T`}T98e|aDnyJqu06>7F>tn9-AR%6H_Rxf+Jd)d!|IX=f7m+^orS-@6rnY&S~AfdhjEC-rm zxB#)cBJYs!apG@}$V0lB`$WT81BKXs1cj+Xo_}IDEvXn@1 zD?@L@>I#gUB{u2b%&j~a?>{ZXq>j&pGkN9Y5`i<=%<$QLuFcUt0sgdmC$5S2Ads=* zm0@FJs>Ysfyp$I31LL|T9V;Y{xTyivm1y$|g0nE_KlAdRKb zT!;)CcU*d@XOMXlvedRKNPZC-SC_}t_W3ek2i3(*Ra0We4*o${!VprhoCtlWtVrW303 z*No?wF*CM|*S8f8{t$NfkM8sH-F+U0n$F&9yevSxaOIufP#uv@!Ua2y3dw*@j$_6i zikHF+c-TCSN)$L{upy)Aq3VX69s+qrOA;G0K_^$XlZLFcmw=2)s3E+h1U9{Ff*pA&ya> z^7p7^3lfkuwn+8OTRwgWu)&ICaey_B4~=8KC=P_rdf_~O)9kNBBPmr29`qIGl7+iK zCmg-2rt3}FHjC+w^3I-Qu7a1`UWM3mv&l>WT^SSV`z4aSMNyC(3`YR5%Z`y$ApXqK zmPn4Qw19H#nzH(sd0%s3~a9?<;v3l0EX^DEeSmGk?-ww7Zf?WY}a{cD_XL@ zv|ZtfjIKU&)tAhTHXS0{LZvh}S8h?q)?IdVBc7a&wBo9J#d~I`s9C5HRxu|u=+d-mGKOzQIo!RQbPten;C4d(&Rx?Ajt#z=Utpx3gjH` z9P^9S0*L@@;F?FnepJlcB~ZURJ=7t+h5{Ke2Uu8uv))S*`1*uJ$U|! z^G_kMo+;LF2a%%l@yL5z4+RR~j>hO#H90FOhP)T$r4z{Gnf`nx5C@(+F$7_ynFr(J zJ=yNf8`S$y^F@`EdRcsMItTF#4*g|6K&9>ydXMBP&@)^jKHA^Lm2ikoO5JAcF7S9= z_{G`ygXbTEr9uiznyhI!I@vNDCj<|2fjHy^h6lH&Fb967EU`47Nmv&(cf;PKMNk< z?x^F`BSk1;;l!y9Sal(r;IS{L1lO!x&uJK&yR^b4ng=rdjM5W*(prpdMk#fB5@p>I zRi~0s9E1t2gQ{sWmBf=O70=$*sL^ZOE-lpa~yJyXP_3+y{;A09n zJ^Z;yNtSsBBgh8w*a~Me^rQy_iYFNEn)pe|D%{WBTs3f9Ri0ZsF{5qPq&MYFqL1Sn z*8f2iuVPmU6zyRzCdkuzLPm82i3W9y;24@6y~6R~!y^Ul7~FelGllv3)mjb!NR1RNIO^&J0vl6a`NyS-!QHMB6pcGNb{52E&r&kDDJ*fPXh2eX%Fh76Dgr z4Q3ikrb|LiX;Y(KtuI%}>&DP!vO)}iAzod9oqhmtL^+o29ozlrtWIhlJil3w%Kd=s z4l=+^QIp7A6e11TCP}=AK_NQ`HM}7x(6`9|Q8wxUztCaK+qSQL%XX0 z^7Ydfk{5aGg{r~*d{7Y%RbvL2LbZXnvD#4W>8shxEEOn86B%`x3O5n(#v8rl}Y+dTal9$xBJ49KJ2c$k)K02(QEMKpe zkAC!E`FaJM-<^h%D^`vj)0s()3j>$UaUDlurYWeG8Ib$>Nr@)&xMkt4TG`C1oft1B z(kb*32bzs3J8jrPHyatq&u*3ei_a0D|Izu!>-La1G0fpNKe$Aj=N`mh)pV;0=RpAl zp8gmqhVDOdc(_0`0p)Kg?VbQAKfjGc;}r}6JC#9V!Vj=>OXe=XF~u%hJ{VCHIeT%; zqZ_($a9m_f>|P^DyIRH@ZON3oE#1<&vry%tMfLJPW8paiw;5Txrs%BCnGQvOM_cpR9&t+sz0RHGMKO;+OS9$2Y@H4in3P_xo9ym_WlU4BJD z1+&@N6lK*unTe$od*@8C8olbRTbg3?KL@MbUc=A`YeG!DRBTdIt)xCWMszkXz#(<| zXrCi9v9L<{;5k4AZt!3ge68XWr-+E>UQ}2|-$qfK@AyzU81&Gzu`JyyCk@F`YSSTu zz^yc&NAes#W-v>})IfVp%&T37#z=4KGxXm;`2(L6oy+sF9n3=mE3-Ghado*MvY zUO}H!+Z5m_0paTi=FMy)dvU#4?$c8^zA9mi>vEdFn(k?l}H9EfZHsWajto@ zzT}kS8BKVR49p8G)qzCaGNYR!t7gd%2&u8|#qOs?Uq`y-JaIrME$5YoQ}5`*S%s4l zT%ox4^#oMs#nxWZrcGgr{n-d~ji1H6QXq*NORz{*AjYfLN|P%U>No@Z?sDcK&`PxE zv#YR57L0S;^yU>C!%(S~zlJdm36W+LYZj@?>FfJKCDM==)1J?u&pLu17AJ1U+Z zs#{4SB&RrOcaq7JOB>Bd4(g1!(prWz#vUa_FL(pAA_IZF5RF|l6KO5m5Uoy7_z@+p zen}yLznb(ZB$o%CjhT9&Lsr64UDROKMP)cQIUb}-Zt^;V-B0ZiZ@?+yxli^i6!&xQ zppZ=6%gzvcgFzC?l&__wsgfF`5_VFq8{;*;n&gn69F(F>=oY#)%%@?CyZRS|D4Ci}~n#C7{nB zaT)HOG+5!=D%!k2D66+E#spIKY7okPgVxw*)PX1j?Dk=`ViqRZT2LUy9$K-AB1c%E zTBAHz@7@;3XjR_!&oaiWHcSTz!BpA;QKxig`vV1=h-NH2u-u5z{CzdBKg?zHT!}?G z&1GJ5{o*-9bJh$AGWy-KrWh>sfMAvW`+^W2je=0ryuXU z>j0*kK;w#K0X_4k!dvo(w{159+3V{!gs5u@v?e|$z+&9@L-xurPOLmGV$KUu^HQo zJl4`l1?S|9%S5sad7B4&5!V>frq@*7xP1fmnleohufQGdC7U*g#Bw9MKGSN6_h`Hx=7IMd& zK}so&zm6#nGJ}l;WX5zj(=`EQWWw@SEJwhM)1_Z~l=eX=nx~SpM}k57=z?r&zDv>i z3MAOVNvseXIipJ1^L8!L&O*(O+oU8}#izNLbH=w)epW&nOOOPl-&F&7dlgFy^(C#{ zMpl*?1}tbBdgtyiiE5i5+gBcpCNLpNmbGcdWvU2SyQZBUT1>a{8Wa9I+so?XCYgt7 z>#`-XhaqnaQ(p>y4C{PpmmwRMrrIkyrhlr!v+dsKm317c-&K5}VY*H;=PfRA6v!6< z#cX5wv1`?y%0EItcm6g5>}RAWz;U|zrCO+COVLqZ%_!5Bq%|`uk0Kv{q5J49_|i%F zSz6tM|L9jFo-*b_rb}t`Sb12+uw=3_VJ+!o@X_^kO4~MmtN`=0q8j6Kubz8RO=XFy zK7M$@^rO53ag!QW2Boi-RybCY6*{wM2!f@l2HA1wB|54|0z>GQiqAyI<5H4%BTFtQ zTY?8^Y)kOD%e&il(K5F;7GP($R}tAXfNBFwFSX!h1-8=?&mH_vmyNFn1mu8aM66oo zXmi3Iuzz#}GJ*Y3*wc{_gW0771!6BHC$KEVBTEp$LQ}jWkDh z#ZfYiHW?^3QG#>Qs3W$u<}I)(nJfW#&UKU-T%k~+&OZg|Q-JjPF*$Y_LUjy9GY*(& zkLm2JpFVzgN2wSZrh6fQsH{O58uTNC{rfwRpY4Yjmn)_zkmC~pEy%OV^>a258qRx^nh#()QD1C>`-wVk^R2&Pa9=u zl?&cW#~ujklGWT>u9D3yRu5`OnJS zdwXog%L>C~8OWV$bWN-RiJ7{RQBZ~9ZHXDNA1Dv7T`2-K5=*;|-{h5c?APT+Umxvu z@FNVDEt63SRXh`C#^@|rivT>+7`ljb2cfsn!SFJ)5u~=I)t)|32tR!11Y-ndkI5E{ zr-#cK@emyiY3UtklS!# z$Wm^n{0%qaQ1~ABYZ#3SUejg@)}&eh@v_(l9T}`k8{B}cb@KP_zn7OOsN_WeyP$66 z$XrEBni!|C7RQ~b(~p{vc$!fs4uJu6OOj_5*X@9m-Y-%I#rD8~%|qj4x&EM5zbKJ* zn(fXa@XZkn$;TogFwascd!t7r!wr}Os?ryiJKCL- z4rwb`<5ip_+RGid4FnP0?i@ZoZ0`uPFqDv94nUdGNf= z^YxjZfuMvx(pL_&;J*axZ-rZ6G(#Zgb?Hxl_VoOm1KL&c)3CpY;&Iz`fm`MffgQg2Uflb+QVjazYq6p*D3e;wn4^p-e{4KC9p@V+TJp&=ZQInF+U*wKS)a=Na7A_p zGvc^|83S~OHHKx}l!xcA^k}zI%9Coh6$~V1qFhKW-Ply!vRABI*VVD?(Mons!VtP8 zn zvk@#?v^UKO4C8%jL?VJU0pMS(sPEg98iqfR*AS<(NS9W%m<&+1E2j&LuH$Kydqa+6 zwv$ZCD8&m05oL+xHYv+Oz69a#>Om%UKu>)$hRp~AC%XoT=`qd3qZ>3UfZI=8wAmZ( zH0tQZM`7de`-{a7+FJ^S2>gC~-9p_^2D$j3IOKEfK;5p|vm4q|{t>9+xIs4wB8Hop zb}i9K<*bRb=J3}9NK>g^CH(#`fZgW}tufdEmEk0e5mrE|TAu;!Y5(|^rxbkKeCv8I zAllAP#3AAq5sV+W^w0~4cJ~8oi1&;jrs}x)#(Q~_k<`qrB+8gn&bqb`3y?I&)pXdV z>cEQKKq1>5&8TjCr~0;K=~QFl`R3tdM{6ag`_&*>LU4hxyVMWrsohr72$?z*q<6#l6EIE~H=oGAv5x;;YqXm6IGUb|d|HsAkm z0OR%6Aqi$Mg)4mvGsF(fZrsK#HpKJ4-d)`<>Y3!EKQRzQm_Eul#4gQn z08G~Sx0P{AF#bD>V9c73Y*NsNGxA^gChGFuerP3ol=jQjP^F>bANB1R?ZN9d8NU*AbEHxfP6+*+n_O!l{M4&7{li{v{yi~yjwzh2uFQ7ldBS<^2J6NOu@MYuW@te~( zw+tjDEY5~;w*}d@l7>;TeZf~Fs>vJT6JG>lBDTeGTtY6pS#7N>)gYOr9Ap;A+oT_T zq9Jyuo!SO%(5G%c8N`EnP-&X10v%(xR^tzBGVs<7Qwq z$ITI;BAo&Hu3EcU)FzD+9RE_saRl4!>KG+-n28llD;Qfgu!Y z-5PVLp2aWMp%xg_;6*7jLqc$^D#Q|?t5X`wJHC04;M~_2Xr^mbnE@ojU{&DW9k(IE zXt44NFKnBn>~LOcfxib3y{+_V)uhYriXkbsiuSR8?uICa)pu7gKHh6qtN_Z33J&Mj z`G=nrSP{$$tSuZPe6ImmZ?8&pLV&HJah3#?kzt7f2LIp9!>!EGcBxS%KwBco>dN{- zWDLArYr|V#D#7%}(Xh=U7aZ@o3*mW^F+{GqpkPqCpV6C-@kZHW9jJ)OvhBP9?K-rh zfGOchXWE?$oL04%jHw?3FM__%s$RUy^>otO|3lN9jHvG2yMP4kH3lT=)Ny-6i25u# zqOA-YN}3+t{PSk<;c`+U>_33}^0biUHe;5Yn*nzC-ovElgG5>Dv%>aAD<&HPG272C z5bW=%S5q+jim*jgBWByXHE~BT#cHt>y`hRCJy{`nSLBmvN*?D;1T7;Dg)wExR*)!i zZ28J9`5+fx%rYrn&X$rcD$NpWe-e`5j^A&d!$>gSTryf!Gp&tKEk$ZGbazT?1o&Q_ zM|!N~Ns=|Uzs~R1RM17hD(JS`Zy0v3!hK$XjBQCaDIEBYnxAqF0*|G}hS!D$a&%-M z(}qG@7pKjy2g>Mw(1!k%zioM`i zi_y6)d1%YfFa~IbIa#m){MI{U@2oLbAh_XR<-nE#eL*J35MuR4MGXtzK%0l#2R9s8ANcYe}nZ!#J z{y!l*npFyW>A>EuD4(m5rR{g!!x|o26xkx2T*elQC~ZJXhbu(go1L5 z$@SLTj_o%w90I_`9lZ!|T2jq3w}y@OchWS14$cBd0}g}RCsb21-9C_@Jm(Z*e&{vA zjV^U+3e@HH!$0cN>sW*2i6rEX+>cqxrQ zhAdWGSJSm|A-FE_0=|2c#_}0A`#yPIaUK5-*_J4*%xIhG7{E=2PI;U!?V(q-oHKdn z6_O0A;8l&Bwz{1DKpW8zkFDYwz{>5!A)YH?THqS00ywQ3_3n5{>`+*=q>igaLlr~R z*KNsC#dZ53-S?k=Dl<&4VkN1hSO(u5KCX?6#%*f^Mt-cB>$)+m%i*I$?WSDW?%=)$ z1q3mMWme(9GG4MyTPAQBllCspNpR1hRoQFTG7NFTdRgix@L?I@E1eRw|LL%hpRoZi z*Cd@`SH3i(7dface0}om!SkCnY`>qD9PHK-O(vk!5;HD~w42Qx+^y=a`-%za{?3T} zQkX#10b)Q3C> z&=T)Zx4gT|S6j3%`zfBUMceZL(XM>2!r%;*ffKReYB;Z~roK){XAaGnl*~JTq6+P? zoL(@t_YPBuaX)VM z$UCCkr_m(kzu`dxbmYpTO@J$)xX?N@vE~qN)(r!whceTtY{oDI*q0<^P|_-0iS+*p zLZZDCF~@Sn%@Vo;ESnip0NZnitEa^>!Ty69>K_NWbg33;XV-7tT%$dtxX|u^AKU}) zi}r{wc8nx7M-T*<@tuJbEXmwr(JD@>%Bo5Gs9sd(5{xyIeu?VA-pJ+XKALiqbX$5W zy6Vuq-1hlp7yJskvoC;}A~-e9c!JAi=eig4-G#>bt3f4${eDIN6Cjw*WO4kDX<2I|IBL64X0>wJK-wLY#j8f`F7I%aG(LZhp*;xC zW@*0kR5`U%pdl0wpxasT0=Kq|&MYxDvF&Xo3H+OAEscwNQ$f2bEuN*@Qd!1>F4@M^ z{pkalp?2%FPywBt=>j!x%i+l~cB-5QuH&AE?m1U>t<|!(NTg=KH>WI92NAHG;N9!k6~t$> zxXNbZCT@7n=}VK%tRIwo@~eOu0XcCKOTt1^7rcTc+^f`VOzX21p}$KZt&2*89xeNo z^A|9O;la<=B5d{hGc%NeNM$GQQ47U+%GO|X9?CiGdCRsm)u!z4D2=cn!xVL;zQ7^3 z(_$P|C6YKXcxh(V#WIS_fu5au3yk03!?j3+6lv!@6YL7TQBhDTWydPH=hq>iaejf0 zx-Uiv<9rh^4nec_%s2*!w1@C3148P|Z9(VR;U}_Qgo{b#M?uyvtxyOw1&LuP<42Ff zWv?>0Nt@i@{>|n{?Tu{T$&Q4N?&H>svS%sv?oT6w01y-rc9X3Hj~xbyaE&{HHSj)Ic8x zZ~9I6%*Rqw<8V?l-ISuwH`ceg3ti$*Otn?8w$u#0>KSgP4rGEZtH-~0{^_d4GyP5E zjT+G$KiiN!c{J5Vy=W}!HiAa<#}4gXFD)Cjg@gymYru7CC5K1B-YC;1LAX*buneU# zspV&=FbZo_!BSk|Chb5PFj3aSDr`ipvw+RUr-Qj?iUI+mVCuJEajke-pki(9DU8ky zwxuL{5-r$?#A|<9*zrIyR>b?a=YLA6txVnh$0;PiI$C?#8(&&*!Q(kIX|1hmhhLF( zTr1(q1{lmZ&3AAyp*(H5Z@nWfv^f`S35%)lkDV-aO1d8Mhdn zRZItt^Vl`;HF#7A+yrmoW1e~N9M>7}?hk&T^OVIxV=I?eBrkIb>vk;~7RJT0tC9|) zgET+1r+ahbY1w2vcJv0}y^KE4#;>`37nJ{McX7wpAUF>}XJjrck-0dJmCWJl>VdLxfM-BG51}jJZUS^A zT$d|9E2nSadgCQ$3!LQ%rmm>1nALf-Rq2fKfkNw*&l8?FW`zm>fpLcsr6bHY_<5$h z^Je;x6iX8NeXzvfM-)LiD=VnW7a~P6NO}0!PkW#~gW8H21Dj`uA3y((c|dXSz9IeQ z4NG%a3f^5!g0Mc>kfqO47i)qvSn2xV!*$KQ&5j;C$9qWKr`o#06)_w8CivADFsEjrg66$8!@6k%z`!GgXg%v0n-&a8Ge*)M_K2J zfl3i%3j#jLd23U2sZAJbq0Pklf+RR2Ynj5788YJAIkfoKAAm7F!|+d8CWfmLl!iem zT`#Rxrjz_>jMB^_HL^)k)IfcPA;}))?C?RO2z(a^Kjdr}+wRXC%uy;=xi6gyQ~+a_ zk2uX;gWpY&KgRmt`G?D#t531e#~uU83Z><+ZbTXZkk9Hz+%Z*vUOGU=N<1-<&`O5S z*(c*L7k(5<33sK4^Y%O>D21>{kf2bP;e&edCv~UEYbRJ~bF1;dnFKDtbO!a+ zyvp|uK%z0(U(h;^gPbd}(zm6z|54dy2S)sD)5V@yyO$k!afJs|UQL`{L?RF{|H)!+ z#umV+kFKDQW`+V*p|j^EhEX)c@y-wSw-qVMe&&w?#G?Iopa4=e>zgJ;S_f@z3L&iZ z$Q|6m;_7Uig=ds!>t`=3Pa}JNrp1&7_qF?+V1xj>kf=G?hl-QovSFW)JqpX5M@Mb4 zdpBh|JQR(M`ENrios`re9Xk=r%?*2Qyl_s97?3RaX7vJ+>6g7GDVgk#0b!pNaUiCy zf!G|rUb)n%6p4?;C_F)qxPp#qMLmOqr)%W@LlD}okAuo7lco)p)1lW6Umq$jC#wOg zR)xx&9*2#8wJMB*f~v@<#%JQ?AW>R&^i2APh!8X2!IUH)I6-E>KlRBng7_z3!^P0h zKsJ`gtJ#kxG6`#FugtujfxWHS%di^Mq^!IV0P!-3HZ#I6>MX}ZFK6RapcFYE>CO%U%yMyW|a(0Fe^_9_|c z;{Y;!cZ7>U>Oq0b=+9Q4{29WB9*i5$2O{oxm}VI?8`!suYfYS-B+Inq>buVz{hT{%C}Zx426tv@k|hBY!x0oBAzan z#JdHQL)Li%^K!fZIQ4`J}b^vkSfvK1;a}~uAB)o>O3LJM{Y_m zWsppXhX5LM+9rT9Hq$(45Tpo!|4!joS){XlH>hAyA)8V9I0m{Fa z!BV93_SZ6jl_rAJxh?G|YX3Z|oK}eEh+&W^tiu4b-IAn$w6nc@F>uxAsK@dY)+e0< z&|H(vS$jSc=zK9Vu`IYZW6+Z3D3|(XeLaP(=hEGN3bb&{L$+CeE%c*SbHQ(B(J9iZt%6I*a>&b+ z270~Mt6=P3a~7QEUXeZIEmr`47^R1+pu$Ir2p=j|Ix+Qpr< zvdShZK~Q3i2+|P3%E_deYzCMi^T`lBnADOnTg=E1b%w5HOsxYik%(Se)l6Ig@!*md za2W`5V2X;A)5A{=0Dt5dS1Y%^+OJ9X)s3FO@J3gC`h@3a;s?~53!m?H58!|-rX%T!?o0?9X9e!kRttTO+uiiKF*x}b|`Pcmj%RhYUeczXHwNI~} z=!fkw{<2Vb)MR=!wQr&}X9(Lf&TREa%g}N2kWCCD4%?v6Smc}~n&zAtVH&!O55odlx_QG- ziZdII##nlgfkt$E8y`7@Q*l=$6TX~GGfReDZJ!;!9iVi3RcM>}ul2j9B^P4k6cO`qU-+EUfe9^Mvo3I+unJ81}>(zT!624`S(OD)p3(_OcBGfPsYE_k3)yc z6KxXJ-iijEH^p8<#l^swU)y_*IlEpwsGE>5SuSKhLtm=_H8YNYK~ZCowcSBim+Dn) zATu(#zG_@`){xcvDqHbarxw~ZSw*ow0jmqIVY0VyaP|Dt#@_F<+_TTM>JD94?!yhc z%{|4G>yg1d`F)7jo!$Q?`l!@)^*JT}WUw{Mwzz(%GNLWSMlv9;%;%Mxz( zFgP;|-5@=jl>A#U;|LKz+pcMNxKditK1NgP6i0~v&M&4NeUeG?!T#r>IRq23`iM-E z4*b9edDZQuh|t%k_3MO({y){-ti4176XE*?@A&{P19lI@SzG&=Gju|{yCvpr;^&W_ zg{-)^s~pr4Ua)6vQuUJ3i-kSY_v3i3GIPwl!IhOd;bY5-2}d}%tjE3w z_Bg8OCexVKPMdpC1(MWAQu2Jz^mLKrXDk6farpl3XYEOo_P4DKqTivX^`((^Z@K-& z7fqwH;Y)JG6z`$z4docu6x|_2RI4;&(CuAqDl_1~$tf{<9vt|M8LrKf0g)NGyJ{SQ zAbZ=cFcWZP#+#W{4}!Ce4)8G6{|sKnvtu%!Yc4VU&)50Xa+$bH6PYIi4aFcO{dJHc z;>sSFAF2zDn48d_x|8AlsP=)sE25U~YeIu2xEl%`?9uMFkAZ^~WK*PBDmWRC09!?l zTYvQ*t{Ds}DTLcUC*6Pr>@HT8jBTPa5yXo=IbR^|6=Uk_>~*9QLoE~v z&%n`6b6a=hyp3bXl3#8~Inq{!pTj9Q^j@pAq+JTAXf40zz>6pCClS!ya9Y+A86LH| zvMuAw?AGRQ=xkU&wjU4`o>v|cD=sp#N-83xb&&~W>7}DD);&vq>zsA6<;SI2%?P;5 zrItf5a`q-``6NeH@TTN#sVkhSR+Wy^R^^LqO@jy7vAAIJfe~5n$>Uh@vSpB@f=kl% zmv-YqmjPxdpy|6B`Rwr1-38lQ4$2ilX20t)p6^$Ze`kq9x zYaK+ELevorSPUDPS)?mfCQ{mVyEhm`#2Hn$F!9uGa0;)bj~^}7J!V(7&d_|+kVd&c zcIn`U;-q=oJk)}66fu2VLu?qaNq-i zPwy^OVlMENr@nce=5gtfxZa{X5?!^Y#D1#*ov^QoHbPH=M>21=9n!VhP*=AKY(r6P zc}ey?NsCzxq6pgvELF#C%y`(BU8;R|W*~~SdlyXS(Bdkp6@XHx8QU^A^_ES~ti5D# zveiX7^7)!m1n)eihpAnn1LKAA7|4Qv6%5)r9I1I-?DJ=b4|S(}OgbfcT%Rf8QM>Vn zPr_lQMAt=cY)KN+CU$PF`4rr4FET5)BCHPDPi)RKdodoCizpkr5@BinocK&)Ocph4 zW*83aB>#=yidtl2eRb$saRby!vpvzqRN8XMLP|to0aOvmLKmk>aKm0>S4pPG;-(%- zp0<-}lKujp%!j~^?l?%LZ9=WxE@rN4L9X|jv|`#MP(%B58O({*$*8(*w={aT#N=r? zDJIYEq21xHi-lF-tn=;I6rzc411-f;j(JtZN>|!M9MHx7{)eZzxC2QHZY@ldX1V7U zl%&ZRVrm{%eAetCV|yj?(yl$+(kSKOoB1(54=I81WjMEaA>)VwJ!!*PV$%)hW-50@ z#qSwBEWvdyuCk)T;k*&EX!lc0p}2_+n_x0kN0><;J^y5o`1<&3BA`H9YODw9C2J19 zc^yfs@M-n3>xb2x%0%?8>G57rL#VHqSpwDx-JqWcb*LW?)k#NZp%w#?Mf|+x8D){% zDX9*((m-T`mz8;`ESTK|&PZ|qD7n}+UX%^-cuJL?l%5f?@uU3M0edRm9>GesdMYJX z%%Yf2+tvcS+`Y6zjKvIXLD==wnNL8h zc*4a3g_E5js=C7ZKCrC$1Cf*NO5)_r5sXNl(Zx(IN>FYcJhs!2pjZJ-R>JWlTee*4 zSi&|)Oo3u}ZehzsGM*i7);TIZC567%H-Wo}RjwJ4Tcby#uRaOBYD_OSWFz9GrCGo% z#5cJ2QVygk;$tWI%=j=EX{k%~RNA zeb%0DjRlIYvSV~}&B$s7RP&C&6**SliYXE=4ZCspm*uV{x@vdOo>qHtj7QZ~$xE>y zMpwn8Ti#bue9iQTq@m@0iyhvI;|9@7LT)aHVij-8&|xhnu>ArXn~E||W_a+*uuR_= z;tI7(XH43fVshj*%8^Qz{rLK4*8&_+jj$e4+)$q3GUos;50|P5c%wkF0R2r+$tMoK zTwE4iQMoMExag>uJkhK10~_OHwfpNC`0E{gJPXB1o@n|FYAu=_r~MgS$LN!Vj`ZWD zu4A&EyT~DSWmMB~ldfP6v@HvkU}4r;BLIy>=Gb}Tde1vEZ$P$9c&@3!d2Od-Rt1RZ zR*TWH)rI9!OUt*Y>Ev{(cPpARl z*w{%ddv6yZ98dTe* zi+d=_FNH<>FJ=A#o?P*8d8S_#6-z7$Sp_=MKMI3eBGoW#dPk*Y_0^dPEVIz;N^GQM zU#UG{xJj8i7}H07UCngW0O-M`j3GFj<~h8rD1wqOVTu(pXlMixv>C3ldHuyc<-%Yt zn*xz)m15L}2ZaL%P}1gJH0^E9;AK8y`idKU(S7^Ead%`q>WK%kDzqG@I$71^hCQS1j=hrQ5-R~Vzel5Jfm&k$=3C6#`UnoO5oX zvp6J3;Afk1(Sx*h8_%Qpe0%(DU-vP+FVXCQFUZ~|9zZ7xJ|$!1*Y2<2P(mPrOR6S2 zNBFhE)N)+q#q)?JV?(b~eiJzs)acikhcQdHd%c*Ru^v|yciY=o-eGxr<#+NxlMD9k zfgQYU2U@p9w<1}-HcO^MYNoiNAZ0KnQ$>4p!DgPF3J$`;u8)EtK&yx~za*3J0s zPFLc~(phr1(q{YxF6?>zGF<3Ub~rMr(p8xST-|teUzyMY!M<8Cv1+5B2Hr9cx^8oJ zXged(k>6Wp&?-Tr@8So#a!t_Cu6eQbnoN(KDj$LwOu{^u!}ge)IL+7Ff#u6oMn%1l zIERk7^5bTv2o#jM6eHzbMT17<7!v{?cABSEoHT1j2k|T%&6hmt#v9 z1|YAspWoy($QA_hgq!xap$M%eODiv|PykUb5PaZH1`R(uMtN1HC?Y%DOjp(5&$>P#A zUM=g}LbInXr!8Rt#cQdQj*Jb=JA4;OfmlzhdPu z9+V22sLk2oV=|HcLMeYSeRj{pqPJ(!?wME4Kf1W#wk@&Uc0RHX41!85@p0&$K{T7A zzIkRqQgVCk7}9sGfpG9N?Hrj-pn!?&sJ~ASAMCr=pFMxVc_|2!<^vLMZ6^e(3HwFV zro4GaAHkaQfMy0uF+6ZsS>eEFZcA)z!k~|iZM;Y@M^y5;ErI+6V`uP7lHiSa|F-(2 zxGz*4lFoFG#XT69XRm>Gvduj9Gi;KGpu(y}tncWn`m8!j6o4K-CR}7jFui0;D4Wb; z(kDBxEQ96I_|!KDEuJ`%b9tP~`KR)Q2W>_16dd)o!eI+Jz&0Gyy>HEVv6%DEa;a^p z#v6xsK}FjaEIql`l#X5Mn0+-4ky7jHY}jrwu+nV(ogO~Ho{2xziq5Dqrsb1mM`N{~ znlhQVUWx{M5*9$=#B=*g-^Azm2o+p#TOzn-J$ts68ur{P9!pYKqy~g7vtG!yXygvz zlvS$IQ(reE=hB36hc_SKYCsyMMMgiq47_ zD-YW(YK=L`d(JSoq@a@u_@fQ9Y6vrJ?oovgt-j3upv^&vGz4mV7Gy_hIfhYth&IY_ zwV7X?RIU+~eq}lTPL`v-@(%6%80?5SavD2MPE4W!frhD76kc z8@080ZorC|A|Ej`(1gY#**JSgAokbsNETtCGAL{{9nLV@=E3NkS_JMgiEP?Ad$Ozn zO1H!~jdPVpVb?CjNV#LyWlQkK;ca*ETYgn9vD-g3ktzBdHl^zZZfR1J51T0yFAScD zDP_Oqhl)$SyL|NJS3JV>h)&tweRu_SD%iK30;xdwYRL&sfjf8ER(Fkqp~(^*M=iO+ zxShU06J%(Q<1OtUu*Kb-jO@^Jaj6MObciaB0;upAph9Sm2-S=Df9CXm|=Ql7$b z{SsGpa0M2RFj-!!??(&F6*1NvgTrYY_67jOOYAv$hf<+21CFiK4qwZ;He&s%T3P9z zNE!6fYr8yQAZTu5D#7Rg1&E3%by zeA+Unt$!NGk6cS$yX+X^fO&GIY*SCsViqNF>1*11-r}6M=NErbdk_}8Dgx_W-18cu(O$ITS|?2u?{3w z48T1Hk;i7_(O`6gLna<(oZCv@kJq;_9&nw$z2@>s0Lrkku(wc`+ayLQn75Gel2GM4 zBwQgatPsuy-3_BQhT87U_I+qHbWgY|*+WJFfW<&Wk`E0-d8PI}gYCMG$I6sSlhN|~ zp2n^X759(Ok1GfX!4oa>BTeCE?e zT$(VS5-LHBRWD6ag+0)lg5_{kQH8GvU1kZsa)}jn z^wFqLp-dV0>kMPtgUc37FwVQm2YP9*f!mT1FXd(*CtucK5`r@R#I>WBP;>~25!n)A z$Gremly01~u4a{aBnRRQSec?>%;YTruDl8pfPgo{(O<8Dzq(O66XHxY!%FWU;_OH2 z3+m>ZNiNi7-#mpT#iDs}-9bNyHUW-{4jfF>;Wzl7? z!p@LbQY7fyK5hKlOi zngLWc+cy{PcUbYL{glSD#?A*hn(30P026iEt{CAmzF9lwZsRZyl3S`G3M(Flf&!| z@I{ETY;b0HhVPhs@RKzd1H7R|GY=QM1LnG_cVT`huP ziUHK7@lF!7Pk*j3j}?>^W?<+*EH?1<)#Gh+({z{NnS zlDPr5GSAZ7?cQ!Ba-?T*mAShnLj^387zZE&ElTVBwcK=vApE`M15QUp%B0cqNgOiP#;b~wX%^LjEs5tDAM8N5pn zG&Ylll%VI79+%aI95)Z~P4G3((x3aiUi9qpqpurMh{%K?h=QRsdqk??dD(`PSK#6l zJ%Lsh#G4s|>^6IiX&L1y$;`uUv*6SB2P#Wy_jK7K@mNq_-j+)_8sBvN6nL~3MQ&ws z8mKw0Qw)`#9)3JE!)JE`T`#oU&>)?986ufJO`Qr%i4K2Sw^e1MxjoZld_?VGpc{wp z9#eGNdez>PNTF>RJYy?RWHcmXQTbqX`v?q5BDKGLy0Og~WU_Q1CMKGQY6)M%h&4O+ ze1=%4cfXYdmgz(8l{t+v@-OBUuXu}qxZq`eJOg0h>r3F>wmY_==Lq8)D>zNchz<>l5(6&0cb=y}jK zGaCn=L9B5dCYcQsheue=2G z-cubNF>)Ph_uE-iFpTD&v>-p*9bWDgXk=Rwv{FE19?I#veZA{nibBU03(`j98d5VX zI>;AMhKnL!fmm+i{ZF2vyMMgwGOnDxQ`!|bpFHk9XK2P(^Q4FA$VP2tu1G81ib#Ai zztMqZl30BK2w6qI%$5M8w7ooDy5*cQ;7n0MGtnGP<_61A$oT_#IqHdl59d#pT1%ce zyuSjbuFTGxw>Qc9*te3h>;%KBfy&oCYYR+#&A{2=CtyC}?vC?#3AAT=0cR`_%@B@s z)6)9VHCR51EC#_ny92m}6wl5)+n;sAU8NZ7c@ODsb(vXeMtiGeM zb{?p43+&ab#;YU?W<)6GI+uWv@92e76LoCav%U$$LuWyflqYUB8(^rOB4+W^Q|OEO>6UB{?BtCtV_)ou@r8D+9F z0^~`6_IDHqtqi9i<1t9Vf9=N1GaR(^5kxZ&lhmaQDhVRZFV&}p7U9K4t?bR95OH;Q z@krZeh5O~sqBI;MCU6FY9@=A=Vj6`f=S;PyLc)k}G4Ez(R9q9D3m5GMtYIlO%Q#i` z5NpN+^JL6Fu-chn#L^Q(XPg-1>t^sdqQ1fXI^4%kVRxA+6e}{B1qdMnbQuIQd(pBS zWdKs*30(GnB};QG{)-3A|Ea!DhK#N8)c%e%Q5!J=n1bv%P#ZTn43`RctbgSlMYs&5 zN(!86;ByksMh~?FmZ0cskBZVtUGG{yBe<|M?hqvK>ES1jtcd0WFIiSzzz_;lqQZ?C zlDs%FGvnnLlWb+LyfLs9k@WXkuP*R8{#IR-J-N46)lN%mX8hXbtfnB>mKzFL4q?{J z6db`d?-+J>B#zb6ys0-&$;$esLWm#aThe#l3JTep+Pcg8{m=s=&K zO5=IM>DSw<6I5tFavbZ zDmhbjj=6@$f_t28?;2aAbU(u)qgq4nh-8?QOa~YY5E#eCX;+idMznwFUB4K$~AiqL$FH|UK zEV%PcDb*7@8u@A5hLTcMp6Nk+(wi~W2cFy8M;`5E2HtKj`?70z<>{Fre7feB92Z+K zfAc|eOB#1qF|e$|JtqP9MJ%nD+?L%FcWY*s25}-?g|l@4TKEvAo}hq)smrnh@NLMfNTkys~|@)#FmdC<{Jb` z-O@J!rGe{K3zO#Pvsxgx_~$0v8bjK{T95P?f-f^FyT0$}wicE$v9u)=y352oHQ)nC zXPqC`_#)g>7ufU-@H2Q+6BXNRAI2UT6~@*|$C%3x%7 z>@Y#lGMDZyN_LZOFxJ+twZ9XAfS>w0r6+p`d3cz{IPdXh&o-f#1a;ENvV@bz6xCg! z2?Oau3EX9{36{nS;taDk7ERkp|LeYZ2YDD&5I!}}y*-y}kE~!zW%6+yy*9z7I20U@rFNVlmYm7q zc#L7(^est>-$CGyJiESJvAwzY18~R1*jA?^{SHiFmH+{(Xo-BR$}u%G>1|L{cMKe5 z&s?`xsKl#AUzmC4(mR{i6JZ+- zF@8f!3R6&HqYe9<5B>Z^P9o8Ce>3_~DjduqxXRnq7_n~?I2$V5hw6>L$DV_`pz(8zKPc6Jw5zGh^C*H;*ppY=utrT5b2#~D92GK*^Kf;6~tO&2W2e8tZ#E~ z&oq=@&0S1>l?LYUVSvx6Ox^mq%|SKumW*y5J$6wn17_8OdOa=Gk*#{;?On{$fqYBt!JNrDD%95qg>sk zkPiMqvL@%y+tLsGfMUX#mO=(Wqzd`C6f~!YKeuj3Jw%`}{YqQQ@hhdRz<#Vq$~-oo zme(nWtQA}yjUZ$+ER;uRdQD4nFUpDo8z|!}_%gwIA=o<~#1Rt$p7TJlJ@C(12o7!@ zU^A^O4H~0yz+Qdi=Be{PHR-oL_>H@l=BNAvuOQRLm;=P? z28w~56XC(?mdoXf&$7F%#GTX|wg+um9Z;1&d*@?M}`Y3ZQZj8U1Hv)U*H4#k~E z&Oe1LbZtsOjLdmV)AywWbCg%dRuk>ZF z2`NYOyz8!d*aL?>8{TJ8;I8o@*6^<@dSVSK)NxZ6X;N!kK@N#&pM{ zYD~!wo6Mt61uvtdGjNk`!_l7q&+g|t61mgyrHo`1I5bA_let2|-tM$aVT@=B2q$|; zdK~uX21S?@D#;|9i4T&usulgEBP<(8<~@}H5i(W#I~s0$MrT*WkzAVqsbR=Ex>x{s zP8i;pvWEo6g+XoFWE;MMryxZZ_c~^nyg9J0y2OV@4#FnyQ zoX)Q3IxQ-Bk!5y#lQ)hA>|&`DUFP)=hE5?2*)MG{2b+1~QJ1Nfc8GPYnc7h&n`TqJ z(yJtVBP>N$vb2JFTm&BxjO2dZ-P{7_&YewK#V`owR%FUz#w)UwbL`KyJtkvs4xHlonz? zv}M|-W*bTui74lZVa>1jQD05_s5X?PL6ZhQWsT_CVZDBzj7Bs+E#tIBLp3OzKW^(h z+kum@A&taPs8q=(S?q}12AnK-Abv3OboH-%PkMRpg(@Xhk7hW?cz~l}EF3OqFBP~g z^`M@=c%}0by?p|>9c-QA+|DLtlhH@} zTT5If8Y@X)u;gGuO;fBP9k-s##sJe3_4d~o%Z%Kn8xnf=E^F-)K|*Q{^)$m~8Em1N zmq|nH%FwanQ(e}F_G>GZ{T7Z{~*kb)?vhDxnOU?sZHC7@??Loj|9 zy<*Eh>(O{f(sG<?V zX}Q)_8XH1jM~Oz7k0|7phm;4*+NKPr2MV+Qjj~!PHbJ%>{*UYFikE6cM6fVIWEtCUOho-@0em{|7I7Bfgmr~r}l(Q;k}NtDIeXP`@@V^nj@ zOwZZn)#vjL>=^-p*E3(rNBSTETqo^9B3uZE^2s0#yxCpEA_8ljxm_gpG5jXe^U+&a zc%2<2v1K9D%%37g%~o5cm?N~UtQoJI$D@{(?fs97Uf2?x ztMHayF$HEy`|{!Zt9wPC^7qJ^Qo>0h*!~u#*!5-bP;d^k3j`&#O@1}mw`>xljzVS` zsA+u|G(E~9=P#!D&6Dxa&_(Mb9m2WzA9Nx0$H&gpJ?3o}7D$Ke zSI4b>sf-X*m!{r!F-#oNXR^kG;$bjWxeWsozQ=~`1Ndv0Pq}_L7a)O@#2sO97#aAO z%6Bi~1@yfxdl#;__<&pieDXhW$mj6j?C>L?q0x!=OjV9pj`$y4W;(wklh463L?+?aa1saTyiqQI7vF3IaYw@BpYV%;NpdBw6G3gWAede zu_JQ}rNh)fZ8*-LuAvoZW%YN;zm7G$DVUzfJOzJrABLNQR*VrakO4FA5Gd)6-eeWAx(?Dgo$h4rV5%WwSMDSC>+DG>`MAy2*)eEI zql?ci8xQ%J!q%v?ze-{wy~T+0VwrcI7;r}iiNvHeuK{m3@BA`eKu5z&lN;sZsiu}o zGh}+*mjQ6|@D-6Nxg8K#{X?~vflm2HxE|{Jpt6t3%>g2?0JCIpXXQ;ZeJm|0BR^od zh-fMUgUWoZGO3%pfU%hOI)h32PZS2dR9pkX+e1L)}OP z=RG!AGHm0(<2TfV%(RJ>0JF4-)gBZ+YW6kHqXuI!?!p9S!aU$1X5N%{=`?1qq{+M# zPpW`V(};3fI2YGZuQPbCj%um*PY={(esUD>TRHNVJ%~Hfw8x97GYE)7`<#!m=dnLg zaoiZKKr$4G9?9J)eb~*gv`?$9zfz$zx)#TaV`e>1ng#d8rT+m=taX>#V|!!t7G~Dx)>4 zAcPE~OSJNFm{bC@dTzJWm9!Kvx#kePL-tDf7QdS4S87yxA4H|%XOzd?VMjMsKv4GK zggAp5OxFR(%BF*Hh>Vd7sbim+n0eclS}%d=nW8CIO{hv$5=V_$1=CuCv}}O4SWTt_ zdJvs8;G_WkhE$1PwRnsBuN}xz25q)Hvf1->|9Co=Ke@{uYGt+iR1=`c~3eW+W)Jc~QbU zAE3?za6re_N84}GuR2Pd1CckDx?#{Mv--`0X8(NEA>kP(%cS{e=;lNNmxC1I=~LIq zhTbE|#0tU;q~nqo3_NfST;-+-v$<0`tWUv+7Z$W<^d9Qdl$o{}ebkD9*@lu~6>+Ky zwpn^*mIgZIrsQ^}@+9ao^aBr$OnP?s9w?t;R7+MM9vkekw9amu*%I>^&&`)3&N|gl zB=%OBTG@E!(2RtUa;K+1Ky~up_zkbzLZP)xm0JR)TszI;f3?AG7016K#T}1x@j)3S z*7nSE4D6U%0LVz*`qRYX0loIiI^r2Uk2Z-5iYgaaD@+TYP= z$dz)qrGv(5hQMWyb$0lhP&`FDGoWMd+G^2$M*5mlZI~{t5Kv}d@9pUS-8~li43J*aE6|JxrW}W!0NF?E3#8;|#%TF+w%OLM z;0!Cz{!Wn_OU+s$hW9Qq?Y%Vy?qxucMQbKzlL3C#3V~iu9*t$U@q7wz%)mFT@@t=- ztcy&K>%BY4V6in3+TTeghkaHQKU2h$L)lF;Dcx`+>&D2>O4DqE2!;x14pZx z2v`_|IQ9+;>rY0gT?=gF6-m_Q!75i;2F+AMHoN&&V$ndHh=L^83imvpoaT58cPt0O zK~xPcv2=W}%W8Y0k~9ZP3I|%)HgVSHrIOY0v?#MoZ=M_BlPy>J&P)6SrzgR;jEui5 zmo`U)e%db&c;07f2vQ#Dt^Ms2MjEuASE_=qp`%lnE8W{;8xbicKG$DohX>C;=^Qk7 zdnJH#enT3jfn&4M0%4QshBp* zag^_6=*ZENO3Uj6LSEs)iKpIc#-WSBc{w-zn{K>qbEH$fEFb#qQYDE8g7GoCtM&{e z2=%nIRM{Mt5a<%|ABTpyU?2yDzNP{=tt_K)TzRpr_GX-6npEQvzbPw^6>^4{$EApJ z!Wf!A?rct_dWA$Hkdb}4$*XX@ZyPmy=!V8$y<2w-J z_#!*hzGB^)b)d;AnS>6AvfaMw`6ou*@_ISVm}Uogu7G<;T%ZzbxmwH-w@=GqMpl5LKSLKq5ymW1e|3 z)>w=OvPI(>c~9&f0Am%oLRE0lND86P(r^DHxnkq=@SAm==+PdB@U6Vz&sxp_omd-$ zCbRjg0Sb5O^)y|$YJMs6bUeW}DBglgYy`>*awWkKO)@5fdkIA!hfpNDGsiZaWOZE_wTXie~In4~10XQ(IS=y#{y0OzzHv@jAmNUkd5yf7G2wm!kia~9E zwN+$kxU@uO>@L2i9GB!xB`Qs{-`dHV6o@2Q63SG^GX1#6v4+&YW*cyRX(772NkOQ*aWOrUa{*nqjq+ zC)wIFBM+VbN!fb&>rI^Kok7IN7#-kyZ|R497KEx1nwIsBl0|v!qh0s)TMiroai2-) zo1K1r4CfP234IhI(C73kl2dt{D3PTN4T2&O$nwo-DaWPb<`&7>4#hSy;+np%JPNLz zf)Ii9+AlReWABWwn(@qxf?f<$-k)Em;xz?Ez80+sxQwsh))k(z=x*=Zw8;|jHbfBo zOl{=Flp$x6UM?BnKZsE!hCg`zZ=qs*ZUPQ?Q>9)1@?a$*N?X_IbW6gmpJ*>BjD3?ahm#Bt zUDA)^fHXC8?%5$G6<;-h<_$DMV?MLDs3b{?#@fWo&|Yr$v?R5cjX2W$-c?3L)NCxnDY#F$cc(l6HjD&8psT!Gy@p1 zp*n`*pjo~KU<)c90Or6$XCqPZsx{F@fXJ*q{jxLgnApUDezs-gn4dFi55hhSesfz9 zE};^oR2Y`@(Ed(Z87-{3n+Zy_p=n1zKTxN{J7-$(JmAtLNCKrx2~=FEdwvhJ_?a%% z)%HcnX+|q^&<@l98toG2(i>}w4+8Mzos)D=$`5p9Y9K#~jI)7SlFTIWA_w(CCt11J zVss1At;A$i&atnbFcrAWPhPJMp6cy_(`6z#J>U;2iHFGA4=Ozh9&<-W!D?N~Q!2zv z;-~!`xMTcg>@#~65jQBqm@9^1=%Tr{xUs9E31Ca!TqpziakVN*D zqYr(RDv;G9R`F(wZ;DB4pt)Bv|g_#B!`uU2Sj-LazJz+xCyHw>-HUh=qQ7n5@)#7T&%>B62Q z!pCiy#<+^%QFmM^gjQKm&TzsvPkgU`qvxz0rmo zlNgYn+F-(>R6}cq8?a0Q)+sJX)TK1KrFdweK8`_>tP%RiE6-!#P8IJB6P{qub*1Gh54TfwNNsU$(4LZu7Y9 zE^xh#dm)4uql{7C^DW}PkBHmf7nGR|I>`7_2{r$>UI-hkkeJtVsEOn3@@kiMl4Ms@ z3EYbPdaX)7YR%YU4J1ovj(bI90WVhr&7vTh-KLe7^{OaHmbLgC8596mI(43yG5E2j zMFHnbfAgecJP0w%xF{wa98nh3apT9a*0*%Ym=#d?+PO8je1T+jVW_qNAqg}Y#g+9a zZR#QR^AB1i3q<*+#F<}(ICDFzNpiL=LvveaSl&cfHi)yH(oqmeyuiIH!YsL!`JLS) z<_e5K|JvW;CR8oZCukcQ^sBYGII~(;nSE_ZP@3Be<}96gl}-+$`0?4K!1M#{@hE*D z5lG>xR@#_idoQU{QvMk{YXwiAi(gH|2d&CaCT4f&OBE*Fp9SiSH!MhM6q^n9Z{gKd zly(f7q?hnZf?&KT@H3ot&@j$AWi)1qx<(IJb zF6JjOCV?T3byZv{n12nMBxUYP={CKWC(t>mRI+C(lY;|zpUazbqghoxvH$K`5Fk$> zh5)Y8sa+-k)HqLuUZu@+M?Pk63&bbaY4eE6K)dloOwuP`V!+$nj`R7LF|c4IzDgz3 zvNUh3LPz?#OM!L3_Vj!kpSTD=X31}cZH#Zn}=Ix*vv{CD|Dcn@J5E)VyO|R zGpYFu)tZI^@zp%Wd8JnT2>cTDf^l`b?A=LvIG(c zAnga;AE8nOe}u(l<>uja?lrb80Cmql%PW%MdOc8E%8;0#fCVht-Tjp@@FJs^#edCZ zWmV;$?^vUvTEDWjn)(iLYx4M{1`TPWwP^sK|D!4 zqU{Y}x`2$2vusP`b9n+_CR6{vtzBKHZP!&kGLn&4iZB-~#5sS1UR$35Jk%ClF3aNyECJ?!hnDnNRm@D4xm~+fI z=9uGu?HlgpoVC}UKVy938{e2~uC@1>zg6HFh|t(=hQqMNA{n7C@4Ub2@36kbime@o zS&WhS%t{^sUfIQBWChYTjxV9+L@+E&FAX4rr@9sa!NkC|usbFV-mQ)0_XupmamFVd z*<-l>-o)ft`INoj~|4BQwGeC-YGLM8iN$9R;CpsumJ_-%YbhF+|OCCVcKD= zawTHGlp#+BJ=scWC%#_*0Z&jT%hjp@T(G@^(>`VD7fGBQMM4E}*76}%XF=Zz%`0l6 zZAe1~lygC5p|PpbK9&dz5%w_c%k+G$_gT8sA|48KTDuifBS6|LKq63Hn}yTK8w(_k z2=*F>0Okk5!l&(>{52>^^tBAQvs_QQtD&SiSBWV2+}z%8mq156uYb08rc6Ejy3}TG z0QC817DefZy=yIJu@byVD49jMW&j_nK6$O{_6odYtH?&F`Ve0C_uz47~1;CR09)_H4&nnWaUS|FDeMPRr3uAETf=pgFzoQp3#^MXa`l)v z`0zO!m4=-I(w3DmKh~rZ{dI;0!GpdrRjcCYb^OsnZ&vGYn7*5ymPSVq;EL7SU|stP1Gt9y$8`;JzrAjM z_UPOL^GGYtAz^RoUma{NO&&4HwhlKS&i)r~jH`PF-dsrY7S&!(X{K$`rXHUM^?27h zJ0B5QXLc)1UFOo!rlc-TebiytdQo>gP(IUiae<59H62L_K~twK4~~QIX!=ERzucd@ zHprFO1ufL6RbFBc(OK~L;XJmMbJ`48NiL5}-{IuGnFSA=F4}lq#CiOrP5-0T&y3{; zeaxnG`%!ys+n@w9#Tj_g5SR;8^vxKY-9HXAKdxx0G1pNYC$;0)gyVCd&6{v|QWTVM zu9`v=G^_NPG(9%!_mz}qZSg9ITYjY6omUi_J%Y{nGQ9YSLNbMe6e=c-Ks)6SrZm_u z{%5{7*iXJ+l>aqD-a8GDhqlX?=v8?GyPTv3KL$|BEu$!IEH~( z3n*goB^x3G0HSGwS)vELfx~)6!Bt3#$Yy3dTuH}G<@-B6Xe1wDw4dpAb`zJwC7eQ%ZT2W*ws*<1 z-VBUv?-st*irb)}_6W**71wseONxSRKRH4NY&qXj{T|+#{rcs5s0ALpH9lZh9T$7e z;F*Y@%328Fz#V?qzLo+D^Xi2r(a$~PIz0MJTIu5gBV3TQGBYu`OZ~7L)t| zM0!#Y9WRL7@|cP+1%_b!o_SiQ9I#>U zYU1s|BTzij(l${EVkO4p5zt|T8NtcO_v|7^kGUDpB;@x%Le7G0!blOWq&0Uu6%VZS z1`ZQ&no(cFo4sImgtbzXAqum(bFhE#DrvkE9Sqna;%GCpfw{-X(`!u1HQn3>UuS5p zaL>gg37;IK5$X44)t;v*0XSO>?%lij-?q{5qEwOgXh*9RWMqAH%4gI#d(LVk z4QsQUC2JA74Y%%&IVSbume=Ju2(dZcM#v^3pT4|t^ImBy@lPE1k9*2icuSKCibZde$6?Loq8h9l{5*xVZHMdpxAwkwaziL zXUPyn6AzSbdfB2!cDerA&8t#EUUaX{6Rumk!5nVa2&cEAKQ8E zi#WE}7Q@RG8jlfh7iyf*S=dzO0wstB?@F-zW#5nL_VNR|)ivkpEwSewe6n9$&a}V# zcV}3mgew(Zt?*pQgWM7_;AN+G9#m(+I-{tK2@K$y(QYsVBjKgPl>~QWe^Zg)02PTo z6cCdR-QGNZa3l5zh>#_(9DfAYifOb2b6-S56gQh^z)nS%1gXAqG;33gu=wh&I)>80 zY+*;GAew^hXx6;5^u~7HtZ5~XbS}-e&PMF^iA|!FUt*^dBWd{g(fE6H)2+eDct-CB&DPn zbPM-6`MhIL0;K(ZfJoNjT;SRv2d5aSxWJe;!Qk}HG0zt=kBW;sJDEWT%AR^5zz@pZ zUfu-lc=tA?Q}uD}*1Ron0vFi4eO&+c zat|(7n(tx|z#K=Jzx%6jLx9{gDS?G;Iol^i!0UR4h%J+xYh=>^9x{G>^x@W+!*BF{ zc&#NUCYx?g;KUuZ^>WyV0J5xiRt`EQre7=ID)9+_^gIdFE2Gk1{ZB!DAt}+nHPn4(Q{NT{t~4;JB^MtOU|;&G(e}k*3}@rF;AxV=t>Ks9OMmnip=|zc&yfxi5t2PZq9y> z^t6rWx*cc_POT0g$j!Viahsid66bOO+z-0&Ajd#qB-c=FpY-Kq+aLjGkoc=g4*#-&<^`5q$<$uvJ*tmp@m#fL~Uk znsR2I^ePr#Yo%3zHx_bJzk-Ys=k=R-xgsXjQHTa-n~?!Mhz~~^&?yDQeF+%3@ixHBj(-B_kT+Wd)Lw=b0Y8-;SPPov6JelqgRcFU|D7UAAe&i$?7|_| zP&j6`cF|U)`64jXs(T6+a;=_gIzhZRdgt{BTm*{D$HKt@#F{HZK*1FU{uLjN2>}JF z5I(5nlPF`XHrJ#R(ZDbun+wPB;Nsw<%NWtPc_AF9m;FL=H3*hp=f6qUd=|^KgiOK% z6p*ijfV^vU*_C#g&HHBQ2GK;Q>w1V9ILu%+Xb$U4FT&J9z_ z>abAu5i&3F2|WeFRQ4Yl2vOEEUZ z5TXE9ZbR*R0fHw2bMf+2DM$YAa}St=J!daYDaA~Vf%t6Wo1tNW(9DTTC+Bd?$uv6P zNQ=%a*?>cCIk~g{ZO{`P*$60`kSRFv{M}#eJPGJ}%x?3y^1@liYUC?t0!vIjcsk&n zHwQVz{I_AT@wb<6kLOxa5_x`z+>NPP90a%z!EHZS0+||f3NRGBF*4D!&thW93FeZn zcSnK;lu6;`>F%Kf=h3A3TSAo1a-^w0ZzvcO5n>N+KDJpvZ@g^>#_-na!vl(x8zWvE z%_Nwhx0$s;+&v4m0tJJZh861%*bku`2<-bD)s-VIF8&InBITC}PyHlTL?c|_gB5>K z*f2k2_cLE?N5rWl3PL;3-ScJwJ`#f9j~$G)Q!p`&g@`;#RK>6QVmY+^6j}=^T1Dz1CdkM`)GYRi?4Dwz?5F+lP3h(p;*%}m{;s&@x7fJ!{ z(IJ|NpukHMi7&tvNb=Bz4v-0#fIam+h#>X_H#bkoh1!#CIu?CA998|COYLJen!k;f z;sPdU8Bj%|TC5Kwq19?ogNrU@(P7sqiUJ+%*8`{4cjQX|lu0%?33hHqTII%U#?vI2 zm(nU|ql1{zo?M1-OBV=II#3t(fia$Jk|WyMsJfv({3+C9Q#xSWpFU1ZI3gw2#gYM(ta|WEp`Dx{2 zo%73nXOAGD0fcyUheKxs-He=#@?utscq0VmcYrlBBP(KaT3W*(<=P_19lV^8I z743p%xETKm3sGc{Ig2)Xh~w&jBdorYU?#i*0hm{IWHgIY_0+r?OyIdY^>kq)aL5hL zt{5(=XgGajgNlONxVIbw_O&P+gP!9$O86-UncEAk%XGZB0Mn?(A-gjsz)z8V60~5R zVGC$ID1wVFVd`?nq(6*6B0V_yc))aCnU&+{Gr7~jyw+M)*dQnsb0v@!9xd)y8~|ZV zx-inQ0Et;s6V%;zF?hXY3XJ)#J9if!KncI;=481arBv>QpXt#Txd=)HxsZY#b|B6!8Kx!K=z;Ep2LP`4-Jo9%wi3K zM^7*{F%r#Yl`gy(R|%PhWvT@~gR%lE_V<(d@|eA&D} zukZDAzr8$wgg@B(?2vT}msyyx*qZCA9Lf?UU@CNMKlT8e+N~J zPTsarTzn=$9; zr{?=?G>Y{O4q6NC>@Kwut;>i#8rjeZlahqQ!8MNt?Ch1zoRd^M>(|*rTaJ?;2N8#% z60G)BmGqGipo2~uqnU$-xi%C$jOEDAuUVG=8Istz#cp?UY}8dQwkS=(pHDC+Frx!w z43>!6W?%uunjJRnJcV~K@-{5Y7A}P!Qbht%lOEJFEEr9IL+P992XG7lpTGO7xt0lL z)CilGRVmH*s<&=-U>F||ni*N%gKk=jXlzjQ#?slDxLx0i;tLZk`+c0ZX44Fj z9I-BXq6>qp!F$PHFNNcC-Zc4mSn-O_n;p{#Ay_!jy!(2^8^nZH$0*1xXuNs7&l>{^ z?;4g*tkC^bEj-t>7mKJfS^ox-^^sh)wC%h?LVJU^-b3IgeK0Qi>Yio{fMb ztg{E>O`@k}P;#~;nXydl@zue!L5Co~%_Hks=|tL~Q~dFV#5IPtPOUZ?HRxmu9N|1M z5s;(d$d2S`eeo25JAN>8*&*|yuSM0D&&F_PaD6F=^i`EdI{r<(nVe#umfi zOSY-P4UC~mbHyy5UMk0P(RK$dqmJ%X0oEqX_Jlio1CP@d zkc7$X={isKd#&-q{W*Crtej3MVbE&|F{q&H2*$3P9Ww`!Y2!>8i^klO9-Km~=I{Q> zThq*(`^4o%=bj4r$IaQsCb#e)PIAu>XJJsmsTs3l5VHvid}Kd&XD7I+4VZ`xoNfjs z{n6)$CYpa(Ich`3>`Wii(Yx`%lx89+)!=UQ=>y3I_l+sn5h!S0M{*xq7ME`rrx@RoVG60`>@FCert{^k1> z`?F}MmJg28Ia8!%U0>6BtA$f7!R}@GwU3Q(e7taD z;)smK#rraVB68;09EeEsV*d4EV>BApJeZ%?IM;En#9RzknF(m~e`jM~xX+a?uAhM73a%-qztz5M;t#qaI1)S_E^C z+51WSZDj_BgLUPq9 zPddSq70{!gu)}#yZ7Lyi;O(vPnbm$0FZ@tfd#vnB?j;a+pt#Egpf97X)C#0Hv3M@S z*7yji&wB)KA;=VrBxtnRWi}{z+w37@Ad5@`+UfJ(XwG9%SAJci^_h5K=|Ld^oyIO! z9HP5`mwHkDOi&Tp`P0cC**J*T%7@QF(U_%#snMym7mt?Ep&0IBn(3!8rK^K`6QG$Y zSZFl~C?Cc+0a6|76(=jn(Z|(>8?$TJDO3fLN4GU{yf1>K8U9X;$91zFB4TUyZ2LzT zA79J>f57Z!`L1sBG`_k2bXNQ*Lt953vc>-2hRckzg_p8a_?U{qfj)A2h~tM?ZSx#7 zBZwe36ADXYv#O*05QYt2?!wOYx^SBYqX-6bc?9;(o7@mVL}`|jhWemWqbO^%KPRW- zkkYZA$l$^Xil`0v2i5V3`Zqx8f2cT@-jOLf6)g5S1J5R%2$M+|K0a_Y@pP_%8gx^3 zk}d$VfVX@j$KzzMKn#!!-qLI&y}CM~V9X7f+UEkq{pf}>k=Z=RY6^+c@My{S?d2s{ z*1KQvh-Ai}r}p5ysELd_Rn|3_`V55(Z9WRn@r}6zX98bW##&?p`k5LVF9OrLDdRrx zmPKwl%L6Z<@%n@e;0lvwQzdGTG#~zZeB!C8^uKI35HS3dNRh)7R5);)H$}53>tBPE5;HH{_5K&La&Px`_xjlmvhCL54zaNsZ1 zVx1}GBE>TZ{x3xKaa*_JQYWS9VidU>K z<4C3Nx(re1iFttohQC{s8o@MBaTEfo1aH9=+%zXVn9mMS9AQk+VVo#GoQtIoFCi;{ z@Vrh{SzxZg;fJ8C7E&F0)(?<3yEkv$rrWhQ)@zCcG(^G+K|}H8l$wy_WK@6EHu1; z4GMAjYu{@1(*7|%3^Iz0oLQmeF~366w}of{)6E5GjFw5;dd+RYpA1T&L!8reOdZ@9 zH)XcIu@)qy=6EWbK(S`ePO(?smM1lUQYogKQr>auL)w7nRK=<*a0KCPIAXrdpvK(g z{>CjUHlqP(0dU$ABHEywwho1`BV{d0a$|NfeGByJnnxIlSzCj=(%paG0B>J)ZGnik%Uk!5u6EO-)ETGs`yeAP@o1l!}vlEuvGBQUeLG?4Py~ zpb&`$F&S?jSoPZk*E=bvsNGE9K9a#lYVa;)g1bRD_KWh{%O_535n-(HXS@hAAxf8? z;Kjl)yBh|)(h&uXs9zj-%+yS)w~S$dk(YyTxCb#^dGY0&z{<98&-2^MccMKQjB7Df z1mR-0feoA6-Sc_{xbD_okORW_x22`&qnId0Ni^ocmW-5fec|#B!1Tp^tD~L>VrH95 z;kvaROpv(71$M_vQlq`U{|_$+!1y&nCK?=6Q=`E5H5!@W6!?HRGGeS?FB@bSztO|^ zLX$8F0hz)NcKI;<0m>Qv;2`CPH^AaC$UY+qRxo}{c%s6Q`pe+c$U+!w8~poFCRXN2 z^u3KQqxI#>cOi~1Wq*8^<0o5p3-)VRs*5m(Qg47 zL{JBXTmFK;M$*Vc`P533J7eZfkYULDici-lVXU9kvDl@{&kt8E5C&~8I9lrr#XG9etra1ZS9j{?j#qd{aG0DU1#jy{!*> zYCloeyxYq&laS(a0PVd_2!i6pJsX0)>EVhJwLB z_~#2s;|QCbOM^|9v#XL*$cT}H&?FRol|6Qe56J)F<(=f+-JADc2Zt^i`i!@R6U8kS zJ7eY1gCSWMqpxXkJ85zE=7geaC-s@Y?S*x0uD|$!={CXN`@9$| zcaTul-fE!2!CQhNOD8PXzSRrK%l?z`yu=5S>QL%4UT`aFM*?8i!`sW(h9mFZfMwS) zf$<__-h#>uWwE^7TwYURa(nsW2Ghp5KZ*Y?KP0kkC zAplNf*Rtiez?SbdY`H4HE)}eqZ!d4bzTvto11v#B;Q#!s4)$w%BOv_YXsj#k=L;}R z0ykxWOfGxGZ@`@k8#H9w;*;I~E8C4w>|-scn)RQ*JZBL6_VVe=E93ktmtTMMJ@5I@ z(@*@weEj=_4G$R_|aec(c_2V f-}`>#1IPQ`{{d+9Q&0WulfN9i|Dm7$$w&Vmk>*rp literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.png b/Mesh_2/doc_tex/Mesh_2/domain-seeds-mesh.png new file mode 100644 index 0000000000000000000000000000000000000000..b1b549692e251c5411777a33446338ec7d19d77a GIT binary patch literal 26218 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 Rek%-=oRkuX;x_Wt4UCX&I_a_jl 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 DHl7a3 literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/domain-seeds.png b/Mesh_2/doc_tex/Mesh_2/domain-seeds.png new file mode 100644 index 0000000000000000000000000000000000000000..a5e1dfc5b637f7f6e9cb116837feaad2f01b42cc GIT binary patch literal 5183 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 J?y8GN{vQKGUb6rI literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/domain.png b/Mesh_2/doc_tex/Mesh_2/domain.png new file mode 100644 index 0000000000000000000000000000000000000000..93c1416afb06bae3a4ed0058798b2b18a09510e0 GIT binary patch literal 5046 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 MrnV;a*L{-z2cq|c9smFU literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/example-conform-Delaunay.eps b/Mesh_2/doc_tex/Mesh_2/example-conform-Delaunay.eps new file mode 100644 index 0000000000000000000000000000000000000000..54a6c14fe7b2188e189bd7c62665277c6a440402 GIT binary patch literal 42063 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 literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/example-conform-Gabriel.eps b/Mesh_2/doc_tex/Mesh_2/example-conform-Gabriel.eps new file mode 100644 index 0000000000000000000000000000000000000000..edd59370c72316660338eece91005612eaa895a7 GIT binary patch literal 53624 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

    -rT?L&e?QU3 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 literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/example-conform-Gabriel.png b/Mesh_2/doc_tex/Mesh_2/example-conform-Gabriel.png new file mode 100644 index 0000000000000000000000000000000000000000..0887eca711771ffdafb332d1dd9f6232e02cd227 GIT binary patch literal 10223 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 H?DhWv4YD+E literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/example-conform.eps b/Mesh_2/doc_tex/Mesh_2/example-conform.eps new file mode 100644 index 0000000000000000000000000000000000000000..e39559bf0d5b42b19c1b8894085e961f7d613833 GIT binary patch literal 39479 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 literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2/example-conform.png b/Mesh_2/doc_tex/Mesh_2/example-conform.png new file mode 100644 index 0000000000000000000000000000000000000000..46b9650316bdf1e3501a1145637bc51d0b460419 GIT binary patch literal 3893 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 void make_conforming_Delaunay_2 (CDT& t)}~and\\ +\ccc{template void make_conforming_Gabriel_2 (CDT& t)}. + +In both cases, the template parameter \ccc{CDT} must be instantiated +by a constrained Delaunay triangulation class. Such a class must be a +model of the concept \ccc{ConstrainedDelaunayTriangulation_2}. + +The geometric traits of the constrained +Delaunay triangulation used to instantiate the parameter \ccc{CDT} has to +be a model of the concept \ccc{ConformingDelaunayTriangulationTraits_2}. + +The constrained Delaunay triangulation \ccc{t} is passed by reference +and is refined into a conforming Delaunay triangulation or into a +conforming Gabriel triangulation by adding vertices. The user is advised to +make a copy of the input triangulation in the case where the original +triangulation has to be preserved for other computations + +The algorithm used by \ccc{make_conforming_Delaunay_2} and +\ccc{make_conforming_Gabriel_2} builds internal data structures that would be +computed twice if the two functions are called consecutively on the same +triangulation. In order to avoid these data to be constructed twice, the +advanced user can use the class \ccc{Triangulation_conformer_2} to +refine a constrained Delaunay triangulation into a conforming Delaunay +triangulation and then into a conforming Gabriel triangulation. For +additional control of the refinement algorithm, this class also provides +separate functions to insert one Steiner point at a time. + +\subsection{Example: Making a Triangulation Conforming Delaunay and Then + Conforming Gabriel} +\label{sec:Mesh_2_example_making_conforming} + +This example inserts several segments into a constrained Delaunay +triangulation, makes it conforming Delaunay, and then conforming +Gabriel. At each step, the number of vertices of the triangulation is +printed. + +\ccIncludeExampleCode{Mesh_2/conforming.C} + +See figures~\ref{Conform-example-conform}, +\ref{Conform-example-conform-Delaunay} +and~\ref{Conform-example-conform-Gabriel}. + +\begin{figure}[htbp] +\begin{center} +\begin{ccTexOnly} +\includegraphics[width=8cm]{Mesh_2/example-conform} +\end{ccTexOnly} +\begin{ccHtmlOnly} + +\end{ccHtmlOnly} +\end{center} +\caption{Initial triangulation.} +\label{Conform-example-conform} +\end{figure} + +\begin{figure}[htbp] +\begin{center} +\begin{ccTexOnly} +\includegraphics[width=8cm]{Mesh_2/example-conform-Delaunay} +\end{ccTexOnly} +\begin{ccHtmlOnly} + +\end{ccHtmlOnly} +\end{center} +\caption{The corresponding conforming Delaunay triangulation.} +\label{Conform-example-conform-Delaunay} +\end{figure} + +\begin{figure}[htbp] +\begin{center} +\begin{ccTexOnly} +\includegraphics[width=8cm]{Mesh_2/example-conform-Gabriel} +\end{ccTexOnly} +\begin{ccHtmlOnly} + +\end{ccHtmlOnly} +\end{center} +\caption{The corresponding conforming Gabriel triangulation.} +\label{Conform-example-conform-Gabriel} +\end{figure} + +\section{Meshes} +\label{sec:Mesh_2_meshes} + + +\subsection{Definitions} +\label{sec:Mesh_2_meshes_definition} + +A mesh is a partition of a given region into simplices whose shapes +and sizes satisfy several criteria. + +The domain is the region that the user wants to mesh. It has to be + a bounded region of the plane. The domain is defined by a \emph{planar + straight line graph}, {\sc Pslg} for short, which is a set of segments + such that two segments in the set are either disjoint or share an + endpoint. The segments of the {\sc Pslg} are constraints that will be + represented by a union of edges in the mesh. The {\sc Pslg} can also + contain isolated points that will appear as vertices of the mesh. + +The segments of the {\sc Pslg} are either segments of the +boundary or internals constraints. The segments of the {\sc Pslg} have to +cover the boundary of the domain. + +The {\sc Pslg} divides the plane into several connected components. By +default, the domain is the union of the bounded connected components. The +user can override this default by providing a set of seed points. Either +seed points mark components to be meshed or they mark components not to be +meshed (holes). + +See figures~\ref{Domain} and~\ref{Domain-mesh} for an example of a domain +defined without using seed points, and a possible mesh of it. See +figure~\ref{Domain-seeds} for another domain defined with the same {\sc + Pslg} and two seed points used to define holes. +In the corresponding mesh (figure~\ref{Domain-seeds-mesh}), these +two holes are triangulated but not meshed. + +\begin{figure}[htbp] +\begin{center} +\begin{ccTexOnly} +\includegraphics[width=8cm]{Mesh_2/domain} +\end{ccTexOnly} +\begin{ccHtmlOnly} + +\end{ccHtmlOnly} +\end{center} +\caption{A domain defined without seed points.} +\label{Domain} +\end{figure} + +\begin{figure}[htbp] +\begin{center} +\begin{ccTexOnly} +\includegraphics[width=8cm]{Mesh_2/domain-mesh} +\end{ccTexOnly} +\begin{ccHtmlOnly} + +\end{ccHtmlOnly} +\end{center} +\caption{A mesh of the domain defined without seed points.} +\label{Domain-mesh} +\end{figure} + +\begin{figure}[htbp] +\begin{center} +\begin{ccTexOnly} +\includegraphics[width=8cm]{Mesh_2/domain-seeds} +\end{ccTexOnly} +\begin{ccHtmlOnly} + +\end{ccHtmlOnly} +\end{center} +\caption{A domain with two seeds points defining holes.} +\label{Domain-seeds} +\end{figure} + +\begin{figure}[htbp] +\begin{center} +\begin{ccTexOnly} +\includegraphics[width=8cm]{Mesh_2/domain-seeds-mesh} +\end{ccTexOnly} +\begin{ccHtmlOnly} + +\end{ccHtmlOnly} +\end{center} +\caption{A mesh of the domain with two seeds defining holes.} +\label{Domain-seeds-mesh} +\end{figure} + +\subsection{Shape and Size Criteria} +\label{sec:Mesh_2_criteria} + +The shape criterion for triangles is a lower bound $B$ on the ratio +between the circumradius and the shortest edge length. Such a bound +implies a lower bound of $\arcsin{\frac{1}{2B}}$ on the minimum angle +of the triangle and an upper bound of $\pi - 2* \arcsin{\frac{1}{2B}}$ +on the maximum angle. Unfortunately, the termination of the algorithm +is guaranteed only if $B \ge \sqrt{2}$, which corresponds to a lower +bound of $20.7$~degrees over the angles. + +The size criterion can be any criterion that tends to prefer small +triangles. For example, the size criterion can be an upper bound on the +length of longest edge of triangles, or an upper bound on the radius of the +circumcircle. The size bound can vary over the domain. For example, +the size criterion could impose a small size for the triangles intersecting +a given line. + +Both types of criteria are defined in an object \ccc{criteria} passed as +parameter of the meshing functions. + +\subsection{The Meshing Algorithm} + +The input to a meshing problem is a {\sc Pslg} and a set of seeds +describing the domain to be meshed, and a set of size and shape +criteria. The algorithm implemented in this package starts with a +constrained Delaunay triangulation of the input {\sc Pslg} and produces a +mesh using the Delaunay refinement method. This method inserts new vertices to +the triangulation, as far as possible from other vertices, and stops when the +criteria are satisfied. + +If all angles between incident segments of the input {\sc Pslg} +are greater than $60$~degrees and if the bound on the +circumradius/edge ratio is greater than $\sqrt{2}$, +the algorithm is guaranteed to terminate with a mesh +satisfying the size and shape criteria. + +If some input angles are smaller than $60$~degrees, the algorithm will +end up with a mesh in which some triangles violate the criteria near small +input angles. This is unavoidable since small angles formed +by input segments cannot be suppressed. Furthermore, it has been +shown (\cite{s-mgdsa-00}), that some domains with small input angles +cannot be meshed with angles even smaller than the small input angles. +Note that if the domain is a polygonal region, the resulting mesh will +satisfy size and shape criteria except for the small input angles. +In addition, the algorithm may succeed in producing meshes with a lower +angle bound greater than $20.7$~degrees, but there is no such guarantee. + +\subsection{Building Meshes} +\label{sec:Mesh_2_building_meshes} + +Meshes are obtained from +constrained Delaunay triangulations by calling the global function \\ +\ccc{template void refine_Delaunay_mesh_2 (CDT + &t, typename CDT::Geom_traits gt)}. \\ +The template parameter \ccc{CDT} must be instantiated by a constrained +Delaunay triangulation class, which is a model of the concept +\ccc{ConstrainedDelaunayTriangulation_2}. In order to override the domain, +a version of this function has two more arguments that define a sequence of +seed points. + +The geometric traits class of \ccc{CDT} has to be a +model of the concept \ccc{DelaunayMeshTraits_2}. This concept +refines the concept \ccc{ConformingDelaunayTriangulationTraits_2} +adding the geometric predicates and constructors. The template parameter +\ccc{Criteria} must be a model of \ccc{MeshingCriteria_2}. This concept +defines criteria that the triangles have to satisfy. +\cgal\ provides two models for this concept: +\begin{itemize} +\item \ccc{Delaunay_mesh_criteria_2}, that defines a shape criterion + that bounds the minimum angle of triangles, +\item \ccc{Delaunay_mesh_size_criteria_2}, that adds to the previous +criterion a bound on the maximum edge length. +\end{itemize} + +If the function \ccc{refine_Delaunay_mesh_2} is called several times on the +same triangulation with different criteria, the algorithm rebuilds the +internal data structure used for meshing at every call. In order to avoid +rebuild the data structure at every call, the advanced user can +use the class \ccc{Delaunay_mesher_2}. This class provides also step +by step functions. Those functions insert one vertex at a time. + +Any object of type \ccc{Delaunay_mesher_2} is constructed from a +reference to a \ccc{CDT}, and has several member functions to define the +domain to be meshed and to mesh the \ccc{CDT}. See the example given below +and the reference manual for details. Note that the \ccc{CDT} should not be +externally modified during the life time of the \ccc{Delaunay_mesher_2} +object. + +\subsection{Example Using the Global Function} + +The following example inserts several segments into a constrained +triangulation and then meshes it using the global function +\ccc{refine_Delaunay_mesh_2}. The size and shape criteria are the default ones +provided by the criteria class \ccc{Delaunay_mesh_criteria_2}. No seeds are +given, meaning that the mesh domain covers the whole plane except the +unbounded component. + +\ccIncludeExampleCode{Mesh_2/mesh_global.C} + +\subsection{Example Using the Class \protect\ccc{Delaunay_mesher_2}} + +This example uses the class \ccc{Delaunay_mesher_2} and calls + the \ccc{refine_mesh()} member function twice, changing the size and + shape criteria in between. In such a case, using twice the global + function \ccc{refine_Delaunay_mesh_2} would be less efficient, + because some internal structures needed by the algorithm would be + built twice. + +\ccIncludeExampleCode{Mesh_2/mesh_class.C} + +\subsection{Example Using Seeds} + +This example uses the global function \ccc{refine_Delaunay_mesh_2} but +defines a domain by using one seed. The size and shape criteria are the +default ones provided by the criteria class \ccc{Delaunay_mesh_criteria_2}. + +\ccIncludeExampleCode{Mesh_2/mesh_with_seeds.C} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/ConformingDelaunayTriangulationTraits_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/ConformingDelaunayTriangulationTraits_2.tex new file mode 100644 index 00000000000..dd9600803fe --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/ConformingDelaunayTriangulationTraits_2.tex @@ -0,0 +1,72 @@ +\begin{ccRefConcept}{ConformingDelaunayTriangulationTraits_2} + +\ccDefinition + +The concept \ccRefName\ refines the concept +\ccc{ConstrainedDelaunayTriangulationTraits_2} by providing a numeric +field type \ccc{FT}, a type \ccc{Vector_2} and several constructors on +\ccc{Vector_2}, \ccc{Point_2}, and a predicate on angles. +The field type has to be a model of +the concept \ccc{SqrtFieldNumberType}. This field type and the +constructors are used by the conforming algorithm to compute Steiner +points on constrained edges. + +\ccRefines + +\ccc{DelaunayTriangulationTraits_2} + +\ccTypes + +\ccNestedType{FT}{The field type. It must be a model of + \ccc{SqrtFieldNumberType}, that is must be a number type + supporting the operations $+$, $-$, $*$, $/$, and $\sqrt{\cdot}$.} +\ccNestedType{Vector_2}{The vector type.} +\ccNestedType{Construct_vector_2}{Constructor object. Must + provide the operator \ccc{Vector_2 operator()(Point a, Point b)} + that computes the vector $b-a$.} +\ccNestedType{Construct_scaled_vector_2}{Constructor object. Must + provide the operator \ccc{Vector_2 operator()(Vector_2 v, FT scale)} + that computes the vector $scale \cdot \mathbf{v}$.} +\ccNestedType{Construct_translated_point_2}{Constructor object. Must + provide the operator \ccc{Point_2 operator()(Point_2 p, Vector_2 v)} + that computes the point $p + \mathbf{v}$.} +\ccNestedType{Construct_midpoint_2}{Constructor object. Must provide + the operator \ccc{Point_2 operator()(Point_2 a, Point_2 b)} that + computes the midpoint of the segment $ab$.} +\ccNestedType{Compute_squared_distance_2}{Constructor object. Must + provide the operator \ccc{FT operator()(Point_2 a, Point_2 b)} that + computes the squared distance between $a$ and $b$.} +\ccNestedType{Angle_2}{Predicate object. Must provide the operator + \ccc{CGAL::Angle operator()(Point_2 p, Point_2 q, Point_2 r)} that + returns OBTUSE, RIGHT or ACUTE depending on the angle formed by the three + points p, q, r (q being the vertex of the angle).} + +\ccCreationVariable{traits} + +\ccHeading{Access to predicate and constructor objects} + +\ccThree{Construct_translated_point_2xx}{construct_translated_point_2_object()}{} +\ccMethod{Construct_vector_2 construct_vector_2_object();}{} +\ccGlue +\ccMethod{Construct_scaled_vector_2 construct_scaled_vector_2_object();}{} +\ccGlue +\ccMethod{Construct_translated_point_2 + construct_translated_point_2_object();}{} +\ccGlue +\ccMethod{Constructor_midpoint_2 construct_midpoint_2_object();}{} +\ccGlue +\ccMethod{Compute_squared_distance_2 + compute_squared_distance_2_object();}{} +\ccGlue +\ccMethod{Angle_2 angle_2_object();}{} + +\ccHasModels +Any model of \ccc{Kernel} concept. In particular, all CGAL kernels. + +\end{ccRefConcept} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/DelaunayMeshFaceBase_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/DelaunayMeshFaceBase_2.tex new file mode 100644 index 00000000000..f3602f53c6e --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/DelaunayMeshFaceBase_2.tex @@ -0,0 +1,32 @@ +\begin{ccRefConcept}{DelaunayMeshFaceBase_2} + +\ccDefinition + +The concept \ccRefName\ refines the concept + \ccc{TriangulationFaceBase_2}. It adds two functions giving access + to a boolean marker, that indicates if the face is in the + meshing domain or not. + +\ccRefines +\ccc{ConstrainedTriangulationFaceBase_2} + +\ccCreationVariable{f} + +\ccAccessFunctions + +\ccMethod{ bool is_in_domain() const;} +{ returns true if this face is in the domain to be refined.} + +\ccMethod{ void set_in_domain(const bool b);} +{ sets if this face is in the domain. } + +\ccHasModels +\ccc{Delaunay_mesh_face_base_2} + +\end{ccRefConcept} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/DelaunayMeshTraits_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/DelaunayMeshTraits_2.tex new file mode 100644 index 00000000000..b8a7b98cf54 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/DelaunayMeshTraits_2.tex @@ -0,0 +1,39 @@ +\begin{ccRefConcept}{DelaunayMeshTraits_2} + +\ccDefinition + +The concept \ccRefName\ refines the concept +\ccc{ConformingDelaunayTriangulationTraits_2}. It provides a construction +object \ccc{Construct_circumcenter_2}. + +\ccRefines + +\ccc{ConformingDelaunayTriangulationTraits_2} + +\ccTypes + +\ccNestedType{Construct_circumcenter_2} {Constructor object. Must provide + an operator \ccc{Point_2 operator()(Point_2 p, + Point_2 q, + Point_2 r);} + that computes the center of the circle passing through the points $p$, + $q$ and $r$. + \ccPrecond $p$, $q$ and $r$ are not collinear.} + +\ccCreationVariable{traits} + +\ccHeading{Access to predicate and constructor objects} + +\ccThree{Construct_circumcenter_2xx}{construct_circumcenter_2_object();}{} +\ccMethod{Construct_circumcenter_2 construct_circumcenter_2_object();}{} + +\ccHasModels +Any model of the \ccc{Kernel} concept. In particular, all CGAL kernels. + +\end{ccRefConcept} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_criteria_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_criteria_2.tex new file mode 100644 index 00000000000..33c7cc4de80 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_criteria_2.tex @@ -0,0 +1,34 @@ +\begin{ccRefClass}{Delaunay_mesh_criteria_2} + +\ccCreationVariable{traits} +\ccDefinition + +The class \ccRefName\ is a model for the \ccc{MeshingCriteria_2} concept. +The shape criterion on triangles is given by a bound $B$ such that for good +triangles $\frac{r}{l} \le B$ where $l$ is the shortest edge length +and $r$ is the circumradius of the triangle. By default, $B=\sqrt{2}$, +which is the best bound one can use with the guarantee that the refinement +algorithm will terminate. The upper bound $B$ is related to a lower bound +$\alpha_{min}$ on the minimum angle in the triangle: +\begin{displaymath} + \sin{ \alpha_{min} } = \frac{1}{2 B} +\end{displaymath} +so $B=\sqrt{2}$ corresponds to $\alpha_{min} \ge 20.7$ degrees. + +\ccInclude{CGAL/Delaunay_mesh_criteria_2.h} + +\ccIsModel + +\ccc{MeshingCriteria_2} + +\ccCreation +\ccConstructor{Delaunay_mesh_criteria_2()}{Default constructor. $B=\sqrt{2}$.} +\ccConstructor{Delaunay_mesh_criteria_2(double b = 0.125)}{Construct + a traits class with bound $B=\sqrt{\frac{1}{4 b}}$.} +\end{ccRefClass} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_face_base_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_face_base_2.tex new file mode 100644 index 00000000000..196f143e4ae --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_face_base_2.tex @@ -0,0 +1,33 @@ +\begin{ccRefClass}{Delaunay_mesh_face_base_2} + +\ccDefinition + +The class \ccRefName\ is a model for the concept +\ccc{DelaunayMeshFaceBase_2}. + +This class can be used directly or it can serve as a base to derive other +classes with some additional attributes (a color for example) tuned to a +specific application. + +\ccInclude{CGAL/Delaunay_mesh_face_base_2.h} + +\ccParameters + +\begin{itemize} +\item The first parameter \ccc{Traits} is the geometric traits class. It must + be the same as the one used for the Delaunay mesh. +\item The second parameter \ccc{Fb} is the base class from which \ccRefName\ + derives. It must be a model of the \ccc{TriangulationFaceBase_2} concept. +\end{itemize} +\ccInheritsFrom +\ccc{Fb} + +\ccIsModel +\ccc{DelaunayMeshFaceBase_2} +\end{ccRefClass} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_size_criteria_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_size_criteria_2.tex new file mode 100644 index 00000000000..f5d38d965f7 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesh_size_criteria_2.tex @@ -0,0 +1,41 @@ +\begin{ccRefClass}{Delaunay_mesh_size_criteria_2} + +\ccCreationVariable{traits} +\ccDefinition + +The class \ccRefName\ is a model for the \ccc{MeshingCriteria_2} concept. +The shape criterion on triangles is given by a bound $B$ such that for good +triangles $\frac{r}{l} \le B$ where $l$ is the shortest edge length +and $r$ is the circumradius of the triangle. By default, $B=\sqrt{2}$, +which is the best bound one can use with the guarantee that the refinement +algorithm will terminate. The upper bound $B$ is related to a lower bound +$\alpha_{min}$ on the minimum angle in the triangle: +\begin{displaymath} + \sin{ \alpha_{min} } = \frac{1}{2 B} +\end{displaymath} +so $B=\sqrt{2}$ corresponds to $\alpha_{min} \ge 20.7$ degrees. + +This traits class defines also a size criteria: all segments of all +triangles must be shorter than a bound $S$. + +\ccInclude{CGAL/Delaunay_mesh_size_criteria_2.h} + +\ccIsModel + +\ccc{MeshingCriteria_2} + +\ccCreation +\ccConstructor{Delaunay_mesh_size_criteria_2()}{Default + constructor. $B=\sqrt{2}$. No bound on size} +\ccConstructor{Delaunay_mesh_size_criteria_2(double b = 0.125, double S = + 0)}{Construct a traits class with bound $B=\sqrt{\frac{1}{4 + b}}$. If $S \neq 0$, the size bound is $S$. If $S = 0$, there is + no bound on size. } + +\end{ccRefClass} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesher_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesher_2.tex new file mode 100644 index 00000000000..c9e02f950dd --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/Delaunay_mesher_2.tex @@ -0,0 +1,154 @@ +\begin{ccRefClass}{Delaunay_mesher_2} + +This class implements a 2D mesh generator. + +\ccParameters The template parameter \ccc{CDT} should be a model of the +concept \ccc{ConstrainedDelaunayTriangulation_2}, and type \ccc{CDT::Face} +should be a model of the concept \ccc{MeshFaceBase_2}. + +The geometric traits class of the instance of \ccc{CDT} has to be +a model of the concept \ccc{DelaunayMeshTraits_2}. + +The template parameter \ccc{Criteria} should be a model of the concept +\ccc{MeshingCriteria_2}. This traits class defines the shape and size +criteria for the triangles of the mesh. \ccc{Criteria::Face_handle} has to +be the same as \ccc{CDT::Face_handle}. + +\ccHeading{Using this class} + +The constructor of the class \ccRefName{} takes a reference to a \ccc{CDT} +as an argument. A call to the refinement method \ccc{refine_mesh()} will +refine the constrained Delaunay triangulation into a mesh satisfying the +size and shape criteria specified in the traits class. Note that if, during +the life time of the \ccRefName\ object, the triangulation is externally +modified, any further call to its member methods may crash. Considere +constructing a new \ccRefName\ object if the triangulation has been +modified. + +\ccHeading{Meshing domain} + +The domain to be mesh is defined by the constrained edges and a set of seed +points. The constrained edges divides the plane into several connected +components. The mesh domain is either the union of the bounded connected +components including at least one seed, or the union of the bounded +connected components that do no contain any seed. Note that the unbounded +component of the plane is never meshed. + +\ccInclude{CGAL/Delaunay_mesher_2.h} + +\ccTypes +\ccTypedef{typedef CDT::Geom_traits Geom_traits;}{the geometric traits class.} +\ccNestedType{Seeds_iterator}{const iterator over defined seeds. Its + value type is \ccc{Geom_traits::Point_2}.} + +\ccCreation +\ccCreationVariable{mesher} + +\ccConstructor{Delaunay_mesher_2(CDT& t, Criteria criteria = Criteria());} +{Create a new mesher, working on \ccc{t}, with meshing criteria + \ccc{criteria}.} + +\ccHeading{Seeds functions} + +The following functions are used to define seeds. + +\ccMethod{void clear_seeds ();}{ Sets seeds to the empty set. All + finite connected components of the constrained triangulation will be + refined.} + +\ccMethod{template + void set_seeds(InputIterator begin, InputIterator end, + const bool mark=false);} + { Sets seeds to the sequence [\ccc{begin}, + \ccc{end}]. If \ccc{mark=true}, the mesh domain + is the union of the bounded connected + components including at least one seed. If + \ccc{mark=false}, the domain is the union of + the bounded components including no seed. Note + that the unbounded component of the plane is + never meshed. + \ccRequire The \ccc{value_type} of + \ccc{begin} and \ccc{end} is + \ccc{Geom_traits::Point_2}.} + +\ccMethod{Seeds_const_iterator seeds_begin () const;} +{ Start of the seeds sequence. } +\ccGlue +\ccMethod{Seeds_const_iterator seeds_end () const;} +{ Past the end of the seeds sequence. } + +\ccHeading{Meshing methods} + +\ccMethod{void refine_mesh(); } +{ Refines the constrained Delaunay triangulation into a mesh + satisfying the criteria defined by the traits. +} + +\ccMethod{ const Criteria& get_criteria();} +{ Returns a const reference to the criteria traits object. } + +\ccMethod{ void set_criteria(Criteria criteria);} +{ Assigns \ccc{criteria} to the criteria traits object. } + +\begin{ccAdvanced} + The function \ccc{set_criteria} scans all faces to recalculate the list of + \emph{bad faces}, that are faces not conforming to the meshing criteria. + This function actually has an optional argument that permits to prevent + this recalculation. The filling of the list of bad faces can then be done + by a call to \ccc{set_bad_faces}. + + \ccMethod{ void set_criteria(Criteria criteria, bool + recalculate_bad_faces);} + { Assigns \ccc{criteria} to the criteria traits object. If + \ccc{recalculate_bad_faces} is \ccc{false}, the list of bad faces is + let empty and the function \ccc{set_bad_faces} should be called before + \ccc{refine_mesh}.} + +\ccMethod{template + void set_bad_faces(InputIterator begin, + InputIterator end);} + { This method permits to set the list of bad triangles + directly, from the sequence [begin, end], so that the + algorithm will not scan the whole set of triangles to + find bad ones. To use if there is a non-naive way to + find bad triangles. \ccRequire The \ccc{value_type} + of \ccc{begin} and \ccc{end} is \ccc{Face_handle}.} + +\end{ccAdvanced} + + +\begin{ccAdvanced} +\ccHeading{Step by step operations} + +The \ccRefName{} class allows, for debugging or demos, to play the +meshing algorithm step by step, using the following methods. + +\ccMethod{ void init(); } + { This method must be called just before the first + call to the following step by step refinement method, + that is when all vertices and constrained edges have been + inserted into the constrained Delaunay triangulation. It + must be called again before any subsequent calls to the + step by step refinement method if new vertices or constrained + edges have been inserted since the last call.} + +\ccMethod{bool is_refinement_done(); } +{ Tests if the step by step refinement algorithm is done. If it returns + \ccc{true}, the following calls to \ccc{step_by_step_refine_mesh} will + not insert any points, until some new constrained segments or points are + inserted in the triangulation and \ccc{init} is called again. } + +\ccMethod{ bool step_by_step_refine_mesh(); } +{ Applies one step of the algorithm, by inserting one point, if the + algorithm is not done. Returns \ccc{false} iff no point has been inserted + because the algorithm is done. } + +\end{ccAdvanced} + +\end{ccRefClass} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/Face_badness.tex b/Mesh_2/doc_tex/Mesh_2_ref/Face_badness.tex new file mode 100644 index 00000000000..37a1344e2e9 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/Face_badness.tex @@ -0,0 +1,12 @@ +\begin{ccRefEnum}{Mesh_2::Face_badness} +\ccInclude{CGAL/Mesh_2/Face_badness.h} + +\ccGlobalEnum{enum Mesh_2::Face_badness { NOT_BAD, BAD, IMPERATIVELY_BAD }; } +\ccRefLabel{NOT_BAD} +\ccRefLabel{IMPERATIVELY_BAD} +\ccRefLabel{BAD} +\ccHtmlCrossLink{NOT_BAD} +\ccHtmlCrossLink{IMPERATIVELY_BAD} +\ccHtmlCrossLink{BAD} + +\end{ccRefEnum} diff --git a/Mesh_2/doc_tex/Mesh_2_ref/Mesher_level.tex b/Mesh_2/doc_tex/Mesh_2_ref/Mesher_level.tex new file mode 100644 index 00000000000..d9a3060c3a0 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/Mesher_level.tex @@ -0,0 +1,302 @@ +% +------------------------------------------------------------------------+ +% | Reference manual page: Mesher_level.tex +% +------------------------------------------------------------------------+ +% | 21.07.2005 Author +% | Package: Package +% | +\RCSdef{\RCSMesherlevelRev}{$Id$} +\RCSdefDate{\RCSMesherlevelDate}{$Date$} +% | +%%RefPage: end of header, begin of main body +% +------------------------------------------------------------------------+ + + +\begin{ccRefClass}{Mesher_level_base} %% 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 generic class +that helps to implement meshing algorithms +based on Delaunay refinement. +Typically, a Delaunay refinement algorithm +involves not only the refinement of the mesh cells +but also the refinements of lower dimensional mesh elements +which represents constaints including e.g. +the boundary of the domain to be meshed. +Such a process can be seen +as a cascade of processes called mesher level where each level +handles the refinement of elements of a given dimension. +The class \ccRefName\ is intended to provide a generic implementation +of a mesher level. +For example, a 3D mesh generator taking into account +constrained facets (that is 2dimensional constraints) +and edges (1-dimensional constraints) will involve +three instances of \ccRefName\ . +The class \ccRefName\ +is designed to serve as the base class +in a CRTP (curiously recurent template pattern ). +It captures what can be seen as the commmon functionalities +of mesher levels, deferring the detailed implementation +of elememtary operations to its derived classes. + + +\ccInclude{CGAL/Mesher_level_base.h} + +\ccParameters +The class \ccRefName\ has five template parameters: \\ +- The parameter \ccc{Tr} is the type of the triangulation underlying + the refinement process. It must be a model of the concept + \ccc{MeshTriangulation}.\\ +- The parameter \ccc{Mesher_level} stands for the derived class +in the CRTP pattern. This classes provides the implementation +of basic operation in the refinement pocess and will be the actual +mesher level used by the meshing application. +It must be a model of the concept \ccc{MesherLevel} \\ +- The parameter \ccc{Element} is the type of mesh elements +refined at this level refines. It is a model of the concept +\ccc{MeshElement} for which there is no requirements.. +- The parameter \ccc{Lower} stands for the next lower mesher level + in the cascade, handling refinement of lower dimensional mesh +elements. It is a model of the concept +\ccc{LowerMesherLevel} which is just a subconcept of +\ccc{MesherLevel}.\\ +- The parameter \ccc{Tr_traits} provides some types related +to the triangulation and in particular the type \ccc{Zone} + It is a model of the concept \ccc{xxx}. + +%\ccIsModel + +%Concept + + +\ccTypedef{typedef Tr Triangulation;} +{The type of the underlying triangulation.} +\ccGlue +\ccTypedef{typedef Tr::Point Point;} +{The type of points inserted into the triangulation.} +\ccGlue +\ccTypedef{typedef Tr::Vertex_handle Vertex_handle;} +{ The vertex handles of the triangulation.} +\ccGlue +\ccTypedef{typedef Tr_traits::Zone Zone;} +{A type describing the conflict zone of a query point in the triangulation, +i.e. the set of elements that would disappear if the query point is +inserted. +} + +XXXXXXXXXX +Suggestion: Having a templated \ccc{Triangulation_traits} + \ccc{template< class Tr> +Triangulation_traits} +with a default parameter \ccc{Triangulation_traits} +for the fifth parameter of \ccc{Mesher_level} +xxxxxxxxxxxxxxxxxxxxxxx + +%\ccNestedType{TYPE}{some nested types} + +\ccCreation +\ccCreationVariable{ml} %% choose variable name + +\ccConstructor{Mesher_level(Lower& lower);} +{Construct a mesher level with \ccc{previous} as previous +(lower dimensional) mesher level.} + + + +\ccHeading{Methods for handling the meshing process} +The following functions use the functions that are implemented in +the derived classes. + +\ccMethod{void scan_triangulation();} + { Called before the first refinement, to initialized the queue of + elements that should be refined.} + + + + +\ccMethod { template + void refine(Mesh_visitor& visitor);} +{ Performs the refinement;} + + +%All these commented function should appear +%under their impl form in the concept for ``Mesher level'' + + +%\ccMethod{ bool no_longer_element_to_refine();} +% { Returns \ccc{true} when there is no \ccc{Element} +% to be refined in this level.} + +%\ccMethod { template +% bool process_one_element(Mesh_visitor& visitor);} +%{ Get the next elements from the queue of to be refined elements +%and try to refine it. Returns \ccc{true} if one point has been inserted.} + +%\ccMethod { +% template +% Mesher_level_conflict_status +% try_to_refine_element(Element e, Mesh_visitor& visitor);} +% {Try to refine element \ccc{e}.} + + +%\ccMethod { Element get_next_element();} +%{ Retrieves the next element that could be refined.} + +%\ccMethod { void pop_next_element();} +%{Remove from the list of to be refined elements +%the next element that could be refined.} + + +%\ccMethod { Point refinement_point(const Element& e);} +%{Compute the point that should be inserted to refine the element \ccc{e}} + +%XXXXXX il y a trop de conflits et ils devraient etre definis. +%Les conflits de " \ccc{conflicts_zone} " ne sont pas les memes que celles des +%\ccc{test_point_conflict} XXXXXXXXXXXXX + + +%\ccMethod{ Zone conflicts_zone(const Point& p, Element e);} +% {Returns the conflict zone of \ccc{p} starting from the +% mesh element \ccc{e}. +% \ccPrecond{ \ccc{e} is assumed to be in conflict with \ccc{p}.}} + +%\ccMethod { Mesher_level_conflict_status +% private_test_point_conflict(const Point& p, Zone& zone);} +%{ Tells if, as regards this level of the refinement process, the +% point \ccc{p} with conflict zone \ccc{zone} may be inserted. +% The return type is made of two booleans: +% - the first one tells if the point can be inserted, +% - in case of, the first one is \ccc{false}, the second one tells if +% the tested element should be reconsidered latter..} + + +%\ccMethod { +% Mesher_level_conflict_status +% test_conflict_from_higher(const Point& p, +% Zone& zone);} +%{ Tells if, as regards this level of the refinement process, the +% point \ccc{p}, +% constructed as the refinement point of an element of +% higher dimension, may be inserted. +% \ccPrecond{The argument \ccc{zone} +% is the connflict zone of \ccc{p}.}} +% The return type is a +% \ccc{Mesher_level_conflict_status} +% telling if +% - the point can be inserted, +% - the point cannot be inserted but the element +% that would be refined by this point has to be reconsidered latter. +% - the point cannot be inserted and the element +% that would be refined by this point has to be dropped. + + +%\ccMethod{ Vertex_handle insert(Point p, Zone& z);} +% { Insertion of point \ccc{p} as a new vertex. +% \ccc{z} is assumed to be the precomputed conflict zone of +% \ccc{p}.} + + + + + + + + +\ccHeading{ Helping methods to maintain the data structures} + +\ccMethod{Triangulation& triangulation();}{Access to the triangulation.} +\ccGlue +\ccMethod{const Triangulation& triangulation();} + {Const access to the triangulation.} + +\ccMethod{ + template + void before_conflicts(const Element& e, const Point& p, + Mesh_visitor& visitor);} +{Actions to be performed before testing conflicts +for point \ccc{p} and element \ccc{e}.} + + +\ccMethod{ template + void before_insertion(Element& e, const Point& p, Zone& zone, + Mesh_visitor& visitor);} +{ + Actions before inserting the point \ccc{p} in order to refine the + element \ccc{e}. + \ccPrecond{The zone of conflicts of \ccc{p} is \ccc{zone}}.} + + + \ccMethod{template + void after_insertion(Vertex_handle vh, Mesh_visitor& visitor);} +{ Actions to be performed after insertion of a point. + \ccc{vh} is the Vertex handle returned by the insertion +and visitor is the visitor.} + + \ccMethod{ template + void after_no_insertion(const Element& e, const Point& p, Zone& zone, + Mesh_visitor& visitor);} +{ Actions to be performed when point \ccc{p} + with conflict zone \ccc{zone} has been tested for insertion and +rejected, meaning that ni insertion took place.} + + + +\begin{ccAdvanced} +\ccHeading{ Method for step by step advance of the meshing} + + \ccMethod{ template + bool try_to_insert_one_point(Mesh_visitor& visitor);} + {Inserts exactly one new vertex in the mesh and returns \ccc{true} + exept when the algorithm is done, in which case no point is inserted +and \ccc{false} is returned.} +\ccGlue + \ccMethod{template + bool one_step(Mesh_visitor& visitor);} + {Applies one step of the algorithm, i. e.tries to refine one element of + lower levels or one element of this level. Returns \c false iff + \ccc{is_algorithm_done()==true}. } + +\ccMethod { bool is_algorithm_done();} +{Returns \ccc{true} when there is no more elements to refine +in this mesher level and in all the cascaded previous levels.} + +\end{ccAdvanced} + + + + + + + +\ccSeeAlso + +\ccc{Some_other_class}, +\ccc{some_other_function}. + +\ccExample + +A short example program. +Instead of a short program fragment, a full running program can be +included using the +\verb|\ccIncludeExampleCode{Package/Mesher_level.C}| +macro. The program example would be part of the source code distribution and +also part of the automatic test suite. + +\begin{ccExampleCode} +void your_example_code() { +} +\end{ccExampleCode} + +%% \ccIncludeExampleCode{Package/Mesher_level.C} + +\end{ccRefClass} + +% +------------------------------------------------------------------------+ +%%RefPage: end of main body, begin of footer +% EOF +% +------------------------------------------------------------------------+ + diff --git a/Mesh_2/doc_tex/Mesh_2_ref/MeshingCriteria_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/MeshingCriteria_2.tex new file mode 100644 index 00000000000..9b5341d8e0a --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/MeshingCriteria_2.tex @@ -0,0 +1,79 @@ +\begin{ccRefConcept}{MeshingCriteria_2} + +\ccDefinition + +The concept \ccRefName\ defines the meshing criteria to be used in the +algorithm. It provides a predicate \ccc{Is_bad} that tests a triangle +according to criteria. The return type of \ccc{Is_bad} is an enum +\ccc{Mesh_2::Face_badness}. + +The possible values of \ccc{Mesh_2::Face_badness} are \ccc{NOT_BAD}, +\ccc{BAD} and \ccc{IMPERATIVELY_BAD}. If the predicate returns \ccc{BAD}, +the triangle is marked as bad and the algorithm will try to destroy it. If +the predicates returns \ccc{IMPERATIVELY_BAD}, the algorithm will destroy +the triangle unconditionally during its execution. + +The termination of the algorithm is guaranteed when criteria are shape +criteria corresponding to a bound on smallest angles not less than +$20.7$ degrees (this corresponds to a radius-edge ratio bound not less +than $\sqrt{2}$). Any size criteria that are satisfied by small enough +tetrahedra can be added to the set of criteria without compromising +the termination. + +Note that, in the presence of input angles smaller than $60$~degrees, +some bad shaped triangles can appear in the finale mesh in the +neighboring of small angles. To achieve termination and the respect of +size criteria everywhere, the \ccc{Is_bad} predicate has to return +\ccc{IMPERATIVELY_BAD} when size criteria are not satisfied, and +\ccc{BAD} when shape criteria are not satisfied. + +% \ccc{IMPERATIVELY_BAD} +% If some input angles are smaller than $60$~degrees, some triangles that do +% not satisfy the criteria could be not destroyed, with guarantees that the +% algorithm will terminate. This predicate should not returns +% \ccc{IMPERATIVELY_BAD} if the only reasons for the triangle to be destroyed +% are shapes criteria. The use of \ccc{IMPERATIVELY_BAD} should be restricted +% to other criteria, such as size criteria. + +\ccRefName\ also provides a type \ccc{Quality} designed to code a quality +measure for triangles. The type \ccc{Quality} must be \emph{less-than + comparable} as the meshing algorithm will order bad triangles by quality, +to split those with smallest quality first. The predicate \ccc{Is_bad} +computes the quality of the triangle as a by-product. + +\ccTypes + +\ccNestedType{Face_handle}{Handle to a face of the triangulation.} + +\ccNestedType{Quality}{Default constructible, copy constructible, + assignable, and less-than comparable type.} + +\ccNestedType{Is_bad} {Predicate object. Must provide two operators. The + first operator \ccc{Mesh_2::Face_badness operator()(Face_handle fh, + Quality& q)} returns \ccc{NOT_BAD} if it satisfies the desired criteria + for mesh triangles, \ccc{BAD} if it does not, and \ccc{IMPERATIVELY_BAD} + if it does not and should be refined unconditionally. In addition, this + operator assigns to \ccc{q} a value measuring the quality of the triangle + pointed by \ccc{fh}. The second operator \ccc{Mesh_2::Face_badness + operator()(Quality q)} returns \ccc{NOT_BAD} if \ccc{q} is the quality + of a good triangle, \ccc{BAD} if the \ccc{q} represents a poor quality, + and \ccc{IMPERATIVELY_BAD} if \ccc{q} represents the quality of a bad + triangle that should be refined unconditionally.} + +\ccCreationVariable{traits} + +\ccHeading{Access to predicate and constructor objects} + +\ccMethod{Is_bad is_bad_object();}{} + +\ccHasModels +\ccc{Delaunay_mesh_criteria_2}\\ +\ccc{Delaunay_mesh_size_criteria_2} + +\end{ccRefConcept} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/Triangulation_conformer_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/Triangulation_conformer_2.tex new file mode 100644 index 00000000000..0813a38af49 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/Triangulation_conformer_2.tex @@ -0,0 +1,115 @@ +\begin{ccRefClass}{Triangulation_conformer_2} + +The class \ccRefName{} is an auxiliary class of +\ccc{Delaunay_mesher_2}. It permits to refine a constrained +Delaunay triangulation into a conforming Delaunay or conforming +Gabriel triangulation. For standard needs, consider using the global +functions \ccc{make_conforming_Gabriel_2} and +\ccc{make_conforming_Delaunay_2}. + +\ccParameters + +The template parameter \ccc{CDT} should be a model of the concept +\ccc{ConstrainedDelaunayTriangulation_2}. + +The geometric traits class of the instance of \ccc{CDT} has to be +a model of the concept \ccc{ConformingDelaunayTriangulationTraits_2}. + +\ccHeading{Using this class} + +The constructor of the class \ccRefName\ takes a reference to a \ccc{CDT} +as an argument. A call to the method \ccc{make_conforming_Delaunay()} or +\ccc{make_conforming_Gabriel()} will refine this contrained Delaunay +triangulation into a conforming Delaunay or conforming Gabriel +triangulation. Note that if, during the life time of the \ccRefName\ +object, the triangulation is externally modified, any further call to its +member methods may lead to undefined behavior. Consider reconstructing a +new \ccRefName\ object if the triangulation has been modified. + +The conforming methods insert points into constrained edges, thereby splitting +them into several sub-constraints. You have access to the initial inserted +constraints if you instantiate the template parameter by a +\ccc{CGAL::Constrained_triangulation_plus_2}. + +\ccInclude{CGAL/Triangulation_conformer_2.h} + +\ccCreation +\ccCreationVariable{m} + +\ccConstructor{Triangulation_conformer_2(CDT& t);} +{Create a new conforming maker, working on \ccc{t}.} + +\ccOperations + +\ccHeading{Conforming methods} + +\ccMethod{ void make_conforming_Delaunay(); } +{ Refines the triangulation into a conforming Delaunay triangulation. + After a call to this method, all triangles fulfill the Delaunay property, + that is the empty circle + property. } + +\ccMethod{ void make_conforming_Gabriel(); } +{ Refines the triangulation into a conforming Gabriel triangulation. + After a call to this method, all constrained edges $e$ have the + \emph{Gabriel property}: the circle with diameter $e$ + does not contain any vertex of the triangulation. } + +\ccHeading{Checking} +The following methods verify that the constrained triangulation is +conforming Delaunay or conforming Gabriel. These methods scan the +whole triangulation and their complexity is proportional to the number +of edges. + +\ccMethod{ bool is_conforming_Delaunay(); } +{ Returns \ccc{true} iff all triangles fulfill the Delaunay property.} + +\ccMethod{ bool is_conforming_Gabriel(); } +{ Returns \ccc{true} iff all constrained edges have the Gabriel property: + their circumsphere is empty. } + +\begin{ccAdvanced} + +\ccHeading{Step by step operations} + +The \ccRefName{} class allows, for debugging or demos, to play the +conforming algorithm step by step, using the following methods. They exist +in two versions, depending on whether you want the triangulation to be +conforming Delaunay or conforming Gabriel, respectively. Any call to a +\ccc{step_by_step_conforming_XX} function requires a previous call to the +corresponding function \ccc{init_XX} and Gabriel and Delaunay methods can +not be mixed between two calls of \ccc{init_XX}. + +\ccMethod{ void init_Delaunay(); } +{ The method must be called after all points and constrained segments + are inserted and before any call to the following methods. If some + points or segments are then inserted in the triangulation, this + method must be called again. } + +\ccMethod{ bool step_by_step_conforming_Delaunay (); } +{ Applies one step of the algorithm, by inserting one point, if the + algorithm is not done. Returns \ccc{false} iff no point has been inserted + because the algorithm is done. } + +\ccMethod{ void init_Gabriel(); }{Analog to + \ccc{init_Delaunay} for Gabriel conforming.} + +\ccMethod{ bool step_by_step_conforming_Gabriel (); }{Analog to + \ccc{step_by_step_conforming_Delaunay()} for Gabriel conforming.} + +\ccMethod{ bool is_conforming_done(); } +{ Tests if the step by step conforming algorithm is done. If it + returns \ccc{true}, the following calls to + \ccc{step_by_step_conforming_XX} will not insert any points, until some + new constrained segments or points are inserted in the triangulation and + \ccc{init_XX} is called again. } + +\end{ccAdvanced} + +\end{ccRefClass} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/intro.tex b/Mesh_2/doc_tex/Mesh_2_ref/intro.tex new file mode 100644 index 00000000000..527b9094b3f --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/intro.tex @@ -0,0 +1,32 @@ +\ccRefChapter{2D Conforming Triangulations and Meshes} +\ccChapterAuthor{Laurent Rineau} + + +\section{Classified Reference Pages} + +\subsection*{Concepts} +\ccRefConceptPage{ConformingDelaunayTriangulationTraits_2}\\ +\ccRefConceptPage{DelaunayMeshTraits_2}\\ +\ccRefConceptPage{MeshingCriteria_2}\\ +\ccRefConceptPage{DelaunayMeshFaceBase_2}% + +\subsection*{Classes} +\ccRefIdfierPage{CGAL::Triangulation_conformer_2}\\ +\ccRefIdfierPage{CGAL::Delaunay_mesher_2}\\ +\ccRefIdfierPage{CGAL::Delaunay_mesh_face_base_2}\\ +\ccRefIdfierPage{CGAL::Delaunay_mesh_criteria_2}\\ +\ccRefIdfierPage{CGAL::Delaunay_mesh_size_criteria_2}\\ +\ccRefIdfierPage{CGAL::Mesh_2::Face_badness} \\ +%\ccRefIdfierPage{CGAL::Mesher_level}% + +\subsection*{Global functions} +\ccRefIdfierPage{CGAL::make_conforming_Delaunay_2}\\ +\ccRefIdfierPage{CGAL::make_conforming_Gabriel_2}\\ +\ccRefIdfierPage{CGAL::refine_Delaunay_mesh_2}% + + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/main.tex b/Mesh_2/doc_tex/Mesh_2_ref/main.tex new file mode 100644 index 00000000000..77cb00ac5bc --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/main.tex @@ -0,0 +1,25 @@ +% +------------------------------------------------------------------------+ +% | 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{Mesh_2_ref/intro.tex} + +\input{Mesh_2_ref/ConformingDelaunayTriangulationTraits_2.tex} +\input{Mesh_2_ref/DelaunayMeshFaceBase_2.tex} +\input{Mesh_2_ref/DelaunayMeshTraits_2.tex} +\input{Mesh_2_ref/Delaunay_mesher_2.tex} +\input{Mesh_2_ref/Delaunay_mesh_criteria_2.tex} +\input{Mesh_2_ref/Delaunay_mesh_face_base_2.tex} +\input{Mesh_2_ref/Delaunay_mesh_size_criteria_2.tex} +\input{Mesh_2_ref/Face_badness.tex} +\input{Mesh_2_ref/make_conforming_Delaunay_2.tex} +\input{Mesh_2_ref/make_conforming_Gabriel_2.tex} +%\input{Mesh_2_ref/Mesher_level.tex} +\input{Mesh_2_ref/MeshingCriteria_2.tex} +\input{Mesh_2_ref/refine_Delaunay_mesh_2.tex} +\input{Mesh_2_ref/Triangulation_conformer_2.tex} + +%% EOF diff --git a/Mesh_2/doc_tex/Mesh_2_ref/make_conforming_Delaunay_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/make_conforming_Delaunay_2.tex new file mode 100644 index 00000000000..b857fc1b754 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/make_conforming_Delaunay_2.tex @@ -0,0 +1,21 @@ +\begin{ccRefFunction}{make_conforming_Delaunay_2} + +\ccInclude{CGAL/Triangulation_conformer_2.h} + +\ccFunction{ template void make_conforming_Delaunay_2 (CDT &t); } +{ Refines the constrained Delaunay triangulation \ccc{t} into a + conforming Delaunay triangulation. After a call to this function, + all edges of \ccc{t} are Delaunay edges. + \ccRequire The template parameter \ccc{CDT} should be a model of the + concept \ccc{ConstrainedDelaunayTriangulation_2}. + The geometric traits class of into the constrained Delaunay + triangulation must be a model of + \ccc{ConformingDelaunayTriangulationTraits_2}.} + +\end{ccRefFunction} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/make_conforming_Gabriel_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/make_conforming_Gabriel_2.tex new file mode 100644 index 00000000000..dddce87c5a9 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/make_conforming_Gabriel_2.tex @@ -0,0 +1,22 @@ +\begin{ccRefFunction}{make_conforming_Gabriel_2} + +\ccInclude{CGAL/Triangulation_conformer_2.h} + +\ccFunction{ template void make_conforming_Gabriel_2 (CDT &t); } +{ Refines the constrained Delaunay triangulation \ccc{t} into a + conforming Gabriel triangulation. After a call to this function, all + constrained edges of \ccc{t} have the \emph{Gabriel property}: the + circle that has $e$ as diameter does not contain any vertex from + the triangulation. + \ccRequire The template parameter \ccc{CDT} should be a model of the + concept \ccc{ConstrainedDelaunayTriangulation_2}. The geometric + traits class of the constrained Delaunay triangulation must be a + model of \ccc{ConformingDelaunayTriangulationTraits_2}.} + +\end{ccRefFunction} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.eps b/Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.eps new file mode 100644 index 00000000000..fd9ab6e0121 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.eps @@ -0,0 +1,133 @@ +%!PS-Adobe-2.0 EPSF-2.0 +%%Title: part_of_a_cluster.fig +%%Creator: fig2dev Version 3.2 Patchlevel 4 +%%CreationDate: Tue May 13 19:26:21 2003 +%%For: lrineau@alioth (Laurent Rineau,stag..L016,7738,) +%%BoundingBox: 0 0 152 146 +%%Magnification: 1.0000 +%%EndComments +/$F2psDict 200 dict def +$F2psDict begin +$F2psDict /mtrx matrix put +/col-1 {0 setgray} bind def +/col0 {0.000 0.000 0.000 srgb} bind def +/col1 {0.000 0.000 1.000 srgb} bind def +/col2 {0.000 1.000 0.000 srgb} bind def +/col3 {0.000 1.000 1.000 srgb} bind def +/col4 {1.000 0.000 0.000 srgb} bind def +/col5 {1.000 0.000 1.000 srgb} bind def +/col6 {1.000 1.000 0.000 srgb} bind def +/col7 {1.000 1.000 1.000 srgb} bind def +/col8 {0.000 0.000 0.560 srgb} bind def +/col9 {0.000 0.000 0.690 srgb} bind def +/col10 {0.000 0.000 0.820 srgb} bind def +/col11 {0.530 0.810 1.000 srgb} bind def +/col12 {0.000 0.560 0.000 srgb} bind def +/col13 {0.000 0.690 0.000 srgb} bind def +/col14 {0.000 0.820 0.000 srgb} bind def +/col15 {0.000 0.560 0.560 srgb} bind def +/col16 {0.000 0.690 0.690 srgb} bind def +/col17 {0.000 0.820 0.820 srgb} bind def +/col18 {0.560 0.000 0.000 srgb} bind def +/col19 {0.690 0.000 0.000 srgb} bind def +/col20 {0.820 0.000 0.000 srgb} bind def +/col21 {0.560 0.000 0.560 srgb} bind def +/col22 {0.690 0.000 0.690 srgb} bind def +/col23 {0.820 0.000 0.820 srgb} bind def +/col24 {0.500 0.190 0.000 srgb} bind def +/col25 {0.630 0.250 0.000 srgb} bind def +/col26 {0.750 0.380 0.000 srgb} bind def +/col27 {1.000 0.500 0.500 srgb} bind def +/col28 {1.000 0.630 0.630 srgb} bind def +/col29 {1.000 0.750 0.750 srgb} bind def +/col30 {1.000 0.880 0.880 srgb} bind def +/col31 {1.000 0.840 0.000 srgb} bind def + +end +save +newpath 0 146 moveto 0 0 lineto 152 0 lineto 152 146 lineto closepath clip newpath +-65.2 198.7 translate +1 -1 scale + +/cp {closepath} bind def +/ef {eofill} bind def +/gr {grestore} bind def +/gs {gsave} bind def +/sa {save} bind def +/rs {restore} bind def +/l {lineto} bind def +/m {moveto} bind def +/rm {rmoveto} bind def +/n {newpath} bind def +/s {stroke} bind def +/sh {show} bind def +/slc {setlinecap} bind def +/slj {setlinejoin} bind def +/slw {setlinewidth} bind def +/srgb {setrgbcolor} bind def +/rot {rotate} bind def +/sc {scale} bind def +/sd {setdash} bind def +/ff {findfont} bind def +/sf {setfont} bind def +/scf {scalefont} bind def +/sw {stringwidth} bind def +/tr {translate} bind def +/tnt {dup dup currentrgbcolor + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add + 4 -2 roll dup 1 exch sub 3 -1 roll mul add srgb} + bind def +/shd {dup dup currentrgbcolor 4 -2 roll mul 4 -2 roll mul + 4 -2 roll mul srgb} bind def + /DrawEllipse { + /endangle exch def + /startangle exch def + /yrad exch def + /xrad exch def + /y exch def + /x exch def + /savematrix mtrx currentmatrix def + x y tr xrad yrad sc 0 0 1 startangle endangle arc + closepath + savematrix setmatrix + } def + +/$F2psBegin {$F2psDict begin /$F2psEnteredState save def} def +/$F2psEnd {$F2psEnteredState restore end} def + +$F2psBegin +10 setmiterlimit +0 slj 0 slc + 0.06000 0.06000 sc +% +% Fig objects follow +% +% +% here starts figure with depth 50 +% Ellipse +7.500 slw +n 1200 2100 106 106 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2400 1500 106 106 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Ellipse +n 2100 2700 106 106 0 360 DrawEllipse gs 0.00 setgray ef gr gs col0 s gr + +% Polyline +n 1200 2100 m + 3600 900 l gs col0 s gr +% Polyline +n 1200 2100 m + 3000 3300 l gs col0 s gr +% Polyline +n 2100 2700 m + 2400 1500 l gs 0.00 setgray ef gr gs col0 s gr +/Times-Roman ff 270.00 scf sf +1800 2250 m +gs 1 -1 sc (f) col0 sh gr +% here ends figure; +$F2psEnd +rs +showpage diff --git a/Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.gif b/Mesh_2/doc_tex/Mesh_2_ref/part_of_a_cluster.gif new file mode 100644 index 0000000000000000000000000000000000000000..d33e65a5d1960f02da741ab28832f83d2c463c02 GIT binary patch literal 26024 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 literal 0 HcmV?d00001 diff --git a/Mesh_2/doc_tex/Mesh_2_ref/refine_Delaunay_mesh_2.tex b/Mesh_2/doc_tex/Mesh_2_ref/refine_Delaunay_mesh_2.tex new file mode 100644 index 00000000000..b122416b7b9 --- /dev/null +++ b/Mesh_2/doc_tex/Mesh_2_ref/refine_Delaunay_mesh_2.tex @@ -0,0 +1,48 @@ +\begin{ccRefFunction}{refine_Delaunay_mesh_2} + + +\ccFunction{ template +void refine_Delaunay_mesh_2 (CDT &t, const Criteria& criteria = Criteria()); } +{ Refines the default domain defined by a constrained Delaunay + triangulation without seeds into a mesh satifying the criteria + defined by the traits \ccc{criteria}. The domain of the mesh + covers all the connected components of the plane defined by the + constrained edges of \ccc{t}, except for the unbounded component. + \ccPrecond The template parameter \ccc{CDT} must be a model of the + concept \ccc{ConstrainedDelaunayTriangulation_2}. The geometric traits + class of the constrained Delaunay triangulation must be a model + of \ccc{DelaunayMeshTraits_2}. + \ccRequire The face of the constrained + Delaunay triangulation must be a model of the concept + \ccc{DelaunayMeshFaceBase_2}. \ccc{Criteria} must be a model of the + concept \ccc{MeshingCriteria_2} and \ccc{CDT::Face_handle} must be the same + as \ccc{Criteria::Face_handle}. } + +\ccFunction{ template +void refine_Delaunay_mesh_2(CDT& t, + InputIterator begin, InputIterator end, + const Criteria& criteria = Criteria(), + bool mark = false); } + { Refines the default domain defined by a constrained + Delaunay triangulation into a mesh + satifying the criteria defined by the traits + \ccc{criteria}.The sequence [\ccc{begin}, \ccc{end}] + gives a set of seeds points, that defines the domain + to be meshed as follows. The constrained edges of + \ccc{t} partition the plane into connected components. + If \ccc{mark=true}, the mesh domain is the union of + the bounded connected components including at least + one seed. If \ccc{mark=false}, the domain is the + union of the bounded components including no seed. + Note that the unbounded component of the plane is + never meshed. + \ccRequire The \ccc{value_type} of \ccc{begin} and + \ccc{end} is \ccc{CDT::Geom_traits::Point_2}.} + +\end{ccRefFunction} + +%%% For emacs/AucTeX: +%%% Local Variables: *** +%%% mode:latex *** +%%% TeX-master: "../Mesh_2.tex" *** +%%% End: *** diff --git a/Mesh_2/dont_submit b/Mesh_2/dont_submit new file mode 100644 index 00000000000..5015e50b2ec --- /dev/null +++ b/Mesh_2/dont_submit @@ -0,0 +1,11 @@ +examples/Mesh_2/makefile +GNUmakefile +TODO +README +bench +Doxyfile +stylesheet.css +utils +implementation.tex +*.kdev* +depends diff --git a/Mesh_2/examples/Mesh_2/GNUmakefile b/Mesh_2/examples/Mesh_2/GNUmakefile new file mode 100644 index 00000000000..329a8e17e44 --- /dev/null +++ b/Mesh_2/examples/Mesh_2/GNUmakefile @@ -0,0 +1,34 @@ +include makefile + +#---------------------------------------------------------------------# +# +# dependencies +# +# if you want deps, create a file my_makefile that contains +# -include depends +# +#---------------------------------------------------------------------# + +-include my_makefile + +dep: + rm -f depends; $(MAKE) depends + +.PHONY: dep + +depends: *.C + cat /dev/null > depends + for f in *.C; do \ + echo >> depends; \ + echo >> depends; \ + echo "$${f%.C}$(OBJ_EXT): \\" >> depends; \ + $(CGAL_CXX) $(CXXFLAGS) -M -MG $$f \ + | grep '\.\./\.\..*/include/CGAL' >> depends; \ + done + test -f depends + +run: all + ./conforming + ./mesh_class + ./mesh_global + ./mesh_with_seeds diff --git a/Mesh_2/examples/Mesh_2/conforming.C b/Mesh_2/examples/Mesh_2/conforming.C new file mode 100644 index 00000000000..560fa7f5258 --- /dev/null +++ b/Mesh_2/examples/Mesh_2/conforming.C @@ -0,0 +1,52 @@ +// file: examples/Mesh_2/conforming.C + +#include +#include +#include + +#include + +struct K : public CGAL::Exact_predicates_inexact_constructions_kernel {}; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CDT::Point Point; +typedef CDT::Vertex_handle Vertex_handle; + +int main() +{ + CDT cdt; + + // construct a constrained triangulation + Vertex_handle + va = cdt.insert(Point( 5., 5.)), + vb = cdt.insert(Point(-5., 5.)), + vc = cdt.insert(Point( 4., 3.)), + vd = cdt.insert(Point( 5.,-5.)), + ve = cdt.insert(Point( 6., 6.)), + vf = cdt.insert(Point(-6., 6.)), + vg = cdt.insert(Point(-6.,-6.)), + vh = cdt.insert(Point( 6.,-6.)); + + cdt.insert_constraint(va,vb); + cdt.insert_constraint(vb,vc); + cdt.insert_constraint(vc,vd); + cdt.insert_constraint(vd,va); + cdt.insert_constraint(ve,vf); + cdt.insert_constraint(vf,vg); + cdt.insert_constraint(vg,vh); + cdt.insert_constraint(vh,ve); + + std::cout << "Number of vertices before: " + << cdt.number_of_vertices() << std::endl; + + // make it conforming Delaunay + CGAL::make_conforming_Delaunay_2(cdt); + + std::cout << "Number of vertices after make_conforming_Delaunay_2: " + << cdt.number_of_vertices() << std::endl; + + // then make it conforming Gabriel + CGAL::make_conforming_Gabriel_2(cdt); + + std::cout << "Number of vertices after make_conforming_Gabriel_2: " + << cdt.number_of_vertices() << std::endl; +} diff --git a/Mesh_2/examples/Mesh_2/makefile b/Mesh_2/examples/Mesh_2/makefile new file mode 100644 index 00000000000..75aac7a1c6d --- /dev/null +++ b/Mesh_2/examples/Mesh_2/makefile @@ -0,0 +1,68 @@ +# Created by the script cgal_create_makefile +# This is the makefile for compiling a CGAL application. + +#---------------------------------------------------------------------# +# include platform specific settings +#---------------------------------------------------------------------# +# Choose the right include file from the /make directory. + +# CGAL_MAKEFILE = ENTER_YOUR_INCLUDE_MAKEFILE_HERE +include $(CGAL_MAKEFILE) + +#---------------------------------------------------------------------# +# compiler flags +#---------------------------------------------------------------------# + +CXXFLAGS = \ + -I../../include \ + -I../../../Triangulation_2/include \ + $(CGAL_CXXFLAGS) \ + $(LONG_NAME_PROBLEM_CXXFLAGS) \ + $(OTHER_CXXFLAGS) + +#---------------------------------------------------------------------# +# linker flags +#---------------------------------------------------------------------# + +LIBPATH = \ + $(CGAL_LIBPATH) + +LDFLAGS = \ + $(LONG_NAME_PROBLEM_LDFLAGS) \ + $(CGAL_LDFLAGS) + +#---------------------------------------------------------------------# +# target entries +#---------------------------------------------------------------------# + +all: \ + conforming$(EXE_EXT) \ + mesh_class$(EXE_EXT) \ + mesh_global$(EXE_EXT) \ + mesh_with_seeds$(EXE_EXT) + +conforming$(EXE_EXT): conforming$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)conforming conforming$(OBJ_EXT) $(LDFLAGS) + +mesh_class$(EXE_EXT): mesh_class$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)mesh_class mesh_class$(OBJ_EXT) $(LDFLAGS) + +mesh_global$(EXE_EXT): mesh_global$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)mesh_global mesh_global$(OBJ_EXT) $(LDFLAGS) + +mesh_with_seeds$(EXE_EXT): mesh_with_seeds$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)mesh_with_seeds mesh_with_seeds$(OBJ_EXT) $(LDFLAGS) + +clean: \ + conforming.clean \ + mesh_class.clean \ + mesh_global.clean \ + mesh_with_seeds.clean + +#---------------------------------------------------------------------# +# suffix rules +#---------------------------------------------------------------------# + +.C$(OBJ_EXT): + $(CGAL_CXX) $(CXXFLAGS) $(OBJ_OPT) $< + diff --git a/Mesh_2/examples/Mesh_2/mesh_class.C b/Mesh_2/examples/Mesh_2/mesh_class.C new file mode 100644 index 00000000000..ed2a625352a --- /dev/null +++ b/Mesh_2/examples/Mesh_2/mesh_class.C @@ -0,0 +1,55 @@ +// file: examples/Mesh_2/mesh_class.C + +#include +#include +#include +#include +#include + +#include + +struct K : public CGAL::Exact_predicates_inexact_constructions_kernel {}; +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Delaunay_mesh_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Delaunay_mesh_size_criteria_2 Criteria; +typedef CGAL::Delaunay_mesher_2 Mesher; + +typedef CDT::Vertex_handle Vertex_handle; +typedef CDT::Point Point; + +int main() +{ + CDT cdt; + + Vertex_handle va = cdt.insert(Point(-4,0)); + Vertex_handle vb = cdt.insert(Point(0,-1)); + Vertex_handle vc = cdt.insert(Point(4,0)); + Vertex_handle vd = cdt.insert(Point(0,1)); + cdt.insert(Point(2, 0.6)); + + cdt.insert_constraint(va, vb); + cdt.insert_constraint(vb, vc); + cdt.insert_constraint(vc, vd); + cdt.insert_constraint(vd, va); + + std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; + + std::cout << "Meshing the triangulation with default criterias..." + << std::endl; + + Mesher mesher(cdt); + mesher.refine_mesh(); + + std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; + + std::cout << "Meshing with new criterias..." << std::endl; + // 0.125 is the default shape bound. It corresponds to abound 20.6 degree. + // 0.5 is the upper bound on the length of the longuest edge. + // See reference manual for Delaunay_mesh_size_traits_2. + mesher.set_criteria(Criteria(0.125, 0.5)); + mesher.refine_mesh(); + + std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; +} diff --git a/Mesh_2/examples/Mesh_2/mesh_global.C b/Mesh_2/examples/Mesh_2/mesh_global.C new file mode 100644 index 00000000000..b5f49746303 --- /dev/null +++ b/Mesh_2/examples/Mesh_2/mesh_global.C @@ -0,0 +1,42 @@ +// file: examples/Mesh_2/mesh_global.C + +#include +#include +#include +#include +#include + +#include + +struct K : public CGAL::Exact_predicates_inexact_constructions_kernel {}; +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Delaunay_mesh_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Delaunay_mesh_size_criteria_2 Criteria; + +typedef CDT::Vertex_handle Vertex_handle; +typedef CDT::Point Point; + +int main() +{ + CDT cdt; + + Vertex_handle va = cdt.insert(Point(-4,0)); + Vertex_handle vb = cdt.insert(Point(0,-1)); + Vertex_handle vc = cdt.insert(Point(4,0)); + Vertex_handle vd = cdt.insert(Point(0,1)); + cdt.insert(Point(2, 0.6)); + + cdt.insert_constraint(va, vb); + cdt.insert_constraint(vb, vc); + cdt.insert_constraint(vc, vd); + cdt.insert_constraint(vd, va); + + std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; + + std::cout << "Meshing the triangulation..." << std::endl; + CGAL::refine_Delaunay_mesh_2(cdt, Criteria(0.125, 0.5)); + + std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; +} diff --git a/Mesh_2/examples/Mesh_2/mesh_with_seeds.C b/Mesh_2/examples/Mesh_2/mesh_with_seeds.C new file mode 100644 index 00000000000..4439e9ec114 --- /dev/null +++ b/Mesh_2/examples/Mesh_2/mesh_with_seeds.C @@ -0,0 +1,55 @@ +// file: examples/Mesh_2/mesh_with_seeds.C + +#include +#include +#include +#include +#include + +#include + +struct K : public CGAL::Exact_predicates_inexact_constructions_kernel {}; +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Delaunay_mesh_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Delaunay_mesh_size_criteria_2 Criteria; + +typedef CDT::Vertex_handle Vertex_handle; +typedef CDT::Point Point; + +int main() +{ + CDT cdt; + Vertex_handle va = cdt.insert(Point(2,0)); + Vertex_handle vb = cdt.insert(Point(0,2)); + Vertex_handle vc = cdt.insert(Point(-2,0)); + Vertex_handle vd = cdt.insert(Point(0,-2)); + + cdt.insert_constraint(va, vb); + cdt.insert_constraint(vb, vc); + cdt.insert_constraint(vc, vd); + cdt.insert_constraint(vd, va); + + va = cdt.insert(Point(3,3)); + vb = cdt.insert(Point(-3,3)); + vc = cdt.insert(Point(-3,-3)); + vd = cdt.insert(Point(3,0-3)); + + cdt.insert_constraint(va, vb); + cdt.insert_constraint(vb, vc); + cdt.insert_constraint(vc, vd); + cdt.insert_constraint(vd, va); + + std::list list_of_seeds; + + list_of_seeds.push_back(Point(0, 0)); + + std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; + + std::cout << "Meshing the domain..." << std::endl; + CGAL::refine_Delaunay_mesh_2(cdt, list_of_seeds.begin(), list_of_seeds.end(), + Criteria()); + + std::cout << "Number of vertices: " << cdt.number_of_vertices() << std::endl; +} diff --git a/Mesh_2/include/CGAL/Delaunay_mesh_area_criteria_2.h b/Mesh_2/include/CGAL/Delaunay_mesh_area_criteria_2.h new file mode 100644 index 00000000000..da0fb1caa9e --- /dev/null +++ b/Mesh_2/include/CGAL/Delaunay_mesh_area_criteria_2.h @@ -0,0 +1,134 @@ +// Copyright (c) 2003-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) : Laurent RINEAU + +#ifndef CGAL_DELAUNAY_MESH_AREA_CRITERIA_2_H +#define CGAL_DELAUNAY_MESH_AREA_CRITERIA_2_H + +#include + +namespace CGAL { + +template +class Delaunay_mesh_area_criteria_2 + : public virtual Delaunay_mesh_criteria_2, + private Delaunay_mesh_size_criteria_2 +/* This class "is a" Delaunay_mesh_criteria_2 and is implemented by + Delaunay_mesh_size_criteria_2. Delaunay_mesh_criteria_2 is a + virtual base class of Delaunay_mesh_size_criteria_2. */ +{ +public: + typedef Delaunay_mesh_criteria_2 Base; + typedef Delaunay_mesh_size_criteria_2 Private_base; + + typedef typename Delaunay_mesh_size_criteria_2::Quality Quality; + + Delaunay_mesh_area_criteria_2(const double aspect_bound = 0.125, + const double area_bound = 0) + : Private_base(aspect_bound, area_bound) {}; + + inline + double area_bound() const { return this->sizebound; }; + + inline + void set_area_bound(const double ab) { this->sizebound = ab; }; + + class Is_bad: public Private_base::Is_bad + { + public: + typedef typename Private_base::Is_bad Is_bad_base; + + typedef typename Tr::Point Point_2; + typedef typename Tr::Triangle Triangle_2; + typedef typename Tr::Face_handle Face_handle; + + Is_bad(const double aspect_bound, + const double area_bound) + : Is_bad_base(aspect_bound, area_bound) {}; + + Mesh_2::Face_badness operator()(Quality q) + { + return Is_bad_base::operator()(q); + } + + Mesh_2::Face_badness operator()(const Face_handle& fh, + Quality& q) const + { + typedef typename Tr::Geom_traits Geom_traits; + + typedef typename Geom_traits::Point_2 Point_2; + typedef typename Geom_traits::Triangle_2 Triangle_2; + typedef typename Geom_traits::Compute_area_2 Compute_area_2; + typedef typename Geom_traits::Compute_squared_distance_2 + Compute_squared_distance_2; + typedef typename Geom_traits::FT FT; + + + Geom_traits geom_traits; + + Compute_area_2 area_2 = geom_traits.compute_area_2_object(); + Compute_squared_distance_2 squared_distance = + geom_traits.compute_squared_distance_2_object(); + + const Point_2& pa = fh->vertex(0)->point(); + const Point_2& pb = fh->vertex(1)->point(); + const Point_2& pc = fh->vertex(2)->point(); + + Triangle_2 t = geom_traits.construct_triangle_2_object()(pa,pb,pc); + double area = CGAL::to_double(area_2(t)); + area=area*area; // squared area + + double + a = CGAL::to_double(squared_distance(pb, pc)), + b = CGAL::to_double(squared_distance(pc, pa)), + c = CGAL::to_double(squared_distance(pa, pb)); + + double min_sine; // squared minimum sine + + if(asquared_size_bound != 0 && + area > this->squared_size_bound ) + return Mesh_2::IMPERATIVELY_BAD; + else + if( min_sine < this->B ) + return Mesh_2::BAD; + else + return Mesh_2::NOT_BAD; + }; + }; // end class Is_bad + + Is_bad is_bad_object() const + { return Is_bad(this->bound(), area_bound()); } +}; + +} //end namespace + +#endif diff --git a/Mesh_2/include/CGAL/Delaunay_mesh_criteria_2.h b/Mesh_2/include/CGAL/Delaunay_mesh_criteria_2.h new file mode 100644 index 00000000000..3674aed8f62 --- /dev/null +++ b/Mesh_2/include/CGAL/Delaunay_mesh_criteria_2.h @@ -0,0 +1,113 @@ +// Copyright (c) 2003-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) : Laurent RINEAU + +#ifndef CGAL_DELAUNAY_MESH_CRITERIA_2_H +#define CGAL_DELAUNAY_MESH_CRITERIA_2_H + +#include + +namespace CGAL { + +template +class Delaunay_mesh_criteria_2 +{ + double B; +public: + typedef typename Tr::Face_handle Face_handle; + + Delaunay_mesh_criteria_2(const double bound = 0.125) : B(bound) {}; + + typedef double Quality; + + inline + double bound() const { return B; }; + + inline + void set_bound(const double bound) { B = bound; }; + + class Is_bad + { + protected: + const double B; + public: + typedef typename Tr::Point Point_2; + + Is_bad(const double bound) : B(bound) {}; + + Mesh_2::Face_badness operator()(const Quality q) const + { + if( q < B ) + return Mesh_2::BAD; + else + return Mesh_2::NOT_BAD; + } + + Mesh_2::Face_badness operator()(const Face_handle& fh, + Quality& q) const + { + typedef typename Tr::Geom_traits Geom_traits; + typedef typename Geom_traits::Compute_area_2 Compute_area_2; + typedef typename Geom_traits::Compute_squared_distance_2 + Compute_squared_distance_2; + typedef typename Geom_traits::Construct_triangle_2 + Construct_triangle_2; + typedef typename Geom_traits::FT FT; + + Geom_traits traits; + + Compute_area_2 area_2 = + traits.compute_area_2_object(); + Compute_squared_distance_2 squared_distance = + traits.compute_squared_distance_2_object(); + Construct_triangle_2 triangle = + traits.construct_triangle_2_object(); + + const Point_2& pa = fh->vertex(0)->point(); + const Point_2& pb = fh->vertex(1)->point(); + const Point_2& pc = fh->vertex(2)->point(); + + double area = 2*CGAL::to_double(area_2(pa, pb, pc)); + area=area*area; // area = 4 * area(triangle) + + double a = CGAL::to_double(squared_distance(pb, pc)); + double b = CGAL::to_double(squared_distance(pc, pa)); + double c = CGAL::to_double(squared_distance(pa, pb)); + + if(a + +namespace CGAL { + +template > +class Delaunay_mesh_face_base_2 : public Fb +{ +public: + typedef Gt Geom_traits; + typedef Constrained_triangulation_face_base_2 CTFb; + typedef typename Fb::Vertex_handle Vertex_handle; + typedef typename Fb::Face_handle Face_handle; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename CTFb::template Rebind_TDS::Other Fb2; + typedef Delaunay_mesh_face_base_2 Other; + }; + +protected: + bool in_domain; + +public: + Delaunay_mesh_face_base_2(): Fb(), in_domain(false) {}; + + Delaunay_mesh_face_base_2(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2) + : Fb(v0,v1,v2), in_domain(false) {}; + + Delaunay_mesh_face_base_2(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2, + Face_handle n0, + Face_handle n1, + Face_handle n2) + : Fb(v0,v1,v2,n0,n1,n2), in_domain(false) {}; + + inline + bool is_in_domain() const { return in_domain; }; + + inline + void set_in_domain(const bool b) { in_domain=b; }; + + /** compatibility with CGAL-3.2 */ + inline + bool is_marked() const { return in_domain; }; + + /** compatibility with CGAL-3.2 */ + inline + void set_marked(const bool b) { in_domain=b; }; +}; + +}; // namespace CGAL + +#endif diff --git a/Mesh_2/include/CGAL/Delaunay_mesh_local_size_criteria_2.h b/Mesh_2/include/CGAL/Delaunay_mesh_local_size_criteria_2.h new file mode 100644 index 00000000000..488f1be74a6 --- /dev/null +++ b/Mesh_2/include/CGAL/Delaunay_mesh_local_size_criteria_2.h @@ -0,0 +1,129 @@ +// Copyright (c) 2003-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) : Laurent RINEAU + +#ifndef CGAL_DELAUNAY_MESH_LOCAL_SIZE_CRITERIA_2_H +#define CGAL_DELAUNAY_MESH_LOCAL_SIZE_CRITERIA_2_H + +#include + +namespace CGAL { + +template +class Delaunay_mesh_local_size_criteria_2 + : public Delaunay_mesh_size_criteria_2 +{ +public: + typedef Delaunay_mesh_size_criteria_2 Base; + typedef typename Base::Base PreviousBase; + typedef typename CDT::Geom_traits Geom_traits; + typedef typename Geom_traits::FT FT; + typedef typename Geom_traits::Point_2 Point; + + typedef typename CDT::Face_handle Face_handle; + +private: + bool local; + Point _p; + +public: + Delaunay_mesh_local_size_criteria_2(const double aspect_bound = 0.125, + const double size_bound = 0, + const bool is_local_size = false, + const Point p = Point()) + : Base(aspect_bound, size_bound), local(is_local_size), _p(p) {}; + + inline + Point point() const { return _p; }; + + inline + void set_point(const Point p) { _p = p; }; + + inline + bool is_local_size() const { return local; }; + + inline + void set_local_size(bool local_size) { local = local_size; }; + + class Is_bad: public Base::Is_bad + { + public: + typedef typename Base::Is_bad Baseclass; + typedef typename Baseclass::Point_2 Point_2; + typedef typename Base::Base PreviousBase; + typedef typename PreviousBase::Is_bad PreviousBaseclass; + typedef Geom_traits Traits; + + typedef typename Base::Quality Quality; + + private: + const bool local; + const Point_2 p; + + public: + Is_bad(const double aspect_bound, + const double size_bound, + const bool l, + const Point_2 _p) + : Base::Is_bad(aspect_bound, size_bound), local(l), p(_p) {}; + + Mesh_2::Face_badness operator()(Quality q) const + { + return Base::Is_bad::operator()(q); + } + + Mesh_2::Face_badness operator()(const Face_handle& fh, + Quality& q) const + { + if(!local) + return Baseclass::operator()(fh,q); + else + { + typename Geom_traits::Orientation_2 orient = + Geom_traits().orientation_2_object(); + + Mesh_2::Face_badness is_non_locally_bad = + Baseclass::operator()(fh,q); + + const Point_2& a = fh->vertex(0)->point(); + const Point_2& b = fh->vertex(1)->point(); + const Point_2& c = fh->vertex(2)->point(); + + Orientation + o1 = orient(a,b,p), + o2 = orient(b,c,p), + o3 = orient(c,a,p); + + if((o1==o2) && (o2==o3)) + return is_non_locally_bad; + else + if( q.sine() < this->B ) + return Mesh_2::BAD; + else + return Mesh_2::NOT_BAD; + }; + } + }; + + Is_bad is_bad_object() const + { return Is_bad(this->bound(), this->size_bound(), local, point()); }; +}; + +}; //end namespace + +#endif diff --git a/Mesh_2/include/CGAL/Delaunay_mesh_size_criteria_2.h b/Mesh_2/include/CGAL/Delaunay_mesh_size_criteria_2.h new file mode 100644 index 00000000000..33ce1fb01cb --- /dev/null +++ b/Mesh_2/include/CGAL/Delaunay_mesh_size_criteria_2.h @@ -0,0 +1,189 @@ +// Copyright (c) 2003-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) : Laurent RINEAU + +#ifndef CGAL_DELAUNAY_MESH_SIZE_CRITERIA_2_H +#define CGAL_DELAUNAY_MESH_SIZE_CRITERIA_2_H + +#include +#include +#include +#include + +namespace CGAL { + +template +class Delaunay_mesh_size_criteria_2 : + public virtual Delaunay_mesh_criteria_2 +{ +protected: + double sizebound; + +public: + typedef Delaunay_mesh_criteria_2 Base; + + Delaunay_mesh_size_criteria_2(const double aspect_bound = 0.125, + const double size_bound = 0) + : Base(aspect_bound), sizebound(size_bound) {}; + + inline + double size_bound() const { return sizebound; }; + + inline + void set_size_bound(const double sb) { sizebound = sb; }; + + // first: squared_minimum_sine + // second: size + struct Quality : public std::pair + { + typedef std::pair Base; + + Quality() : Base() {}; + Quality(double _sine, double _size) : Base(_sine, _size) {}; + + const double& size() const { return second; } + const double& sine() const { return first; } + + // q1 1 ) + if( q.size() > 1 ) + return ( size() > q.size() ); + else + return true; // *this is big but not q + else + if( q.size() > 1 ) + return false; // q is big but not *this + return( sine() < q.sine() ); + } + + std::ostream& operator<<(std::ostream& out) const + { + return out << "(size=" << size() + << ", sine=" << sine() << ")"; + } + }; + + class Is_bad: public Base::Is_bad + { + protected: + const double squared_size_bound; // squared size bound on edge length + public: + typedef typename Base::Is_bad::Point_2 Point_2; + + Is_bad(const double aspect_bound, + const double size_bound) + : Base::Is_bad(aspect_bound), squared_size_bound(size_bound * size_bound) {}; + + Mesh_2::Face_badness operator()(const Quality q) const + { + if( q.size() > 1 ) + return Mesh_2::IMPERATIVELY_BAD; + if( q.sine() < this->B ) + return Mesh_2::BAD; + else + return Mesh_2::NOT_BAD; + } + + Mesh_2::Face_badness operator()(const typename CDT::Face_handle& fh, + Quality& q) const + { + typedef typename CDT::Geom_traits Geom_traits; + typedef typename Geom_traits::Compute_area_2 Compute_area_2; + typedef typename Geom_traits::Compute_squared_distance_2 + Compute_squared_distance_2; + typedef typename Geom_traits::Construct_triangle_2 + Construct_triangle_2; + typedef typename Geom_traits::FT FT; + + Geom_traits traits; /** @warning traits with data!! */ + + Compute_squared_distance_2 squared_distance = + traits.compute_squared_distance_2_object(); + + const Point_2& pa = fh->vertex(0)->point(); + const Point_2& pb = fh->vertex(1)->point(); + const Point_2& pc = fh->vertex(2)->point(); + + double + a = CGAL::to_double(squared_distance(pb, pc)), + b = CGAL::to_double(squared_distance(pc, pa)), + c = CGAL::to_double(squared_distance(pa, pb)); + + double max_length; // squared max edge length + double second_max_length; + + if(a 1 ) + { + q.first = 1; // (do not compute sine) + return Mesh_2::IMPERATIVELY_BAD; + } + } + + Compute_area_2 area_2 = traits.compute_area_2_object(); + + double area = 2*CGAL::to_double(area_2(pa, pb, pc)); + + q.first = (area * area) / (max_length * second_max_length); // (sine) + + if( q.sine() < this->B ) + return Mesh_2::BAD; + else + return Mesh_2::NOT_BAD; + } + }; + + Is_bad is_bad_object() const + { return Is_bad(this->bound(), size_bound()); } +}; + +} // end namespace CGAL + +#endif diff --git a/Mesh_2/include/CGAL/Delaunay_mesher_2.h b/Mesh_2/include/CGAL/Delaunay_mesher_2.h new file mode 100644 index 00000000000..cba14e89f67 --- /dev/null +++ b/Mesh_2/include/CGAL/Delaunay_mesher_2.h @@ -0,0 +1,366 @@ +// Copyright (c) 2004-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) : Laurent RINEAU + +#ifndef CGAL_DELAUNAY_MESHER_2_H +#define CGAL_DELAUNAY_MESHER_2_H + +#include +#include +#include + +namespace CGAL { + +template +class Delaunay_mesher_2 +{ + + /** \name \c Tr types */ + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + typedef typename Tr::Edge Edge; + + typedef typename Tr::Point Point; + + /** \name Types needed for private member datas */ + typedef Mesh_2::Refine_edges_with_clusters > Edges_level; + + typedef Mesh_2::Refine_faces Faces_level; + +public: + + typedef Tr Triangulation; + typedef Crit Criteria; + typedef Mesh_2::Clusters Clusters; + + /** \name Types needed to mark the domain for Delaunay_mesh_2 */ + + typedef std::list Seeds; + typedef typename Seeds::const_iterator Seeds_iterator; + typedef Seeds_iterator Seeds_const_iterator; + +private: + // --- PRIVATE MEMBER DATAS --- + Tr& tr; + Criteria criteria; + Null_mesher_level null_level; + Null_mesh_visitor null_visitor; + Clusters clusters_; + Edges_level edges_level; + Faces_level faces_level; + Mesh_2::Refine_edges_visitor_from_faces visitor; + + Seeds seeds; + bool seeds_mark; +public: + /** \name CONSTRUCTORS */ + Delaunay_mesher_2(Tr& tr_, const Criteria& criteria_ = Criteria()) + : tr(tr_), + criteria(criteria_), + null_level(), + null_visitor(), + clusters_(tr), + edges_level(tr, clusters_, null_level), + faces_level(tr, criteria, edges_level), + visitor(faces_level, null_visitor), + initialized(false) + { + } + + Delaunay_mesher_2(Tr& tr_, Edges_level& edges_level_, + const Criteria& criteria_ = Criteria()) + : tr(tr_), + criteria(criteria_), + null_level(), + null_visitor(), + clusters_(tr), + edges_level(edges_level_), + faces_level(tr, criteria, edges_level), + visitor(faces_level, null_visitor), + initialized(false) + { + } + + /** SEEDS HANDLING FUNCTIONS */ + + Seeds_const_iterator seeds_begin() const + { + return seeds.begin(); + } + + Seeds_const_iterator seeds_end() const + { + return seeds.end(); + } + +private: + /** \name INITIALIZED */ + + bool initialized; + +public: + /** \name MARKING FUNCTIONS */ + + /** The value type of \a InputIterator should be \c Point, and represents + seeds. Connected components of seeds are marked with the value of + \a mark. Other components are marked with \c !mark. The connected + component of infinite faces is always marked with \c false. + */ + template + void set_seeds(InputIterator b, InputIterator e, + const bool mark = false, + const bool do_it_now = false) + { + seeds.clear(); + std::copy(b, e, std::back_inserter(seeds)); + seeds_mark=mark; + if(do_it_now) mark_facets(); + } + + void clear_seeds() + { + seeds.clear(); + seeds_mark = false; + } + + void mark_facets() + { + mark_facets(tr, seeds.begin(), seeds.end(), seeds_mark); + } + + /** Procedure that marks facets according to a list of seeds. */ + template + static void mark_facets(Tr& tr, + Seeds_it begin, + Seeds_it end, + bool mark = false) + { + if (tr.dimension()<2) return; + if( begin != end ) + { + for(typename Tr::All_faces_iterator it=tr.all_faces_begin(); + it!=tr.all_faces_end(); + ++it) + it->set_in_domain(!mark); + + for(Seeds_it sit=begin; sit!=end; ++sit) + { + Face_handle fh=tr.locate(*sit); + if(fh!=NULL) + propagate_marks(fh, mark); + } + } + else + mark_convex_hull(tr); + propagate_marks(tr.infinite_face(), false); + } + + /** + * Marks all faces of the convex hull but those connected to the + * infinite faces. + */ + static void mark_convex_hull(Tr& tr) + { + for(typename Tr::All_faces_iterator fit=tr.all_faces_begin(); + fit!=tr.all_faces_end(); + ++fit) + fit->set_in_domain(true); + propagate_marks(tr.infinite_face(), false); + } + + /** Propagates the mark \c mark recursivly. */ + static void propagate_marks(const Face_handle fh, bool mark) + { + // std::queue only works with std::list on VC++6, and not with + // std::deque, which is the default + // But it should be fixed by VC++7 know. [Laurent Rineau 2003/03/24] + std::queue*/> face_queue; + fh->set_in_domain(mark); + face_queue.push(fh); + while( !face_queue.empty() ) + { + Face_handle fh = face_queue.front(); + face_queue.pop(); + for(int i=0;i<3;i++) + { + const Face_handle& nb = fh->neighbor(i); + if( !fh->is_constrained(i) && (mark != nb->is_in_domain()) ) + { + nb->set_in_domain(mark); + face_queue.push(nb); + } + } + } + } + /** \name MESHING FUNCTIONS */ + + void refine_mesh() + { + if(initialized != true) init(); + faces_level.refine(visitor); + } + + /** \name REMESHING FUNCTIONS */ + + void set_criteria(const Criteria& criteria_, + bool recalculate_bad_faces = true) + { + criteria = criteria_; + if (recalculate_bad_faces) faces_level.scan_triangulation(); + } + + const Criteria& get_criteria() const + { + return criteria; + } + + template + void set_bad_faces(Fh_it begin, Fh_it end) + { + faces_level.set_bad_faces(begin, end); + } + + /** \name STEP BY STEP FUNCTIONS */ + + /** + Initialize the data structures + (The call of this function is REQUIRED before any step by step + operation). + */ + void init() + { + mark_facets(); + clusters_.create_clusters(); + edges_level.scan_triangulation(); + faces_level.scan_triangulation(); + initialized = true; + } + + bool is_refinement_done () + { + return faces_level.is_algorithm_done(); + }; + + bool + step_by_step_refine_mesh() + { + return faces_level.try_to_insert_one_point(visitor); + } + + bool try_one_step_refine_mesh() + { + return faces_level.one_step(visitor); + } + + /** \name ACCESS FUNCTIONS */ + + const Mesh_2::Clusters& clusters() const + { + return clusters_; + } + + const Triangulation& triangulation() const + { + return tr; + } + + /** \name DEBUGGING FUNCTIONS */ + + typedef typename Edges_level::Constrained_edge Constrained_edge; + + bool is_edges_refinement_done() + { + return edges_level.is_algorithm_done(); + } + + Edge next_encroached_edge() + { + return edges_level.get_next_element(); + } + + const Face_handle next_bad_face() + { + return faces_level.get_next_element(); + } + + const Point next_refinement_point() + { + if( !edges_level.is_algorithm_done() ) + return edges_level.refinement_point(next_encroached_edge()); + else + return faces_level.refinement_point(next_bad_face()); + } + + typedef typename Edges_level::Edges_const_iterator + Encroached_edges_const_iterator; + + typedef typename Faces_level::Bad_faces_const_iterator + Bad_faces_const_iterator; + + Encroached_edges_const_iterator encroached_edges_begin() const + { + return edges_level.begin(); + } + + Encroached_edges_const_iterator encroached_edges_end() const + { + return edges_level.end(); + } + + Bad_faces_const_iterator bad_faces_begin() const + { + return faces_level.begin(); + } + + Bad_faces_const_iterator bad_faces_end() const + { + return faces_level.end(); + } +}; // end class Delaunay_mesher_2 + +// --- GLOBAL FUNCTIONS --- + +template +void +refine_Delaunay_mesh_2(Tr& t, + const Criteria& criteria = Criteria()) +{ + typedef Delaunay_mesher_2 Mesher; + + Mesher mesher(t, criteria); + mesher.refine_mesh(); +} + +template +void +refine_Delaunay_mesh_2(Tr& t, + InputIterator b, InputIterator e, + const Criteria& criteria = Criteria(), + bool mark = false) +{ + typedef Delaunay_mesher_2 Mesher; + + Mesher mesher(t, criteria); + mesher.set_seeds(b, e, mark); + mesher.refine_mesh(); +} + +} // end namespace CGAL + +#endif // CGAL_DELAUNAY_MESHER_2_H diff --git a/Mesh_2/include/CGAL/Double_map.h b/Mesh_2/include/CGAL/Double_map.h new file mode 100644 index 00000000000..03350054944 --- /dev/null +++ b/Mesh_2/include/CGAL/Double_map.h @@ -0,0 +1,218 @@ +// Copyright (c) 2003-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) : Laurent RINEAU + +#ifndef CGAL_DOUBLE_MAP_H +#define CGAL_DOUBLE_MAP_H + +#include +#include +#include +#include + +namespace CGAL { + +template , + class _Reverse_compare = std::less<_Data> > +class Double_map +{ +public: + typedef _Key Key; + typedef _Data Data; + typedef _Direct_compare Direct_compare; + typedef _Reverse_compare Reverse_compare; + + typedef Double_map Self; + + typedef std::multimap Reverse_func; + typedef typename Reverse_func::iterator reverse_iterator; + typedef std::map Direct_func; + + typedef typename Direct_func::value_type Direct_entry; + // std::pair + typedef typename Reverse_func::value_type Reverse_entry; + // std::pair ; + + typedef typename Direct_func::size_type size_type; + + + typedef typename Direct_func::iterator direct_iterator; + typedef reverse_iterator iterator; + typedef typename Direct_func::const_iterator direct_const_iterator; + + typedef direct_const_iterator const_iterator; + +private: + // Private members + Direct_func direct_func; + Reverse_func reverse_func; + +public : + // The default constructor + Double_map () {} + + // The copy constructor + Double_map(const Self& dm) + { + copy(dm); + } + + // Queries + bool empty() const + { + CGAL_assertion(is_valid()); + return(direct_func.empty()); + } + + size_type size() const + { + CGAL_assertion(is_valid()); + return direct_func.size(); + } + + bool is_valid() const + { + return(direct_func.size()==reverse_func.size()); + } + + void clear() + { + direct_func.clear(); + reverse_func.clear(); + } + + Self& operator=(const Self& dm) + { + if(&dm != this) + copy(dm); + return *this; + } + + void copy(const Self& dm) + { + clear(); + + reverse_func = dm.reverse_func; + + for(reverse_iterator rit = reverse_func.begin(); + rit != reverse_func.end(); + ++rit) + { + direct_func[rit->second] = rit; + } + } + + // Assignation + bool insert(const Key& k, const Data& d) + { + direct_iterator direct_hint = direct_func.lower_bound(k); + + if(direct_hint != direct_func.end() && + direct_hint->first == k) + return false; + + reverse_iterator reverse_it = reverse_func.insert(Reverse_entry(d, k)); + + direct_func.insert(direct_hint, Direct_entry(k, reverse_it)); + + CGAL_assertion(is_valid()); + return(true); + } + + bool erase(const Key& k); + + // Access + reverse_iterator front() + { + CGAL_assertion(is_valid() && !empty()); + return(reverse_func.begin()); + } + + void pop_front() + { + CGAL_assertion(is_valid()); + reverse_iterator rit = reverse_func.begin(); + direct_iterator pos = direct_func.find(rit->second); + CGAL_assertion(pos != direct_func.end()); + CGAL_assertion(pos->second == rit); + + direct_func.erase(pos); + reverse_func.erase(rit); + CGAL_assertion(is_valid()); + } + + const_iterator begin() const + { + return direct_func.begin(); + } + + const_iterator end() const + { + return direct_func.end(); + } + + void dump_direct_func(std::ostream& out) + { + for(typename Direct_func::iterator it = direct_func.begin(); + it != direct_func.end(); + ++it) + out << it->second->first << " " + << "(" + << it->first->vertex(0)->point() << ", " + << it->first->vertex(1)->point() << ", " + << it->first->vertex(2)->point() + << ")" << std::endl; + } + + void dump_reverse_func(std::ostream& out) + { + for(typename Reverse_func::iterator it = reverse_func.begin(); + it != reverse_func.end(); + ++it) + out << it->first << " " + << "(" + << it->second->vertex(0)->point() << ", " + << it->second->vertex(1)->point() << ", " + << it->second->vertex(2)->point() + << ")" << std::endl; + } +}; + +template +bool +Double_map<_Key, _Data, _Direct_compare, _Reverse_compare>:: +erase(const Key& k) +{ + CGAL_assertion(is_valid()); + direct_iterator pos = direct_func.find(k); + if (pos == direct_func.end()) + return false; + else + { + reverse_func.erase(pos->second); + direct_func.erase(pos); + } + + CGAL_assertion(is_valid()); + return true; +} + +} // end namespace CGAL + +#endif // CGAL_DOUBLE_MAP_H diff --git a/Mesh_2/include/CGAL/Filter_circulator.h b/Mesh_2/include/CGAL/Filter_circulator.h new file mode 100644 index 00000000000..4a4759383b4 --- /dev/null +++ b/Mesh_2/include/CGAL/Filter_circulator.h @@ -0,0 +1,98 @@ +// Copyright (c) 2003-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) : Laurent RINEAU + +#ifndef CGAL_FILTRED_CIRCULATOR_H +#define CGAL_FILTRED_CIRCULATOR_H + +namespace CGAL { + +template +class Filter_circulator : public Circ +{ + bool is_null; + Pred test; + +public: + typedef Filter_circulator Self; + + + Filter_circulator(const Pred p=Pred()): is_null(true), test(p) {}; + + Filter_circulator(const Self& c): Circ(c), is_null(c.is_null), + test(c.test) {}; + + Self& operator=(const Self& c) + { + //this->Circ::operator=(c); // This does not work with bcc + //*this = c; // This does not work with VC++6 + static_cast(*this) = static_cast(c); + is_null=c.is_null; + test=c.test; + return *this; + } + + Filter_circulator(const Circ& c, const Pred& p=Pred()) + : Circ(c), is_null(false), test(p) + { + if(test(static_cast(*this))) + is_null=false; + else + { + Self end(*this); + do { + this->Circ::operator++(); + } while( !test(static_cast(*this)) && (*this)!=end ); + if((*this)==end) + is_null=true; + } + }; + + bool operator==( CGAL_NULL_TYPE ) const { + return is_null; + } + + bool operator!=( CGAL_NULL_TYPE ) const { + return !is_null; + } + + bool operator==(const Self& c) const + { + return is_null==c.is_null && this->Circ::operator==(c); + } + + bool operator!=( const Self& c) const { return !(*this == c); } + + Self& operator++() { + CGAL_assertion(!is_null); + do { + this->Circ::operator++(); + } while( !test(static_cast(*this)) ); + return *this; + } + + Self operator++(int) { + Self tmp= *this; + ++*this; + return tmp; + } +}; + +} + +#endif diff --git a/Mesh_2/include/CGAL/IO/File_poly.h b/Mesh_2/include/CGAL/IO/File_poly.h new file mode 100644 index 00000000000..fd3d7560949 --- /dev/null +++ b/Mesh_2/include/CGAL/IO/File_poly.h @@ -0,0 +1,164 @@ +// 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) : Laurent RINEAU + +#ifndef CGAL_FILE_POLY_H +#define CGAL_FILE_POLY_H + +namespace CGAL { + +template +inline +void +read_triangle_poly_file(CDT& t, std::istream &f) +{ + read_triangle_poly_file(t, f, Emptyset_iterator()); +} + +//the function that reads a Shewchuk Triangle .poly file +template +void +read_triangle_poly_file(CDT& t, std::istream &f, + OutputIterator seeds) +{ + typedef typename CDT::Vertex_handle Vertex_handle; + typedef typename CDT::Point Point; + + t.clear(); + + unsigned int number_of_points; + skip_comment_OFF(f); + f >> number_of_points; + skip_until_EOL(f); + skip_comment_OFF(f); + + // read vertices + std::vector vertices(number_of_points); + for(unsigned int i = 0; i < number_of_points; ++i) + { + unsigned int j; + Point p; + f >> j >> p; + skip_until_EOL(f); skip_comment_OFF(f); + vertices[--j] = t.insert(p); + } + + // read segments + unsigned int number_of_segments; + f >> number_of_segments; + skip_until_EOL(f); skip_comment_OFF(f); + for(unsigned int k = 0; k < number_of_segments; ++k) + { + unsigned int l, v1, v2; + f >> l >> v1 >> v2; + skip_until_EOL(f); skip_comment_OFF(f); + t.insert_constraint(vertices[--v1], vertices[--v2]); + } + + // read holes + unsigned int number_of_holes; + f >> number_of_holes; + for(unsigned int m = 0; m < number_of_holes; ++m) + { + unsigned int n; + Point p; + f >> n >> p; + skip_until_EOL(f); skip_comment_OFF(f); + *seeds++ = p; + } +} + +//the function that write a Shewchuk Triangle .poly file +template +void +write_triangle_poly_file(const CDT& t, std::ostream &f, + InputIterator begin, InputIterator end) +{ + typedef typename CDT::Vertex_handle Vertex_handle; + typedef typename CDT::Finite_vertices_iterator + Finite_vertices_iterator; + typedef typename CDT::Finite_edges_iterator + Finite_edges_iterator; + + std::map index; + + // write vertices + f << "# Shewchuk Triangle .poly file, produced by the CGAL::Mesh_2 package" + << std::endl + << "# Neither attributes nor boundary markers are used." << std::endl + << t.number_of_vertices() << " " << 2 << " " + << 0 << " " << 0 << std::endl; + + f << std::endl; + + unsigned int vertices_counter = 0; + for(Finite_vertices_iterator vit = t.finite_vertices_begin(); + vit != t.finite_vertices_end(); + ++vit) + { + f << ++vertices_counter << " " << vit->point() << std::endl; + index[vit] = vertices_counter; + } + + f << std::endl; + + // write constrained edges + + int number_of_constrained_edges = 0; + for(Finite_edges_iterator it = t.finite_edges_begin(); + it != t.finite_edges_end(); + ++it) + if(it->first->is_constrained(it->second)) + ++number_of_constrained_edges; + + f << number_of_constrained_edges << " " << 0 << std::endl; + unsigned int edges_counter = 0; + + for(Finite_edges_iterator eit = t.finite_edges_begin(); + eit != t.finite_edges_end(); + ++eit) + if(eit->first->is_constrained(eit->second)) + f << ++edges_counter << " " + << index[eit->first->vertex(t.cw(eit->second))] << " " + << index[eit->first->vertex(t.ccw(eit->second))] + << std::endl; + + f << std::endl; + + + // write seeds, assuming that the seeds unmarks faces + f << std::distance(begin, end) << std::endl; + unsigned int seeds_counter = 0; + for(InputIterator sit = begin; + sit!=end; ++sit) + f << ++seeds_counter << " " << *sit << std::endl; +} + +//the same without holes. +template +void +write_triangle_poly_file(const CDT& t, std::ostream &f) +{ + std::list l; + + write_triangle_poly_file(t, f, l.begin(), l.end()); +} + +} // end namespace CGAL + +#endif // CGAL_FILE_POLY_H diff --git a/Mesh_2/include/CGAL/Mesh_2/Clusters.h b/Mesh_2/include/CGAL/Mesh_2/Clusters.h new file mode 100644 index 00000000000..0dbf0809c07 --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Clusters.h @@ -0,0 +1,558 @@ +// Copyright (c) 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) : Laurent RINEAU + +#ifndef CGAL_MESH_2_CLUSTERS_H +#define CGAL_MESH_2_CLUSTERS_H + +#include + +#include +#include + +namespace CGAL { + +namespace Mesh_2 +{ + + namespace details + { + template + class Is_edge_constrained { + const Tr* tr_; + public: + typedef Is_edge_constrained Self; + typedef typename Tr::Edge_circulator Edge_circulator; + + Is_edge_constrained(const Tr& tr) : tr_(&tr) + {} + + bool operator()(const Edge_circulator& ec) const + { + return tr_->is_constrained(*ec); + } + }; + } // end namespace details + +template +class Clusters +{ + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Point Point; + typedef typename Tr::Geom_traits Geom_traits; + typedef typename Geom_traits::FT FT; + typedef FT Squared_length; /** > + Constrained_edge_circulator; + +public: + /** \name Clusters public types */ + + /** + * \c Cluster register several informations about clusters. + * A cluster is a set of vertices v_i incident to one vertice + * v_0, so that angles between segments [v_0, v_i] is less than 60 + * degres. + */ + struct Cluster { + bool reduced ; /**< Is the cluster reduced? */ + + /** + * Smallest_angle gives the two vertices defining the + * smallest angle in the cluster. + */ + std::pair smallest_angle; + + FT rmin; // @fixme: rmin has no meaning if reduced=false!!! + Squared_length minimum_squared_length; + + /** + * The following map tells what vertices are in the cluster and if + * the corresponding segment has been splitted once. + */ + typedef std::map Vertices_map; + Vertices_map vertices; + + bool is_reduced() const { + return reduced; + } + + bool is_reduced(const Vertex_handle v) { + return vertices[v]; + } + }; +private: + /** \name Clusters associated types */ + + typedef std::multimap Cluster_map; + typedef typename Cluster_map::value_type Cluster_map_value_type; + + template + struct Pair_get_first: public std::unary_function + { + typedef typename Pair::first_type result; + const result& operator()(const Pair& p) const + { + return p.first; + } + }; + + typedef typename Cluster::Vertices_map Cluster_vertices_map; + +private: + /* --- protected datas --- */ + + Tr& tr; /**< The triangulation itself. */ + + /** + * Multimap \c Vertex_handle -> \c Cluster + * Each vertex can have several clusters. + */ + Cluster_map cluster_map; + +public: + typedef typename Cluster_map::const_iterator const_iterator; + typedef typename Cluster_map::iterator iterator; + + Clusters(Tr& tr_) : tr(tr_) + { + } + + /** For all vertices, calls create_clusters_of_vertex(). */ + void create_clusters(); + +private: + /** + * Computes clusters of the vertex \c v, using the auxiliary function + * construct_cluster(). + */ + void create_clusters_of_vertex(const Vertex_handle v); + + /** + * Adds the sequence [\c begin, \c end] to the cluster \c c and adds it + * to the clusters of the vertex \c v. + */ + void construct_cluster(const Vertex_handle v, + Constrained_edge_circulator begin, + const Constrained_edge_circulator& end, + Cluster c = Cluster()); + +public: + /** \name Functions to manage clusters during the refinement process. */ + + /** + * Update the cluster of [\c va,\c vb], putting \c vm instead of \c vb. + * If reduction=false, the edge [va,vm] is not set reduced. + */ + void update_cluster(Cluster& c, iterator it, + const Vertex_handle va, const Vertex_handle vb, + const Vertex_handle vm, + bool reduction = true); + + /** + * Returns the cluster of [\c va,\c vb] in \c c and return true + * if it is in a cluster. Returns also a const_iterator in \c it. + */ + bool get_cluster(const Vertex_handle va, const Vertex_handle vb, + Cluster& c, iterator& it); + + /** Const version of get_cluster(). */ + bool get_cluster(const Vertex_handle va, const Vertex_handle vb, + Cluster& c, const_iterator& it) const; + + /** \name Auxiliary functions that return a boolean. */ + + /** + * Tells if the angle is less than 60 degres. + * Uses squared_cosine_of_angle_times_4() and used by + * create_clusters_of_vertex(). + */ + bool is_small_angle(const Point& pleft, + const Point& pmiddle, + const Point& pright) const; + +private: + /** \name Helping computing functions */ + + /** Returns the squared cosine of the angle + times 4. */ + FT squared_cosine_of_angle_times_4(const Point& pleft, + const Point& pmiddle, + const Point& pright) const; + + /** Helper functions to access the two vertices of an Edge + source is the vertex around which the circulator turns. */ + //@{ + Vertex_handle source(const Edge_circulator& ec) const + { + return ec->first->vertex(tr.cw(ec->second)); + } + + Vertex_handle target(const Edge_circulator& ec) const + { + return ec->first->vertex(tr.ccw(ec->second)); + } + //@} + +public: + /** \name CONST ACCESS FUNCTIONS */ + typedef typename boost::transform_iterator< + Pair_get_first, + typename Cluster_map::const_iterator> + Cluster_vertices_iterator; + + typedef typename boost::transform_iterator< + Pair_get_first, + typename Cluster_vertices_map::const_iterator> + Vertices_in_cluster_iterator; + + int size() const + { + return cluster_map.size(); + } + + Cluster_vertices_iterator clusters_vertices_begin() const + { + return Cluster_vertices_iterator(cluster_map.begin()); + } + + Cluster_vertices_iterator clusters_vertices_end() const + { + return Cluster_vertices_iterator(cluster_map.end()); + } + + unsigned int number_of_clusters_at_vertex(const Vertex_handle& vh) const + { + typedef typename Cluster_map::const_iterator Iterator; + typedef std::pair Range; + Range range = cluster_map.equal_range(vh); + return std::distance(range.first, range.second); + } + + // returns the sequence of vertices bellonging to the n-th cluster of vh + std::pair + vertices_in_cluster_sequence(const Vertex_handle& vh, + const unsigned int n) const + { + typedef typename Cluster_map::const_iterator Iterator; + typedef std::pair Range; + typedef typename Range::first_type Clusters_iterator; + typedef Pair_get_first + Get_first; + + Range range = cluster_map.equal_range(vh); + Iterator first = range.first; + std::advance(first, n); + const Cluster& c = first->second; + + return + std::make_pair(Vertices_in_cluster_iterator(c.vertices.begin()), + Vertices_in_cluster_iterator(c.vertices.end())); + } + +}; // end class Clusters + +template +void Clusters:: +update_cluster(Cluster& c, iterator it, Vertex_handle va, + Vertex_handle vb, Vertex_handle vm, bool reduction) +{ + typename Geom_traits::Compute_squared_distance_2 squared_distance = + tr.geom_traits().compute_squared_distance_2_object(); + + cluster_map.erase(it); + + c.vertices.erase(vb); + c.vertices[vm] = reduction; + + if(vb==c.smallest_angle.first) + c.smallest_angle.first = vm; + if(vb==c.smallest_angle.second) + c.smallest_angle.second = vm; + + FT l = squared_distance(va->point(),vm->point()); + if(lfirst)) + ++it; // @todo: use std::find and an object class + if(it==c.vertices.end()) + c.reduced = true; + } + + if(c.is_reduced()) + c.rmin = squared_distance(c.smallest_angle.first->point(), + c.smallest_angle.second->point())/FT(4); + cluster_map.insert(Cluster_map_value_type(va,c)); +} + +template +bool Clusters:: +get_cluster(Vertex_handle va, Vertex_handle vb, Cluster& c, + const_iterator& it) const +{ + typedef std::pair Range; + + Range range = cluster_map.equal_range(va); + + for(it = range.first; it != range.second; it++) + { + const Cluster &cl = it->second; + if(cl.vertices.find(vb)!=cl.vertices.end()) { + c = it->second; + return true; + } + } + return false; +} + +template +bool Clusters:: +get_cluster(Vertex_handle va, Vertex_handle vb, Cluster& c, + iterator& it) +{ + typedef std::pair Range; + + Range range = cluster_map.equal_range(va); + + for(it = range.first; it != range.second; it++) + { + const Cluster &cl = it->second; + if(cl.vertices.find(vb)!=cl.vertices.end()) { + c = it->second; + return true; + } + } + return false; +} + +template +void Clusters:: +create_clusters() +{ + cluster_map.clear(); +#ifndef CGAL_IT_IS_A_CONSTRAINED_TRIANGULATION_PLUS + for(typename Tr::Finite_vertices_iterator vit = tr.finite_vertices_begin(); + vit != tr.finite_vertices_end(); + vit++) + create_clusters_of_vertex(vit); +#else + Unique_hash_map created(false); + for(typename Tr::Subconstraint_iterator it = tr.subconstraints_begin(); + it != tr.subconstraints_end(); ++it) { + Vertex_handle vh = it->first.first; + if(!created[vh]){ + created[vh] = true; + create_clusters_of_vertex(vh); + } + + vh = it->first.second; + if(!created[vh]){ + created[vh] = true; + create_clusters_of_vertex(vh); + } + } +#endif +} + +template +void Clusters:: +create_clusters_of_vertex(const Vertex_handle v) +{ + details::Is_edge_constrained test(tr); + + Constrained_edge_circulator begin(tr.incident_edges(v),test); + + // This circulator represents all constrained edges around the + // vertex v. An edge [v,v'] is represented by the vertex v'. + + if(begin == 0) return; // if there is only one vertex + + Constrained_edge_circulator + current(begin), next(begin), cluster_begin(begin); + ++next; // next is always just after current. + if(current == next) return; + + bool in_a_cluster = false; + do + { + if(is_small_angle(target(current)->point(), v->point(), + target(next)->point())) + { + if(!in_a_cluster) + { + // at this point, current is the beginning of a cluster + in_a_cluster = true; + cluster_begin = current; + } + } + else + if(in_a_cluster) + { + // at this point, current is the end of a cluster and + // cluster_begin is its beginning + construct_cluster(v, cluster_begin, current); + in_a_cluster = false; + } + ++next; + ++current; + } while( current!=begin ); + if(in_a_cluster) + { + Cluster c; + iterator it; + if(get_cluster(v, target(begin), c, it)) + { + // get the cluster and erase it from the clusters map + cluster_map.erase(it); + construct_cluster(v, cluster_begin, begin, c); + } + else + construct_cluster(v, cluster_begin, current); + } +} + +template +void Clusters:: +construct_cluster(Vertex_handle v, + Constrained_edge_circulator begin, + const Constrained_edge_circulator& end, + Cluster c) +{ + typename Geom_traits::Compute_squared_distance_2 squared_distance = + tr.geom_traits().compute_squared_distance_2_object(); + + if(c.vertices.empty()) + { + c.reduced = false; + // c.rmin is not initialized because + // reduced=false! + c.minimum_squared_length = + squared_distance(v->point(), target(begin)->point()); + Constrained_edge_circulator second(begin); + ++second; + c.smallest_angle.first = target(begin); + c.smallest_angle.second = target(second); + } + + bool all_edges_in_cluster=false; // tell if all incident edges are + // in the cluster + if(begin==end) + all_edges_in_cluster=true; + + const Point& vp = v->point(); + + FT greatest_cosine = + squared_cosine_of_angle_times_4(c.smallest_angle.first->point(), + v->point(), + c.smallest_angle.second->point()); + + Constrained_edge_circulator next(begin); + ++next; + do + { + c.vertices[target(begin)] = false; + Squared_length l = squared_distance(vp, + target(begin)->point()); + c.minimum_squared_length = + std::min(l,c.minimum_squared_length); + + if(all_edges_in_cluster || begin!=end) + { + FT cosine = + squared_cosine_of_angle_times_4(target(begin)->point(), + v->point(), + target(next)->point()); + if(cosine>greatest_cosine) + { + greatest_cosine = cosine; + c.smallest_angle.first = target(begin); + c.smallest_angle.second = target(next); + } + } + } + while(next++,begin++!=end); + typedef typename Cluster_map::value_type Value_key_pair; + cluster_map.insert(Value_key_pair(v,c)); +} + +template +bool Clusters:: +is_small_angle(const Point& pleft, + const Point& pmiddle, + const Point& pright) const +{ + typename Geom_traits::Angle_2 angle = + tr.geom_traits().angle_2_object(); + typename Geom_traits::Orientation_2 orient = + tr.geom_traits().orientation_2_object(); + + if( angle(pleft, pmiddle, pright)==OBTUSE ) + return false; + if( orient(pmiddle,pleft,pright)==RIGHT_TURN) + return false; + + FT cos_alpha = squared_cosine_of_angle_times_4(pleft, pmiddle, + pright); + + if(cos_alpha > 1) + { + return true; //the same cluster + } + else + { + return false; //another cluster + } +} + +template +typename Clusters::FT +Clusters:: +squared_cosine_of_angle_times_4(const Point& pb, const Point& pa, + const Point& pc) const +{ + typename Geom_traits::Compute_squared_distance_2 squared_distance = + tr.geom_traits().compute_squared_distance_2_object(); + + const FT + a = squared_distance(pb, pc), + b = squared_distance(pa, pb), + c = squared_distance(pa, pc); + + const FT num = a-(b+c); + + return (num*num)/(b*c); +} + +} // end namespace Mesh_2 + +} // end namespace CGAL + +#endif // CGAL_MESH_2_CLUSTERS_H diff --git a/Mesh_2/include/CGAL/Mesh_2/Face_badness.h b/Mesh_2/include/CGAL/Mesh_2/Face_badness.h new file mode 100644 index 00000000000..f36f989f17d --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Face_badness.h @@ -0,0 +1,30 @@ +// 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) : Laurent RINEAU + +#ifndef CGAL_MESH_2_FACE_BADNESS_H +#define CGAL_MESH_2_FACE_BADNESS_H + +namespace CGAL +{ + namespace Mesh_2 + { + enum Face_badness { NOT_BAD, BAD, IMPERATIVELY_BAD }; + } +} +#endif // CGAL_MESH_2_FACE_BADNESS_H diff --git a/Mesh_2/include/CGAL/Mesh_2/Filtered_queue_container.h b/Mesh_2/include/CGAL/Mesh_2/Filtered_queue_container.h new file mode 100644 index 00000000000..5b58051e110 --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Filtered_queue_container.h @@ -0,0 +1,101 @@ +// 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) : Laurent RINEAU + +#ifndef CGAL_FILTRED_QUEUE_CONTAINER_H +#define CGAL_FILTRED_QUEUE_CONTAINER_H + +#include +#include + +namespace CGAL { + + namespace Mesh_2 { + + /** This container is a filtered queue: front() and empty() use an + object predicate to test if the element is ok. */ + template + class Filtered_queue_container + { + public: + typedef Elt Element; + typedef Pred Predicate; + + typedef typename std::deque::const_iterator const_iterator; + private: + // --- private datas --- + std::deque d; + Predicate test; + + public: + Filtered_queue_container(Predicate p) : d(), test(p) {} + Filtered_queue_container() : test() {} + + void clear() + { + d.clear(); + } + + bool empty() + { + if(d.empty()) + return true; + + while( !test(d.front()) ) + { + d.pop_front(); + if( d.empty() ) + return true; + } + + return false; + } + + Element& get_next_element() + { + while( !test(d.front()) ) + d.pop_front(); + return d.front(); + } + + void add_element(const Element& e) + { + d.push_back(e); + } + + void remove_next_element() + { + d.pop_front(); + } + + const_iterator begin() const + { + return d.begin(); + } + + const_iterator end() const + { + return d.end(); + } + }; // end Simple_queue_container + + } // end namespace Mesh_2 + +} // end namespace CGAL + +#endif // CGAL_FILTRED_QUEUE_CONTAINER_H diff --git a/Mesh_2/include/CGAL/Mesh_2/README b/Mesh_2/include/CGAL/Mesh_2/README new file mode 100644 index 00000000000..30d815f220c --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/README @@ -0,0 +1,6 @@ +No header in this sub-directory, but Face_badness.h, is documented. They +are internal headers of the Mesh_2 packages, and should not be used. + +If you want to use some undocumented functionnality, please contact me +(Laurent Rineau ) so that we can see if I can move +some internal details to the documented interface. diff --git a/Mesh_2/include/CGAL/Mesh_2/Refine_edges.h b/Mesh_2/include/CGAL/Mesh_2/Refine_edges.h new file mode 100644 index 00000000000..50df547f52d --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Refine_edges.h @@ -0,0 +1,642 @@ +// Copyright (c) 2004-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) : Laurent RINEAU + +#ifndef CGAL_MESH_2_REFINE_EDGES_H +#define CGAL_MESH_2_REFINE_EDGES_H + +#include +#include +#include + +#include +#include +#include +#include + +namespace CGAL { + +/** + * \namespace Mesh_2 + * Defines classes that are not yet documented. + * + * \namespace Mesh_2::details + * Namespace for internal use. + */ + +namespace Mesh_2 { + + namespace details { + + /** This class defines several auxiliary types for \c Refine_edges. */ + template + struct Refine_edges_base_types + { + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + + typedef std::pair Constrained_edge; + + /** Object predicate that tests if a given \c Constrained_Edge is + really an edge of the triangulation and is constrained. + */ + class Is_a_constrained_edge { + const Tr& tr; + public: + /** \param tr_ points to the triangulation. */ + explicit Is_a_constrained_edge(const Tr& tr_) : tr(tr_) {} + + bool operator()(const Constrained_edge& ce) const + { + Face_handle fh; + int i; + return tr.is_edge(ce.first, ce.second, fh,i) && + fh->is_constrained(i); + } + }; + + typedef ::CGAL::Mesh_2::Filtered_queue_container + Default_container; + }; + + }; // end namespace details + + + /** + * Predicate class that verifies that an edge is locally conforming + * Gabriel. Moreover, This classes defines a predicate that test if an + * edge is encroached by a given point. + * \param Tr The type of the trianglation. + */ + template + struct Is_locally_conforming_Gabriel + { + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + typedef typename Tr::Point Point; + typedef typename Tr::Geom_traits Geom_traits; + + /** Operator that takes an edge (\c fh, \c index). */ + bool operator()(Tr& ct, + const Face_handle& fh, + const int i) const + { + typedef typename Geom_traits::Angle_2 Angle_2; + + const Angle_2 angle = ct.geom_traits().angle_2_object(); + + const Vertex_handle& va = fh->vertex(ct. cw(i)); + const Vertex_handle& vb = fh->vertex(ct.ccw(i)); + + const Point& a = va->point(); + const Point& b = vb->point(); + + const Vertex_handle& vi = fh->vertex(i); + const Vertex_handle& mvi = fh->mirror_vertex(i); + + return( ( ct.is_infinite(vi) || + angle(a, vi->point(), b) != OBTUSE) + && + ( ct.is_infinite(mvi) || + angle(a, mvi->point(), b) != OBTUSE) + ); + } + + /** Operator that takes an edge (\c va, \c vb). */ + bool operator()(Tr& ct, + const Vertex_handle& va, + const Vertex_handle& vb) const + { + Face_handle fh; + int i; + CGAL_assertion_code( bool should_be_true = ) + ct.is_edge(va, vb, fh, i); + CGAL_assertion( should_be_true == true ); + + return this->operator()(ct, fh, i); + } + + /** + * Operator that takes an edge (\c fh, \c index) and a point \c p. + * Tests if the point encroached the edge. + */ + bool operator()(Tr& ct, + const Face_handle& fh, + const int i, + const Point& p) const + { + return this->operator()(ct, + fh->vertex(ct. cw(i)), + fh->vertex(ct.ccw(i)), + p); + } + + /** + * Operator that takes an edge (\c va, \c vb) and a point \c p. + * Tests if the point encroached the edge. + */ + bool operator()(Tr& ct, + const Vertex_handle& va, + const Vertex_handle& vb, + const Point& p) const + { + typedef typename Geom_traits::Angle_2 Angle_2; + + const Angle_2 angle = ct.geom_traits().angle_2_object(); + + const Point& a = va->point(); + const Point& b = vb->point(); + + return( angle(a, p, b) != OBTUSE ); + } + }; + + /** + * Predicate class that verifies that an edge is locally conforming + * Delaunay. + * \param Tr The type of the trianglation. + */ + template + struct Is_locally_conforming_Delaunay + { + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + typedef typename Tr::Point Point; + typedef typename Tr::Geom_traits Geom_traits; + + /** Operator that takes an edge (\c fh, \c index). */ + bool operator()(Tr& ct, + const Face_handle& fh, + const int i) const + { + typedef typename Geom_traits::Side_of_oriented_circle_2 + Side_of_oriented_circle_2; + + Side_of_oriented_circle_2 in_circle = + ct.geom_traits().side_of_oriented_circle_2_object(); + + const Vertex_handle& vi = fh->vertex(i); + const Vertex_handle& mvi = fh->mirror_vertex(i); + + if(ct.is_infinite(vi) || ct.is_infinite(mvi)){ + return true; + } + + const Point& a = fh->vertex(ct. cw(i))->point(); + const Point& b = fh->vertex(ct.ccw(i))->point(); + const Point& c = vi->point(); + const Point& d = mvi->point(); + + return( in_circle(c, b, a, d) == ON_NEGATIVE_SIDE ); + } + + /** Operator that takes an edge (\c va, \c vb). */ + bool operator()(Tr& ct, + const Vertex_handle& va, + const Vertex_handle& vb) const + { + typedef typename Geom_traits::Side_of_oriented_circle_2 + Side_of_oriented_circle_2; + + Side_of_oriented_circle_2 in_circle = + ct.geom_traits().side_of_oriented_circle_2_object(); + + Face_handle fh; + int i; + CGAL_assertion_code( bool test = ) + ct.is_edge(va, vb, fh, i); + CGAL_assertion( test == true ); + + const Vertex_handle& vi = fh->vertex(i); + const Vertex_handle& mvi = fh->mirror_vertex(i); + + if(ct.is_infinite(vi) || ct.is_infinite(mvi)){ + return true; + } + + const Point& a = va->point(); + const Point& b = vb->point(); + const Point& c = vi->point(); + const Point& d = mvi->point(); + + return( in_circle(c, b, a, d) == ON_NEGATIVE_SIDE ); + } + }; + +/** + * This class is the base for the first level of Mesh_2: the edge + * conforming level. It does not handle clusters. + * + * \param Tr is the type of triangulation on which the level acts. + * \param Is_locally_conform defines the locally conform criterion: Gabriel + * or Delaunay. It defaults to the Garbriel criterion. + * \param Container is the type of container. It defaults to a filtered + * queue of \c Vertex_handle pair (see \c Filtered_queue_container). + */ +template < + class Tr, + class Is_locally_conform = Is_locally_conforming_Gabriel, + class Container = + typename details::Refine_edges_base_types::Default_container +> +class Refine_edges_base : + public No_private_test_point_conflict, + public No_after_no_insertion +{ +public: + typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; + typedef typename Tr::Face_circulator Face_circulator; + + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + typedef typename Tr::Edge Edge; + typedef typename Tr::Point Point; + typedef typename Tr::Geom_traits Geom_traits; + + typedef Triangulation_mesher_level_traits_2 Triangulation_traits; + + typedef typename Triangulation_traits::Zone Zone; + + typedef typename details::Refine_edges_base_types::Constrained_edge + Constrained_edge; + +protected: + /* --- protected datas --- */ + + Tr& tr; /**< The triangulation itself. */ + + /** Predicates to filter edges. */ + typedef typename details::Refine_edges_base_types + ::Is_a_constrained_edge Is_a_constrained_edge; + + const Is_a_constrained_edge is_a_constrained_edge; + + Container edges_to_be_conformed; /**< Edge queue */ + + /** The object predicate that defines the locally conform criteria. */ + Is_locally_conform is_locally_conform; + + Vertex_handle va, vb; + + bool imperatively; + +public: + /** \name CONSTRUCTORS */ + + Refine_edges_base(Tr& tr_) : + tr(tr_), is_a_constrained_edge(tr_), + edges_to_be_conformed(is_a_constrained_edge), + is_locally_conform(), imperatively(false), converter(tr_) + { + } + + /** \name HELPING FUNCTIONS */ + + void clear() + { + edges_to_be_conformed.clear(); + } + + void set_imperative_refinement(bool b) + { + imperatively = b; + } + + /** \name Functions that this level must declare. */ + + Tr& triangulation_ref_impl() + { + return tr; + } + + const Tr& triangulation_ref_impl() const + { + return tr; + } + + Zone conflicts_zone_impl(const Point& p, Edge edge) + { + Zone zone; + + typedef std::back_insert_iterator OutputItFaces; + typedef std::back_insert_iterator OutputItEdges; + + OutputItFaces faces_out(zone.faces); + OutputItEdges edges_out(zone.boundary_edges); + + const Face_handle& f = edge.first; + const int i = edge.second; + *faces_out++ = f; + const Face_handle n = f->neighbor(i); + *faces_out++ = n; + const int ni = f->mirror_index(i); + std::pair + pit = std::make_pair(faces_out,edges_out); + pit = triangulation_ref_impl().propagate_conflicts(p,f,Tr::ccw(i),pit); + pit = triangulation_ref_impl().propagate_conflicts(p,f,Tr:: cw(i),pit); + pit = triangulation_ref_impl().propagate_conflicts(p,n,Tr::ccw(ni),pit); + pit = triangulation_ref_impl().propagate_conflicts(p,n,Tr:: cw(ni),pit); + return zone; + } + + Vertex_handle insert_impl(const Point& p, Zone& zone) + { + return triangulation_ref_impl().star_hole(p, + zone.boundary_edges.begin(), + zone.boundary_edges.end(), + zone.faces.begin(), + zone.faces.end() + ); + } + + /** Scans all constrained edges and put them in the queue if they are + encroached. */ + void scan_triangulation_impl() + { + clear(); +#ifndef CGAL_IT_IS_A_CONSTRAINED_TRIANGULATION_PLUS + for(Finite_edges_iterator ei = tr.finite_edges_begin(); + ei != tr.finite_edges_end(); + ++ei) + if(ei->first->is_constrained(ei->second) && + !is_locally_conform(tr, ei->first, ei->second) ) + add_constrained_edge_to_be_conformed(*ei); + +#else + for(typename Tr::Subconstraint_iterator it = tr.subconstraints_begin(); + it != tr.subconstraints_end(); ++it) + { + const Vertex_handle& v1 = it->first.first; + const Vertex_handle& v2 = it->first.second; + + if(fh->is_constrained(i) && + !is_locally_conform(tr, v1, v2) ) + add_constrained_edge_to_be_conformed(v1, v2); + } +#endif + } // end scan_triangulation_impl() + + /** Tells if the queue of edges to be conformed is empty or not. */ + bool no_longer_element_to_refine_impl() + { + return edges_to_be_conformed.empty(); + } + + /** Get the next edge to conform. */ + Edge get_next_element_impl() + { + Constrained_edge edge = edges_to_be_conformed.get_next_element(); + + Face_handle fh; + int index; + + CGAL_assertion_code( bool should_be_true =) + tr.is_edge(edge.first, edge.second, fh, index); + CGAL_assertion( should_be_true == true ); + + return Edge(fh, index); + } + + /** Pop the first edge of the queue. */ + void pop_next_element_impl() + { + edges_to_be_conformed.remove_next_element(); + } + + /** This version computes the refinement point without handling + clusters. The refinement point of an edge is just the middle point of + the segment. + Saves the handles of the edge that will be splitted. + This function is overridden in class Refine_edge_with_clusters. + */ + Point refinement_point_impl(const Edge& edge) + { + typename Geom_traits::Construct_midpoint_2 + midpoint = tr.geom_traits().construct_midpoint_2_object(); + + va = edge.first->vertex(tr.cw (edge.second)); + vb = edge.first->vertex(tr.ccw(edge.second)); + + return midpoint(va->point(), vb->point()); + } + + /** Store the edge. */ + void before_conflicts_impl(const Edge&, const Point&) + { + } + + /** + * Test if the edges of the boundary are locally conforming. + * Push which that are not in the list of edges to be conformed. + */ + Mesher_level_conflict_status + test_point_conflict_from_superior_impl(const Point& p, + Zone& z) + { + Mesher_level_conflict_status status = NO_CONFLICT; + + for(typename Zone::Edges_iterator eit = z.boundary_edges.begin(); + eit != z.boundary_edges.end(); ++eit) + { + const Face_handle& fh = eit->first; + const int& i = eit->second; + + if(fh->is_constrained(i) && !is_locally_conform(tr, fh, i, p)) + { + add_constrained_edge_to_be_conformed(*eit); + status = CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED; + } + } + + return status; + } + + /** Unmark as constrained. */ + void before_insertion_impl(const Edge& e, const Point&, + const Zone&) + { + const Face_handle& f = e.first; + const int& i = e.second; + + f->set_constraint(i, false); + (f->neighbor(i))->set_constraint(f->mirror_index(i), false); + } + + /** + * Scans the edges of the star boundary, to test if they are both + * locally conforming. If not, push them in the list of edges to be + * conformed. + * + */ + void after_insertion_impl(const Vertex_handle& v) + { +#ifdef CGAL_MESH_2_VERBOSE + std::cerr << "E"; +#endif + // @todo Perhaps we should remove destroyed edges too. + // @warning This code has been rewroten! + + Face_circulator fc = tr.incident_faces(v), fcbegin(fc); + if( fc == 0 ) return; + + do { + const int i = fc->index(v); + CGAL_assertion( i>=0 && i < 4); + if( fc->is_constrained(i) && + !is_locally_conform(tr, fc, i) ) + add_constrained_edge_to_be_conformed(Edge(fc, i)); + ++fc; + } while( fc != fcbegin ); + + Face_handle fh; + int index; + + CGAL_assertion_code(bool should_be_true = ) + tr.is_edge(va, v, fh, index); + CGAL_assertion(should_be_true == true); + + fh->set_constraint(index,true); + fh->neighbor(index)->set_constraint(fh->mirror_index(index),true); + + CGAL_assertion_code( should_be_true = ) + tr.is_edge(vb, v, fh, index); + CGAL_assertion(should_be_true == true); + + fh->set_constraint(index,true); + fh->neighbor(index)->set_constraint(fh->mirror_index(index),true); + + if(!is_locally_conform(tr, va, v)) + add_constrained_edge_to_be_conformed(va, v); + + if(!is_locally_conform(tr, vb, v)) + add_constrained_edge_to_be_conformed(vb, v); + } // end after_insertion_impl + +protected: + /** \name Auxiliary functions */ + + /** Add an \c Edge \c e in the queue. */ + void add_constrained_edge_to_be_conformed(const Edge& e) + { + const Vertex_handle& va = e.first->vertex(tr. cw(e.second)); + const Vertex_handle& vb = e.first->vertex(tr.ccw(e.second)); + edges_to_be_conformed.add_element(std::make_pair(va, vb)); + } + + /** Add an edge (\c va,\c vb) in the queue. */ + void add_constrained_edge_to_be_conformed(const Vertex_handle& va, + const Vertex_handle& vb) + { + edges_to_be_conformed.add_element(std::make_pair(va, vb)); + } + +private: /** \name DEBUGGING TYPES AND DATAS */ + class From_pair_of_vertex_to_edge + : public std::unary_function + { + Tr& tr; + public: + From_pair_of_vertex_to_edge(Tr& t) : tr(t) {}; + + const Edge operator()(const Constrained_edge edge) const + { + Face_handle fh; + int index; + tr.is_edge(edge.first, edge.second, fh, index); + return Edge(fh, index); + } + }; // end From_pair_of_vertex_to_edge + + // -- private data member -- + From_pair_of_vertex_to_edge converter; + +private: + + typedef boost::filter_iterator + Aux_edges_filter_iterator; + +public: /** \name DEBUGGING FUNCTIONS */ + typedef boost::transform_iterator< + From_pair_of_vertex_to_edge, + Aux_edges_filter_iterator> Edges_const_iterator; + + Edges_const_iterator begin() const + { + return Edges_const_iterator( + Aux_edges_filter_iterator(is_a_constrained_edge, + this->edges_to_be_conformed.begin(), + this->edges_to_be_conformed.end()), + converter); + } + + Edges_const_iterator end() const + { + return Edges_const_iterator( + Aux_edges_filter_iterator(is_a_constrained_edge, + this->edges_to_be_conformed.end(), + this->edges_to_be_conformed.end()), + converter); + } +}; // end class Refine_edges_base + + namespace details { + template + struct Refine_edges_types + { + typedef Triangulation_mesher_level_traits_2 Triangulation_traits; + + typedef Mesher_level < + Tr, + Self, + typename Tr::Edge, + Null_mesher_level, + Triangulation_traits> Edges_mesher_level; + }; // end Refine_edges_types + } // end namespace details + +template , + typename Base = Refine_edges_base > +struct Refine_edges : + public Base, + public details::Refine_edges_types >::Edges_mesher_level +{ + typedef Refine_edges Self; + + typedef typename details::Refine_edges_types Types; + + typedef typename Types::Edges_mesher_level Mesher; +public: + Refine_edges(Tr& t, + Null_mesher_level& null_level) + : Base(t), Mesher(null_level) + { + } +}; // end Refine_edges + + +} // end namespace Mesh_2 + +} // end namespace CGAL + +#endif // CGAL_MESH_2_REFINE_EDGES_H diff --git a/Mesh_2/include/CGAL/Mesh_2/Refine_edges_visitor.h b/Mesh_2/include/CGAL/Mesh_2/Refine_edges_visitor.h new file mode 100644 index 00000000000..091d1142726 --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Refine_edges_visitor.h @@ -0,0 +1,158 @@ +// Copyright (c) 2004-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) : Laurent RINEAU + +#ifndef CGAL_MESH_2_REFINE_EDGES_VISITOR_H +#define CGAL_MESH_2_REFINE_EDGES_VISITOR_H + +#include + +namespace CGAL { +namespace Mesh_2 { + +/** + * This class is the visitor needed when Refine_edges if called from + * Refine_faces. + * \param Faces_base should be instanciated with Refine_face_base. + */ +template +class Refine_edges_visitor : public ::CGAL::Null_mesh_visitor +{ +public: + typedef typename Mesher_base::Triangulation Tr; + typedef typename Tr::Edge Edge; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + typedef typename Tr::Point Point; + typedef typename Triangulation_mesher_level_traits_2::Zone Zone; + + typedef typename details::Refine_edges_base_types::Constrained_edge + Constrained_edge; +private: + Mesher_base& mesher_base; + Vertex_handle va, vb; + bool mark_at_right, mark_at_left; + Null_mesh_visitor& null_mesh_visitor; + +public: + Refine_edges_visitor(Mesher_base& mesher_base_, + Null_mesh_visitor& null) + : mesher_base(mesher_base_), + null_mesh_visitor(null) + { + } + + Null_mesh_visitor previous_level() const { return null_mesh_visitor; } + + /** + * Store vertex handles and markers at left and right of the edge \c e. + */ + void before_conflicts(const Edge& e, const Point&) + { + const Face_handle& fh = e.first; + const int edge_index = e.second; + + va = fh->vertex(Tr::cw (edge_index)); + vb = fh->vertex(Tr::ccw(edge_index)); + + mark_at_right = fh->is_in_domain(); + mark_at_left = fh->neighbor(edge_index)->is_in_domain(); + } + + void before_insertion(const Edge&, const Point& p, Zone& z) + { + mesher_base.before_insertion_impl(Face_handle(), p, z); + } + + /** Restore markers in the star of \c v. */ + void after_insertion(const Vertex_handle& v) + { + Tr& tr = mesher_base.triangulation_ref_impl(); + + int dummy; + // if we put edge_index instead of dummy, Intel C++ does not find + // a matching function for is_edge + Face_handle fh; + + tr.is_edge(va, v, fh, dummy); + // set fh to the face at the right of [va,v] + + typename Tr::Face_circulator fc = tr.incident_faces(v, fh), fcbegin(fc); + // circulators are counter-clockwise, so we start at the right of + // [va,v] + do { + if( !tr.is_infinite(fc) ) + fc->set_in_domain(mark_at_right); + ++fc; + } while ( fc->vertex(tr.ccw(fc->index(v))) != vb ); + // we are now at the left of [va,vb] + do { + if( !tr.is_infinite(fc) ) + fc->set_in_domain(mark_at_left); + ++fc; + } while ( fc != fcbegin ); + + // then let's update bad faces + mesher_base.compute_new_bad_faces(v); + + CGAL_expensive_assertion(mesher_base.check_bad_faces()); + } + + template + void after_no_insertion(E, P, Z) const {} +}; // end class Refine_edges_visitor + +/** + * This class is the visitor for Refine_faces. + */ +template +class Refine_edges_visitor_from_faces +{ +public: + typedef Refine_edges_visitor Previous_level; + +private: + Previous_level previous; + +public: + + Refine_edges_visitor_from_faces(Mesher_base& mesher_base, + Null_mesh_visitor& null) + : previous(mesher_base, null) + { + } + + Previous_level& previous_level() { return previous; } + + template + void before_conflicts(E, P) const {} + + template + void before_insertion(E, P, Z) const {} + + template + void after_insertion(V) const {} + + template + void after_no_insertion(E, P, Z) const {} +}; // end class Refine_edges_visitor_from_faces + +} // end namespace Mesh_2 +} // end namespace CGAL + +#endif // CGAL_MESH_2_REFINE_EDGES_VISITOR_H diff --git a/Mesh_2/include/CGAL/Mesh_2/Refine_edges_with_clusters.h b/Mesh_2/include/CGAL/Mesh_2/Refine_edges_with_clusters.h new file mode 100644 index 00000000000..66a796cd94e --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Refine_edges_with_clusters.h @@ -0,0 +1,308 @@ +// Copyright (c) 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) : Laurent RINEAU + +#ifndef CGAL_MESH_2_REFINE_EDGES_WITH_CLUSTERS_H +#define CGAL_MESH_2_REFINE_EDGES_WITH_CLUSTERS_H + +#include +#include + +namespace CGAL { + +namespace Mesh_2 { +/** + * This class is the base for the first level of Mesh_2: the edge + * conforming level. It \e does handle clusters. + * To handle clusters, an helping \c Clusters object is used. + * + * \param Tr is the type of triangulation on which the level acts. + * \param Is_locally_conform defines the locally conform criterion: Gabriel + * or Delaunay. It defaults to the Garbriel criterion. + * \param Container is the type of container. It defaults to a filtered + * queue of \c Vertex_handle pair (see \c Filtered_queue_container). + */ +template < + class Tr, + class Is_locally_conform = Is_locally_conforming_Gabriel, + class Container = + typename details::Refine_edges_base_types::Default_container +> +class Refine_edges_base_with_clusters : + public Refine_edges_base +{ + typedef Refine_edges_base Super; + + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + typedef typename Tr::Edge Edge; + typedef typename Tr::Point Point; + typedef typename Tr::Geom_traits Geom_traits; + + typedef typename Geom_traits::FT FT; + + typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; + typedef typename Tr::Face_circulator Face_circulator; + + typedef typename Triangulation_mesher_level_traits_2::Zone Zone; + + typedef typename Clusters::Cluster Cluster; + typedef typename Clusters::iterator clusters_iterator; + + + /* --- private data --- */ + Clusters& clusters; + + bool va_has_a_cluster, vb_has_a_cluster; + bool cluster_splitted; + Cluster ca, cb; + clusters_iterator ca_it, cb_it; + + using Super::triangulation_ref_impl; + +public: + /** \name CONSTRUCTORS */ + + Refine_edges_base_with_clusters(Tr& tr_, Clusters& c_) + : Super(tr_), clusters(c_) + { + } + + + /** \name FUNCTIONS NEEDED BY Mesher_level OVERIDDEN BY THIS CLASS. */ + + Point refinement_point_impl(const Edge& edge) + { + typename Geom_traits::Construct_midpoint_2 + midpoint = this->triangulation_ref_impl().geom_traits().construct_midpoint_2_object(); + + this->va = edge.first->vertex(Tr::cw (edge.second)); + this->vb = edge.first->vertex(Tr::ccw(edge.second)); + +// std::cerr << "refinement_point_impl\n" << this->va->point() << " / " +// << this->vb->point() << std::endl; + + va_has_a_cluster = false; + vb_has_a_cluster = false; + cluster_splitted = false; + + // true bellow to remove ca and cb because they will + // be restored by update_cluster(...). + if( clusters.get_cluster(this->va,this->vb,ca,ca_it) ) { + if( clusters.get_cluster(this->vb,this->va,cb,cb_it) ) + { // both ends are clusters + va_has_a_cluster = true; + vb_has_a_cluster = true; + return midpoint(this->va->point(), this->vb->point()); + } + else { + // va only is a cluster + va_has_a_cluster = true; + return split_cluster_point(this->va,this->vb,ca); + } + } else + if( clusters.get_cluster(this->vb,this->va,cb,cb_it) ){ + // vb only is a cluster + vb_has_a_cluster = true; + return split_cluster_point(this->vb,this->va,cb); + }else{ + // no cluster + return midpoint(this->va->point(), this->vb->point()); + } + }; + + void after_insertion_impl(const Vertex_handle& v) + { +#ifdef CGAL_MESH_2_DEBUG_CLUSTERS + std::cerr << "update_clusters" << std::endl; + std::cerr << "va_has_a_cluster=" << va_has_a_cluster + << std::endl + << "vb_has_a_cluster=" << vb_has_a_cluster + << std::endl; + std::cerr << "clusters.size()=" << clusters.size() << std::endl; +#endif // CGAL_MESH_2_DEBUG_CLUSTERS + Super::after_insertion_impl(v); + if( va_has_a_cluster ) + clusters.update_cluster(ca,ca_it,this->va,this->vb,v,cluster_splitted); + if( vb_has_a_cluster ) + clusters.update_cluster(cb,cb_it,this->vb,this->va,v,cluster_splitted); +#ifdef CGAL_MESH_2_DEBUG_CLUSTERS + std::cerr << "clusters.size() after update_cluster=" + << clusters.size() << std::endl; +#endif // CGAL_MESH_2_DEBUG_CLUSTERS + } + + /** + * Test if the edges of the boundary are locally conforming. + * Push which that are not in the list of edges to be conformed. + */ + Mesher_level_conflict_status + test_point_conflict_from_superior_impl(const Point& p, + Zone& z) + { + Mesher_level_conflict_status status = NO_CONFLICT; + + Tr& tr = triangulation_ref_impl(); + + for(typename Zone::Edges_iterator eit = z.boundary_edges.begin(); + eit != z.boundary_edges.end(); ++eit) + { + const Face_handle& fh = eit->first; + const int& i = eit->second; + + if(fh->is_constrained(i) && !is_locally_conform(tr, fh, i, p)) + { + const Vertex_handle& v1 = fh->vertex( tr.cw (i)); + const Vertex_handle& v2 = fh->vertex( tr.ccw(i)); + + status = CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED; + + bool v1_has_a_cluster = clusters.get_cluster(v1,v2,ca,ca_it); + bool v2_has_a_cluster = clusters.get_cluster(v2,v1,cb,cb_it); + + if( ( v1_has_a_cluster && v2_has_a_cluster) || + (!v1_has_a_cluster && !v2_has_a_cluster) ) + { + // two clusters or no cluster + add_constrained_edge_to_be_conformed(v1, v2); + // status = CONF//CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED; + } + else + { + // only one cluster: c or c2 + if(v2_has_a_cluster) + ca = cb; +// What Shewchuk says: +// - If the cluster is not reduced (all segments don't have the same +// length as [v1,v2]), then split the edge +// - Else, let rmin be the minimum insertion radius introduced by the +// potential split, let T be the triangle whose circumcenter +// encroaches [v1,v2] and let rg be the length of the shortest edge +// of T. If rmin >= rg, then split the edge. + + if( this->imperatively || !ca.is_reduced() || + ca.rmin >= shortest_edge_squared_length(fh) ) + add_constrained_edge_to_be_conformed(v1,v2); + else + status = CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED; + } + } + }; // after here edges encroached by p are in the list of edges to + // be conformed. + + return status; + } + +private: + /** \name Auxiliary functions to handle clusters. */ + + FT shortest_edge_squared_length(Face_handle f) + { + typename Geom_traits::Compute_squared_distance_2 squared_distance = + this->tr.geom_traits().compute_squared_distance_2_object(); + + const Point& pa = (f->vertex(0))->point(); + const Point& pb = (f->vertex(1))->point(); + const Point& pc = (f->vertex(2))->point(); + + FT a, b, c; + a = squared_distance(pb, pc); + b = squared_distance(pc, pa); + c = squared_distance(pa, pb); + + return (min(a, min(b, c))); + } + + Point split_cluster_point(Vertex_handle va, Vertex_handle vb, Cluster& c) + { + typename Geom_traits::Construct_vector_2 vector = + this->tr.geom_traits().construct_vector_2_object(); + typename Geom_traits::Construct_scaled_vector_2 scaled_vector = + this->tr.geom_traits().construct_scaled_vector_2_object(); + typename Geom_traits::Compute_squared_distance_2 squared_distance = + this->tr.geom_traits().compute_squared_distance_2_object(); + typename Geom_traits::Construct_midpoint_2 midpoint = + this->tr.geom_traits().construct_midpoint_2_object(); + typename Geom_traits::Construct_translated_point_2 translate = + this->tr.geom_traits().construct_translated_point_2_object(); + + typedef typename Geom_traits::FT FT; + + + cluster_splitted = true; + + const Point& a = va->point(); + const Point& b = vb->point(); + + if( c.is_reduced() ) + return midpoint(a, b); + else + { + const Point m = midpoint(a, b); + + typename Geom_traits::Vector_2 v = vector(a,m); + v = scaled_vector(v,CGAL_NTS sqrt(c.minimum_squared_length / + squared_distance(a,b))); + + Point i = translate(a,v), i2(i); + + do { + i = translate(a,v); + v = scaled_vector(v,FT(2)); + i2 = translate(a,v); + } while(squared_distance(a,i2) <= squared_distance(a,m)); + if( squared_distance(i,m) > squared_distance(m,i2) ) + i = i2; + //here i is the best point for splitting + return i; + } + } + +protected: +}; // end class Refine_edges_base_with_clusters + +template < + typename Tr, + typename Is_locally_conform = Is_locally_conforming_Gabriel, + typename Base = Refine_edges_base_with_clusters +> +struct Refine_edges_with_clusters : + public Base, + public details::Refine_edges_types + >::Edges_mesher_level +{ + typedef Refine_edges_with_clusters Self; + typedef typename details::Refine_edges_types::Edges_mesher_level + Mesher; +public: + Refine_edges_with_clusters(Tr& t, + Clusters& c, + Null_mesher_level& null_level) + : Base(t, c), Mesher(null_level) + { + } +}; // end Refine_edges_with_clusters + +} // end namespace Mesh_2 + +} // end namespace CGAL + +#endif // CGAL_MESH_2_REFINE_EDGES_WITH_CLUSTERS_H diff --git a/Mesh_2/include/CGAL/Mesh_2/Refine_faces.h b/Mesh_2/include/CGAL/Mesh_2/Refine_faces.h new file mode 100644 index 00000000000..ad77e9992f4 --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Refine_faces.h @@ -0,0 +1,437 @@ +// Copyright (c) 2004-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) : Laurent RINEAU + +#ifndef CGAL_MESH_2_REFINE_FACES_H +#define CGAL_MESH_2_REFINE_FACES_H + +#include +#include +#include + +namespace CGAL { + +namespace Mesh_2 { + +// Previous is the whole previous edges_level. +template +class Refine_faces_base : + public Triangulation_mesher_level_traits_2, + public No_test_point_conflict, + public No_after_no_insertion +{ + /** \name Types from Tr. */ + + typedef Tr Triangulation; + + typedef typename Tr::Geom_traits Geom_traits; + typedef typename Geom_traits::FT FT; + typedef FT Squared_length; + + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + + typedef typename Tr::Face_circulator Face_circulator; + typedef typename Tr::Finite_faces_iterator Finite_faces_iterator; + typedef typename Tr::All_faces_iterator All_faces_iterator; + typedef typename Tr::Point Point; + + typedef Triangulation_mesher_level_traits_2 Triangulation_traits; + typedef typename Triangulation_traits::Zone Zone; + +public: + using Triangulation_mesher_level_traits_2::triangulation_ref_impl; + +protected: // --- PROTECTED TYPES --- + /** Meshing criteria. */ + typedef typename Criteria::Is_bad s_bad; + typedef typename Criteria::Quality Quality; + + /** \name typedefs for private members types */ + + typedef CGAL::Double_map Bad_faces; + +protected: + // --- PROTECTED MEMBER DATAS --- + + Criteria& criteria; /**is_in_domain() ) + { + Quality q; + Mesh_2::Face_badness badness = is_bad(fit, q); + if( badness != Mesh_2::NOT_BAD ) + push_in_bad_faces(fit, q); + } + } + } + + Zone conflicts_zone_impl(const Point& p, Face_handle fh) + { + Zone zone; + + zone.fh = triangulation_ref_impl().locate(p, zone.locate_type, zone.i, fh); + + triangulation_ref_impl(). + get_conflicts_and_boundary(p, + std::back_inserter(zone.faces), + std::back_inserter(zone.boundary_edges), + fh + ); +#ifdef CGAL_MESH_2_DEBUG_CONFLICTS_ZONE + std::cerr << "get_conflicts_and_boundary(" << p << "):" << std::endl + << "faces: " << zone.faces.size() << std::endl + << "edges: " << zone.boundary_edges.size() << std::endl; +#endif // CGAL_MESH_2_DEBUG_CONFLICTS_ZONE + return zone; + } + + /** Tells if the map of faces to be conformed is empty or not. */ + bool no_longer_element_to_refine_impl() const + { + return bad_faces.empty(); + } + + /** Get the next face to conform. */ + Face_handle get_next_element_impl() + { + Face_handle fh = bad_faces.front()->second; + current_badness = is_bad(bad_faces.front()->first); + + CGAL_assertion_code + (typename Geom_traits::Orientation_2 orientation = + triangulation_ref_impl().geom_traits().orientation_2_object() + ); + CGAL_assertion(orientation(fh->vertex(0)->point(), + fh->vertex(1)->point(), + fh->vertex(2)->point()) != COLLINEAR ); + return fh; + } + + /** Pop the first face of the map. */ + void pop_next_element_impl() + { + bad_faces.pop_front(); + } + + /** Returns the circumcenter of the face. */ + Point refinement_point_impl(const Face_handle& f) const + { + return triangulation_ref_impl().circumcenter(f); + } + + /** \todo ?? */ + void before_conflicts_impl(const Face_handle&, const Point&) + { /// @todo modularize + previous.set_imperative_refinement(current_badness == + Mesh_2::IMPERATIVELY_BAD); + } + + /** Remove the conflicting faces from the bad faces map. */ + void before_insertion_impl(const Face_handle& fh, const Point&, + Zone& zone) + { + /** @todo Perhaps this function is useless. */ + for(typename Zone::Faces_iterator fh_it = zone.faces.begin(); + fh_it != zone.faces.end(); + ++fh_it) + { + if(*fh_it != fh && (*fh_it)->is_in_domain() ) + remove_bad_face(*fh_it); + (*fh_it)->set_in_domain(false); + } + } + + /** Restore markers in the star of \c v. */ + void after_insertion_impl(const Vertex_handle& v) + { +#ifdef CGAL_MESH_2_VERBOSE + std::cerr << "*"; +#endif + typename Tr::Face_circulator fc = + triangulation_ref_impl().incident_faces(v), fcbegin(fc); + do { + fc->set_in_domain(true); + } while (++fc != fcbegin); + compute_new_bad_faces(v); + } + +private: + /** \name AUXILIARY FUNCTIONS */ + + /** Auxiliary function called to put a new face in the map. */ + void push_in_bad_faces(Face_handle fh, const Quality& q); + + +public: + /** \name Functions that maintain the map of bad faces. */ + + /** + * Updates the map with faces incident to the vertex \a v. + * @todo The visitor should be made friend, instead of this function to + * be public. + */ + void compute_new_bad_faces(Vertex_handle v); + + /** Auxiliary function called to erase a face handle from the map. */ + void remove_bad_face(Face_handle fh); + +public: + /** \name ACCESS FUNCTION */ + + Mesh_2::Face_badness is_bad(const Face_handle fh, Quality& q) const; + Mesh_2::Face_badness is_bad(const Face_handle fh) const; + Mesh_2::Face_badness is_bad(Quality q) const; + + /** + * Adds the sequence [\c begin, \c end[ to the list + * of bad faces. + * Use this overriden function if the list of bad faces can be + * computed easily without testing all faces. + * \param Fh_it is an iterator of \c Face_Handle. + */ + template + void set_bad_faces(Fh_it begin, Fh_it end) + { + bad_faces.clear(); +#ifdef CGAL_MESH_2_DEBUG_BAD_FACES + std::cerr << "bad_faces.clear()\n"; +#endif // CGAL_MESH_2_DEBUG_BAD_FACES + for(Fh_it pfit=begin; pfit!=end; ++pfit) + push_in_bad_faces(*pfit, Quality()); + } + +}; // end class Refine_faces_base + +// --- PRIVATE MEMBER FUNCTIONS --- + +template +inline +void Refine_faces_base:: +push_in_bad_faces(Face_handle fh, const Quality& q) +{ +#ifdef CGAL_MESH_2_DEBUG_BAD_FACES + std::cerr << "push_in_bad_faces(" + << fh->vertex(0)->point() << "," + << fh->vertex(1)->point() << "," + << fh->vertex(2)->point() << ")\n"; +#endif // CGAL_MESH_2_DEBUG_BAD_FACES + CGAL_assertion_code + (typename Geom_traits::Orientation_2 orientation = + triangulation_ref_impl().geom_traits().orientation_2_object() + ); + CGAL_assertion( orientation(fh->vertex(0)->point(), + fh->vertex(1)->point(), + fh->vertex(2)->point()) != COLLINEAR ); + CGAL_assertion(fh->is_in_domain()); + bad_faces.insert(fh, q); +} + +template +inline +void Refine_faces_base:: +remove_bad_face(Face_handle fh) +{ +#ifdef CGAL_MESH_2_DEBUG_BAD_FACES + std::cerr << "bad_faces.erase(" + << fh->vertex(0)->point() << "," + << fh->vertex(1)->point() << "," + << fh->vertex(2)->point() << ")\n"; +#endif // CGAL_MESH_2_DEBUG_BAD_FACES + bad_faces.erase(fh); +} + +template +void Refine_faces_base:: +compute_new_bad_faces(Vertex_handle v) +{ + typename Tr::Face_circulator fc = v->incident_faces(), fcbegin(fc); + do { + if(!triangulation_ref_impl().is_infinite(fc)) + if( fc->is_in_domain() ) + { + Quality q; + Mesh_2::Face_badness badness = is_bad(fc, q); + if( badness != Mesh_2::NOT_BAD ) + push_in_bad_faces(fc, q); + } + fc++; + } while(fc!=fcbegin); +} + +template +inline +Mesh_2::Face_badness +Refine_faces_base:: +is_bad(const Face_handle f, Quality& q) const +{ + return criteria.is_bad_object()(f, q); +} + +template +inline +Mesh_2::Face_badness +Refine_faces_base:: +is_bad(const Face_handle f) const +{ + Quality q; + return criteria.is_bad_object()(f, q); +} + +template +inline +Mesh_2::Face_badness +Refine_faces_base:: +is_bad(Quality q) const +{ + return criteria.is_bad_object()(q); +} + + namespace details { + template + struct Refine_faces_types + { + typedef Mesher_level < + Tr, + Self, + typename Tr::Face_handle, + Previous, + Triangulation_mesher_level_traits_2 + > + Faces_mesher_level; + }; // end Refine_faces_types + } // end namespace details + +template > +class Refine_faces : + public Base, + public details::Refine_faces_types, + Previous>::Faces_mesher_level +{ + typedef typename Tr::Geom_traits Geom_traits; + + template + struct Pair_get_first: public std::unary_function + { + typedef typename Pair::first_type result; + const result& operator()(const Pair& p) const + { + return p.first; + } + }; + +public: + typedef Refine_faces Self; + typedef typename details::Refine_faces_types + ::Faces_mesher_level Mesher; + + typedef Tr Triangulation; + + typedef typename Base::Bad_faces Bad_faces; + + typedef typename boost::transform_iterator< + Pair_get_first, + typename Bad_faces::const_iterator> + Bad_faces_const_iterator; + +public: + Refine_faces(Tr& t, Criteria& criteria, Previous& previous) + : Base(t, criteria, previous), Mesher(previous) + { + } + + /** \name DEBUGGING FUNCTIONS */ + + Bad_faces_const_iterator begin() const + { + return Bad_faces_const_iterator(this->bad_faces.begin()); + } + + Bad_faces_const_iterator end() const + { + return Bad_faces_const_iterator(this->bad_faces.end()); + } + + bool check_bad_faces() + { + CGAL_assertion_code + (typename Geom_traits::Orientation_2 orientation = + this->triangulation_ref_impl().geom_traits().orientation_2_object() + ); + for(Bad_faces_const_iterator fit = begin(); + fit != end(); + ++fit) + if( orientation((*fit)->vertex(0)->point(), + (*fit)->vertex(1)->point(), + (*fit)->vertex(2)->point()) == COLLINEAR ) + { + std::cerr << "collinear(" + << (*fit)->vertex(0)->point() << ", " + << (*fit)->vertex(1)->point() << ", " + << (*fit)->vertex(2)->point()<< ") == true" + << std::endl; + std::cerr << "Dump of bad_faces:" << std::endl; + this->bad_faces.dump_direct_func(std::cerr); + + return false; + } + return true; + } + +}; // end Refine_faces + +} // end namespace Mesh_2 + +} // end namespace CGAL + +#endif // CGAL_MESH_2_REFINE_FACES_H diff --git a/Mesh_2/include/CGAL/Mesh_2/Triangulation_mesher_level_traits_2.h b/Mesh_2/include/CGAL/Mesh_2/Triangulation_mesher_level_traits_2.h new file mode 100644 index 00000000000..8816051d31c --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Triangulation_mesher_level_traits_2.h @@ -0,0 +1,78 @@ +// 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) : Laurent RINEAU + +#ifndef CGAL_MESH_2_TRIANGULATION_MESHER_LEVEL_TRAITS_2_H +#define CGAL_MESH_2_TRIANGULATION_MESHER_LEVEL_TRAITS_2_H + +#include +#include + +namespace CGAL { + +template +struct Triangulation_mesher_level_traits_2 : + public Triangulation_ref_impl +{ + typedef Tr Triangulation; + typedef typename Tr::Point Point; + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Face_handle Face_handle; + typedef typename Tr::Edge Edge; + + using Triangulation_ref_impl::triangulation_ref_impl; + + Triangulation_mesher_level_traits_2(Tr& tr) + : Triangulation_ref_impl(tr) + { + } + + struct Zone { + typedef std::list Faces; + typedef std::list Edges; + public: + typedef typename Faces::iterator Faces_iterator; + typedef typename Edges::iterator Edges_iterator; + + typename Tr::Locate_type locate_type; + Face_handle fh; + int i; + Faces faces; + Edges boundary_edges; + }; + + Vertex_handle insert_impl(const Point& p, Zone& zone) + { +#ifdef CGAL_MESH_2_DEBUG_INSERTIONS + std::cerr << "insert(" << p << "): " + << zone.boundary_edges.size() << " edges." << std::endl; +#endif + if( zone.locate_type == Tr::VERTEX ) + return zone.fh->vertex(zone.i); + return triangulation_ref_impl(). + star_hole(p, + zone.boundary_edges.begin(), + zone.boundary_edges.end(), + zone.faces.begin(), + zone.faces.end()); + } +}; // end Triangulation_mesher_level_traits_2 + +}; // end namespace CGAL + +#endif // CGAL_MESH_2_TRIANGULATION_MESHER_LEVEL_TRAITS_2_H diff --git a/Mesh_2/include/CGAL/Mesh_2/Triangulation_mesher_level_traits_3.h b/Mesh_2/include/CGAL/Mesh_2/Triangulation_mesher_level_traits_3.h new file mode 100644 index 00000000000..578374ac61a --- /dev/null +++ b/Mesh_2/include/CGAL/Mesh_2/Triangulation_mesher_level_traits_3.h @@ -0,0 +1,109 @@ +// Copyright (c) 2004-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$ $Date$ +// +// +// Author(s) : Laurent RINEAU + +#ifndef CGAL_MESH_2_TRIANGULATION_MESHER_LEVEL_TRAITS_3_H +#define CGAL_MESH_2_TRIANGULATION_MESHER_LEVEL_TRAITS_3_H + +#include +#include +#include + +namespace CGAL { + + namespace Mesh_2 { + namespace details { + + template + struct Type_of_points + { + typedef typename Tr::Point Point; + }; + + template + struct Type_of_points + { + typedef typename Tr::Weighted_point Point; + }; + + } // end namespace Mesh_2::details + } // end namespace Mesh_2 + +template +struct Triangulation_mesher_level_traits_3 : + public Triangulation_ref_impl +{ + typedef Tr Triangulation; + + typedef typename Mesh_2::details::Type_of_points::Point Point; + + typedef typename Tr::Vertex_handle Vertex_handle; + typedef typename Tr::Cell_handle Cell_handle; + typedef typename Tr::Facet Facet; + + using Triangulation_ref_impl::triangulation_ref_impl; + + Triangulation_mesher_level_traits_3(Tr& t) + : Triangulation_ref_impl(t) + { + } + + class Zone { + typedef std::vector Cells; + typedef std::vector Facets; + public: + typedef typename Cells::iterator Cells_iterator; + typedef typename Facets::iterator Facets_iterator; + typedef typename Cells::const_iterator Cells_const_iterator; + typedef typename Facets::const_iterator Facets_const_iterator; + + typedef typename Tr::Locate_type Locate_type; + + Zone() { + cells.reserve(64); + boundary_facets.reserve(32); + internal_facets.reserve(64); + } + + Locate_type locate_type; + Cell_handle cell; + int i, j; + + Cells cells; + Facets boundary_facets; + Facets internal_facets; + }; + + Vertex_handle insert_impl(const Point& p, Zone& zone) + { + if( zone.locate_type == Tr::VERTEX + ) return zone.cell->vertex(zone.i); + + const Facet& f = *(zone.boundary_facets.begin()); + return triangulation_ref_impl().insert_in_hole(p, + zone.cells.begin(), + zone.cells.end(), + f.first, f.second); + } + +}; // end Triangulation_mesher_level_traits_3 + +}; // end namespace CGAL + +#endif // CGAL_MESH_2_TRIANGULATION_MESHER_LEVEL_TRAITS_3_H diff --git a/Mesh_2/include/CGAL/Mesher_level.h b/Mesh_2/include/CGAL/Mesher_level.h new file mode 100644 index 00000000000..095cfa3d960 --- /dev/null +++ b/Mesh_2/include/CGAL/Mesher_level.h @@ -0,0 +1,375 @@ +// Copyright (c) 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) : Laurent RINEAU + +#ifndef CGAL_MESHER_LEVEL_H +#define CGAL_MESHER_LEVEL_H + +namespace CGAL { + +enum Mesher_level_conflict_status { + NO_CONFLICT = 0, + CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED, + CONFLICT_AND_ELEMENT_SHOULD_BE_DROPPED +}; + +struct Null_mesher_level { + + template + void refine(Visitor) {} + + template + Mesher_level_conflict_status test_point_conflict_from_superior(P, Z) + { + return NO_CONFLICT; + } + + bool is_algorithm_done() const + { + return true; + } + + template + bool try_to_insert_one_point(Visitor) + { + return false; + } + + template + bool one_step(Visitor) + { + return false; + } + +}; // end Null_mesher_level + +template < + class Tr, /**< The triangulation type. */ + class Derived, /**< Derived class, that implements methods. */ + class Element, /**< Type of elements that this level refines. */ + class Previous, /* = Null_mesher_level, */ + /**< Previous level type, defaults to + \c Null_mesher_level. */ + class Triangulation_traits /** Traits class that defines types for the + triangulation. */ + > +class Mesher_level +{ +public: + /** Type of triangulation that is meshed. */ + typedef Tr Triangulation; + /** Type of point that are inserted into the triangulation. */ + typedef typename Triangulation::Point Point; + /** Type of vertex handles that are returns by insertions into the + triangulation. */ + typedef typename Triangulation::Vertex_handle Vertex_handle; + /** Type of the conflict zone for a point that can be inserted. */ + typedef typename Triangulation_traits::Zone Zone; + + typedef Element Element_type; + typedef Previous Previous_level; + +private: + /** \name Private member functions */ + + /** Curiously recurring template pattern. */ + //@{ + Derived& derived() + { + return static_cast(*this); + } + + const Derived& derived() const + { + return static_cast(*this); + } + //@} + + /** \name Private member datas */ + + Previous& previous_level; /**< The previous level of the refinement + process. */ +public: + typedef Mesher_level Self; + + /** \name CONSTRUCTORS */ + Mesher_level(Previous_level& previous) + : previous_level(previous) + { + } + + /** \name FUNCTIONS IMPLEMENTED IN THE CLASS \c Derived */ + + /** Access to the triangulation */ + Triangulation& triangulation() + { + return derived().triangulation_ref_impl(); + } + + /** Access to the triangulation */ + const Triangulation& triangulation() const + { + return derived().triangulation_ref_impl(); + } + + Vertex_handle insert(Point p, Zone& z) + { + return derived().insert_impl(p, z); + } + + Zone conflicts_zone(const Point& p, Element e) + { + return derived().conflicts_zone_impl(p, e); + } + + /** Called before the first refinement, to initialized the queue of + elements that should be refined. */ + void scan_triangulation() + { + derived().scan_triangulation_impl(); + } + + /** Tells if, as regards the elements of type \c Element, the refinement is + done. */ + bool no_longer_element_to_refine() + { + return derived().no_longer_element_to_refine_impl(); + } + + /** Retrieves the next element that could be refined. */ + Element get_next_element() + { + return derived().get_next_element_impl(); + } + + /** Remove from the list the next element that could be refined. */ + void pop_next_element() + { + derived().pop_next_element_impl(); + } + + /** Gives the point that should be inserted to refine the element \c e */ + Point refinement_point(const Element& e) + { + return derived().refinement_point_impl(e); + } + + /** Actions before testing conflicts for point \c p and element \c e */ + template + void before_conflicts(const Element& e, const Point& p, + Mesh_visitor& visitor) + { + visitor.before_conflicts(e, p); + derived().before_conflicts_impl(e, p); + } + + /** Tells if, as regards this level of the refinement process, if the + point conflicts with something, and do what is needed. The return + type is made of two booleans: + - the first one tells if the point can be inserted, + - in case of, the first one is \c false, the second one tells if + the tested element should be reconsidered latter. + */ + Mesher_level_conflict_status private_test_point_conflict(const Point& p, + Zone& zone) + { + return derived().private_test_point_conflict_impl(p, zone); + } + + /** Tells if, as regards this level of the refinement process, if the + point conflicts with something, and do what is needed. The return + type is made of two booleans: + - the first one tells if the point can be inserted, + - in case of, the first one is \c false, the second one tells if + the tested element should be reconsidered latter. + This function is called by the superior level, if any. + */ + Mesher_level_conflict_status + test_point_conflict_from_superior(const Point& p, + Zone& zone) + { + return derived().test_point_conflict_from_superior_impl(p, zone); + } + + /** + * Actions before inserting the point \c p in order to refine the + * element \c e. The zone of conflicts is \c zone. + */ + template + void before_insertion(Element& e, const Point& p, Zone& zone, + Mesh_visitor& visitor) + { + visitor.before_insertion(e, p, zone); + derived().before_insertion_impl(e, p, zone); + } + + /** Actions after having inserted the point. + * \param vh is the vertex handle of the inserted point, + * \param visitor is the visitor. + */ + template + void after_insertion(Vertex_handle vh, Mesh_visitor& visitor) + { + derived().after_insertion_impl(vh); + visitor.after_insertion(vh); + } + + /** Actions after testing conflicts for point \c p and element \c e + * if no point is inserted. */ + template + void after_no_insertion(const Element& e, const Point& p, Zone& zone, + Mesh_visitor& visitor) + { + derived().after_no_insertion_impl(e, p, zone); + visitor.after_no_insertion(e, p, zone); + } + + /** \name MESHING PROCESS + * + * The following functions use the functions that are implemented in the + * derived classes. + * + */ + + /** + * Tells it the algorithm is done, regarding elements of type \c Element + * or elements of previous levels. + */ + bool is_algorithm_done() + { + return ( previous_level.is_algorithm_done() && + no_longer_element_to_refine() ); + } + + /** Refines elements of this level and previous levels. */ + template + void refine(Mesh_visitor& visitor) + { + while(! is_algorithm_done() ) + { + previous_level.refine(visitor.previous_level()); + if(! no_longer_element_to_refine() ) + process_one_element(visitor); + } + } + + /** + * This function takes one element from the queue, and try to refine + * it. It returns \c true if one point has been inserted. + * @todo Merge with try_to_refine_element(). + */ + template + bool process_one_element(Mesh_visitor& visitor) + { + Element e = get_next_element(); + + const Mesher_level_conflict_status result + = try_to_refine_element(e, visitor); + + if(result != CONFLICT_BUT_ELEMENT_CAN_BE_RECONSIDERED) + pop_next_element(); + return result == NO_CONFLICT; + } + + template + Mesher_level_conflict_status + try_to_refine_element(Element e, Mesh_visitor& visitor) + { + const Point& p = refinement_point(e); + + before_conflicts(e, p, visitor); + + Zone zone = conflicts_zone(p, e); + + const Mesher_level_conflict_status result = test_point_conflict(p, zone); + + if(result == NO_CONFLICT) + { + before_insertion(e, p, zone, visitor); + + Vertex_handle v = insert(p, zone); + + after_insertion(v, visitor); + + return NO_CONFLICT; + } + else + after_no_insertion(e, p, zone, visitor); + return result; + } + + /** Return (can_split_the_element, drop_element). */ + Mesher_level_conflict_status + test_point_conflict(const Point& p, Zone& zone) + { + const Mesher_level_conflict_status result = + previous_level.test_point_conflict_from_superior(p, zone); + + if( result != NO_CONFLICT ) + return result; + return private_test_point_conflict(p, zone); + } + + /** \name STEP BY STEP FUNCTIONS */ + + /** + * Inserts exactly one point, if possible, and returns \c false if no + * point has been inserted because the algorithm is done. + */ + template + bool try_to_insert_one_point(Mesh_visitor& visitor) + { + while(! is_algorithm_done() ) + { + if( previous_level.try_to_insert_one_point(visitor.previous_level()) ) + return true; + if(! no_longer_element_to_refine() ) + if( process_one_element(visitor) ) + return true; + } + return false; + } + + /** + * Applies one step of the algorithm: tries to refine one element of + * previous level or one element of this level. Return \c false iff + * is_algorithm_done()==true . + */ + template + bool one_step(Mesh_visitor& visitor) + { + if( ! previous_level.is_algorithm_done() ) + previous_level.one_step(visitor.previous_level()); + else + if( ! no_longer_element_to_refine() ) + process_one_element(visitor); + return ! is_algorithm_done(); + } + +}; // end Mesher_level + +} // end namespace CGAL + +#include +#include + +#endif // CGAL_MESHER_LEVEL_H diff --git a/Mesh_2/include/CGAL/Mesher_level_default_implementations.h b/Mesh_2/include/CGAL/Mesher_level_default_implementations.h new file mode 100644 index 00000000000..3a7dd670acf --- /dev/null +++ b/Mesh_2/include/CGAL/Mesher_level_default_implementations.h @@ -0,0 +1,137 @@ +// 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) : Laurent RINEAU + +#ifndef CGAL_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H +#define CGAL_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H + +#include + +namespace CGAL { + +/** This class implements the two get_triangulation_ref() functions. + \param Tr The triangulation type */ +template +class Triangulation_ref_impl +{ + Tr& tr; +public: + Triangulation_ref_impl(Tr& t) : tr(t) + { + } + + Tr& triangulation_ref_impl() + { + return tr; + } + const Tr& triangulation_ref_impl() const + { + return tr; + } + +}; // end class Triangulation_ref_impl + +/** This struct implements an empty private_test_point_conflict_impl() + function. */ +struct No_private_test_point_conflict +{ + template + Mesher_level_conflict_status + private_test_point_conflict_impl(const Point&, const Zone&) const + { + return NO_CONFLICT; + } +}; // end No_private_test_point_conflict + +/** This struct implements an empty test_point_conflict_from_superior_impl() + function. */ +struct No_test_point_conflict_from_superior +{ + template + Mesher_level_conflict_status + test_point_conflict_from_superior_impl(const Point&, const Zone&) const + { + return NO_CONFLICT; + } +}; // end No_test_point_conflict_from_superior + +/** This struct implements empty functions: + - private_test_point_conflict_impl() and + - test_point_conflict_from_superior_impl(). +*/ +struct No_test_point_conflict : + public No_private_test_point_conflict, + public No_test_point_conflict_from_superior +{ +}; + +/** This struct implements an empty before_insertion_impl() + function. */ +struct No_before_insertion +{ + template + void before_insertion_impl(const Cell_handle&, const Point&, + Zone& ) + { + } +}; // end No_before_insertion + +/** This struct implements an empty after_insertion_impl() + function. */ +struct No_after_insertion +{ + template + void after_insertion_impl(const Vertex_handle&) + { + } +}; // end No_after_insertion + +/** This struct implements an empty after_insertion_impl() + function. */ +struct No_after_no_insertion +{ + template + void after_no_insertion_impl(const Cell_handle&, const Point&, + const Zone& ) + { + } +}; // end No_after_no_insertion + +/** This struct implements empty functions: + - before_insertion_impl(), + - after_insertion_impl(), + - after_no_insertion_impl() +*/ +struct No_before_after_insertion : + public No_after_insertion, + public No_before_insertion, + public No_after_no_insertion +{ +}; + +/** This struct implements an empty before_conflicts_impl() function. */ +struct No_before_conflicts { + template + void before_conflicts_impl(const Face_handle&, const Point&) + { + } +}; + +} // end namespace CGAL + +#endif // CGAL_MESHER_LEVEL_DEFAULT_IMPLEMENTATIONS_H diff --git a/Mesh_2/include/CGAL/Mesher_level_visitors.h b/Mesh_2/include/CGAL/Mesher_level_visitors.h new file mode 100644 index 00000000000..c271856d105 --- /dev/null +++ b/Mesh_2/include/CGAL/Mesher_level_visitors.h @@ -0,0 +1,128 @@ +// 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) : Laurent RINEAU + +#ifndef CGAL_MESHER_LEVEL_VISITORS_H +#define CGAL_MESHER_LEVEL_VISITORS_H + +namespace CGAL { + +template +class Null_mesh_visitor_level +{ + Previous_level previous; +public: + typedef Previous_level Previous_visitor; + + Null_mesh_visitor_level(Previous_level p) : previous(p) + { + } + + Previous_level& previous_level() + { + return previous; + } + + template + void before_conflicts(E, P) const {} + + template + void before_insertion(E, P, Z) const {} + + template + void after_insertion(V) const {} + + template + void after_no_insertion(E, P, Z) const {} +}; // end class Null_mesh_visitor_level + +class Null_mesh_visitor +{ +public: + typedef Null_mesh_visitor Previous_visitor; + + const Null_mesh_visitor& previous_level() const + { + return *this; + } + + template + void before_conflicts(E, P) const {} + + template + void before_insertion(E, P, Z) const {} + + template + void after_insertion(V) const {} + + template + void after_no_insertion(E, P, Z) const {} +}; // end class Null_mesh_visitor + +template +struct Combine_mesh_visitor { + typedef Combine_mesh_visitor + Previous_visitor; + + V1* v1; + V2* v2; + + Combine_mesh_visitor(V1* v1_, V2* v2_) + : v1(v1_), v2(v2_) + { + } + + Previous_visitor previous_level() + { + return Previous_visitor(&(v1->previous_level()), + &(v2->previous_level())); + } + + template + void before_conflicts(E e, P p) + { + v1->before_conflicts(e, p); + v2->before_conflicts(e, p); + } + + template + void before_insertion(E e, P p, Z z) + { + v1->before_insertion(e, p, z); + v2->before_insertion(e, p, z); + } + + template + void after_insertion(V v) + { + v1->after_insertion(v); + v2->after_insertion(v); + } + + template + void after_no_insertion(E e, P p, Z z) + { + v1->after_no_insertion(e, p, z); + v2->after_no_insertion(e, p, z); + } +}; // end class Combine_mesh_visitor + +} // end namespace CGAL + +#endif // CGAL_MESHER_LEVEL_VISITORS_H diff --git a/Mesh_2/include/CGAL/Triangulation_conformer_2.h b/Mesh_2/include/CGAL/Triangulation_conformer_2.h new file mode 100644 index 00000000000..454cf30a40b --- /dev/null +++ b/Mesh_2/include/CGAL/Triangulation_conformer_2.h @@ -0,0 +1,262 @@ +// 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) : Laurent RINEAU + +#ifndef CGAL_TRIANGULATION_CONFORMER_2_H +#define CGAL_TRIANGULATION_CONFORMER_2_H + +#include + +namespace CGAL { + +template +class Triangulation_conformer_2 +{ + typedef typename Tr::Finite_edges_iterator Finite_edges_iterator; + typedef typename Tr::Vertex_handle Vertex_handle; + + typedef Mesh_2::Refine_edges_with_clusters > Edges_level_Gabriel; + + typedef Mesh_2::Refine_edges_with_clusters > Edges_level_Delaunay; + +protected: + /** \name INITIALIZED */ + + enum Initialization { + NONE, /**< \c this is not initialized. */ + CLUSTERS, /**< \c this clusters are initialized. */ + DELAUNAY, /**< \c this has been \e Delaunay-initialized. */ + GABRIEL /**< \c this has been \e Gabriel-initialized. */ + }; + +// --- PROTECTED DATAS --- + Initialization initialized; + Tr& tr; + Null_mesher_level null_level; + Null_mesh_visitor null_visitor; + Mesh_2::Clusters clusters; + Edges_level_Gabriel edges_level_Gabriel; + Edges_level_Delaunay edges_level_Delaunay; + +public: + /** \name CONSTRUCTORS */ + Triangulation_conformer_2(Tr& tr_) + : initialized(NONE), + tr(tr_), + null_level(), null_visitor(), + clusters(tr_), + edges_level_Gabriel(tr, clusters, null_level), + edges_level_Delaunay(tr, clusters, null_level) + { + } + +private: + /** \name CHECKING METHODS*/ + + template + bool is_conforming_XXX(Is_locally_conforming is_locally_conforming) const + { + for(Finite_edges_iterator ei = tr.finite_edges_begin(); + ei != tr.finite_edges_end(); + ++ei) + if(ei->first->is_constrained(ei->second) && + !is_locally_conform(this, ei->first, ei->second) ) + return false; + return true; + } + +public: /** \name ACCESS TO CLUSTERS */ + typedef typename Mesh_2::Clusters::Cluster_vertices_iterator + Cluster_vertices_iterator; + typedef typename Mesh_2::Clusters::Vertices_in_cluster_iterator + Vertices_in_cluster_iterator; + +public: + /** \name ACCESS FUNCTIONS */ + + /** Access to the private initialized member data. */ + //@{ + void set_initialized(Initialization init) { initialized = init; } + Initialization get_initialized() const { return initialized; } + //@} + + int number_of_constrained_edges() + { + int nedges = 0; + for(typename Tr::Finite_edges_iterator eit = tr.finite_edges_begin(); + eit != tr.finite_edges_end(); + ++eit) + if(eit->first->is_constrained(eit->second)) + ++nedges; + return nedges; + } + + int number_of_clusters_vertices() const + { + return clusters.size(); + } + + Cluster_vertices_iterator clusters_vertices_begin() const + { + return clusters.clusters_vertices_begin(); + } + + Cluster_vertices_iterator clusters_vertices_end() const + { + return clusters.clusters_vertices_end(); + } + + unsigned int number_of_clusters_at_vertex(const Vertex_handle& vh) + { + return clusters.number_of_clusters_at_vertex(vh); + } + + // returns the sequence of vertices bellonging to the n-th cluster of vh + std::pair + vertices_in_cluster_sequence(const Vertex_handle& vh, + const unsigned int n) + { + return clusters.vertices_in_cluster_sequence(); + } + +public: + /** \name CHECKING METHODS */ + + bool is_conforming_Delaunay() + { + typedef typename Mesh_2::Is_locally_conforming_Delaunay Is_loc_conf; + + return is_conforming_XXX(Is_loc_conf()); + } + + bool is_conforming_Gabriel() + { + typedef typename Mesh_2::Is_locally_conforming_Gabriel Is_loc_conf; + + return is_conforming_XXX(Is_loc_conf()); + } + + /** \name CONFORMING FUNCTIONS */ + + void make_conforming_Delaunay() + { + if(initialized!=DELAUNAY) init_Delaunay(); + edges_level_Delaunay.refine(null_visitor); + } + + void make_conforming_Gabriel() + { + if(initialized!=GABRIEL) init_Gabriel(); + edges_level_Gabriel.refine(null_visitor); + } + + /** \name STEP BY STEP FUNCTIONS */ + + // Note: step by step functions are not efficient at all! +private: + void init_clusters() + { + if(initialized == NONE) + clusters.create_clusters(); + initialized = CLUSTERS; + } + +public: + /** + Initializes the data structures + (The call of this function is REQUIRED before any step by step + operation). + */ + //@{ + void init_Delaunay() + { + init_clusters(); + initialized = DELAUNAY; + edges_level_Delaunay.scan_triangulation(); + } + void init_Gabriel() + { + init_clusters(); + initialized = GABRIEL; + edges_level_Gabriel.scan_triangulation(); + } + //@} + + /** Tells if all constrained edges are conformed. */ + bool is_conforming_done() + // This function cannot be "const" because, as edges_to_be_conformed is + // filtred, its empty() method is not const. + { return ( edges_level_Gabriel.no_longer_element_to_refine() + && edges_level_Delaunay.no_longer_element_to_refine() ); + } + + /** Execute on step of the algorithm. + init_XXX() should have been called before. + */ + //@{ + bool try_one_step_conforming_Delaunay() + { + return edges_level_Delaunay.one_step(null_visitor); + } + + bool try_one_step_conforming_Gabriel() + { + return edges_level_Gabriel.one_step(null_visitor); + } + + bool step_by_step_conforming_Delaunay() + { + return edges_level_Delaunay.try_to_insert_one_point(null_visitor); + } + + bool step_by_step_conforming_Gabriel() + { + return edges_level_Gabriel.try_to_insert_one_point(null_visitor); + } + //@} + +}; // end Triangulation_conformer_2 + + +// --- GLOBAL FUNCTIONS --- + +template +void +make_conforming_Gabriel_2(Tr& t) +{ + typedef Triangulation_conformer_2 Conform; + + Conform conform(t); + conform.make_conforming_Gabriel(); +} + +template +void +make_conforming_Delaunay_2(Tr& t) +{ + typedef Triangulation_conformer_2 Conform; + + Conform conform(t); + conform.make_conforming_Delaunay(); +} + +} // end namespace CGAL + +#endif // CGAL_TRIANGULATION_CONFORMER_2_H diff --git a/Mesh_2/maintainer b/Mesh_2/maintainer new file mode 100644 index 00000000000..481d9d62c47 --- /dev/null +++ b/Mesh_2/maintainer @@ -0,0 +1 @@ +Laurent Rineau diff --git a/Mesh_2/stylesheet.css b/Mesh_2/stylesheet.css new file mode 100644 index 00000000000..461907b311b --- /dev/null +++ b/Mesh_2/stylesheet.css @@ -0,0 +1,213 @@ +H1 { + text-align: center; + font-family: Arial, Helvetica, sans-serif; +} +H2 { + font-family: Geneva, Arial, Helvetica, sans-serif; +} +CAPTION { font-weight: bold } +DIV.qindex { + width: 100%; + background-color: #eeeeff; + border: 1px solid #B0B0B0; + text-align: center; + margin: 2px; + padding: 2px; +} +A.qindex { + text-decoration: none; + font-weight: bold; + color: #1A419D; + padding: 2px; +} +A.qindex:visited { + text-decoration: none; + font-weight: bold; + color: #1A419D + padding: 2px; +} +A.qindex:hover { + text-decoration: none; + background-color: #ddddff; + padding: 2px; +} +A.qindexHL { + text-decoration: none; + font-weight: bold; + background-color: #6666cc; + color: #ffffff; + padding: 2 6px; + border: 1px double #9295C2; + } +A.qindexHL:hover { + text-decoration: none; + background-color: #6666cc; + color: #ffffff; + padding: 2px 6px; +} +A.qindexHL:visited { text-decoration: none; background-color: #6666cc; color: #ffffff } +A.el { text-decoration: none; font-weight: bold } +A.elRef { font-weight: bold } +A.code { text-decoration: none; font-weight: normal; color: #1A419D} +A.codeRef { font-weight: normal; color: #1A419D} +A:hover { text-decoration: none; background-color: #f2f2ff } +DL.el { margin-left: -1cm } +PRE.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + margin-top: 4px; + margin-bottom: 4px; + margin-left: 2px; + margin-right: 8px; + padding-left: 6px; + padding-right: 6px; + padding-top: 4px; + padding-bottom: 4px; +} +DIV.fragment { + border: 1px solid #CCCCCC; + background-color: #f5f5f5; + padding: 6px; +} +DIV.ah { background-color: black; font-weight: bold; color: #ffffff; margin-bottom: 3px; margin-top: 3px } +TD.md { background-color: #F4F4FB; font-weight: bold; } +TD.mdname1 { background-color: #F4F4FB; font-weight: bold; color: #602020; } +TD.mdname { background-color: #F4F4FB; font-weight: bold; color: #602020; width: 600px; } +DIV.groupHeader { margin-left: 16px; margin-top: 12px; margin-bottom: 6px; font-weight: bold } +DIV.groupText { margin-left: 16px; font-style: italic; font-size: smaller } +BODY { + background: white; + background-image:url(http://www.cs.uu.nl/CGAL/images/cgal-bg2.gif); + color: black; + margin-right: 20px; + margin-left: 20px; +} +TD.indexkey { + background-color: #eeeeff; + font-weight: bold; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TD.indexvalue { + background-color: #eeeeff; + font-style: italic; + padding-right : 10px; + padding-top : 2px; + padding-left : 10px; + padding-bottom : 2px; + margin-left : 0px; + margin-right : 0px; + margin-top : 2px; + margin-bottom : 2px; + border: 1px solid #CCCCCC; +} +TR.memlist { + background-color: #f0f0f0; +} +P.formulaDsp { text-align: center; } +IMG.formulaDsp { } +IMG.formulaInl { vertical-align: middle; } +SPAN.keyword { color: #008000 } +SPAN.keywordtype { color: #604020 } +SPAN.keywordflow { color: #e08000 } +SPAN.comment { color: #800000 } +SPAN.preprocessor { color: #806020 } +SPAN.stringliteral { color: #002080 } +SPAN.charliteral { color: #008080 } +.mdTable { + border: 1px solid #868686; + background-color: #F4F4FB; +} +.mdRow { + padding: 8px 10px; +} +.mdescLeft { + font-size: smaller; + font-family: Arial, Helvetica, sans-serif; + background-color: #FAFAFA; + padding-left: 8px; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; +} +.mdescRight { + font-size: smaller; + font-family: Arial, Helvetica, sans-serif; + font-style: italic; + background-color: #FAFAFA; + padding-left: 4px; + border-top: 1px none #E0E0E0; + border-right: 1px none #E0E0E0; + border-bottom: 1px none #E0E0E0; + border-left: 1px none #E0E0E0; + margin: 0px; + padding-bottom: 0px; + padding-right: 8px; +} +.memItemLeft { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-style: solid; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-family: Geneva, Arial, Helvetica, sans-serif; + font-size: 12px; +} +.memItemRight { + padding: 1px 0px 0px 8px; + margin: 4px; + border-top-width: 1px; + border-right-width: 1px; + border-bottom-width: 1px; + border-left-width: 1px; + border-top-style: solid; + border-top-color: #E0E0E0; + border-right-color: #E0E0E0; + border-bottom-color: #E0E0E0; + border-left-color: #E0E0E0; + border-right-style: none; + border-bottom-style: none; + border-left-style: none; + background-color: #FAFAFA; + font-family: Geneva, Arial, Helvetica, sans-serif; + font-size: 13px; +} +.search { color: #003399; + font-weight: bold; +} +FORM.search { + margin-bottom: 0px; + margin-top: 0px; +} +INPUT.search { font-size: 75%; + color: #000080; + font-weight: normal; + background-color: #eeeeff; +} +TD.tiny { font-size: 75%; +} +a { + color: #252E78; +} +a:visited { + color: #3D2185; +} diff --git a/Mesh_2/test/Mesh_2/GNUmakefile b/Mesh_2/test/Mesh_2/GNUmakefile new file mode 100644 index 00000000000..c9bba9b02d6 --- /dev/null +++ b/Mesh_2/test/Mesh_2/GNUmakefile @@ -0,0 +1,73 @@ +# Created by the script cgal_create_makefile +# This is the makefile for compiling a CGAL application. + +#---------------------------------------------------------------------# +# include platform specific settings +#---------------------------------------------------------------------# +# Choose the right include file from the /make directory. + +# CGAL_MAKEFILE = ENTER_YOUR_INCLUDE_MAKEFILE_HERE +include $(CGAL_MAKEFILE) + +#---------------------------------------------------------------------# +# compiler flags +#---------------------------------------------------------------------# + +CXXFLAGS = \ + -I../../include \ + $(CGAL_CXXFLAGS) \ + $(LONG_NAME_PROBLEM_CXXFLAGS) + +#---------------------------------------------------------------------# +# linker flags +#---------------------------------------------------------------------# + +LIBPATH = \ + $(CGAL_LIBPATH) + +LDFLAGS = \ + $(LONG_NAME_PROBLEM_LDFLAGS) \ + $(CGAL_LDFLAGS) + +#---------------------------------------------------------------------# +# target entries +#---------------------------------------------------------------------# + +all: \ + test_conforming$(EXE_EXT) \ + test_double_map$(EXE_EXT) \ + test_filtred_container$(EXE_EXT) \ + test_meshing$(EXE_EXT) + +test_conforming$(EXE_EXT): test_conforming$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)test_conforming test_conforming$(OBJ_EXT) $(LDFLAGS) + +test_double_map$(EXE_EXT): test_double_map$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)test_double_map test_double_map$(OBJ_EXT) $(LDFLAGS) + +test_filtred_container$(EXE_EXT): test_filtred_container$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)test_filtred_container test_filtred_container$(OBJ_EXT) $(LDFLAGS) + +test_meshing$(EXE_EXT): test_meshing$(OBJ_EXT) + $(CGAL_CXX) $(LIBPATH) $(EXE_OPT)test_meshing test_meshing$(OBJ_EXT) $(LDFLAGS) + +clean: \ + test_conforming.clean \ + test_double_map.clean \ + test_filtred_container.clean \ + test_meshing.clean + + +run: all + ./test_conforming + ./test_filtred_container + ./test_meshing + ./test_double_map + +#---------------------------------------------------------------------# +# suffix rules +#---------------------------------------------------------------------# + +.C$(OBJ_EXT): + $(CGAL_CXX) $(CXXFLAGS) $(OBJ_OPT) $< + diff --git a/Mesh_2/test/Mesh_2/fish-and-rectangle.poly b/Mesh_2/test/Mesh_2/fish-and-rectangle.poly new file mode 100644 index 00000000000..c14df05c9c1 --- /dev/null +++ b/Mesh_2/test/Mesh_2/fish-and-rectangle.poly @@ -0,0 +1,86 @@ +# Shewchuk Triangle .poly file, produced by the CGAL::Mesh_2 package +# Neither attributes nor boundary markers are used. +31 2 0 0 + +1 -0.25 0 +2 -0.5 1 +3 -0.5 -1 +4 0 0.5 +5 0 -0.5 +6 0.5 1 +7 0.5 -1 +8 1 0 +9 0.25 0 +10 0.5 0.5 +11 0.5 -0.5 +12 0.75 0 +13 -0.5 0.5 +14 -0.5 -0.5 +15 -0.75 0 +16 -1.16776 0.228134 +17 1.65174 0.239833 +18 -0.634827 0.230345 +19 -0.365731 0.231462 +20 -0.307925 0.231701 +21 0.367252 0.234503 +22 0.632199 0.235602 +23 0.881681 0.236638 +24 1.61664 -0.13454 +25 -1.26135 -0.216435 +26 0.922859 -0.154282 +27 0.669251 -0.161499 +28 0.335498 -0.170996 +29 -0.29725 -0.189001 +30 -0.345182 -0.190365 +31 -0.650474 -0.199052 + +44 0 +1 25 16 +2 29 1 +3 19 13 +4 20 19 +5 6 4 +6 4 2 +7 21 22 +8 22 23 +9 12 22 +10 5 7 +11 3 5 +12 10 21 +13 17 24 +14 23 6 +15 17 23 +16 10 22 +17 27 11 +18 28 27 +19 11 28 +20 26 7 +21 12 27 +22 26 27 +23 16 18 +24 18 15 +25 20 2 +26 13 18 +27 30 14 +28 31 30 +29 14 31 +30 1 30 +31 29 3 +32 26 8 +33 24 26 +34 18 19 +35 19 1 +36 20 1 +37 23 8 +38 9 21 +39 21 20 +40 28 9 +41 31 15 +42 30 29 +43 29 28 +44 31 25 + +3 +1 0.505223 0.0994429 +2 -0.0329387 0.0409471 +3 0.879596 0.0292479 diff --git a/Mesh_2/test/Mesh_2/fish.edg b/Mesh_2/test/Mesh_2/fish.edg new file mode 100644 index 00000000000..b87d3bff6f2 --- /dev/null +++ b/Mesh_2/test/Mesh_2/fish.edg @@ -0,0 +1,17 @@ +16 +-0.25 0.0 -0.5 1.0 +-0.25 0.0 -0.5 -1.0 +-0.5 1.0 0.0 0.5 +-0.5 -1.0 0.0 -0.5 + 0.0 0.5 0.5 1.0 + 0.0 -0.5 0.5 -1.0 + 0.5 1.0 1.0 0.0 + 0.5 -1.0 1.0 0.0 + 0.25 0.0 0.5 0.5 +0.25 0.0 0.5 -0.5 +0.5 0.5 0.75 0.0 +0.5 -0.5 0.75 0.0 +-0.25 0.0 -0.5 0.5 +-0.25 0.0 -0.5 -0.5 +-0.5 0.5 -0.75 0.0 +-0.5 -0.5 -0.75 0.0 \ No newline at end of file diff --git a/Mesh_2/test/Mesh_2/fish.poly b/Mesh_2/test/Mesh_2/fish.poly new file mode 100644 index 00000000000..5c1f291f094 --- /dev/null +++ b/Mesh_2/test/Mesh_2/fish.poly @@ -0,0 +1,40 @@ +# Shewchuk Triangle .poly file, produced by the CGAL::Mesh_2 package +# Neither attributes nor boundary markers are used. +15 2 0 0 + +1 -0.25 0 +2 -0.5 1 +3 -0.5 -1 +4 0 0.5 +5 0 -0.5 +6 0.5 1 +7 0.5 -1 +8 1 0 +9 0.25 0 +10 0.5 0.5 +11 0.5 -0.5 +12 0.75 0 +13 -0.5 0.5 +14 -0.5 -0.5 +15 -0.75 0 + +16 0 +1 15 14 +2 5 3 +3 3 1 +4 6 4 +5 4 2 +6 12 10 +7 5 7 +8 10 9 +9 7 8 +10 8 6 +11 9 11 +12 12 11 +13 13 15 +14 14 1 +15 13 1 +16 2 1 + +1 +1 0.505223 0.0994429 diff --git a/Mesh_2/test/Mesh_2/test_conforming.C b/Mesh_2/test/Mesh_2/test_conforming.C new file mode 100644 index 00000000000..cced03c1d56 --- /dev/null +++ b/Mesh_2/test/Mesh_2/test_conforming.C @@ -0,0 +1,102 @@ +#include +#include +#include + +#include + +#include +#include + +struct K : public CGAL::Exact_predicates_inexact_constructions_kernel {}; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CDT::Point Point; +typedef CDT::Vertex_handle Vertex_handle; + +typedef CDT::size_type size_type; + +template +typename CTr::size_type number_of_constrained_edges(const CTr& tr) +{ + typename CTr::size_type nedges = 0; + for(typename CTr::Finite_edges_iterator eit = tr.finite_edges_begin(); + eit != tr.finite_edges_end(); + ++eit) + if(tr.is_constrained(*eit)) + ++nedges; + return nedges; +} + +int main() +{ + CDT cdt; + + // CHECK FIRST read_triangle_poly_file AND operator>> OF CDT + + // read a poly file + + std::cout << "Reading fish.poly...\n"; + std::ifstream poly_file("fish.poly"); + CGAL::read_triangle_poly_file(cdt, poly_file); + + const size_type number_of_vertices_poly = cdt.number_of_vertices(); + const size_type number_of_constrained_edges_poly = + number_of_constrained_edges(cdt); + + std::cout << "number of vertices: " << number_of_vertices_poly + << "\nnumber of constrained edges: " + << number_of_constrained_edges_poly << "\n\n"; + + // read a CGAL file (edg file). + + std::cout << "Reading fish.edg...\n"; + + std::ifstream edg_file("fish.edg"); + + cdt.clear(); + + size_type nedges = 0; + edg_file >> nedges; + for(size_type n = 0; n < nedges; ++n) { + Point p1, p2; + edg_file >> p1 >> p2; + cdt.insert_constraint(p1, p2); + } + + const size_type number_of_vertices_edg = cdt.number_of_vertices(); + const size_type number_of_constrained_edges_edg = + number_of_constrained_edges(cdt); + + std::cout << "number of vertices: " << number_of_vertices_edg + << "\nnumber of constrained edges: " + << number_of_constrained_edges_edg << "\n\n"; + + + // check that numbers of constrained edges and vertices are the same + + CGAL_assertion( number_of_constrained_edges_edg == + number_of_constrained_edges_poly ); + + CGAL_assertion( number_of_vertices_edg == number_of_vertices_poly ); + + // CONFORMING + + std::cout << "Conforming...\n"; + CDT cdt2=cdt; + + // Gabriel for cdt + make_conforming_Gabriel_2(cdt); + // Delaunay, then Gabriel for cdt2 + make_conforming_Delaunay_2(cdt2); + std::cout << "Number of vertices after make_conforming_Delaunay_2: " + << cdt2.number_of_vertices() << "\n"; + CGAL_assertion( cdt2.number_of_vertices() == 17 ); + make_conforming_Gabriel_2(cdt2); + std::cout << "Number of vertices after make_conforming_Gabriel_2: " + << cdt2.number_of_vertices() << "\n"; + CGAL_assertion( cdt2.number_of_vertices() == 29 ); + + // check that numbers of vertices are the same in cdt and cdt2 + CGAL_assertion( cdt2.number_of_vertices() == + cdt.number_of_vertices() ); + +} diff --git a/Mesh_2/test/Mesh_2/test_double_map.C b/Mesh_2/test/Mesh_2/test_double_map.C new file mode 100644 index 00000000000..2178c4714bb --- /dev/null +++ b/Mesh_2/test/Mesh_2/test_double_map.C @@ -0,0 +1,80 @@ +#include +#include +#include +#include + +#include +#include + +typedef CGAL::Double_map Map; + +int main(int, char**) +{ + Map f; + Map f2; + + for(int n=0; n<500; n++) + { + int i=CGAL::default_random.get_int(0,1000); + f.insert(i, i*i); + } + + CGAL_assertion(f.size()<=500); + + f2 = f; // check the assignment + f2 = f2; // check the auto-assignment + Map f3(f); // check the copy constructor + + CGAL_assertion(f.size() == f2.size()); + CGAL_assertion(f.size() == f3.size()); + + int i, i2; + i2 = 0; + while(!f.empty()) + { + i = f.front()->second; + f2.erase(i); + f3.erase(i); + int new_i2 = f.front()->first; + CGAL_assertion(new_i2>=i2); + i2=new_i2; + CGAL_assertion(i2 == i*i); + f.pop_front(); + } + + CGAL_assertion(f.size()==0); + CGAL_assertion(f2.empty()); + CGAL_assertion(f3.empty()); + + for(int n=0; n<500; n++) + { + f.insert(n, n*n); + } + + CGAL_assertion(f.size()==500); + + i2=0; + int counter = 0; + while(!f.empty()) + { + i = f.front()->second; + int new_i2 = f.front()->first; + CGAL_assertion(new_i2>=i2); + i2=new_i2; + CGAL_assertion(i2 == i*i); + f.pop_front(); + ++counter; + } + + CGAL_assertion(f.size()==0); + CGAL_assertion(counter==500); + + for(int n=0; n<500; n++) + { + f.insert(n, n*n); + } + f.clear(); + CGAL_assertion(f.size()==0); + + return 0; +} diff --git a/Mesh_2/test/Mesh_2/test_filtred_container.C b/Mesh_2/test/Mesh_2/test_filtred_container.C new file mode 100644 index 00000000000..b7d0a20fbfe --- /dev/null +++ b/Mesh_2/test/Mesh_2/test_filtred_container.C @@ -0,0 +1,42 @@ +#include +#include +#include + +#include +#include + +class Is_odd { +public: + bool operator()(const int i) const + { + return (i%2)==1; + } +}; + +typedef CGAL::Mesh_2::Filtered_queue_container Queue; + +int main(int, char**) +{ + Queue q; + + int + real_number_of_odds=0, + detected_number_of_odds=0; + + for(int n=0; n<500; n++) + { + int i=CGAL::default_random.get_int(0,1000); + if((i%2)==1) ++real_number_of_odds; + q.add_element(i); + } + + while(!q.empty()) + { + ++detected_number_of_odds; + q.remove_next_element(); + } + + std::cout << "detected = " << detected_number_of_odds << std::endl + << "really = " << real_number_of_odds << std::endl; + return detected_number_of_odds!=real_number_of_odds; +} diff --git a/Mesh_2/test/Mesh_2/test_meshing.C b/Mesh_2/test/Mesh_2/test_meshing.C new file mode 100644 index 00000000000..b40f469593f --- /dev/null +++ b/Mesh_2/test/Mesh_2/test_meshing.C @@ -0,0 +1,167 @@ +// 154 515 565 +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +struct K : public CGAL::Exact_predicates_inexact_constructions_kernel {}; +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Delaunay_mesh_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2 CDT; +typedef CGAL::Delaunay_mesh_size_criteria_2 Criteria; +typedef CDT::size_type size_type; + +typedef CDT::Point Point; + +template +typename CTr::size_type number_of_constrained_edges(const CTr& tr) +{ + typename CTr::size_type nedges = 0; + for(typename CTr::Finite_edges_iterator eit = tr.finite_edges_begin(); + eit != tr.finite_edges_end(); + ++eit) + if(tr.is_constrained(*eit)) + ++nedges; + return nedges; +} + +int main() +{ + CDT cdt; + + std::vector seeds; + seeds.reserve(32); + + std::cerr << "Reading fish-and-rectangle.poly..."; + std::ifstream poly_file("fish-and-rectangle.poly"); + CGAL::read_triangle_poly_file(cdt, poly_file, std::back_inserter(seeds)); + + const size_type inititial_number_of_vertices = cdt.number_of_vertices(); + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() + << "\nNumber of seeds: " << seeds.size() << "\n\n"; + + std::cerr << "Saving the triangulation...\n\n"; + CDT cdt2 = cdt; + + std::cerr << "1/ First tests:\n\n"; + + std::cerr << "Meshing the triangulation with size 0..."; + CGAL::refine_Delaunay_mesh_2(cdt, + seeds.begin(), seeds.end(), + Criteria()); + const size_type number_of_vertices0 = cdt.number_of_vertices(); + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() << "\n\n"; + CGAL_assertion( 64 <= cdt.number_of_vertices() && + cdt.number_of_vertices() <= 72 ); + CGAL_assertion( seeds.size() == 3 ); + + std::cerr << "Meshing the triangulation with size 0.2..."; + CGAL::refine_Delaunay_mesh_2(cdt, + seeds.begin(), seeds.end(), + Criteria(0.125, 0.2)); + + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() << "\n\n"; + CGAL_assertion( 180 <= cdt.number_of_vertices() && + cdt.number_of_vertices() <= 200 ); + + std::cerr << "Meshing the triangulation with size 0.1..."; + CGAL::refine_Delaunay_mesh_2(cdt, + seeds.begin(), seeds.end(), + Criteria(0.125, 0.1)); + const size_type number_of_vertices1 = cdt.number_of_vertices(); + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() << "\n\n"; + CGAL_assertion( 580 <= cdt.number_of_vertices() && + cdt.number_of_vertices() <= 640 ); + + cdt = cdt2; + std::cerr << "Triangulation restored.\n"; + std::cerr << "Number of vertices: " << cdt.number_of_vertices() << "\n\n"; + + std::cerr << "Meshing the triangulation with Delaunay_mesh_criteria_2()..."; + CGAL::refine_Delaunay_mesh_2(cdt, + seeds.begin(), seeds.end(), + CGAL::Delaunay_mesh_criteria_2()); + const size_type number_of_vertices0bis = cdt.number_of_vertices(); + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() << "\n\n"; + + CGAL_assertion( number_of_vertices0 == number_of_vertices0bis ); + + cdt = cdt2; + std::cerr << "Triangulation restored.\n"; + std::cerr << "Number of vertices: " << cdt.number_of_vertices() << "\n\n"; + + std::cerr << "2/ Comparaison between refine_Delaunay_mesh_2() and other" + << " possibilities:\n\n"; + + std::cerr << "Meshing the triangulation with size 0.1, with " + << "refine_Delaunay_mesh_2()..."; + CGAL::refine_Delaunay_mesh_2(cdt, + seeds.begin(), seeds.end(), + Criteria(0.125, 0.1)); + const size_type number_of_vertices1bis = cdt.number_of_vertices(); + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() + << "\n\n"; + + CGAL_assertion( number_of_vertices1bis <= number_of_vertices1 ); + + cdt = cdt2; + + std::cerr << "Meshing the triangulation with size 0.1, with " + << "mesher.refine_mesh()..."; + { + CGAL::Delaunay_mesher_2 mesher(cdt, Criteria(0.125, 0.1)); + mesher.set_seeds(seeds.begin(), seeds.end()); + mesher.refine_mesh(); + } + const size_type number_of_vertices2 = cdt.number_of_vertices(); + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() + << "\n\n"; + + CGAL_assertion( number_of_vertices2 == number_of_vertices1bis ); + + cdt = cdt2; + + std::cerr << "Meshing the triangulation with size 0.1, with\n" + << "a loop of mesher.try_one_step_refine_mesh()..."; + size_type step = 0; + { + CGAL::Delaunay_mesher_2 mesher(cdt, Criteria(0.125, 0.1)); + mesher.set_seeds(seeds.begin(), seeds.end()); + mesher.init(); + while(mesher.try_one_step_refine_mesh()) + ++step; + } + const size_type number_of_vertices3 = cdt.number_of_vertices(); + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() + << "\nNumber of steps: " << step << "\n\n"; + + CGAL_assertion( step + inititial_number_of_vertices >= number_of_vertices3 ); + CGAL_assertion( number_of_vertices3 == number_of_vertices2 ); + + cdt = cdt2; + + std::cerr << "Meshing the triangulation with size 0.1, with\n" + << "a loop of mesher.step_by_step_refine_mesh()..."; + step = 0; + { + CGAL::Delaunay_mesher_2 mesher(cdt, Criteria(0.125, 0.1)); + mesher.set_seeds(seeds.begin(), seeds.end()); + mesher.init(); + while(mesher.step_by_step_refine_mesh()) + ++step; + } + const size_type number_of_vertices4 = cdt.number_of_vertices(); + std::cerr << " done.\nNumber of vertices: " << cdt.number_of_vertices() + << "\nNumber of steps: " << step << "\n\n"; + + CGAL_assertion( number_of_vertices4 == number_of_vertices2 ); + CGAL_assertion( number_of_vertices4 == step + inititial_number_of_vertices ); +} diff --git a/Mesh_2/utils/Mesh_2/polygon2poly.C b/Mesh_2/utils/Mesh_2/polygon2poly.C new file mode 100644 index 00000000000..c3feb5a502a --- /dev/null +++ b/Mesh_2/utils/Mesh_2/polygon2poly.C @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include +#include + +typedef CGAL::Simple_cartesian K1; +typedef CGAL::Filtered_kernel K2; +struct K : public K2 {}; + +typedef CGAL::Triangulation_vertex_base_2 Vb; +typedef CGAL::Constrained_triangulation_face_base_2 Fb; +typedef CGAL::Triangulation_data_structure_2 Tds; +typedef CGAL::Constrained_Delaunay_triangulation_2 Tr; +typedef CGAL::Conforming_Delaunay_triangulation_2 Conform; +typedef Conform::Vertex_handle Vertex_handle; + +typedef K::Point_2 Point; + +Conform conform; + +int main(int, char**) +{ + unsigned int number_of_points; + std::cin >> number_of_points; + CGAL::skip_until_EOL(std::cin); + CGAL::skip_comment_OFF(std::cin); + + // read vertices + std::vector vertices(number_of_points); + for(unsigned int i = 0; i < number_of_points; ++i) + { + Point p; + std::cin >> p; + CGAL::skip_until_EOL(std::cin); CGAL::skip_comment_OFF(std::cin); + vertices[i] = conform.insert(p); + } + + // les segments sont formes de 2 points consecutifs + // read segments + unsigned int k; + for(k = 0; k < number_of_points-1; ++k) + { + conform.insert_constraint(vertices[k], vertices[k+1]); + } + + // le dernier segment, qui relie le dernier point au premier + conform.insert_constraint(vertices[k], vertices[0]); + + + write_poly(conform, std::cout); + return 0; +};