From 1a83f9670ab2b5a0086ed784695cdf3847771e22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 19 Oct 2012 12:53:47 +0000 Subject: [PATCH 002/114] move to feature branch --- .gitattributes | 3 + .../main.aux | 34 + .../main.tex | 13 + .../AFSR_cell_base_3.tex | 37 + .../AFSR_options.tex | 14 + .../AFSR_vertex_base_3.tex | 33 + .../AFSR_vertex_base_with_id_3.tex | 31 + ...Advancing_front_surface_reconstruction.tex | 71 + .../Surface_face_base_2.tex | 39 + .../Surface_vertex_base_2.tex | 29 + .../intro.tex | 16 + .../main.tex | 8 + .../write_to_file_vrml2.tex | 18 + .../CMakeLists.txt | 33 + .../extract.cpp | 501 +++++ .../fill.cpp | 138 ++ .../include/CGAL/AFSR/Surface_face_base_2.h | 89 + .../include/CGAL/AFSR/Surface_vertex_base_2.h | 76 + .../include/CGAL/AFSR/construct_surface_2.h | 127 ++ .../include/CGAL/AFSR/orient.h | 120 + .../include/CGAL/AFSR_cell_base_3.h | 222 ++ .../include/CGAL/AFSR_options.h | 48 + .../include/CGAL/AFSR_vertex_base_3.h | 473 ++++ .../include/CGAL/AFSR_vertex_base_with_id_3.h | 546 +++++ .../Advancing_front_surface_reconstruction.h | 1956 +++++++++++++++++ .../include/CGAL/IO/AFSR_vrml.h | 68 + .../Advancing_front_surface_reconstruction.h | 965 ++++++++ .../include/CGAL/Tvb_3_2.h | 94 + 28 files changed, 5802 insertions(+) create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_options.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_face_base_2.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_vertex_base_2.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/intro.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/main.tex create mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex create mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt create mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp create mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h diff --git a/.gitattributes b/.gitattributes index e2e066e2669..0478f01eae9 100644 --- a/.gitattributes +++ b/.gitattributes @@ -51,6 +51,9 @@ AABB_tree/test/AABB_tree/data/cube.off -text AABB_tree/test/AABB_tree/data/finger.off -text AABB_tree/test/AABB_tree/data/pinion.off -text AABB_tree/test/AABB_tree/data/tetrahedron.off -text +Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux -text +Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/Kniesmoothed.xyz -text +Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/hand_pierre_wt-shuffled.xyz -text Algebraic_foundations/doc_tex/Algebraic_foundations/Algebraic_foundations.png -text Algebraic_foundations/doc_tex/Algebraic_foundations/Algebraic_foundations2.png -text Algebraic_foundations/doc_tex/Algebraic_foundations/algebraic_structures.tex -text diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux new file mode 100755 index 00000000000..01003caf766 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux @@ -0,0 +1,34 @@ +\relax +\@writefile{toc}{\contentsline {chapter}{\numberline {1}Advancing Front Surface Reconstuction}{1}} +\@writefile{lof}{\addvspace {10\p@ }} +\@writefile{lot}{\addvspace {10\p@ }} +\@writefile{lof}{\contentsline {xchapter}{Advancing Front Surface Reconstuction}{1}} +\@writefile{lot}{\contentsline {xchapter}{Advancing Front Surface Reconstuction}{1}} +\newlabel{chap:surface_reconstruction}{{1}{1}} +\@writefile{toc}{\contentsline {section}{\numberline {1.1}Introduction}{1}} +\@setckpt{Advancing_front_surface_reconstruction/main}{ +\setcounter{page}{2} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{chapter}{1} +\setcounter{section}{1} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{r@tfl@t}{0} +\setcounter{LT@tables}{0} +\setcounter{LT@chunks}{0} +\setcounter{mtc}{1} +\setcounter{minitocdepth}{2} +\setcounter{ptc}{0} +\setcounter{parttocdepth}{2} +} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.tex new file mode 100755 index 00000000000..713ddc1e4fe --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.tex @@ -0,0 +1,13 @@ +\chapter{Advancing Front Surface Reconstuction} +\label{chap:surface_reconstruction} +\ccChapterAuthor{Frank Da and David Cohen-Steiner} + + +\section{Introduction} + +This package offers an algorithm for surface reconstruction from an unorganized point set. +The algorithm selects facets of the 3D Delaunay triangulation of the points. + + + + diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex new file mode 100755 index 00000000000..b78473321b2 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex @@ -0,0 +1,37 @@ +\begin{ccRefClass}{AFSR_cell_base_3} + +\ccDefinition + The class \ccRefName\ is the cell class that must be blended in the cell parameter +of the 3D Delaunay triagulation. It mainly provides storage and methods used by the +Advancing front surface reconstruction algorithm. + + +\ccInclude{CGAL/AFSR_cell_base_2.h} + +\ccInheritsFrom + +\ccc{CellBase} + +%\ccTypes + +%\ccTypedef{typedef Kernel::FT FT;}{The number type.} + +%\ccCreation +%\ccCreationVariable{c} + +%\ccConstructor{AFSR_cell_base_3();}{Default constructor} + +%\ccOperations + +%\ccMemberFunction{bool has_facet_on_surface() const;}{Returns \ccc{true}, iff the facet is on the surface.} + +%\ccSeeAlso + +%\ccRefIdfierPage{} + +\end{ccRefClass} + + + + + diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_options.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_options.tex new file mode 100755 index 00000000000..06b2ffae373 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_options.tex @@ -0,0 +1,14 @@ +\begin{ccRefClass}{AFSR_options} + +\ccDefinition + +The class \ccRefName\ is used as a container of the options of the surface reconstruction algorithm. + +\ccInclude{CGAL/AFSR_options.h} + + +%\ccSeeAlso + +%\ccRefIdfierPage{} + +\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex new file mode 100755 index 00000000000..bffba82de7d --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex @@ -0,0 +1,33 @@ +\begin{ccRefClass}{AFSR_vertex_base_3} + +\ccDefinition + +The class \ccRefName\ is the vertex class that must be blended in the vertex parameter +of the 3D Delaunay triagulation. It mainly provides storage and methods used by the +Advancing front surface reconstruction algorithm. + +\ccInclude{CGAL/AFSR_vertex_base_3.h} + + +\ccInheritsFrom + +\ccc{VertexBase} + +%\ccTypes + +%\ccTypedef{typedef Kernel::FT FT;}{The number type.} + +%\ccCreation +%\ccCreationVariable{v} + +%\ccConstructor{Surface_vertex_base_2();}{Default constructor} + +%\ccOperations + +%\ccMemberFunction{Vertex_handle_3 vertex_3() const;}{Returns the vertex handle in the 3D Delaunay triangulation.} + +%\ccSeeAlso + +%\ccRefIdfierPage{} + +\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex new file mode 100755 index 00000000000..276a2aef984 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex @@ -0,0 +1,31 @@ +\begin{ccRefClass}{AFSR_vertex_base_with_id_3} + +\ccDefinition + +The class \ccRefName\ is the vertex class that must be blended in the vertex parameter +of the 3D Delaunay triagulation. It mainly provides storage and methods used by the +Advancing front surface reconstruction algorithm. + +\ccInclude{CGAL/AFSR_vertex_base_with_id_3.h} + + + +%\ccTypes + +%\ccTypedef{typedef Kernel::FT FT;}{The number type.} + +%\ccCreation +\ccCreationVariable{v} + +%\ccConstructor{Surface_vertex_base_2();}{Default constructor} + +\ccOperations + +\ccMemberFunction{int& id() const;}{Returns a reference to an \ccc{int} that is not used or altered by the + surface reconstruction algorithm.} + +%\ccSeeAlso + +%\ccRefIdfierPage{} + +\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex new file mode 100755 index 00000000000..16deda0cf40 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex @@ -0,0 +1,71 @@ +\begin{ccRefClass}{Advancing_front_surface_reconstruction} + +\ccDefinition + +The class \ccRefName\ extracts a surface from a 3D Delaunay triangulation. + +\ccInclude{CGAL/Advancing_front_surface_reconstruction.h} + +\ccParameters + +The parameter for \ccc{Delaunay_3} must be a 3D Delaunay triangulation where \ccc{CGAL::AFSR_vertex_base_3} +or \ccc{CGAL::AFSR_vertex_base_with_id_3} and \ccc{CGAL::AFSR_cell_base_3} must be blended in the vertex and face class. + + + +\ccTypes + +\ccTypedef{typedef Delaunay_3 Triangulation_3;}{} +\ccTypedef{typedef CGAL::Triple Edge;}{For \ccc{(ch,i,j)}, this is the edge between vertices \ccc{i} and \ccc{j} in cell \ccc{*ch}.} + +\ccTypedef{typedef std::pair Edge_incident_facet;}{For \ccc{((ch,i,j),k)}, this is the facet adjacent to the edge \ccc{(,i,j)}, and + opposite to vertex \ccc{k}, in the cell \ccc{*ch}.} +\ccGlue +\ccNestedType{TDS_2}{The type of the 2D triangulation data structure describing the reconstructed surface.} +\ccNestedType{TDS_2::Vertex}{It is model of the concept \ccc{TriangulationDataStructure_2::Vertex} and has additionally the + method \ccc{vertex_3()} that returns a \ccc{Triangulation_3::Vertex_handle} to the associated 3D vertex.} +\ccNestedType{TDS_2::Face}{It is model of the concept \ccc{TriangulationDataStructure_2::Face} and has additionally the + method \ccc{facet()} that returns the associated \ccc{Triangulation_3::Facet}.} + +\ccNestedType{Boundary_iterator}{This forward iterator allows to visit all contours. It + visits the entry point of the contour twice. This allows to + detect that the traversal of the border is finished. One more increment + brings us to the vertex on the next boundary. The value type of the iterator is \ccc{Triangulation_3::Vertex}.} + +\ccNestedType{Outlier_iterator}{This bidirectional iterator allows to enumerate all points that were removed + from the 3D Delaunay triangulation during the surface reconstruction. The value type + of the iterator is \ccc{Kernel::Point_3}.} + +\ccCreation +\ccCreationVariable{es} + +\ccConstructor{Advancing_front_surface_reconstruction(Delaunay_3& del, AFSR_options opt);}{} + +\ccOperations + +\ccMemberFunction{const TDS_2& tds_2() const;}{Returns a const reference to the reconstructed surface. } +\ccMemberFunction{bool is_on_surface(TDS_2::Vertex_handle vh;}{Returns true, iff the vertex is on the reconstructed surface.} + + +\ccMemberFunction{const Triangulation_3& triangulation() const;}{Returns a const reference to the 3D Delaunay triangulation.} + +\ccMemberFunction{Boundary_iterator boundaries_begin() const;}{} +\ccMemberFunction{Boundary_iterator boundaries_end() const;}{} + +\ccMemberFunction{Outlier_iterator outliers_begin() const;}{} +\ccMemberFunction{Outlier_iterator outliers_end() const;}{} + +\ccMemberFunction{bool has_on_surface(Triangulation_3::Facet f) const;} + {Returns \ccc{true}, iff the facet is on the reconstructed surface.} + +\ccMemberFunction{Edge_incident_facet next(const Edge_incident_facet& f) const;}{returns the next facet around the edge.} +\ccMemberFunction{Edge_incident_facet previous(const Edge_incident_facet& f) const;}{returns the previous facet around the edge.} + +\ccMemberFunction{Facet next_surface_facet(const Edge_incident_facet& f) const}{returns the next facet ariund the edge, + which is on the reconstructed surface.} + +%\ccSeeAlso + +%\ccRefIdfierPage{} + +\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_face_base_2.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_face_base_2.tex new file mode 100755 index 00000000000..d9328eba201 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_face_base_2.tex @@ -0,0 +1,39 @@ +\begin{ccRefClass}{AFSR::Surface_face_base_2} + +\ccDefinition + +The class \ccRefName\ is the face class used in the triangulation data structure +that describes the reconstructed surface. A face is either part of this +surface, or it is not part of the surface but adjacent to the boundary of the surface. + +The face class stores a facet of the 3D Delaunay triangulation, if it +is part of the surface. + +\ccInclude{CGAL/AFSR/Surface_face_base_2.h} + + +%\ccTypes + +%\ccTypedef{typedef Kernel::FT FT;}{The number type.} + +%\ccCreation +\ccCreationVariable{f} + +%\ccConstructor{Surface_face_base_2();}{Default constructor} + +\ccOperations + +\ccMemberFunction{Facet facet() const;}{Returns the facet in the 3D Delaunay triangulation.} + +\ccMemberFunction{bool is_on_surface() const;}{Returns \ccc{true}, iff the face is on the surface.} + +%\ccSeeAlso + +%\ccRefIdfierPage{} + +\end{ccRefClass} + + + + + diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_vertex_base_2.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_vertex_base_2.tex new file mode 100755 index 00000000000..2a2845e231d --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_vertex_base_2.tex @@ -0,0 +1,29 @@ +\begin{ccRefClass}{AFSR::Surface_vertex_base_2} + +\ccDefinition + +The class \ccRefName\ is the vertex class used in the 2D triangulation data structure +that describes the reconstructed surface. It stores a vertex handle to its +correpsonding vertex in the 3D Delaunay triangulation. + +\ccInclude{CGAL/AFSR/Surface_vertex_base_2.h} + + +%\ccTypes + +%\ccTypedef{typedef Kernel::FT FT;}{The number type.} + +%\ccCreation +\ccCreationVariable{v} + +%\ccConstructor{Surface_vertex_base_2();}{Default constructor} + +\ccOperations + +\ccMemberFunction{Vertex_handle_3 vertex_3() const;}{Returns the vertex handle in the 3D Delaunay triangulation.} + +%\ccSeeAlso + +%\ccRefIdfierPage{} + +\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/intro.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/intro.tex new file mode 100755 index 00000000000..ee184dd930d --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/intro.tex @@ -0,0 +1,16 @@ +\chapter{Advancing Front Surface Reconstruction} +\label{chap:surface_reconstruction_ref} +\ccChapterAuthor{Frank Da and David Cohen-Steiner} + + +\ccHeading{Classes} + +\ccRefIdfierPage{CGAL::Advancing_front_surface_reconstruction}\\ +\ccRefIdfierPage{CGAL::AFSR_options}\\ +\ccRefIdfierPage{CGAL::AFSR_face_base_3}\\ +\ccRefIdfierPage{CGAL::AFSR_vertex_base_3}\\ +\ccRefIdfierPage{CGAL::AFSR_vertex_base_with_id_3} + +\ccHeading{Functions} + +\ccRefIdfierPage{CGAL::write_to_file_vrml2} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/main.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/main.tex new file mode 100755 index 00000000000..1501aa839d0 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/main.tex @@ -0,0 +1,8 @@ + +\input{Advancing_front_surface_reconstruction_ref/intro.tex} + +\input{Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex} +\input{Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex} +\input{Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex} +\input{Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex} +\input{Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex} \ No newline at end of file diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex new file mode 100755 index 00000000000..cc7ffd4a287 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex @@ -0,0 +1,18 @@ +\begin{ccRefFunction}{write_to_file_vrml2} + +\ccDefinition + +The function \ccRefName\ writes the reconstructed surface to a file. + +\ccInclude{CGAL/IO/Advancing_front_surface_reconstruction.h} + +\ccFunction{template +void +write_to_file_vrml2(char* foutput, const Surface& S, + bool boundary, double red, double green, double blue, bool no_header);} +{Opens a file with the basename \ccc{foutput} and the file extension \ccc{.wrl}, and writes the +reconstructed surface to this file. If \ccc{boundary} is \ccc{true} the boundary is drawn. +The color of the facets is defined by \ccc{red}, \ccc{green}, and \ccc{blue}. If \ccc{no_header} is +\ccc{true}, the VRML header is not written.} + +\end{ccRefFunction} \ No newline at end of file diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt new file mode 100644 index 00000000000..1ff756f5b94 --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt @@ -0,0 +1,33 @@ +# Created by the script cgal_create_cmake_script +# This is the CMake script for compiling a CGAL application. + + +project( Advancing_front_surface_reconstruction_example ) + +CMAKE_MINIMUM_REQUIRED(VERSION 2.4.5) + +set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) + +if ( COMMAND cmake_policy ) + cmake_policy( SET CMP0003 NEW ) +endif() + +find_package(CGAL QUIET COMPONENTS Core ) + +if ( CGAL_FOUND ) + + include( ${CGAL_USE_FILE} ) + + include( CGAL_CreateSingleSourceCGALProgram ) + + include_directories (BEFORE ../../include) +# include_directories (BEFORE ../../../../../trunk/Triangulation_2/include) + + create_single_source_cgal_program( "extract.cpp" ) + +else() + + message(STATUS "This program requires the CGAL library, and will not be compiled.") + +endif() + diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp new file mode 100644 index 00000000000..2bf5dd81adc --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -0,0 +1,501 @@ +#define NOLAZY +#define BLIND + + +#include +#include +#include +#include +#include +#include +#include +#include + + +// Kernel +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + + + + + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + +typedef Kernel::Point_3 Point; +typedef Kernel::Vector_3 Vector; +typedef Kernel::Point_2 Point_2; + +typedef CGAL::AFSR_vertex_base_with_id_3 LVb; +typedef CGAL::Triangulation_hierarchy_vertex_base_3 HVb; + +typedef CGAL::Triangulation_cell_base_3 Cb; +typedef CGAL::AFSR_cell_base_3 LCb; + + +typedef CGAL::Triangulation_data_structure_3 Tds; + + +typedef CGAL::Delaunay_triangulation_3 Delaunay_Triangulation_3; +typedef CGAL::Triangulation_hierarchy_3 Triangulation_3; +typedef Triangulation_3::Vertex_handle Vertex_handle; + +typedef CGAL::Advancing_front_surface_reconstruction Surface; +typedef CGAL::AFSR_options Options; + + +//--------------------------------------------------------------------- + +bool +file_input(const Options& opt, std::vector& points) +{ + const char* finput = opt.finname; + int number_of_points = opt.number_of_points; + bool xyz = opt.xyz; + + std::ios::openmode mode = (opt.binary) ? std::ios::binary : std::ios::in; + std::ifstream is(finput, mode); + + if(opt.binary){ + CGAL::set_binary_mode(is); + } + if(is.fail()) + { + std::cerr << "+++unable to open file for input" << std::endl; + exit(0); + return false; + } + else + std::cout << "Input from file : " << finput << std::endl; + + int n; + if(! xyz){ + is >> n; + std::cout << " reading " << n << " points" << std::endl; + points.reserve(n); + CGAL::copy_n(std::istream_iterator(is), n, std::back_inserter(points)); + } else { + // we do not know beforehand how many points we will read + std::istream_iterator it(is), eof; + while(it!= eof){ + points.push_back(*it); + it++; + } + n = points.size(); + } + + + if ( (number_of_points > 0 ) && (number_of_points < n )) + { + points.erase(points.begin()+number_of_points, points.begin()+n); + + std::cout << std::endl + << " and randomize a sub-sample of " << number_of_points + << " points." << + std::endl << std::endl; + } + return true; +} + + + +void usage(char* program) +{ + std::cerr << std::endl << "NAME " << std::endl + << program << " - surface extension -" << std::endl << std::endl; + + std::cerr << std::endl << "OPTIONS" << std::endl + << " -shuffle : random shuffle" << std::endl + << " -xyz : input data in xyz format" << std::endl + << " -no_border -nb : " << std::endl + << " -in fname : reads points from file ./fname" << std::endl + << " -out fname : writes points to file ./fname" << std::endl + << " -out_format -of : choose file format for output (iv, wrl, oogl, medit," << std::endl + << " ply, stl, all, none)" << std::endl + << " -rgb r g b : color of the surface" << std::endl + << " -no_header : The Vrml header and footer are not written" << std::endl + << " -area a : No faces larger than area * average_area" << std::endl + << " -perimeter p : No faces larger than perimeter * average_perimeter" << std::endl + << " -abs_area a : No faces larger than abs_area" << std::endl + << " -abs_perimeter p : No faces with perimeter longer than abs_perimeter" << std::endl + << " -number_of_points n : set a number of points for a sub-sample" << std::endl + + << "\n Options for internal use" << std::endl + + << " -sect_in fname : reads points from sections file ./fname" << std::endl + << " -binary : binary I/O" << std::endl + << " -delta x : set the delta constant" << std::endl + << " -ki x y : set the K interval (default : [1.1 5])" << std::endl + << " -ks x : set the K step (default : .1)" << std::endl + << " -k x : set the K constant (only one pass)" << std::endl + << " -Delaunay : display the underlying Delaunay triangulation" << std::endl + << " -max_of_connected_components x : set the max of connected components" << std::endl + << " (default : non-active)" << std::endl + << " -post x : set a number for the post process" << std::endl + << " -contours : display contours" << std::endl; +} + + + +bool +parse(int argc, char* argv[], Options &opt) +{ + std::strcpy(opt.program, argv[0]); + --argc; + argv++; + if(argc == 0) + std::cout << "nothing ???" << std::endl; + + while ((argc > 0) && (argv[0][0] == '-')){ + if ((!std::strcmp(argv[0], "-D")) || (!std::strcmp(argv[0], "-Delaunay"))) { + opt.Delaunay = true; + argv++; + argc--; + std::cout << "-D "; + } + else if ((!std::strcmp(argv[0], "-c")) || (!std::strcmp(argv[0], "-contours"))) { + opt.contour = true; + argv++; + argc--; + std::cout << "-c "; + } + else if ((!std::strcmp(argv[0], "-s")) || (!std::strcmp(argv[0], "-shuffle"))) { + opt.shuffle = true; + argv++; + argc--; + std::cout << "-s "; + } + else if ((!std::strcmp(argv[0], "-b")) || (!std::strcmp(argv[0], "-binary"))) { + opt.binary = true; + argv++; + argc--; + std::cout << "-b "; + } + else if ((!std::strcmp(argv[0], "-x")) || (!std::strcmp(argv[0], "-xyz"))) { + opt.xyz = true; + argv++; + argc--; + std::cout << "-x "; + } + else if ((!std::strcmp(argv[0], "-nb")) || (!std::strcmp(argv[0], "-no_border"))) { + opt.K = HUGE_VAL; + opt.K_init = opt.K; + argv++; + argc--; + std::cout << "-nb "; + } + else if ((!std::strcmp(argv[0], "-nh")) || (!std::strcmp(argv[0], "-no_header"))) { + opt.no_header = true; + argv++; + argc--; + std::cout << "-nh "; + } + else if ((!std::strcmp(argv[0], "-d")) || (!std::strcmp(argv[0], "-delta"))){ + if (sscanf(argv[1], "%lf", &opt.delta) != 1) { + std::cerr << "Argument for delta must be a number" + << std::endl; + } + argv += 2; + argc -= 2; + std::cout << "-d " << opt.delta << " "; + } + else if ((!std::strcmp(argv[0], "-a")) || (!std::strcmp(argv[0], "-area"))){ + if (sscanf(argv[1], "%lf", &opt.area) != 1) { + std::cerr << "Argument for area must be a number" + << std::endl; + } + argv += 2; + argc -= 2; + std::cout << "-a " << opt.area << " "; + } + else if ((!std::strcmp(argv[0], "-pe")) || (!std::strcmp(argv[0], "-perimeter"))){ + if (sscanf(argv[1], "%lf", &opt.perimeter) != 1) { + std::cerr << "Argument for perimeter must be a number" + << std::endl; + } + argv += 2; + argc -= 2; + std::cout << "-perimeter " << opt.perimeter << " "; + } + else if ((!std::strcmp(argv[0], "-aa")) || (!std::strcmp(argv[0], "-abs_area"))){ + if (sscanf(argv[1], "%lf", &opt.abs_area) != 1) { + std::cerr << "Argument for abs_area must be a number" + << std::endl; + } + argv += 2; + argc -= 2; + std::cout << "-abs_area " << opt.abs_area << " "; + } + else if ((!std::strcmp(argv[0], "-ae")) || (!std::strcmp(argv[0], "-abs_perimeter"))){ + if (sscanf(argv[1], "%lf", &opt.abs_perimeter) != 1) { + std::cerr << "Argument for abs_perimeter must be a number" + << std::endl; + } + argv += 2; + argc -= 2; + std::cout << "-abs_perimeter " << opt.abs_perimeter << " "; + } + else if ((!std::strcmp(argv[0], "-ki"))){ + if ((sscanf(argv[1], "%lf", &opt.K_init) != 1)|| + (sscanf(argv[2], "%lf", &opt.K) != 1)){ + std::cerr << "Argument for K must be a number" + << std::endl; + } + argv += 3; + argc -= 3; + std::cout << "-ki " << opt.K_init << " " << opt.K << " "; + } + else if ((!std::strcmp(argv[0], "-rgb"))){ + if ((sscanf(argv[1], "%lf", &opt.red) != 1)|| + (sscanf(argv[2], "%lf", &opt.green) != 1) || + (sscanf(argv[3], "%lf", &opt.blue) != 1)){ + std::cerr << "Argument for rgb must be three numbers" + << std::endl; + } + argv += 4; + argc -= 4; + std::cout << "-rgb " << opt.red << " " << opt.green << " " << opt.blue << " " ; + } + else if ((!std::strcmp(argv[0], "-ks"))){ + if (sscanf(argv[1], "%lf", &opt.K_step) != 1) { + std::cerr << "Argument for K must be a number" + << std::endl; + } + argv += 2; + argc -= 2; + std::cout << "-ks " << opt.K_step << " "; + } + else if ((!std::strcmp(argv[0], "-k"))){ + if (sscanf(argv[1], "%lf", &opt.K) != 1) { + std::cerr << "Argument for K must be a number" + << std::endl; + } + opt.K_init = opt.K; + argv += 2; + argc -= 2; + std::cout << "-k " << opt.K_init << " "; + } + else if ((!std::strcmp(argv[0], "-n")) || (!std::strcmp(argv[0], "-number_of_points"))){ + if (sscanf(argv[1], "%d", &opt.number_of_points) != 1) { + std::cerr << "Argument for the number of points must be a number" + << std::endl; + } + argv += 2; + argc -= 2; + std::cout << "-n " << opt.number_of_points << " "; + } + else if ((!std::strcmp(argv[0], "-m")) || (!std::strcmp(argv[0], "-max_of_connected_components"))){ + if (sscanf(argv[1], "%d", &opt.max_connected_comp) != 1) { + std::cerr << "Argument for the number of connected components must be a number" + << std::endl; + } + /* + if(opt.max_connected_comp < 1) { + std::cerr << "Argument for the number of connected components must be a positive number" + << "It is set to 1" << std::endl; + opt.max_connected_comp = 1; + } + */ + argv += 2; + argc -= 2; + std::cout << "-m " << opt.max_connected_comp << " "; + } + else if ((!std::strcmp(argv[0], "-p")) || (!std::strcmp(argv[0], "-post"))){ + if (sscanf(argv[1], "%d", &opt.NB_BORDER_MAX) != 1) { + std::cerr << "Argument for post process must be a number" + << std::endl; + } + argv += 2; + argc -= 2; + std::cout << "-p " << opt.NB_BORDER_MAX << " "; + } + else if ((!std::strcmp(argv[0], "-i")) || (!std::strcmp(argv[0], "-in"))) { + std::strcpy(opt.finname, argv[1]); + opt.file_input = true; + argv += 2; + argc -= 2; + std::cout << "-i " << opt.finname << " "; + } + else if ((!std::strcmp(argv[0], "-s")) || (!std::strcmp(argv[0], "-sect_in"))) { + std::strcpy(opt.finname, argv[1]); + opt.Section_file = true; + opt.file_input = true; + argv += 2; + argc -= 2; + std::cout << "-s " << opt.finname << " "; + } + else if ((!std::strcmp(argv[0], "-o")) || (!std::strcmp(argv[0], "-out"))) { + std::strcpy(opt.foutname, argv[1]); + opt.file_output = true; + argv += 2; + argc -= 2; + std::cout << "-o " << opt.foutname << " "; + } + else if ((!std::strcmp(argv[0], "-of")) || (!std::strcmp(argv[0], "-out_format"))) { + if (!std::strcmp(argv[1], "wrl")) + opt.out_format = 0; + else if (!std::strcmp(argv[1], "oogl")) + opt.out_format = 1; + else if (!std::strcmp(argv[1], "medit")) + opt.out_format = 2; + else if (!std::strcmp(argv[1], "ply")) + opt.out_format = 3; + else if(!std::strcmp(argv[1], "iv")) + opt.out_format = 4; + else if(!std::strcmp(argv[1], "stl")) + opt.out_format = 5; + else if (!std::strcmp(argv[1], "all")) + opt.out_format = -1; + else if (!std::strcmp(argv[1], "none")) + opt.out_format = -2; + else + std::cout << "unrecognized file format." << std::endl; + opt.file_output = true; + std::cout << "-of " << argv[1] << " "; + argv += 2; + argc -= 2; + } + else if ((!std::strcmp(argv[0], "-?")) || + (!std::strcmp(argv[0], "-h")) || + (!std::strcmp(argv[0], "-help"))) { + usage(opt.program); + return false; + } + else { + std::cerr << "unrecognized option " << argv[0] << std::endl; + usage(opt.program); + return false; + } + } + if(argc > 0){ + std::cerr << "unrecognized option " << argv[0] << std::endl; + usage(opt.program); + return false; + } + return true; +} + + +//___________________________________________ +int main(int argc, char* argv[]) +{ + CGAL::Timer timer, total; + total.start(); + timer.start(); + //parse command line + Options opt; + std::cout << "Option line for this execution is :" << std::endl; + if (!parse(argc, argv, opt)) + exit(0); + std::cout << std::endl << std::endl; + + Triangulation_3 dt; + + std::vector points; + + file_input(opt, points); + + std::cout << "Time for reading " << timer.time() << " sec." << std::endl; + + + std::vector index(points.size()); + for(int i = 0; i < points.size(); i++){ + index[i] = i; + } + if(opt.shuffle){ + std::cout << "Random shuffling" << std::endl; + std::random_shuffle(index.begin(), index.end()); + } + + std::cout << "Compute Delaunay Tetrahedrization " << std::endl; + CGAL::Timer t1; + t1.start(); + + for(int i =0; i < points.size(); i++){ + Vertex_handle vh = dt.insert(points[index[i]]); + vh->id() = index[i]; + } + t1.stop(); + std::cout << " Inserted " << dt.number_of_vertices() << " points, " + << dt.number_of_cells() << " cells computed in " + << t1.time() << " sec." << std::endl; + + if (dt.dimension() < 3) { + std::cout << "-- 2D sample of points ???" << std::endl; + exit(0); + } + + index.clear(); + points.clear(); + + { + Surface S(dt, opt); + + const Surface::TDS_2& tds_2 = S.tds_2(); + + for(Surface::TDS_2::Face_iterator fit = tds_2.faces_begin(); fit != tds_2.faces_end(); ++fit){ + if( fit->is_on_surface()){ + Surface::Facet facet = fit->facet(); + Surface::Cell_handle ch = facet.first; + int fi = facet.second; + int i,j,k; + Surface::Vertex_handle vh3 = ch->vertex(Triangulation_3::vertex_triple_index(fi,0)); + for(i=0; i<3 ; i++){ + if(fit->vertex(i)->vertex_3()== vh3){ + break; + } + } + vh3 = ch->vertex(Triangulation_3::vertex_triple_index(fi,1)); + for(j=0; j<3; j++){ + if(fit->vertex(j)->vertex_3()== vh3){ + break; + } + } + vh3 = ch->vertex(Triangulation_3::vertex_triple_index(fi,2)); + for(k=0; k<3 ; k++){ + if (fit->vertex(k)->vertex_3()== vh3){ + break; + } + } + + if((i+j+k) != 3){ + std::cerr << "i = " << i << "; j = " << j << "; k = " << k << std::endl; + } + + } + + } + + + std::cout << "Total time: " << timer.time() << " sec." << std::endl; + write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); + + + std::cout << " " << S.number_of_outliers() + << " outliers." << std::endl; + std::cout << " Reconstructed surface: " << S.number_of_facets() << + " facets, " << S.number_of_vertices() << " vertices." << std::endl; + std::cout << " " << S.number_of_border_edges() << + " border edges." << std::endl; + std::cout << " number of connected components <= " + << (std::max)(1, S.number_of_connected_components()-1) + << std::endl << std::endl; + } + total.stop(); + std::cout << "Total = " << total.time() << " sec." << std::endl; + return 0; +} + + + + diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp new file mode 100644 index 00000000000..91b210b2f82 --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp @@ -0,0 +1,138 @@ +#include +#include +#include +#include +#include +#include +#include + + +typedef double NT; + +struct K : public CGAL::Filtered_kernel > {}; +typedef K::Point_3 Point; +typedef K::Vector_3 Vector; +typedef K::Segment_3 Segment; +typedef K::Triangle_3 Triangle; + +NT +weight(const Point& p, const Point& q, const Point& r){ + NT area = std::sqrt(Triangle(p,q,r).squared_area()); + NT l1 = std::sqrt((p-q) * (p-q)); + NT l2 = std::sqrt((p-r) * (p-r)); + NT l3 = std::sqrt((q-r) * (q-r)); + if(l1>l2) std::swap(l1,l2); + if(l2>l3) std::swap(l2,l3); + if(l1>l2) std::swap(l1,l2); + if(l2>l3) std::swap(l2,l3); + + // Taken from Piecewise-Linear Interpolation between Polygonal Slices + // from Gill Barequet and Micha Sharir + return 0.85 * area + 0.05 * (l1 +l2 + l3) + 0.1 * l3/l1; +} + + +void +insert(std::set >& triangles, int i, int j, int k){ + std::cout << i << ", " << j << ", " << k << std::endl; + if(i>j) std::swap(i,j); + if(j>k) std::swap(j,k); + if(i>j) std::swap(i,j); + if(j>k) std::swap(j,k); + std::cout << i << ", " << j << ", " << k << std::endl; + triangles.insert(CGAL::make_triple(i,j,k)); +} + + +void +collect(int i, int k, int n, const std::vector& O, std::set >& triangles){ + + std::cout << "collect(" << i << ", " << k << ")" << std::endl; + if((i+2) == k){ + insert(triangles, i, i+1, k); + }else { + int o = O[i*n+k]; + + if(o != (i+1)){ + collect(i, o, n, O, triangles); + } + insert(triangles, i, o, k); + if(o != (k-1)){ + collect(o, k, n, O, triangles); + } + } +} + + + +int +main(){ + + int n; + std::cin >> n; + + std::vector points(n); + CGAL::copy_n(std::istream_iterator(std::cin), n, points.begin()); + + + std::set > triangles; + + std::vector W(n*n); + std::vector O(n*n); + + for(int i = 0; i <= n-2; i++){ + W[i*n + i + 1] = 0; + } + for(int i = 0; i <= n-3; i++){ + W[i*n + i + 2] = weight(points[i], points[i+1], points[i+3]); + } + + for(int j = 3; j <= n-1; j++){ + for(int i=0; i <= n - j - 1; i++){ + int k = i + j; + double lmin = -1; + int lmin_index; + for(int m = i+1; m < k; m++){ + double d = W[i*n + m] + W[m*n + k] + weight(points[i], points[m], points[k]); + if( (lmin == -1) || (d < lmin )){ + lmin = d; + lmin_index = m; + } + } + W[i*n + k] = lmin; + O[i*n + k] = lmin_index; + + } + } + + collect(0, n-1, n, O, triangles); + + std::cout << "Shape {\n" + "appearance Appearance {\n" + "material Material { diffuseColor .9 .5 .1}}\n" + "geometry\n" + "IndexedFaceSet {\n" + "coord DEF def_coords Coordinate {\n" + "point [ \n" ; + + for (int i = 0; i < n; i++){ + std::cout << points[i].x() << " " << points[i].y() << " " << points[i].z() << ",\n "; + } + std::cout << "]\n" + "}\n" + "solid FALSE\n" + "coordIndex [ \n"; + + for(std::set >::iterator it = triangles.begin(); + it != triangles.end(); + it++){ + std::cout << it->first << ", " << it->second << ", " << it->third << ", -1,\n "; + } + std::cout << "]\n" + "}# IndexedFaceSet\n" + "}# Shape\n"; + + return 1; +} + + diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h new file mode 100755 index 00000000000..739dcd1261e --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h @@ -0,0 +1,89 @@ +#ifndef CGAL_AFSR_SURFACE_FACE_BASE_2_H +#define CGAL_AFSR_SURFACE_FACE_BASE_2_H + +// This face class stores a facet in the tetrahedrization +// When it gets reoriented by the TDS, it also changes the facet + +namespace CGAL { +namespace AFSR { + +template < typename GT, + typename F3, + typename Fb = CGAL::Triangulation_ds_face_base_2<> > +class Surface_face_base_2 + : public Fb +{ + typedef typename Fb::Triangulation_data_structure Tds; + +public: + typedef typename Tds::Face_handle Face_handle; + typedef typename Tds::Vertex_handle Vertex_handle; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Fb::template Rebind_TDS::Other Fb2; + typedef Surface_face_base_2 Other; + }; + +private: + F3 _facet; + bool _is_on_surface; + +public: + Surface_face_base_2() + : Fb(), _is_on_surface(true) + {} + + Surface_face_base_2(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2) + : Fb(v0, v1, v2), _is_on_surface(true) + {} + + Surface_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), _is_on_surface(true) + {} + + void set_facet(const F3& facet) + { + _facet = facet; + } + + const F3& facet() const + { + return _facet; + } + + void set_is_on_surface(bool is_on_surface) + { + _is_on_surface = is_on_surface; + } + + bool is_on_surface() const + { + return _is_on_surface; + } + + + void reorient() + { + + Fb::reorient(); + if( is_on_surface()){ + _facet = std::make_pair(_facet.first->neighbor(_facet.second), + _facet.first->neighbor(_facet.second)->index(_facet.first)); + } + } + +}; + + +} // namespace AFSR +} // namespace CGAL + +#endif // CGAL_AFSR_SURFACE_FACE_BASE_2_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h new file mode 100755 index 00000000000..d33628cf794 --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h @@ -0,0 +1,76 @@ +// Copyright (c) 2005 GeometryFactory Sarl +// 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. +// +// +// Author(s) : Andreas Fabri + + +#ifndef CGAL_AFSR_SURFACE_VERTEX_BASE_2_H +#define CGAL_AFSR_SURFACE_VERTEX_BASE_2_H + +#include +#include + +namespace CGAL { +namespace AFSR { + +template < typename GT, + typename V3, + typename Vb = CGAL::Triangulation_ds_vertex_base_2<> > +class Surface_vertex_base_2 + : public Vb + +{ + typedef typename Vb::Triangulation_data_structure Tds; +public: + typedef GT Geom_traits; + typedef typename GT::Point_3 Point; + typedef Tds Triangulation_data_structure; + typedef typename Tds::Face_handle Face_handle; + typedef typename Tds::Vertex_handle Vertex_handle; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef Surface_vertex_base_2 Other; + }; + +private: + V3 _vertex; +public: + Surface_vertex_base_2() : Vb() {} + Surface_vertex_base_2(Face_handle f) : Vb(f) {} + + void set_vertex(const V3& v) + { + _vertex = v; + } + + V3 vertex_3() const + { + return _vertex; + } + + const Point& point() const { return vertex->point(); } + + +}; + + + + + +} // namespace AFSR +} // namespace CGAL + +#endif //CGAL::AFSR_SURFACE_VERTEX_BASE_2_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h new file mode 100755 index 00000000000..079cce8232c --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h @@ -0,0 +1,127 @@ +#ifndef CGAL_AFSR_CONSTRUCT_SURFACE_2 + +namespace CGAL { + +template +class Advancing_front_surface_reconstruction; + +namespace AFSR { + + +template +typename TDS::Vertex_handle +construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface) +{ + + typedef typename TDS::Vertex_handle Vertex_handle; + typedef std::pair Vh_pair; + typedef typename TDS::Face_handle Face_handle; + typedef typename TDS::Edge Edge; + + + Triangulation& T = surface.triangulation(); + // create an infinite-vertex and infinite faces with the + // boundary edges if any. + // return the infinite vertex if created + Vertex_handle vinf; + + std::vector vvh; + if(tds.number_of_vertices() != 0){ + tds.clear(); + } + int dim = 2; + tds.set_dimension(dim); + + CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); + + int i=0; + for (typename Triangulation::Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++){ + typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; + if ((!v_it->is_exterior()) && d == -1){ + d = i; + Vertex_handle vh = tds.create_vertex(); + vvh.push_back(vh); + vh->set_vertex(Triangulation::Vertex_handle(v_it)); + i++; + } + } + std::map edge_map; + + for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + typename Triangulation::Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; + + Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]], + vvh[vertex_index_map[c->vertex(i2)]], + vvh[vertex_index_map[c->vertex(i3)]]); + fh->set_facet(*f_it); + vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh); + vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh); + vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh); + for (int ih = 0; ih < 3; ++ih) { + tds.set_adjacency(fh, ih, edge_map); + } + } + + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]], + vvh[vertex_index_map[n->vertex(i2)]], + vvh[vertex_index_map[n->vertex(i3)]]); + fh->set_facet(std::make_pair(n, ni)); + vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh); + vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh); + vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh); + for (int ih = 0; ih < 3; ++ih) { + tds.set_adjacency(fh, ih, edge_map); + } + } + + } + + if ( !edge_map.empty()) { + vinf = tds.create_vertex(); + std::map inf_edge_map; + while (!edge_map.empty()) { + Face_handle fh = edge_map.begin()->second.first; + int ih = edge_map.begin()->second.second; + Face_handle fn = tds.create_face( vinf, + fh->vertex(TDS::cw(ih)), + fh->vertex(TDS::ccw(ih))); + fn->set_facet(std::make_pair(Triangulation::Cell_handle(),0)); + fn->set_is_on_surface(false); + vinf->set_face(fn); + tds.set_adjacency(fn, 0, fh, ih); + tds.set_adjacency(fn, 1, inf_edge_map); + tds.set_adjacency(fn, 2, inf_edge_map); + edge_map.erase(edge_map.begin()); + } + CGAL_triangulation_assertion(inf_edge_map.empty()); + } + + tds.reorient_faces(); + return vinf; + +} + + +} // namespace AFSR +} // namespace CGAL +#endif // CGAL_AFSR_CONSTRUCT_SURFACE_2 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h new file mode 100755 index 00000000000..fe0e9f5938a --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h @@ -0,0 +1,120 @@ +#ifndef CGAL_AFSR_ORIENT + +namespace CGAL { +namespace AFSR { + + +template +typename TDS::Vertex_handle +orient(TDS& tds, const Advancing_front_surface_reconstruction& surface) +{ + + typedef typename TDS::Vertex_handle Vertex_handle; + typedef std::pair Vh_pair; + typedef typename TDS::Face_handle Face_handle; + typedef typename TDS::Edge Edge; + + Triangulation& T = surface.triangulation(); + // create an infinite-vertex and infinite faces with the + // boundary edges if any. + // return the infinite vertex if created + Vertex_handle vinf; + + std::vector vvh; + if(tds.number_of_vertices() != 0) tds.clear(); + int dim = 2; + tds.set_dimension(dim); + + CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); + + int i=0; + for (typename Triangulation::Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++){ + typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; + if ((!v_it->is_exterior()) && d == -1){ + d = i; + Vertex_handle vh = tds.create_vertex(); + vvh.push_back(vh); + vh->set_point(v_it->point()); + i++; + } + } + std::map edge_map; + + + for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + typename Triangulation::Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; + + Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]], + vvh[vertex_index_map[c->vertex(i2)]], + vvh[vertex_index_map[c->vertex(i3)]]); + vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh); + vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh); + vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh); + for (int ih = 0; ih < 3; ++ih) { + tds.set_adjacency(fh, ih, edge_map); + } + } + + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]], + vvh[vertex_index_map[n->vertex(i2)]], + vvh[vertex_index_map[n->vertex(i3)]]); + vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh); + vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh); + vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh); + for (int ih = 0; ih < 3; ++ih) { + tds.set_adjacency(fh, ih, edge_map); + } + } + + } + + if ( !edge_map.empty()) { + vinf = tds.create_vertex(); + std::map inf_edge_map; + while (!edge_map.empty()) { + Face_handle fh = edge_map.begin()->second.first; + int ih = edge_map.begin()->second.second; + Face_handle fn = tds.create_face( vinf, + fh->vertex(TDS::cw(ih)), + fh->vertex(TDS::ccw(ih))); + vinf->set_face(fn); + tds.set_adjacency(fn, 0, fh, ih); + tds.set_adjacency(fn, 1, inf_edge_map); + tds.set_adjacency(fn, 2, inf_edge_map); + edge_map.erase(edge_map.begin()); + } + CGAL_triangulation_assertion(inf_edge_map.empty()); + } + + + tds.reorient_faces(); + return vinf; + +} + + + +} // namespace AFSR +} // namespace CGAL + +#endif CGAL_AFSR_ORIENT diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h new file mode 100755 index 00000000000..7274c0263c1 --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h @@ -0,0 +1,222 @@ +#ifndef CGAL_AFSR_CELL_BASE_3_H +#define CGAL_AFSR_CELL_BASE_3_H + +namespace CGAL { + +template < class CellBase > +class AFSR_cell_base_3 : public CellBase +{ + +public: + template < typename TDS2 > + struct Rebind_TDS { + typedef typename CellBase::template Rebind_TDS::Other Cb2; + typedef AFSR_cell_base_3 Other; + }; + + typedef typename CellBase::Vertex_handle Vertex_handle; + typedef typename CellBase::Cell_handle Cell_handle; + +private: + +#ifdef AFSR_FACET_NUMBER + int _facet_number[4]; +#endif + typedef double coord_type; +#ifdef AFSR_LAZY + typedef typename CGAL::Simple_cartesian::Point_3 D_Point; +#endif + //-------------------- DATA MEMBERS --------------------------------- + + coord_type* _smallest_radius_facet_tab; + unsigned char selected_facet; +#ifdef AFSR_LAZY + D_Point* _circumcenter; + coord_type* _squared_radius; +#endif + + //-------------------- CONSTRUCTORS ---------------------------------- + +public: + + AFSR_cell_base_3() + : CellBase(), + _smallest_radius_facet_tab(NULL), selected_facet(0) +#ifdef AFSR_LAZY + , _circumcenter(NULL), _squared_radius(NULL) +#endif + { +#ifdef AFSR_FACET_NUMBER + for(int i = 0; i < 4; i++){ + _facet_number[i] = -1; + } +#endif + } + + AFSR_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) + : CellBase( v0, v1, v2, v3), + _smallest_radius_facet_tab(NULL), selected_facet(0) +#ifdef AFSR_LAZY + , _circumcenter(NULL), _squared_radius(NULL) +#endif + { +#ifdef FACET_NUMBER + for(int i = 0; i < 4; i++){ + _facet_number[i] = -1; + } +#endif + } + + AFSR_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) + : CellBase(v0, v1, v2, v3, + n0, n1, n2, n3), + _smallest_radius_facet_tab(NULL), selected_facet(0) +#ifdef AFSR_LAZY + , _circumcenter(NULL), _squared_radius(NULL) +#endif + { +#ifdef AFSR_FACET_NUMBER + for(int i = 0; i < 4; i++){ + _facet_number[i] = -1; + } +#endif + } + + //-------------------- DESTRUCTOR ----------------------------------- + + inline ~AFSR_cell_base_3() + { + if (_smallest_radius_facet_tab != NULL) + delete[] _smallest_radius_facet_tab; +#ifdef AFSR_LAZY + if (_circumcenter != NULL) + delete _circumcenter; + if (_squared_radius != NULL) + delete _squared_radius; +#endif + } + + //-------------------- MEMBER FUNCTIONS ---------------------------- + +public: + + inline void clear() + { + if (_smallest_radius_facet_tab != NULL) + delete[] _smallest_radius_facet_tab; + _smallest_radius_facet_tab = NULL; + selected_facet = 0; +#ifdef AFSR_LAZY + if (_circumcenter != NULL) + delete _circumcenter; + _circumcenter = NULL; + if (_squared_radius != NULL) + delete _squared_radius; + _squared_radius = NULL; +#endif + } + + //------------------------------------------------------------------- + + inline coord_type get_smallest_radius(const int& i) + { + if (_smallest_radius_facet_tab == NULL) + return -1; + return _smallest_radius_facet_tab[i]; + } + + inline void set_smallest_radius(const int& i, const coord_type& c) + { + if (_smallest_radius_facet_tab == NULL) + { + _smallest_radius_facet_tab = new coord_type[4]; + for(int i = 0; i < 4; i++) + _smallest_radius_facet_tab[i] = -1; + } + _smallest_radius_facet_tab[i] = c; + } + + // pour un controle de l'allocation memoire... utile??? + inline bool alloc_smallest_radius_tab(coord_type* ptr) + { + if (_smallest_radius_facet_tab==NULL) + { + _smallest_radius_facet_tab = ptr; + return true; + } + return false; + } + + + //------------------------------------------------------------------- +void +set_facet_number(int i, int n) +{ +#ifdef FACET_NUMBER + _facet_number[i] = n; +#endif +} +int +facet_number(int i) +{ +#ifdef FACET_NUMBER + return _facet_number[i]; +#endif + return 0; +} + //------------------------------------------------------------------- + + inline void select_facet(const int& i) + { + selected_facet |= (1 << i); + } + + inline void unselect_facet(const int& i) + { + selected_facet &= (15 - (1 << i)); + } + + inline bool is_selected_facet(const int& i) + { + return selected_facet & (1 << i); + } + + inline bool has_facet_on_surface(const int& i) + { + return selected_facet & (1 << i); + } + +#ifdef AFSR_LAZY + + //------------------------------------------------------------------- + + inline D_Point* get_lazy_circumcenter() + { + return _circumcenter; + } + + inline void set_lazy_circumcenter(const D_Point& p) + { + _circumcenter = new D_Point(p); + } + + //------------------------------------------------------------------- + + inline coord_type* get_lazy_squared_radius() + { + return _squared_radius; + } + + inline void set_lazy_squared_radius(const coord_type& sr) + { + _squared_radius = new coord_type(sr); + } + +#endif //AFSR_LAZY + +}; + +} // namespace CGAL + +#endif // CGAL_AFSR_CELL_BASE_3_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h new file mode 100755 index 00000000000..faa18effc01 --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h @@ -0,0 +1,48 @@ +#ifndef CGAL_AFSR_OPTIONS_H +#define CGAL_AFSR_OPTIONS_H + + +namespace CGAL { + +class AFSR_options { +public: + AFSR_options() + : file_input(true), file_output(false), + Delaunay(false), contour(false), shuffle(false), binary(false), xyz(false), + Section_file(false), number_of_points(-1), max_connected_comp(-1), + delta(.86), K_init(1.1), K_step(.1), K(5), out_format(0), + NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false), area(0), perimeter(0), + abs_area(0), abs_perimeter(0) + { + std::strcpy(finname,"finput"); + std::strcpy(foutname,"foutput"); + } + + char program[100]; + char finname[100]; + char foutname[100]; + bool file_input; + bool file_output; + bool Delaunay; + bool contour; + bool shuffle; + bool binary; + bool xyz; + bool Section_file; + int number_of_points; + int max_connected_comp; + double delta; + double K_init; + double K_step; + double K; + int out_format; + int NB_BORDER_MAX; + double red, green, blue; + bool no_header; + double area, perimeter, abs_area, abs_perimeter; +}; + + +} // namespace CGAL + +#endif // CGAL_AFSR_OPTIONS_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h new file mode 100755 index 00000000000..1820698a372 --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h @@ -0,0 +1,473 @@ +#ifndef CGAL_AFSR_VERTEX_BASE_3_H +#define CGAL_AFSR_VERTEX_BASE_3_H + +#include + +#include +#include +#include + +#include + +namespace CGAL { + +template > +class AFSR_vertex_base_3 : public VertexBase +{ +public: + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename VertexBase::template Rebind_TDS::Other Vb2; + typedef AFSR_vertex_base_3 Other; + }; + + + typedef VertexBase Base; + typedef typename Base::Vertex_handle Vertex_handle; + typedef typename Base::Cell_handle Cell_handle; + typedef typename VertexBase::Point Point; + typedef double coord_type; + + typedef Triple< Cell_handle, int, int > Edge; + typedef std::pair< Edge, int > Edge_incident_facet; + typedef std::pair< Edge_incident_facet, Edge_incident_facet > IO_edge_type; + + typedef coord_type criteria; + + typedef std::pair< criteria, IO_edge_type > Radius_edge_type; + typedef std::pair< Radius_edge_type, int > Border_elt; + typedef std::pair< Vertex_handle, Border_elt > Next_border_elt; + +private: + + //par convention je remplis d'abord first et si necessaire second... + typedef std::pair< Next_border_elt*, Next_border_elt*> Intern_successors_type; + +public: + + typedef std::pair< criteria, IO_edge_type* > Radius_ptr_type; + typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; + typedef std::pair< criteria, Edge_like > Incidence_request_elt; + typedef std::list< Incidence_request_elt > Incidence_request_type; + typedef typename Incidence_request_type::iterator Incidence_request_iterator; + + // typedef std::set< void* > Interior_edge_set_type; + + //-------------------- DATA MEMBERS --------------------------------- + +private: + + int _mark; + int _post_mark; + Intern_successors_type* _incident_border; + + // Instead of having a set per vertex, there is a global list. + static std::list interior_edges; + // and two iterators per vertex in this list + // Note that ie_last is not past the end + // ie_first == ie_last == interior_edge.end() iff the set is empty + typename std::list::iterator ie_first, ie_last; + + + // We do the same for the incidence requests + static std::list< Incidence_request_elt > incidence_requests; + typename std::list< Incidence_request_elt >::iterator ir_first, ir_last; + //-------------------- CONSTRUCTORS --------------------------------- + +public: + + AFSR_vertex_base_3() + : VertexBase(), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new Intern_successors_type(new Next_border_elt(), + new Next_border_elt()); + _incident_border->first->first = NULL; + _incident_border->second->first = NULL; + } + + AFSR_vertex_base_3(const Point & p) + : VertexBase(p), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new Intern_successors_type(new Next_border_elt(), + new Next_border_elt()); + _incident_border->first->first = NULL; + _incident_border->second->first = NULL; + } + + AFSR_vertex_base_3(const Point & p, Cell_handle f) + : VertexBase(p, f), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new Intern_successors_type(new Next_border_elt(), + new Next_border_elt()); + _incident_border->first->first = NULL; + _incident_border->second->first = NULL; + } + + AFSR_vertex_base_3(Cell_handle f) + : VertexBase(f), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new Intern_successors_type(new Next_border_elt(), + new Next_border_elt()); + _incident_border->first->first = NULL; + _incident_border->second->first = NULL; + } + + AFSR_vertex_base_3(const AFSR_vertex_base_3& other) + : VertexBase(), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new Intern_successors_type(new Next_border_elt(), + new Next_border_elt()); + _incident_border->first->first = NULL; + _incident_border->second->first = NULL; + } + //-------------------- DESTRUCTOR ----------------------------------- + + ~AFSR_vertex_base_3() + { + if (_incident_border != NULL) + { + delete _incident_border->first; + delete _incident_border->second; + delete _incident_border; + } + if(ir_first != incidence_requests.end()){ + assert(ir_last != incidence_requests.end()); + typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last); + e++; + incidence_requests.erase(b, e); + } + + if(ie_first != interior_edges.end()){ + assert(ie_last != interior_edges.end()); + typename std::list::iterator b(ie_first), e(ie_last); + e++; + interior_edges.erase(b, e); + } + } + + //-------------------- MEMBER FUNCTIONS ----------------------------- + + inline void re_init() + { + if (_incident_border != NULL) + { + delete _incident_border->first; + delete _incident_border->second; + delete _incident_border; + } + + if(ir_first != incidence_requests.end()){ + assert(ir_last != incidence_requests.end()); + typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last); + e++; + incidence_requests.erase(b, e); + ir_first = incidence_requests.end(); + ir_last = incidence_requests.end(); + } + + _incident_border = new Intern_successors_type(new Next_border_elt(), + new Next_border_elt()); + _incident_border->first->first = NULL; + _incident_border->second->first = NULL; + _mark = -1; + _post_mark = -1; + } + + //------------------------------------------------------------------- + + inline bool is_on_border(const int& i) const + { + if (_incident_border == NULL) return false; //vh is interior + if (_incident_border->first->first != NULL) + { + if (_incident_border->second->first != NULL) + return ((_incident_border->first->second.second == i)|| + (_incident_border->second->second.second == i)); + return (_incident_border->first->second.second == i); + } + return false; //vh is still exterior + } + + inline Next_border_elt* get_next_on_border(const int& i) const + { + if (_incident_border == NULL) return NULL; //vh is interior + if (_incident_border->first->first != NULL) + if (_incident_border->first->second.second == i) + return _incident_border->first; + if (_incident_border->second->first != NULL) + if (_incident_border->second->second.second == i) + return _incident_border->second; + return NULL; + } + + + inline void remove_border_edge(Vertex_handle v) + { + if (_incident_border != NULL) + { + if (_incident_border->second->first == v) + { + _incident_border->second->first = NULL; + set_interior_edge(v); + return; + } + if (_incident_border->first->first == v) + { + if (_incident_border->second->first != NULL) + { + Next_border_elt* tmp = _incident_border->first; + _incident_border->first = _incident_border->second; + _incident_border->second = tmp; + _incident_border->second->first = NULL; + set_interior_edge(v); + return; + } + else + { + _incident_border->first->first = NULL; + set_interior_edge(v); + return; + } + } + } + } + + inline bool is_border_edge(Vertex_handle v) const + { + if (_incident_border == NULL) return false; + return ((_incident_border->first->first == v)|| + (_incident_border->second->first == v)); + } + + inline Next_border_elt* get_border_elt(Vertex_handle v) const + { + if (_incident_border == NULL) return NULL; + if (_incident_border->first->first == v) return _incident_border->first; + if (_incident_border->second->first == v) return _incident_border->second; + return NULL; + } + + inline Next_border_elt* first_incident() const + { + if (_incident_border == NULL) return NULL; + return _incident_border->first; + } + + inline Next_border_elt* second_incident() const + { + if (_incident_border == NULL) return NULL; + return _incident_border->second; + } + + + inline void set_next_border_elt(const Next_border_elt& elt) + { + if (_incident_border->first->first == NULL) + *_incident_border->first = elt; + else + { + if (_incident_border->second->first != NULL) + std::cerr << "+++probleme de MAJ du bord " << std::endl; + *_incident_border->second = elt; + } + } + + //------------------------------------------------------------------- + // pour gerer certaines aretes interieures: a savoir celle encore connectee au + // bord (en fait seule, les aretes interieures reliant 2 bords nous + // interressent...) + + inline bool is_interior_edge(Vertex_handle v) const + { + + bool r1; + if(ie_first == interior_edges.end()){ + r1 = false; + }else { + typename std::list::iterator b(ie_first), e(ie_last); + e++; + typename std::list::iterator r = std::find(b, e, v); + r1 = ( r != e); + } + + return r1; + } + + inline void set_interior_edge(Vertex_handle v) + { + if(ie_last == interior_edges.end()){ // empty set + assert(ie_first == ie_last); + ie_last = interior_edges.insert(ie_last, v); + ie_first = ie_last; + } else { + typename std::list::iterator e(ie_last); + e++; +#ifdef DEBUG + typename std::list::iterator r = std::find(ie_first, e, v); +#endif + assert(r == e); + ie_last = interior_edges.insert(e, v); + } + } + + inline void remove_interior_edge(Vertex_handle v) + { + if(ie_first == interior_edges.end()){ + assert(ie_last == ie_first); + } else if(ie_first == ie_last){ // there is only one element + if(*ie_first == v){ + interior_edges.erase(ie_first); + ie_last = interior_edges.end(); + ie_first = ie_last; + } + } else { + typename std::list::iterator b(ie_first), e(ie_last); + e++; + typename std::list::iterator r = std::find(b, e, v); + if(r != e){ + if(r == ie_first){ + ie_first++; + } + if(r == ie_last){ + ie_last--; + } + interior_edges.erase(r); + } + } + } + + //------------------------------------------------------------------- + + inline void set_incidence_request(const Incidence_request_elt& ir) + { + if(ir_last == incidence_requests.end()){ + assert(ir_first == ir_last); + ir_last = incidence_requests.insert(ir_last, ir); + ir_first = ir_last; + } else { + typename std::list::iterator e(ir_last); + e++; + ir_last = incidence_requests.insert(e, ir); + } + } + + inline bool is_incidence_requested() const + { + if(ir_last == incidence_requests.end()){ + assert(ir_first == incidence_requests.end()); + } + return (ir_last != incidence_requests.end()); + } + + inline Incidence_request_iterator incidence_request_begin() + { + return ir_first; + } + + inline Incidence_request_iterator get_incidence_request_end() + { + if(ir_last != incidence_requests.end()){ + assert(ir_first != incidence_requests.end()); + Incidence_request_iterator it(ir_last); + it++; + return it; + } + return ir_last; + } + + inline void erase_incidence_request() + { + if(ir_last != incidence_requests.end()){ + assert(ir_first != incidence_requests.end()); + ir_last++; + incidence_requests.erase(ir_first, ir_last); + ir_first = incidence_requests.end(); + ir_last = incidence_requests.end(); + } + } + + + //------------------------------------------------------------------- + + inline bool is_on_border() const + { + return (_mark > 0); + } + + inline bool not_interior() const + { + return (_mark != 0); + } + + inline int number_of_incident_border() const + { + return _mark; + } + + inline bool is_exterior() const + { + return (_mark < 0); + } + + //------------------------------------------------------------------- + + inline void inc_mark() + { + if (_mark==-1) + _mark=1; + else + _mark++; + } + + inline void dec_mark() + { + _mark--; + if(_mark == 0) + { + delete _incident_border->first; + delete _incident_border->second; + delete _incident_border; + _incident_border = NULL; + erase_incidence_request(); + } + } + + //------------------------------------------------------------------- + + inline void set_post_mark(const int& i) + { + _post_mark = i; + } + + inline bool is_post_marked(const int& i) + { + return (_post_mark == i); + } +}; + +template +std::list::Vertex_handle> AFSR_vertex_base_3::interior_edges; + +template +std::list::Incidence_request_elt> AFSR_vertex_base_3::incidence_requests; + +} // namespace CGAL + +#endif //CGAL_AFSR_VERTEX_BASE_3_H + diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h new file mode 100755 index 00000000000..81c60fce4cb --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h @@ -0,0 +1,546 @@ +#ifndef CGAL_AFSR_VERTEX_BASE_WITH_ID_3_H +#define CGAL_AFSR_VERTEX_BASE_WITH_ID_3_H + +#include + +#include + +#include +#include +#include + +#include + + +namespace CGAL { + +template > +class AFSR_vertex_base_with_id_3 : public VertexBase +{ +public: + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename VertexBase::template Rebind_TDS::Other Vb2; + typedef AFSR_vertex_base_with_id_3 Other; + }; + + + + + typedef VertexBase Base; + typedef typename Base::Vertex_handle Vertex_handle; + typedef typename Base::Cell_handle Cell_handle; + typedef typename VertexBase::Point Point; + typedef double coord_type; + + typedef Triple< Cell_handle, int, int > Edge; + typedef std::pair< Edge, int > Edge_incident_facet; + typedef std::pair< Edge_incident_facet, Edge_incident_facet > IO_edge_type; + + typedef coord_type criteria; + + typedef std::pair< criteria, IO_edge_type > Radius_edge_type; + typedef std::pair< Radius_edge_type, int > Border_elt; + typedef std::pair< Vertex_handle, Border_elt > Next_border_elt; + +private: + + //par convention je remplis d'abord first et si necessaire second... + typedef std::pair< Next_border_elt*, Next_border_elt*> Intern_successors_type; + + + +public: + + typedef std::pair< criteria, IO_edge_type* > Radius_ptr_type; + typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; + typedef std::pair< criteria, Edge_like > Incidence_request_elt; + typedef std::list< Incidence_request_elt > Incidence_request_type; + typedef typename Incidence_request_type::iterator Incidence_request_iterator; + + // typedef std::set< void* > Interior_edge_set_type; + + //-------------------- DATA MEMBERS --------------------------------- + +private: + int _id; + int _mark; + int _post_mark; + Intern_successors_type* _incident_border; + + // Instead of having a set per vertex, there is a global list. + static std::list interior_edges; + // and two iterators per vertex in this list + // Note that ie_last is not past the end + // ie_first == ie_last == interior_edge.end() iff the set is empty + typename std::list::iterator ie_first, ie_last; + + + // We do the same for the incidence requests + static std::list< Incidence_request_elt > incidence_requests; + typename std::list< Incidence_request_elt >::iterator ir_first, ir_last; + + static std::list bbb; + static boost::object_pool nbe_pool; + static boost::object_pool ist_pool; + + + + + //-------------------- CONSTRUCTORS --------------------------------- + + +public: + + Intern_successors_type* new_border() + { + Intern_successors_type* ret; + /* + std::allocator nbea; + std::allocator ista; + Next_border_elt nbe; + Next_border_elt* p1 = nbea.allocate(1); + Next_border_elt* p2 = nbea.allocate(1); + nbea.construct(p1, nbe); + nbea.construct(p1, nbe); + + ret = ista.allocate(1); + ista.construct(ret, std::make_pair(p1, p2)); + */ + + Next_border_elt* p1 = nbe_pool.malloc(); + Next_border_elt* p2 = nbe_pool.malloc(); + ret = ist_pool.malloc(); + + Intern_successors_type ist(p1,p2); + *ret = ist; + + + /* + ret = new Intern_successors_type(new Next_border_elt(), + new Next_border_elt()); + */ + ret->first->first = NULL; + ret->second->first = NULL; + return ret; + } + + + void delete_border() + { + /* + std::allocator nbea; + std::allocator ista; + nbea.destroy(_incident_border->first); + nbea.destroy(_incident_border->second); + nbea.deallocate(_incident_border->first, 1); + nbea.deallocate(_incident_border->second, 1); + ista.destroy(_incident_border); + ista.deallocate(_incident_border, 1); + */ + /* + delete _incident_border->first; + delete _incident_border->second; + */ + //nbe_pool.free(_incident_border->first); + //nbe_pool.free(_incident_border->second); + //delete _incident_border; + + _incident_border = NULL; + + + } + + + AFSR_vertex_base_with_id_3() + : VertexBase(), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new_border(); + } + + AFSR_vertex_base_with_id_3(const Point & p) + : VertexBase(p), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new_border(); + } + + AFSR_vertex_base_with_id_3(const Point & p, Cell_handle f) + : VertexBase(p, f), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new_border(); + } + + AFSR_vertex_base_with_id_3(Cell_handle f) + : VertexBase(f), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new_border(); + } + + AFSR_vertex_base_with_id_3(const AFSR_vertex_base_with_id_3& other) + : VertexBase(), _mark(-1), + _post_mark(-1), + ie_first(interior_edges.end()), ie_last(interior_edges.end()), + ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) + { + _incident_border = new_border(); + } + //-------------------- DESTRUCTOR ----------------------------------- + + ~AFSR_vertex_base_with_id_3() + { + if (_incident_border != NULL) + { + delete_border(); + } + if(ir_first != incidence_requests.end()){ + assert(ir_last != incidence_requests.end()); + typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last); + e++; + incidence_requests.erase(b, e); + } + + if(ie_first != interior_edges.end()){ + assert(ie_last != interior_edges.end()); + typename std::list::iterator b(ie_first), e(ie_last); + e++; + interior_edges.erase(b, e); + } + } + + //-------------------- MEMBER FUNCTIONS ----------------------------- + + int& id() + { + return _id; + } + + const int& id() const + { + return _id; + } + + inline void re_init() + { + if (_incident_border != NULL) + { + delete_border(); + //delete _incident_border->first; + //delete _incident_border->second; + //delete _incident_border; + } + + if(ir_first != incidence_requests.end()){ + assert(ir_last != incidence_requests.end()); + typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last); + e++; + incidence_requests.erase(b, e); + ir_first = incidence_requests.end(); + ir_last = incidence_requests.end(); + } + + _incident_border = new_border(); + _mark = -1; + _post_mark = -1; + } + + //------------------------------------------------------------------- + + inline bool is_on_border(const int& i) const + { + if (_incident_border == NULL) return false; //vh is interior + if (_incident_border->first->first != NULL) + { + if (_incident_border->second->first != NULL) + return ((_incident_border->first->second.second == i)|| + (_incident_border->second->second.second == i)); + return (_incident_border->first->second.second == i); + } + return false; //vh is still exterior + } + + inline Next_border_elt* get_next_on_border(const int& i) const + { + if (_incident_border == NULL) return NULL; //vh is interior + if (_incident_border->first->first != NULL) + if (_incident_border->first->second.second == i) + return _incident_border->first; + if (_incident_border->second->first != NULL) + if (_incident_border->second->second.second == i) + return _incident_border->second; + return NULL; + } + + + inline void remove_border_edge(Vertex_handle v) + { + if (_incident_border != NULL) + { + if (_incident_border->second->first == v) + { + _incident_border->second->first = NULL; + set_interior_edge(v); + return; + } + if (_incident_border->first->first == v) + { + if (_incident_border->second->first != NULL) + { + Next_border_elt* tmp = _incident_border->first; + _incident_border->first = _incident_border->second; + _incident_border->second = tmp; + _incident_border->second->first = NULL; + set_interior_edge(v); + return; + } + else + { + _incident_border->first->first = NULL; + set_interior_edge(v); + return; + } + } + } + } + + inline bool is_border_edge(Vertex_handle v) const + { + if (_incident_border == NULL) return false; + return ((_incident_border->first->first == v)|| + (_incident_border->second->first == v)); + } + + inline Next_border_elt* get_border_elt(Vertex_handle v) const + { + if (_incident_border == NULL) return NULL; + if (_incident_border->first->first == v) return _incident_border->first; + if (_incident_border->second->first == v) return _incident_border->second; + return NULL; + } + + inline Next_border_elt* first_incident() const + { + if (_incident_border == NULL) return NULL; + return _incident_border->first; + } + + inline Next_border_elt* second_incident() const + { + if (_incident_border == NULL) return NULL; + return _incident_border->second; + } + + + inline void set_next_border_elt(const Next_border_elt& elt) + { + if (_incident_border->first->first == NULL) + *_incident_border->first = elt; + else + { + if (_incident_border->second->first != NULL) + std::cerr << "+++probleme de MAJ du bord " << std::endl; + *_incident_border->second = elt; + } + } + + //------------------------------------------------------------------- + // pour gerer certaines aretes interieures: a savoir celle encore connectee au + // bord (en fait seule, les aretes interieures reliant 2 bords nous + // interressent...) + + inline bool is_interior_edge(Vertex_handle v) const + { + + bool r1; + if(ie_first == interior_edges.end()){ + r1 = false; + }else { + typename std::list::iterator b(ie_first), e(ie_last); + e++; + typename std::list::iterator r = std::find(b, e, v); + r1 = ( r != e); + } + + return r1; + } + + inline void set_interior_edge(Vertex_handle v) + { + if(ie_last == interior_edges.end()){ // empty set + assert(ie_first == ie_last); + ie_last = interior_edges.insert(ie_last, v); + ie_first = ie_last; + } else { + typename std::list::iterator e(ie_last); + e++; +#ifdef DEBUG + typename std::list::iterator r = std::find(ie_first, e, v); + assert(r == e); +#endif + ie_last = interior_edges.insert(e, v); + } + } + + inline void remove_interior_edge(Vertex_handle v) + { + if(ie_first == interior_edges.end()){ + assert(ie_last == ie_first); + } else if(ie_first == ie_last){ // there is only one element + if(*ie_first == v){ + interior_edges.erase(ie_first); + ie_last = interior_edges.end(); + ie_first = ie_last; + } + } else { + typename std::list::iterator b(ie_first), e(ie_last); + e++; + typename std::list::iterator r = std::find(b, e, v); + if(r != e){ + if(r == ie_first){ + ie_first++; + } + if(r == ie_last){ + ie_last--; + } + interior_edges.erase(r); + } + } + } + + //------------------------------------------------------------------- + + inline void set_incidence_request(const Incidence_request_elt& ir) + { + if(ir_last == incidence_requests.end()){ + assert(ir_first == ir_last); + ir_last = incidence_requests.insert(ir_last, ir); + ir_first = ir_last; + } else { + typename std::list::iterator e(ir_last); + e++; + ir_last = incidence_requests.insert(e, ir); + } + } + + inline bool is_incidence_requested() const + { + if(ir_last == incidence_requests.end()){ + assert(ir_first == incidence_requests.end()); + } + return (ir_last != incidence_requests.end()); + } + + inline Incidence_request_iterator incidence_request_begin() + { + return ir_first; + } + + inline Incidence_request_iterator get_incidence_request_end() + { + if(ir_last != incidence_requests.end()){ + assert(ir_first != incidence_requests.end()); + Incidence_request_iterator it(ir_last); + it++; + return it; + } + return ir_last; + } + + inline void erase_incidence_request() + { + if(ir_last != incidence_requests.end()){ + assert(ir_first != incidence_requests.end()); + ir_last++; + incidence_requests.erase(ir_first, ir_last); + ir_first = incidence_requests.end(); + ir_last = incidence_requests.end(); + } + } + + + //------------------------------------------------------------------- + + inline bool is_on_border() const + { + return (_mark > 0); + } + + inline bool not_interior() const + { + return (_mark != 0); + } + + inline int number_of_incident_border() const + { + return _mark; + } + + inline bool is_exterior() const + { + return (_mark < 0); + } + + //------------------------------------------------------------------- + + inline void inc_mark() + { + if (_mark==-1) + _mark=1; + else + _mark++; + } + + inline void dec_mark() + { + _mark--; + if(_mark == 0) + { + delete_border(); + erase_incidence_request(); + } + } + + //------------------------------------------------------------------- + + inline void set_post_mark(const int& i) + { + _post_mark = i; + } + + inline bool is_post_marked(const int& i) + { + return (_post_mark == i); + } +}; + + +template +boost::object_pool::Next_border_elt> AFSR_vertex_base_with_id_3::nbe_pool; + +template +boost::object_pool::Intern_successors_type> AFSR_vertex_base_with_id_3::ist_pool; + + + +template +std::list::Vertex_handle> AFSR_vertex_base_with_id_3::interior_edges; + +template +std::list::Incidence_request_elt> AFSR_vertex_base_with_id_3::incidence_requests; + +} // namespace CGAL + +#endif // CGALAFSR_VERTEX_BASE_3_H + diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h new file mode 100755 index 00000000000..b07feecc4ea --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -0,0 +1,1956 @@ +#ifndef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H +#define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H + +// In order to activate lazy evaluation: +// #define LAZY + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + +class AFSR_options; + +// This iterator allows to visit all contours. It has the particularity +// that it visits the entry point of the contour twice. This allows to +// detect that the traversal of the border is finished. One more increment +// brings us to the next vertex. + + + +template < class Surface> +class Advancing_front_surface_reconstruction_boundary_iterator { +private: + Advancing_front_surface_reconstruction_boundary_iterator(){} +public: + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef Advancing_front_surface_reconstruction_boundary_iterator Self; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Vertex Vertex; + + const Surface& S; + int mark; + Finite_vertices_iterator first_vertex; + Vertex_handle pos; + bool first, last; + + Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_, int m) + : S(S_), mark(m), first_vertex(S.triangulation().finite_vertices_begin()), pos(first_vertex) + { + if (pos->number_of_incident_border() <= 0){ + advance_to_next_boundary(); + } + first = true; + last = false; + } + + Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_) + : S(S_), pos(NULL) + {} + + Advancing_front_surface_reconstruction_boundary_iterator(const Self& s) + : S(s.S), mark(s.mark), first_vertex(s.first_vertex), pos(s.pos), first(s.first), last(s.last) + {} + + bool operator==(const Self &s) const + { + return pos == s.pos; + } + + bool operator!=(const Self &s) const + { + return pos != s.pos; + } + + + Self operator++() + { + if(pos == NULL) { + return *this; + } + if(first){ + advance_on_boundary(); + first = false; + } else if (last) { + advance_to_next_boundary(); + first = true; + last = false; + } else { + advance_on_boundary(); + if(&*pos == &*first_vertex){ + last = true; + } + } + return *this; + } + + Vertex_handle operator*() + { + return pos; + } + + void advance_on_boundary() + { + if(pos == NULL) { + return; + } + pos = pos->first_incident()->first; + pos->set_post_mark(mark); + } + + void advance_to_next_boundary() + { + if(pos == NULL) { + return; + } + do { + first_vertex++; + } while((first_vertex != S.triangulation().finite_vertices_end()) && + (! ((first_vertex->is_on_border()) + && ! first_vertex->is_post_marked(mark)))); + if(first_vertex != S.triangulation().finite_vertices_end()) { + pos = first_vertex; + pos->set_post_mark(mark); + + } else { + pos = NULL; + } + } +}; + + +template +class Advancing_front_surface_reconstruction { + +public: + typedef Triangulation Triangulation_3; + typedef Advancing_front_surface_reconstruction Extract; + typedef typename Triangulation_3::Geom_traits Geom_traits; + + typedef typename Kernel::FT coord_type; + + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Kernel::Segment_3 Segment; + typedef typename Kernel::Triangle_3 Triangle; + typedef typename Kernel::Sphere_3 Sphere; + + typedef typename Triangulation_3::Cell Cell; + typedef typename Triangulation_3::Vertex Vertex; + typedef typename Triangulation_3::Edge Edge; + typedef typename Triangulation_3::Facet Facet; + typedef typename Triangulation_3::Cell_handle Cell_handle; + typedef typename Triangulation_3::Vertex_handle Vertex_handle; + + typedef typename Triangulation_3::Cell_circulator Cell_circulator; + typedef typename Triangulation_3::Facet_circulator Facet_circulator; + + typedef typename Triangulation_3::Locate_type Locate_type; + + typedef typename Triangulation_3::Finite_cells_iterator Finite_cells_iterator; + typedef typename Triangulation_3::Finite_facets_iterator Finite_facets_iterator; + typedef typename Triangulation_3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Triangulation_3::Finite_edges_iterator Finite_edges_iterator; + + typedef typename Triangulation_3::All_cells_iterator All_cells_iterator; + typedef typename Triangulation_3::All_facets_iterator All_facets_iterator; + typedef typename Triangulation_3::All_vertices_iterator All_vertices_iterator; + typedef typename Triangulation_3::All_edges_iterator All_edges_iterator; + + typedef typename Triangulation_3::Vertex::Edge_incident_facet Edge_incident_facet; + typedef typename Triangulation_3::Vertex::IO_edge_type IO_edge_type; + typedef typename Triangulation_3::Vertex::criteria criteria; + typedef typename Triangulation_3::Vertex::Radius_edge_type Radius_edge_type; + typedef typename Triangulation_3::Vertex::Border_elt Border_elt; + typedef typename Triangulation_3::Vertex::Next_border_elt Next_border_elt; + typedef typename Triangulation_3::Vertex::Radius_ptr_type Radius_ptr_type; + + typedef typename Triangulation_3::Vertex::Incidence_request_iterator Incidence_request_iterator; + typedef typename Triangulation_3::Vertex::Incidence_request_elt Incidence_request_elt; + + typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; + typedef CGAL::Triple< Vertex_handle, Vertex_handle, Vertex_handle > Facet_like; + + + typedef std::multimap< criteria, IO_edge_type*, + std::less > Ordered_border_type; + typedef typename Ordered_border_type::iterator Ordered_border_iterator; + + enum Validation_case {NOT_VALID, NOT_VALID_CONNECTING_CASE, FINAL_CASE, + EAR_CASE, EXTERIOR_CASE, CONNECTING_CASE}; + + //===================================================================== + //===================================================================== +private: + + Triangulation_3& T; + + Ordered_border_type _ordered_border; + int _number_of_border; + + const coord_type SLIVER_ANGULUS; // = sampling quality of the surface + coord_type DELTA; // = sampling quality of the border + coord_type K, min_K; + const coord_type eps; + const coord_type inv_eps_2; // 1/(eps^2) + const coord_type eps_3; // test de ^3 donc points tel 1e-7 soit petit + const criteria STANDBY_CANDIDATE; + const criteria STANDBY_CANDIDATE_BIS; + const criteria NOT_VALID_CANDIDATE; + + const double area; + const double perimeter; + const double abs_area; + const double abs_perimeter; + double total_area; + double total_perimeter; + //--------------------------------------------------------------------- + + CGAL::Timer t1; + + //--------------------------------------------------------------------- + //Pour une visu correcte + //pour retenir les facettes selectionnees + int _vh_number; + int _facet_number; + + //--------------------------------------------------------------------- + //Pour le post traitement + mutable int _postprocessing_counter; + int _size_before_postprocessing; + + std::list outliers; + + int _number_of_connected_components; + +public: + Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt) + : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), + eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), + STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), + NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), _vh_number(T.number_of_vertices()), _facet_number(0), + _postprocessing_counter(0), _size_before_postprocessing(0), area(opt.area), perimeter(opt.perimeter), + abs_area(opt.abs_area), abs_perimeter(opt.abs_perimeter), + total_area(0), total_perimeter(0), _number_of_connected_components(0) + { + bool re_init = false; + do + { + _number_of_connected_components++; + + if (re_init = init(re_init)) + { + std::cerr << "Growing connected component " << _number_of_connected_components << std::endl; + extend(opt.K_init, opt.K_step, opt.K); + + if ((number_of_facets() > T.number_of_vertices())&& + (opt.NB_BORDER_MAX > 0)) + // en principe 2*nb_sommets = nb_facettes: y a encore de la marge!!! + { + while(postprocessing(opt.NB_BORDER_MAX)){ + extend(opt.K_init, opt.K_step, opt.K); + } + } + } + }while(re_init && + ((_number_of_connected_components < opt.max_connected_comp)|| + (opt.max_connected_comp < 0))); + + _tds_2_inf = AFSR::construct_surface(_tds_2, *this); + } + + ~Advancing_front_surface_reconstruction() + {} + + + typedef Triangulation_data_structure_2, + AFSR::Surface_face_base_2 > TDS_2; + + + mutable TDS_2 _tds_2; + + mutable typename TDS_2::Vertex_handle _tds_2_inf; + + const TDS_2& tds_2() const + { + return _tds_2; + } + + bool is_on_surface(const typename TDS_2::Vertex_handle vh) const + { + return vh != _tds_2_inf; + } + + + + int number_of_connected_components() const + { + return _number_of_connected_components; + } + + + Triangulation_3& + triangulation() const + { + return T; + } + + + + + + int number_of_facets() const + { + return _facet_number; + } + + int number_of_vertices() const + { + return _vh_number; + } + + int number_of_outliers() const + { + return outliers.size(); + } + + typedef typename std::list::const_iterator Outlier_iterator; + + Outlier_iterator outliers_begin() const + { + return outliers.begin(); + } + + Outlier_iterator outliers_end() const + { + return outliers.end(); + } + + typedef Advancing_front_surface_reconstruction_boundary_iterator Boundary_iterator; + + Boundary_iterator boundaries_begin() const + { + return Boundary_iterator(*this, get_next_mark()); + } + + Boundary_iterator boundaries_end() const + { + return Boundary_iterator(*this); + } + + + int get_next_mark() const + { + _postprocessing_counter++; + return _postprocessing_counter; + } + + + + Next_border_elt* get_border_elt(const Vertex_handle& v1, const Vertex_handle& v2) + { + return v1->get_border_elt(v2); + } + + //public + + IO_edge_type* get_border_IO_elt(const Vertex_handle& v1, const Vertex_handle& v2) + { + return &get_border_elt(v1,v2)->second.first.second; + } + + IO_edge_type* set_border_elt(const Vertex_handle& v1, const Vertex_handle& v2, + const Border_elt& e) + { + v1->set_next_border_elt(Next_border_elt (v2, e)); + return get_border_IO_elt(v1, v2); + } + + + IO_edge_type* set_again_border_elt(const Vertex_handle& v1, const Vertex_handle& v2, + const Border_elt& e) + { + get_border_elt(v1,v2)->second = e; + return get_border_IO_elt(v1, v2); + } + + //--------------------------------------------------------------------- + + bool is_border_elt(Edge_like& key, Border_elt& result) const + { + Next_border_elt* it12 = key.first->get_border_elt(key.second); + if (it12 != NULL) + { + result = it12->second; + return true; + } + + Next_border_elt* it21 = key.second->get_border_elt(key.first); + if (it21 != NULL) + { + result = it21->second; + std::swap(key.first, key.second); + return true; + } + return false; + } + + //--------------------------------------------------------------------- + bool is_border_elt(Edge_like& key) const { + Next_border_elt* it12 = key.first->get_border_elt(key.second); + if (it12 != NULL) + { + return true; + } + + Next_border_elt* it21 = key.second->get_border_elt(key.first); + if (it21 != NULL) + { + std::swap(key.first, key.second); + return true; + } + return false; + } + //--------------------------------------------------------------------- + + bool is_ordered_border_elt(const Edge_like& key, Border_elt& result) const + { + Next_border_elt* it12 = key.first->get_border_elt(key.second); + if (it12 != NULL) + { + result = it12->second; + return true; + } + return false; + } + + //--------------------------------------------------------------------- + + void + remove_border_elt(const Edge_like& ordered_key) + { + ordered_key.first->remove_border_edge(ordered_key.second); + } + + //--------------------------------------------------------------------- + + bool is_ordered_border_elt(const Edge_like& e, + IO_edge_type* &ptr) const + { + Vertex_handle v1 = e.first; + + Next_border_elt* it12 = v1->get_border_elt(e.second); + if (it12 != NULL) + { + ptr = &it12->second.first.second; + return true; + } + return false; + } + + //--------------------------------------------------------------------- + void set_incidence_request(const Vertex_handle& v, + const criteria& value, + const Edge_like& e) + { + Incidence_request_elt incident_elt(value, e); + v->set_incidence_request(incident_elt); + } + + //--------------------------------------------------------------------- + + bool is_interior_edge(const Edge_like& key) const + // pour gerer certaines aretes interieures: a savoir celle encore connectee au + // bord (en fait seule, les aretes interieures reliant 2 bords nous + // interressent...) + { + return (key.first->is_interior_edge(key.second)|| + key.second->is_interior_edge(key.first)); + } + + //--------------------------------------------------------------------- + +#ifdef AFSR_LAZY + + coord_type get_lazy_squared_radius(const Cell_handle& c) + { + if (c->get_lazy_squared_radius() != NULL) + return *(c->get_lazy_squared_radius()); + + c->set_lazy_squared_radius + (squared_radius(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point())); + return *(c->get_lazy_squared_radius()); + } + + Point get_lazy_circumcenter(const Cell_handle& c) + { + if (c->get_lazy_circumcenter() != NULL) + return *(c->get_lazy_circumcenter()); + + c->set_lazy_circumcenter + (circumcenter(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point())); + return *(c->get_lazy_circumcenter()); + } + +#endif //NOLAZY + + //--------------------------------------------------------------------- + + Edge_incident_facet next(const Edge_incident_facet& e) const + { + Cell_handle c = e.first.first; + int i = e.second; + int i1 = e.first.second, i2 = e.first.third; + int i3 = (6 - e.second - i1 - i2); + + Cell_handle n = c->neighbor(i); + int j1 = n->index(c->vertex(i1)), j2 = n->index(c->vertex(i2)); + int j = n->index(c->vertex(i3)); + return Edge_incident_facet(Edge(n, j1, j2), j); + } + + //--------------------------------------------------------------------- + + Edge_incident_facet previous(const Edge_incident_facet& e) const + { + Cell_handle c = e.first.first; + int i = e.second; + int i1 = e.first.second, i2 = e.first.third; + int i3 = (6 - e.second - i1 - i2); + + Cell_handle n = c->neighbor(i3); + int j1 = n->index(c->vertex(i1)), j2 = n->index(c->vertex(i2)); + int j = n->index(c->vertex(i)); + return Edge_incident_facet(Edge(n, j1, j2), j); + } + + //--------------------------------------------------------------------- + + bool + my_coplanar(const Point& p, const Point& q, + const Point& r, const Point& s) const + { + coord_type qpx = q.x()-p.x(); + coord_type qpy = q.y()-p.y(); + coord_type qpz = q.z()-p.z(); + coord_type rpx = r.x()-p.x(); + coord_type rpy = r.y()-p.y(); + coord_type rpz = r.z()-p.z(); + coord_type spx = s.x()-p.x(); + coord_type spy = s.y()-p.y(); + coord_type spz = s.z()-p.z(); + + coord_type den = CGAL::determinant(qpx,qpy,qpz, + rpx,rpy,rpz, + spx,spy,spz); + return (CGAL_NTS abs(den) < eps_3); + } + + //--------------------------------------------------------------------- + + + bool + my_collinear(const Point& p, const Point& q, const Point& s) const + { + coord_type psx = p.x()-s.x(); + coord_type psy = p.y()-s.y(); + coord_type psz = p.z()-s.z(); + coord_type qsx = q.x()-s.x(); + coord_type qsy = q.y()-s.y(); + coord_type qsz = q.z()-s.z(); + coord_type rsx = psy*qsz-psz*qsy; + coord_type rsy = psz*qsx-psx*qsz; + coord_type rsz = psx*qsy-psy*qsx; + + coord_type den = CGAL::determinant(psx,psy,psz, + qsx,qsy,qsz, + rsx,rsy,rsz); + + return (CGAL_NTS abs(den) < eps_3); + } + + //--------------------------------------------------------------------- + + void + select_facet(const Cell_handle& c, const int& i) + { + if(area!=0){ + total_area += compute_area(c->vertex((i+1)&3)->point(), + c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point()); + } + if(perimeter != 0){ + total_perimeter += compute_perimeter(c->vertex((i+1)&3)->point(), + c->vertex((i+2)&3)->point(), + c->vertex((i+3)&3)->point()); + } + c->select_facet(i); + _facet_number++; + c->set_facet_number(i, _facet_number); + } + + + void + unselect_facet(const Cell_handle& c, const int& i) + { + c->unselect_facet(i); + } + + int number_of_border_edges() + { + int _border_count(0); + for(Finite_edges_iterator e_it=T.finite_edges_begin(); + e_it!=T.finite_edges_end(); + e_it++) + { + Cell_handle c = (*e_it).first; + int i1 = (*e_it).second, i2 = (*e_it).third; + Edge_like key(c->vertex(i1), c->vertex(i2)); + + if (is_border_elt(key)) + _border_count++; + } + return _border_count; + } + + + + + //===================================================================== + + coord_type get_smallest_radius_delaunay_sphere(const Cell_handle& c, + const int& index) const + { + int i1, i2, i3; + + Cell_handle n = c->neighbor(index); + // lazy evaluation ... + coord_type value = c->get_smallest_radius(index); + if ((value >= 0)&&(n->get_smallest_radius(n->index(c)) == value)) + return value; + + const Point& cp0 = c->vertex(index)->point(); + const Point& cp1 = c->vertex((index+1) & 3)->point(); + const Point& cp2 = c->vertex((index+2) & 3)->point(); + const Point& cp3 = c->vertex((index+3) & 3)->point(); + + const Point& np0 = n->vertex(0)->point(); + const Point& np1 = n->vertex(1)->point(); + const Point& np2 = n->vertex(2)->point(); + const Point& np3 = n->vertex(3)->point(); + + bool c_is_plane(my_coplanar(cp0, cp1, cp2, cp3)); + bool n_is_plane(my_coplanar(np0, np1, np2, np3)); + + bool c_is_infinite(T.is_infinite(c)); + bool n_is_infinite(T.is_infinite(n)); + if ((c_is_plane && n_is_plane)|| + (c_is_plane && n_is_infinite)|| + (n_is_plane && c_is_infinite)|| + my_collinear(cp1, cp2, cp3)) + value = HUGE_VAL; + else + { + if (c_is_infinite||n_is_infinite||c_is_plane||n_is_plane) + { + int ind; + Cell_handle cc; + if(c_is_infinite||c_is_plane) + { + cc = n; + ind = n->index(c); + } + else + { + cc = c; + ind = index; + } + i1 = (ind+1) & 3; + i2 = (ind+2) & 3; + i3 = (ind+3) & 3; + + const Point& pp0 = cc->vertex(ind)->point(); + const Point& pp1 = cc->vertex(i1)->point(); + const Point& pp2 = cc->vertex(i2)->point(); + const Point& pp3 = cc->vertex(i3)->point(); + + Sphere facet_sphere(pp1, pp2, pp3); + if (squared_distance(facet_sphere.center(), pp0) < + facet_sphere.squared_radius()) + { +#ifdef AFSR_LAZY + value = get_lazy_squared_radius(cc); +#else + value = squared_radius(pp0, pp1, pp2, pp3); +#endif + } + else + value = facet_sphere.squared_radius(); + } + else + { + Point cc, cn; +#ifdef AFSR_LAZY + cc = get_lazy_circumcenter(c); + cn = get_lazy_circumcenter(n); +#else + cc = circumcenter(cp0, cp1, cp2, cp3); + cn = circumcenter(np0, np1, np2, np3); +#endif + // computation of the distance of cp1 to the dual segment cc, cn... + Vector V(cc - cn), Vc(cc - cp1), Vn(cp1 - cn); + coord_type ac(V * Vc), an(V * Vn), norm_V(V * V); + if ((ac > 0) && (an > 0)) + { + value = (Vc*Vc) - ac*ac/norm_V; + if ((value < 0)||(norm_V > inv_eps_2)) + value = squared_radius(cp1, cp2, cp3); + } + else + { + if (ac <= 0) + value = squared_distance(cc, cp1); + else // (an <= 0) + value = squared_distance(cn, cp1); + } + } + } + // cache computed values + c->set_smallest_radius(index, value); + n->set_smallest_radius(n->index(c), value); + + return value; + } +//--------------------------------------------------------------------- + coord_type + compute_area(const Point& p1, const Point& p2, const Point& p3) const + { + return typename Kernel::Compute_area_3()(p1,p2,p3); + } +//--------------------------------------------------------------------- + coord_type + compute_perimeter(const Point& p1, const Point& p2, const Point& p3) const + { + return sqrt(squared_distance(p1,p2)) + + sqrt(squared_distance(p2,p3)) + + sqrt(squared_distance(p3,p1)); + } + + //--------------------------------------------------------------------- + // For a border edge e we determine the incident facet which has the highest + // chance to be a natural extension of the surface + + Radius_edge_type compute_value(const Edge_incident_facet& e) + { + Cell_handle c = e.first.first; + int i = e.second; + int i1 = e.first.second, i2 = e.first.third; + int i3 = 6 - e.second - i1 - i2; + + Edge_incident_facet e_it = e, predone = previous(e); + Cell_handle c_predone = predone.first.first; + + coord_type min_valueP = NOT_VALID_CANDIDATE, min_valueA = HUGE_VAL; + Facet min_facet, min_facetA; + bool border_facet(false); + + coord_type pscal; + const Point& p1 = c->vertex(i1)->point(); + const Point& p2 = c->vertex(i2)->point(); + const Point& pc = c->vertex(i3)->point(); + + Vector P2P1 = p1-p2, P2Pn, PnP1; + + Vector v2, v1 = cross_product(pc-p2, P2P1); + + coord_type norm, norm1 = v1*v1; + coord_type norm12 = P2P1*P2P1; + + e_it = next(e_it); + bool succ_start(true); + + do + { + Cell_handle neigh = e_it.first.first; + Facet facet_it(neigh, e_it.second); + + if (!T.is_infinite(facet_it)) + { + int n_ind = facet_it.second; + int n_i1 = e_it.first.second; + int n_i2 = e_it.first.third; + int n_i3 = 6 - n_ind - n_i1 - n_i2; + + coord_type tmp=0; + coord_type ar=0, pe=0; + + // If the triangle has a very large area and a very high perimeter, + // we do not want to consider it as a good candidate. + + if( (abs_area != 0) || ( (_facet_number > 1000) && (area != 0)) ){ + ar = compute_area(facet_it.first->vertex(n_i1)->point(), + facet_it.first->vertex(n_i2)->point(), + facet_it.first->vertex(n_i3)->point()); + } + + if( (abs_perimeter != 0) || ( (_facet_number > 1000) && (perimeter != 0)) ){ + pe = compute_perimeter(facet_it.first->vertex(n_i1)->point(), + facet_it.first->vertex(n_i2)->point(), + facet_it.first->vertex(n_i3)->point()); + } + + if( ((abs_area != 0)&&(ar > abs_area)) || ((abs_perimeter != 0) && (pe > abs_perimeter)) ){ + tmp = HUGE_VAL; + } + + if((tmp != HUGE_VAL) && (_facet_number > 1000)){ + if(area != 0){ + coord_type avg_area = total_area/_facet_number; + if(ar > (area * avg_area)){ + tmp = HUGE_VAL; + } + } + if((perimeter != 0) && (tmp != HUGE_VAL)){ + coord_type avg_perimeter = total_perimeter/_facet_number; + if(pe > (perimeter * avg_perimeter)){ + tmp = HUGE_VAL; + } + } + } + + + if(tmp != HUGE_VAL){ + tmp = get_smallest_radius_delaunay_sphere(neigh, n_ind); + } + + Edge_like el1(neigh->vertex(n_i1),neigh->vertex(n_i3)), + el2(neigh->vertex(n_i2),neigh->vertex(n_i3)); + + if ((tmp != HUGE_VAL)&& + neigh->vertex(n_i3)->not_interior()&& + (!is_interior_edge(el1))&&(!is_interior_edge(el2))) + { + const Point& pn = neigh->vertex(n_i3)->point(); + + P2Pn = pn-p2; + v2 = cross_product(P2P1,P2Pn); + + //pas necessaire de normer pour un bon echantillon: + // on peut alors tester v1*v2 >= 0 + norm = sqrt(norm1 * (v2*v2)); + pscal = v1*v2; + //SLIVER_ANGULUS represente la qualite d'echantillonnage de la + //surface + bool sliver_facet = ((succ_start || (neigh == c_predone))&& + (pscal <= -SLIVER_ANGULUS*norm)); + + if (succ_start) succ_start = false; + + if (!sliver_facet) + { + if (tmp < min_valueA) + { + PnP1 = p1-pn; + // DELTA represente la qualite d'echantillonnage du bord + border_facet = !((P2P1*P2Pn >= + -DELTA*sqrt(norm12*(P2Pn*P2Pn)))&& + (P2P1*PnP1 >= + -DELTA*sqrt(norm12*(PnP1*PnP1)))); + + min_facetA = facet_it; + min_valueA = tmp; + min_valueP = pscal/norm; + } + } + } + } + e_it = next(e_it); + } + while(e_it.first.first != c); + + criteria value; + + if ((min_valueA == HUGE_VAL) || border_facet) // bad facets case + { + min_facet = Facet(c, i); // !!! sans aucune signification.... + value = NOT_VALID_CANDIDATE; // Attention a ne pas inserer dans PQ + } + else + { + min_facet = min_facetA; + + //si on considere seulement la pliure value appartient a [0, 2] + //value = coord_type(1) - min_valueP; + + // si la pliure est bonne on note suivant le alpha sinon on prend en compte la + // pliure seule... pour discriminer entre les bons slivers... + // si on veut discriminer les facettes de bonnes pliures plus finement + // alors -(1+1/min_valueA) app a [-inf, -1] + // -min_valueP app a [-1, 1] + + if (min_valueP > SLIVER_ANGULUS) + value = -(coord_type(1) + coord_type(1)/min_valueA); + else + { + //on refuse une trop grande non-uniformite + coord_type tmp = get_smallest_radius_delaunay_sphere(c, i); + if (min_valueA <= K * tmp) + value = - min_valueP; + else + { + value = STANDBY_CANDIDATE; // tres mauvais candidat mauvaise pliure + // + grand alpha... a traiter plus tard.... + min_K = + (std::min)(min_K, + min_valueA/tmp); + } + } + } + + Cell_handle n = min_facet.first; + int ni1 = n->index(c->vertex(i1)), ni2 = n->index(c->vertex(i2)); + + return + Radius_edge_type(value, IO_edge_type(e, Edge_incident_facet + (Edge(n, ni1, ni2), + min_facet.second))); + } + + //===================================================================== + //===================================================================== + + // The parameter re_init is true the first time only + // Returns true, iff it found a face where the next surface can grow + bool + init(const bool& re_init) + { + Facet min_facet; + coord_type min_value = HUGE_VAL; + int i1, i2, i3; + + if (!re_init) + for(Finite_facets_iterator facet_it = T.finite_facets_begin(); + facet_it != T.finite_facets_end(); + facet_it++) + { + coord_type value = get_smallest_radius_delaunay_sphere((*facet_it).first, + (*facet_it).second); + if (value < min_value) + { + min_facet = *facet_it; + min_value = value; + } + } + else //if (re_init) + for(Finite_facets_iterator facet_it = T.finite_facets_begin(); + facet_it != T.finite_facets_end(); + facet_it++) + { + Cell_handle c = (*facet_it).first; + int index = (*facet_it).second; + if (c->vertex((index+1) & 3)->is_exterior()) + if (c->vertex((index+2) & 3)->is_exterior()) + if (c->vertex((index+3) & 3)->is_exterior()) + { + coord_type value = get_smallest_radius_delaunay_sphere(c, index); + coord_type pe=0; + if(abs_perimeter != 0){ + pe = compute_perimeter(c->vertex((index+1)&3)->point(), + c->vertex((index+2)&3)->point(), + c->vertex((index+3)&3)->point()); + if(pe > abs_perimeter){ + value = min_value; + } + } + + if (value < min_value) + { + min_facet = *facet_it; + min_value = value; + } + } + } + + if (min_value != HUGE_VAL) + { + Cell_handle c_min = min_facet.first; + + int ind = min_facet.second; + i1 = (ind+1) & 3; + i2 = (ind+2) & 3; + i3 = (ind+3) & 3; + + Radius_edge_type e12, e23, e31; + + e12 = compute_value(Edge_incident_facet(Edge(c_min, i1, i2), ind)); + e23 = compute_value(Edge_incident_facet(Edge(c_min, i2, i3), ind)); + e31 = compute_value(Edge_incident_facet(Edge(c_min, i3, i1), ind)); + + IO_edge_type* p12 = set_border_elt(c_min->vertex(i1), c_min->vertex(i2), + Border_elt(e12, _number_of_border)); + IO_edge_type* p23 = set_border_elt(c_min->vertex(i2), c_min->vertex(i3), + Border_elt(e23, _number_of_border)); + IO_edge_type* p31 = set_border_elt(c_min->vertex(i3), c_min->vertex(i1), + Border_elt(e31, _number_of_border)); + + c_min->vertex(i1)->inc_mark(); + c_min->vertex(i2)->inc_mark(); + c_min->vertex(i3)->inc_mark(); + _ordered_border.insert(Radius_ptr_type (e12.first, p12)); + _ordered_border.insert(Radius_ptr_type (e23.first, p23)); + _ordered_border.insert(Radius_ptr_type (e31.first, p31)); + + select_facet(c_min, ind); + return true; + } + return false; + } + + //--------------------------------------------------------------------- + // test de reciprocite avant de recoller une oreille anti-singularite + int + test_merge(const Edge_like& ordered_key, const Border_elt& result, + const Vertex_handle& v, const coord_type& ear_alpha) + { + Edge_incident_facet Ifacet = result.first.second.first; + + const Point& p1 = (ordered_key.first)->point(); + const Point& p2 = (ordered_key.second)->point(); + const Point& pc = v->point(); + + Cell_handle neigh = Ifacet.first.first; + int n_ind = Ifacet.second; + int n_i1 = Ifacet.first.second; + int n_i2 = Ifacet.first.third; + int n_i3 = (6 - n_ind - n_i1 - n_i2); + + const Point& pn = neigh->vertex(n_i3)->point(); + Vector v1 = cross_product(pc-p2,p1-p2), + v2 = cross_product(p1-p2,pn-p2); + coord_type norm = sqrt((v1*v1)*(v2*v2)); + + if (v1*v2 > SLIVER_ANGULUS*norm) + return 1; // label bonne pliure sinon: + + if (ear_alpha <= K*get_smallest_radius_delaunay_sphere(neigh, n_ind)) + return 2; // label alpha coherent... + + return 0; //sinon oreille a rejeter... + } + + + //--------------------------------------------------------------------- + + void + ordered_map_erase(const criteria& value, const IO_edge_type* pkey) + { + int number_of_conflict = _ordered_border.count(value); + if (number_of_conflict == 1) + { + _ordered_border.erase(_ordered_border.find(value)); + + } + + else if (number_of_conflict > 1) + { + Ordered_border_iterator elt_it = + _ordered_border.find(value); + // si ca foire jamais on peut s'areter des que l'elt + // est trouve!!! + for(int jj=0; (jjsecond) == ((long) pkey)) + { + _ordered_border.erase(elt_it); + return; + } + elt_it++; + } + } + } + + //--------------------------------------------------------------------- + + void + force_merge(const Edge_like& ordered_key, const Border_elt& result) + { + criteria value = result.first.first; + IO_edge_type* pkey = get_border_IO_elt(ordered_key.first, ordered_key.second); + + ordered_map_erase(value, pkey); + + remove_border_elt(ordered_key); + } + + //--------------------------------------------------------------------- + + void dequeue_incidence_request(const Vertex_handle& v) + { + if (v->is_incidence_requested()) + { + for(Incidence_request_iterator v_it = v->incidence_request_begin(); + v_it != v->get_incidence_request_end(); + v_it++) + { + IO_edge_type* ptr; + + if (is_ordered_border_elt(v_it->second, ptr)) + _ordered_border.insert(Radius_ptr_type(v_it->first, ptr)); + } + v->erase_incidence_request(); + } + } + + + //--------------------------------------------------------------------- + + void + merge_ear(const Edge_like& ordered_el1, const Border_elt& result1, + const Edge_like& ordered_key, + const Vertex_handle& v1, const Vertex_handle& v2, + const Edge_incident_facet& edge_Ifacet_2) + { + remove_border_elt(ordered_key); + force_merge(ordered_el1, result1); + + Radius_edge_type e2 = compute_value(edge_Ifacet_2); + + IO_edge_type* p2; + if (ordered_el1.first == v1) + p2 = set_border_elt(v2, ordered_el1.second, + Border_elt(e2,result1.second)); + else + p2 = set_border_elt(ordered_el1.first, v2, + Border_elt(e2,result1.second)); + + v1->dec_mark(); + + _ordered_border.insert(Radius_ptr_type(e2.first, p2)); + + //depiler les eventuelles requettes de connections avortees... zones etoilees, + //en effet le bord a change donc on peut peut etre maintenant. + dequeue_incidence_request(v2); + + if (ordered_el1.first == v1) + dequeue_incidence_request(ordered_el1.second); + else + dequeue_incidence_request(ordered_el1.first); + } + + //--------------------------------------------------------------------- + + void + border_extend(const Edge_like& ordered_key, const Border_elt& result12, + const Vertex_handle& v1, const Vertex_handle& v2, + const Vertex_handle& v3, + const Radius_edge_type& e1, const Radius_edge_type& e2, + IO_edge_type* &p1, IO_edge_type* &p2) + { + remove_border_elt(ordered_key); + + //depiler v3 avant de le mettre a jour... pour reperer s'il est sur un bord + if (v3->is_on_border()) + dequeue_incidence_request(v3); + + if (ordered_key.first == v1) + { + p1 = set_border_elt(v1, v3, Border_elt(e1,result12.second)); + p2 = set_border_elt(v3, v2, Border_elt(e2,result12.second)); + } + else + { + p2 = set_border_elt(v2, v3, Border_elt(e2,result12.second)); + p1 = set_border_elt(v3, v1, Border_elt(e1,result12.second)); + } + + v3->inc_mark(); + + //depiler les eventuelles requettes de connections avortees... zones etoilees, + //en effet le bord a change donc on peut peut etre maintenant. + dequeue_incidence_request(v1); + dequeue_incidence_request(v2); + } + + //===================================================================== + + Validation_case + validate(const Edge_incident_facet& edge_Efacet, + const criteria& value) + { + int i = (6 - edge_Efacet.second + - edge_Efacet.first.second + - edge_Efacet.first.third); + Cell_handle c = edge_Efacet.first.first; + + Vertex_handle v1 = c->vertex(edge_Efacet.first.second), + v2 = c->vertex(edge_Efacet.first.third); + + Edge_like ordered_el1(c->vertex(i), v1); + Edge_like ordered_el2(c->vertex(i), v2); + Border_elt result1, result2, result12; + + Edge_like ordered_key(v1,v2); + + if (!is_border_elt(ordered_key, result12)) + std::cerr << "+++probleme coherence bord " << std::endl; + + bool is_border_el1 = is_border_elt(ordered_el1, result1), + is_border_el2 = is_border_elt(ordered_el2, result2); + + Radius_edge_type e1, e2; + + if (c->vertex(i)->not_interior()) + { + if ((!is_interior_edge(ordered_el1))&& + (!is_interior_edge(ordered_el2))) + { + //toujours utile meme avec l'essai de try_to_close_border avant + //validate pour la resolution de singularite par oreille qui elle + //doit etre dans Delaunay. + if (is_border_el1&&is_border_el2) + { + remove_border_elt(ordered_key); + force_merge(ordered_el1, result1); + force_merge(ordered_el2, result2); + + v1->dec_mark(); + v2->dec_mark(); + c->vertex(i)->dec_mark(); + + select_facet(c, edge_Efacet.second); + + return FINAL_CASE; + } + + //--------------------------------------------------------------------- + //on peut alors marquer v1 et on pourrait essayer de merger + //sans faire de calcul inutile??? + if (is_border_el1) + { + Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), + edge_Efacet.second); + merge_ear(ordered_el1, result1, + ordered_key, v1, v2, edge_Ifacet_2); + + select_facet(c, edge_Efacet.second); + + return EAR_CASE; + } + + //--------------------------------------------------------------------- + //idem pour v2 + if (is_border_el2) + { + Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), + edge_Efacet.second); + merge_ear(ordered_el2, result2, + ordered_key, v2, v1, edge_Ifacet_1); + + select_facet(c, edge_Efacet.second); + + return EAR_CASE; + } + + + //--------------------------------------------------------------------- + if ((!is_border_el1)&&(!is_border_el2)) + { + // si on veut s'interdir de spliter un bord (pelure d'orange....) + // seulement c->vertex(i)->is_exterior() + // pour s'autoriser des split de bord surface a bord->sphere ou Moebius... + // alors || is_on_same_border: + // if (c->vertex(i)->is_exterior() || is_on_same_border) + // pour passer au tore (changementde type de topologie) + // recoller deux bord different... + // if (c->vertex(i)->not_interior() deja teste en haut + + if(c->vertex(i)->is_exterior()) + { + Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), + edge_Efacet.second); + + Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), + edge_Efacet.second); + e1 = compute_value(edge_Ifacet_1); + e2 = compute_value(edge_Ifacet_2); + + IO_edge_type* p1; + IO_edge_type* p2; + + border_extend(ordered_key, result12, + v1, v2, c->vertex(i), + e1, e2, p1, p2); + + // if e1 contain HUGE_VAL there is no candidates to + // continue: compute_value is not valid... + + _ordered_border.insert(Radius_ptr_type(e1.first, p1)); + + _ordered_border.insert(Radius_ptr_type(e2.first, p2)); + + select_facet(c, edge_Efacet.second); + + return EXTERIOR_CASE; + } + else // c->vertex(i) is a border point (and now there's only 1 + // border incident to a point... _mark<1 even if th orientation + // may be such as one vh has 2 successorson the same border... + { + // a ce niveau on peut tester si le recollement se fait en + // maintenant la compatibilite d'orientation des bords (pour + // surface orientable...) ou si elle est brisee... + Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), + edge_Efacet.second); + Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), + edge_Efacet.second); + + e1 = compute_value(edge_Ifacet_1); + e2 = compute_value(edge_Ifacet_2); + + if ((e1.first >= STANDBY_CANDIDATE)&&(e2.first >= STANDBY_CANDIDATE)) + return NOT_VALID_CONNECTING_CASE; + + // vu compute value: les candidats oreilles fournis sont sans + // aretes interieures et le sommet oppose n'est pas non plus interieur + Edge_incident_facet ear1 = e1.second.second; + Edge_incident_facet ear2 = e2.second.second; + + int ear1_i = (6 - ear1.second + - ear1.first.second + - ear1.first.third); + Cell_handle ear1_c = ear1.first.first; + Border_elt result_ear1; + + int ear2_i = (6 - ear2.second + - ear2.first.second + - ear2.first.third); + Cell_handle ear2_c = ear2.first.first; + Border_elt result_ear2; + + Edge_like ear1_e, ear2_e; + // pour maintenir la reconstruction d'une surface orientable : + // on verifie que les bords se recollent dans des sens opposes + if (ordered_key.first==v1) + { + ear1_e = Edge_like(c->vertex(i), ear1_c ->vertex(ear1_i)); + ear2_e = Edge_like(ear2_c ->vertex(ear2_i), c->vertex(i)); + } + else + { + ear1_e = Edge_like(ear1_c ->vertex(ear1_i), c->vertex(i)); + ear2_e = Edge_like(c->vertex(i), ear2_c ->vertex(ear2_i)); + } + + //maintient la surface orientable + bool is_border_ear1 = is_ordered_border_elt(ear1_e, result_ear1); + bool is_border_ear2 = is_ordered_border_elt(ear2_e, result_ear2); + bool ear1_valid(false), ear2_valid(false); + + if (is_border_ear1&&(e1.first < STANDBY_CANDIDATE)&& + (e1.first <= value)&& + (result12.second==result_ear1.second)) + { + ear1_valid = test_merge(ear1_e, result_ear1, v1, + get_smallest_radius_delaunay_sphere(ear1_c, + ear1.second)); + } + + if (is_border_ear2&&(e2.first < STANDBY_CANDIDATE)&& + (e2.first <= value)&& + (result12.second==result_ear2.second)) + { + ear2_valid = test_merge(ear2_e, result_ear2, v2, + get_smallest_radius_delaunay_sphere(ear2_c, + ear2.second)); + } + + if ((!ear1_valid)&&(!ear2_valid)) + return NOT_VALID_CONNECTING_CASE; + + IO_edge_type* p1; + IO_edge_type* p2; + + border_extend(ordered_key, result12, + v1, v2, c->vertex(i), + e1, e2, p1, p2); + + if (ear1_valid&&ear2_valid&&(ear1_e==ear2_e)) + { + if (e1.first < e2.first) + { + Validation_case res = validate(ear1, e1.first); + if (!((res == EAR_CASE)||(res == FINAL_CASE))) + std::cerr << "+++probleme de recollement : cas " + << res << std::endl; + e2 = compute_value(edge_Ifacet_2); + + if (ordered_key.first == v1) + p2 = set_again_border_elt(c->vertex(i), v2, + Border_elt(e2, result2.second)); + else + p2 = set_again_border_elt(v2, c->vertex(i), + Border_elt(e2, result2.second)); + + _ordered_border.insert(Radius_ptr_type(e2.first, p2)); + } + else + { + Validation_case res = validate(ear2, e2.first); + if (!((res == EAR_CASE)||(res == FINAL_CASE))) + std::cerr << "+++probleme de recollement : cas " + << res << std::endl; + e1 = compute_value(edge_Ifacet_1); + + if (ordered_key.first == v1) + p1 = set_again_border_elt(v1, c->vertex(i), + Border_elt(e1, result1.second)); + else + p1 = set_again_border_elt(c->vertex(i), v1, + Border_elt(e1, result1.second)); + + _ordered_border.insert(Radius_ptr_type(e1.first, p1)); + } + } + else// les deux oreilles ne se recollent pas sur la meme arete... + { + // on resoud la singularite. + if (ear1_valid) + { + Validation_case res = validate(ear1, e1.first); + if (!((res == EAR_CASE)||(res == FINAL_CASE))) + std::cerr << "+++probleme de recollement : cas " + << res << std::endl; + } + if (ear2_valid) + { + Validation_case res = validate(ear2, e2.first); + if (!((res == EAR_CASE)||(res == FINAL_CASE))) + std::cerr << "+++probleme de recollement : cas " + << res << std::endl; + } + // on met a jour la PQ s'il y a lieu... mais surtout pas + // avant la resolution de la singularite + if (!ear1_valid) + { + _ordered_border.insert(Radius_ptr_type(e1.first, p1)); + } + if (!ear2_valid) + { + _ordered_border.insert(Radius_ptr_type(e2.first, p2)); + } + } + + select_facet(c, edge_Efacet.second); + + return CONNECTING_CASE; + } + } + } + } + return NOT_VALID; + } + + //===================================================================== + void re_compute_values() + { + if(!_ordered_border.empty()) + { + Ordered_border_type _ordered_border_tmp; + do + { + Ordered_border_iterator e_it = _ordered_border.begin(); + Edge_incident_facet mem_Ifacet = e_it->second->first; + Cell_handle c_tmp = mem_Ifacet.first.first; + _ordered_border.erase(e_it); + Vertex_handle v1 = c_tmp->vertex(mem_Ifacet.first.second); + Vertex_handle v2 = c_tmp->vertex(mem_Ifacet.first.third); + + Radius_edge_type new_candidate; + new_candidate = compute_value(mem_Ifacet); + + if (new_candidate.first == STANDBY_CANDIDATE) + { + // a garder pour un K un peu plus grand... + new_candidate.first = STANDBY_CANDIDATE_BIS; + } + + Border_elt result; + Edge_like key_tmp(v1,v2); + is_border_elt(key_tmp, result); + IO_edge_type* pnew = + set_again_border_elt(key_tmp.first, key_tmp.second, + Border_elt (new_candidate, result.second)); + _ordered_border_tmp.insert(Radius_ptr_type(new_candidate.first, pnew)); + } + while(!_ordered_border.empty()); + + _ordered_border.swap(_ordered_border_tmp); + } + } + + //--------------------------------------------------------------------- + + void + extend(const coord_type& K_init, const coord_type& K_step, const coord_type& K_max) + { + // initilisation de la variable globale K: qualite d'echantillonnage requise + K = K_init; // valeur d'initialisation de K pour commencer prudemment... + + Vertex_handle v1, v2; + t1.start(); + if (_ordered_border.empty()) return; + do + { + min_K = HUGE_VAL; // pour retenir le prochain K necessaire pour progresser... + do + { + Ordered_border_iterator e_it = _ordered_border.begin(); + + criteria value = e_it->first; + if (value >= STANDBY_CANDIDATE) + re_compute_values(); + else + { + Edge_incident_facet candidate = e_it->second->second; + Cell_handle c_ext = candidate.first.first; + int i1, i2 , i3; + i1 = candidate.first.second; + i2 = candidate.first.third; + i3 = (6 - i1- i2 - candidate.second); + + Edge_incident_facet mem_Ifacet = e_it->second->first; + Cell_handle c_tmp = mem_Ifacet.first.first; + + v1 = c_tmp->vertex(mem_Ifacet.first.second); + v2 = c_tmp->vertex(mem_Ifacet.first.third); + + Radius_edge_type mem_e_it(e_it->first, *e_it->second); + + _ordered_border.erase(e_it); + + Validation_case validate_result = validate(candidate, value); + + if ((validate_result == NOT_VALID)|| + (validate_result == NOT_VALID_CONNECTING_CASE)) + { + Radius_edge_type new_candidate; + Border_elt result; + Edge_like key_tmp(v1,v2); + is_border_elt(key_tmp, result); + + if (validate_result == NOT_VALID_CONNECTING_CASE) + set_incidence_request(c_ext->vertex(i3), value, key_tmp); + + if (validate_result == NOT_VALID) + { + new_candidate = compute_value(mem_Ifacet); + if ((new_candidate != mem_e_it)) + // &&(new_candidate.first < NOT_VALID_CANDIDATE)) + { + IO_edge_type* pnew = + set_again_border_elt(key_tmp.first, key_tmp.second, + Border_elt (new_candidate, result.second)); + _ordered_border.insert(Radius_ptr_type(new_candidate.first, + pnew)); + } + } + } + } + } + while((!_ordered_border.empty())&& + (_ordered_border.begin()->first < STANDBY_CANDIDATE_BIS)); + + K += (std::max)(K_step, min_K-K+eps); + // on augmente progressivement le K mais on a deja rempli sans + // faire des betises auparavant... + } + while((!_ordered_border.empty())&&(K <= K_max)&&(min_K != HUGE_VAL)); + t1.stop(); + +#ifdef VERBOSE + if ((min_K < HUGE_VAL)&&(!_ordered_border.empty())) { + std::cout << " [ next K required = " << min_K << " ]" << std::endl; + } +#endif // VERBOSE + } + + + + + //--------------------------------------------------------------------- + // En principe, si l'allocateur de cellules etait bien fait on aurait pas besoin + // de mettre a jour les valeurs rajoutees pour les cellules a la main... + + void re_init_for_free_cells_cache(const Vertex_handle& vh) + { + std::list ch_set; + T.incident_cells(vh, std::back_inserter(ch_set)); + for (typename std::list::iterator c_it = ch_set.begin(); + c_it != ch_set.end(); + c_it++) + (*c_it)->clear(); + } + + + //--------------------------------------------------------------------- + + void swap_selected_facets_on_conflict_boundary(const Vertex_handle& vh) + { + std::list ch_set; + T.incident_cells(vh, std::back_inserter(ch_set)); + for (typename std::list::iterator c_it = ch_set.begin(); + c_it != ch_set.end(); c_it++) + { + Cell_handle c = *c_it; + int index = c->index(vh); + Cell_handle neigh = c->neighbor(index); + int n_ind = neigh->index(c); + neigh->set_smallest_radius(n_ind, -1); // pour obliger le recalcul + // si c est selectionnee c'est qu'elle est aussi le mem_IFacet renvoye par + // compute_value... donc a swapper aussi + if (c->is_selected_facet(index)) + { + int fn = c->facet_number(index); + unselect_facet(c, index); + neigh->select_facet(n_ind); + neigh->set_facet_number(n_ind, fn); + int i1 = (n_ind+1) & 3; + int i2 = (n_ind+2) & 3; + int i3 = (n_ind+3) & 3; + Edge_like key(neigh->vertex(i1), neigh->vertex(i2)); + + if (is_border_elt(key)) + { + Edge_incident_facet ei_facet(Edge(neigh, i1, i2), + n_ind); + *get_border_IO_elt(key.first, key.second) = + IO_edge_type(ei_facet, ei_facet); + } + key = Edge_like(neigh->vertex(i1), neigh->vertex(i3)); + if (is_border_elt(key)) + { + Edge_incident_facet ei_facet(Edge(neigh, i1, i3), + n_ind); + *get_border_IO_elt(key.first, key.second) = + IO_edge_type(ei_facet, ei_facet); + } + key = Edge_like(neigh->vertex(i3), neigh->vertex(i2)); + if (is_border_elt(key)) + { + Edge_incident_facet ei_facet(Edge(neigh, i3, i2), + n_ind); + *get_border_IO_elt(key.first, key.second) = + IO_edge_type(ei_facet, ei_facet); + } + } + } + } + + //--------------------------------------------------------------------- + + Facet next_surface_facet(const Edge_incident_facet& start) + { + Edge_incident_facet circ = next(start); + Cell_handle c = start.first.first; + do + { + Cell_handle ch = circ.first.first; + int ind = circ.second; + Cell_handle neigh = ch->neighbor(ind); + int n_ind = neigh->index(ch); + if (ch->is_selected_facet(ind)) + return Facet(ch, ind); + if (neigh->is_selected_facet(n_ind)) + return Facet(neigh, n_ind); + circ = next(circ); + } + while(circ.first.first != c); + // si on passe par la, alors y a eu un probleme.... + std::cerr << "+++probleme dans la MAJ avant remove..." << std::endl; + + return Facet(c, start.second); + } + + //--------------------------------------------------------------------- + + void retract_border_for_incident_facets(const Vertex_handle& vh) + { + Next_border_elt border_elt = *(vh->first_incident()); + int border_index = border_elt.second.second; + Vertex_handle vh_succ = border_elt.first; + IO_edge_type io_edge = border_elt.second.first.second; + Edge_incident_facet i_facet = io_edge.first; + Cell_handle c = i_facet.first.first; + int i1 = c->index(vh); + int i2 = c->index(vh_succ); + int index = i_facet.second; + int i3 = 6 - index - i1 - i2; + Vertex_handle vh_int = c->vertex(i3); + ordered_map_erase(border_elt.second.first.first, + get_border_IO_elt(vh, vh_succ)); + vh->remove_border_edge(vh_succ); + // 1- a virer au cas ou car vh va etre detruit + vh_succ->remove_interior_edge(vh); + bool while_cond(true); + do + { + _facet_number--; + + assert(c->is_selected_facet(index)); + unselect_facet(c, index); + + Facet f32 = + next_surface_facet(Edge_incident_facet(Edge(c, i3, i2), + index)); + + if (!vh_int->is_on_border()) + { + vh_int->re_init(); + vh_int->inc_mark(); + } + + Edge_incident_facet e32(Edge(f32.first, + f32.first->index(vh_int), + f32.first->index(vh_succ)), f32.second); + Radius_edge_type rad_elt_32(STANDBY_CANDIDATE, IO_edge_type(e32, e32)); + Border_elt result; + if (is_ordered_border_elt(Edge_like(vh_int, vh), result)) + { + ordered_map_erase(result.first.first, get_border_IO_elt(vh_int, vh)); + vh_int->remove_border_edge(vh); + // 1- a virer au cas ou car vh va etre detruit + vh_int->remove_interior_edge(vh); + while_cond = false; + } + // a titre preventif... on essaye de s'assurer de marquer les aretes + // interieures au sens large... + + // 2- a virer a tout pris pour que maintenir le sens de interior edge + vh_int->remove_interior_edge(vh_succ); + vh_succ->remove_interior_edge(vh_int); + + IO_edge_type* p32 = set_border_elt(vh_int, vh_succ, + Border_elt(rad_elt_32, border_index)); + _ordered_border.insert(Radius_ptr_type (STANDBY_CANDIDATE, p32)); + + // incrementation... + if (while_cond) + { + Facet f31 = + next_surface_facet(Edge_incident_facet(Edge(c, i3, i1), + index)); + + c = f31.first; + index = f31.second; + i1 = c->index(vh); + vh_succ = vh_int; + i2 = c->index(vh_int); + i3 = 6 - index - i1 - i2; + vh_int = c->vertex(i3); + } + } + while(while_cond); + } + + //--------------------------------------------------------------------- + + bool create_singularity(const Vertex_handle& vh) + { + // Pour reperer le cas de triangle isole + if (vh->is_on_border()) + { + // vh sommet 0 + Next_border_elt border_elt = *(vh->first_incident()); + Vertex_handle vh_1 = border_elt.first;// sommet 1 + border_elt = *(vh_1->first_incident()); + Vertex_handle vh_2 = border_elt.first;// sommet 2 + border_elt = *(vh_2->first_incident()); + Vertex_handle vh_3 = border_elt.first;// sommet 0 ??? + Cell_handle c; + int i, j, k; + if ((vh_3 == vh)&&(T.is_facet(vh, vh_1, vh_2, c, i ,j ,k))) + { + int l = 6-i-j-k; + Cell_handle neigh = c->neighbor(l); + + if + (c->is_selected_facet(l)||neigh->is_selected_facet(neigh->index(c))) + return true; + } + } + + + // Reperer le cas d'aretes interieures... + std::list vh_list; + T.incident_vertices(vh, std::back_inserter(vh_list)); + + for (typename std::list::iterator v_it = vh_list.begin(); + v_it != vh_list.end(); v_it++) + if ((*v_it)->is_on_border() && is_interior_edge(Edge_like(vh, *v_it))) + return true; + return false; + } + + + //--------------------------------------------------------------------- + + void + store_outlier(const Point& p){ + outliers.push_back(p); + } + + void dec_vh_number() + { + _vh_number--; + } + + struct Remove : public std::unary_function + { + + Extract& E; + Triangulation_3& T; + + Remove(Extract& E_, Triangulation_3& T_) : E(E_), T(T_) {} + + bool operator()(Vertex_handle vh) { + if (vh->is_exterior()) + { + E.swap_selected_facets_on_conflict_boundary(vh); + E.re_init_for_free_cells_cache(vh); + Point p = vh->point(); + T.remove(vh); + E.dec_vh_number(); + E.store_outlier(p); + + return true; + } + else if (vh->is_on_border()&&(!E.create_singularity(vh))) + { + E.swap_selected_facets_on_conflict_boundary(vh); + E.retract_border_for_incident_facets(vh); + E.re_init_for_free_cells_cache(vh); + Point p = vh->point(); + T.remove(vh); + E.dec_vh_number(); + E.store_outlier(p); + + return true; + } + else + { } + return false; + } + }; + + + //--------------------------------------------------------------------- + + bool postprocessing(int NB_BORDER_MAX) + { + _postprocessing_counter++; + + std::list L_v; + + // Pour controler les sommets choisis sur le bord... + + // nombre d'aretes a partir duquel on considere que c'est irrecuperable NB_BORDER_MAX + + int vh_on_border_inserted(0); + for(Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++) + { + v_it->erase_incidence_request(); + if ((v_it->is_on_border())&& + (!v_it->is_post_marked(_postprocessing_counter))) + { + std::list L_v_tmp; + Vertex_handle vprev_it(v_it), done(vprev_it), vh_it; + // Vertex_handle vsucc_it; + int v_count(0); + // collect all vertices on the border + do + { + vh_it = vprev_it->first_incident()->first; + L_v_tmp.push_back(vh_it); + vh_it->set_post_mark(_postprocessing_counter); + vprev_it = vh_it; + v_count++; + } + while((vprev_it != done)&&(v_count < NB_BORDER_MAX)); + // we stopped either because we did a complete tour, or because + // the border was so long that we consider it as too big to close + // e.g., if it is a terrain with only one real border at the exterior + if (v_count < NB_BORDER_MAX) + { + L_v.insert(L_v.begin(), L_v_tmp.begin(), L_v_tmp.end()); + vh_on_border_inserted += v_count; + } + + } + if (v_it->is_exterior()) + L_v.push_back(v_it); + } + + unsigned int itmp, L_v_size_mem; + L_v_size_mem = L_v.size(); + if ((vh_on_border_inserted != 0)&& // pour ne post-traiter que les bords + (L_v.size() < .1 * _size_before_postprocessing)) + { + { + do + { + itmp = L_v.size(); + typename std::list::iterator new_end = + std::remove_if(L_v.begin(), L_v.end(), Remove(*this,T)); + L_v.erase(new_end, L_v.end()); + } + while (!L_v.empty() && (L_v.size() < itmp)); + } +#ifdef VERBOSE + if(L_v.size() > 0){ + std::cout << " " << L_v.size() << " non regular points." << std::endl; + } +#endif // VERBOSE + re_compute_values(); + } + else{ + return false; + } + // we stop if we removed more than 10% of points or after 20 rounds + if ((L_v_size_mem == L_v.size())|| + ((_size_before_postprocessing - T.number_of_vertices()) > + .1 * _size_before_postprocessing)|| + (_postprocessing_counter > 20)){ + return false; + } + + min_K = HUGE_VAL; + // fin-- + // if (_postprocessing_counter < 5) + // return true; + return true; + } + + +}; // class Advancing_front_surface_reconstruction + +} // namespace CGAL + +#endif // CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h new file mode 100755 index 00000000000..aa399136818 --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h @@ -0,0 +1,68 @@ +#ifndef CGAL_AFSR_VRML_H +#define CGAL_AFSR_VRML_H + +namespace CGAL { + +template < class Vb, class Fb> +void +afsr_vrml_output(const Triangulation_data_structure_2& tds, + std::ostream& os, double r, double g, double b, + typename Triangulation_data_structure_2::Vertex_handle v, bool skip_infinite) +{ + typedef typename Triangulation_data_structure_2::Vertex_handle Vertex_handle; + typedef typename Triangulation_data_structure_2::Vertex_iterator Vertex_iterator; + typedef typename Triangulation_data_structure_2::Face_iterator Face_iterator; + + // ouput to a vrml file style + // Point are assumed to be 3d points with a stream operator << + // if non NULL, v is the vertex to be output first + // if skip_inf is true, the point in the first vertex is not output + // and the faces incident to v are not output + // (it may be for instance the infinite vertex of the terrain) + + os << "#VRML V2.0 utf8" << std::endl; + os << "Shape {\n" + << "appearance Appearance {\n" + << "material Material { diffuseColor " << r << " " << g << " " << b << "}}\n"; + os << "\tgeometry IndexedFaceSet {" << std::endl; + os << "\t\tcoord Coordinate {" << std::endl; + os << "\t\t\tpoint [" << std::endl; + + std::map vmap; + Vertex_iterator vit; + Face_iterator fit; + + int inum = 0; + for( vit= tds.vertices_begin(); vit != tds.vertices_end() ; ++vit) { + if ( v != vit) { + vmap[vit] = inum++; + os << "\t\t\t\t" << *vit << ","<< std::endl; + } + } + + os << "\t\t\t]" << std::endl; + os << "\t\t}" << std::endl; + os << "\t\tsolid FALSE\n" + "\t\tcoordIndex [" << std::endl; + + // faces + for(fit= tds.faces_begin(); fit != tds.faces_end(); ++fit) { + if (!skip_infinite || !fit->has_vertex(v)) { + os << "\t\t\t"; + os << vmap[(*fit).vertex(0)] << ", "; + os << vmap[(*fit).vertex(1)] << ", "; + os << vmap[(*fit).vertex(2)] << ", "; + os << "-1, " << std::endl; + } + } + os << "\t\t]" << std::endl; + os << "\t}" << std::endl; + os << "}" << std::endl; + return; +} + + +} // namespace CGAL + +#endif + diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h new file mode 100755 index 00000000000..31cc943795b --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -0,0 +1,965 @@ +#ifndef CGAL_IO_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H +#define CGAL_IO_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H + + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace CGAL { + + +template +struct Is_not_exterior { + bool operator()(const Vertex& v)const { + return ! v.is_exterior(); + } +}; + +template +void +write_to_file_medit(char* foutput, const Surface& S) +{ + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Vertex Vertex; + typedef typename Surface::Cell_handle Cell_handle; + + Triangulation_3& T = S.triangulation(); + + char foutput_points[100]; + char foutput_faces[100]; + std::strcpy(foutput_points, foutput); + std::strcpy(foutput_faces, foutput); + strcat(foutput_points, ".points"); + strcat(foutput_faces, ".faces"); + std::ofstream os_points(foutput_points, std::ios::out); + std::ofstream os_faces(foutput_faces, std::ios::out); + if((os_points.fail())||(os_faces.fail())) + std::cerr << "+++unable to open file for output" << std::endl; + else + std::cout << ">> files for output : " << foutput_points + << ", " << foutput_faces << std::endl; + + os_points.clear(); + os_faces.clear(); + + CGAL::set_ascii_mode(os_points); + CGAL::set_ascii_mode(os_faces); + + // af: what is the relationship to _vh_number in Extract_surface + int _vh_number = std::count_if(T.finite_vertices_begin(), + T.finite_vertices_end(), + Is_not_exterior()); + + os_points << _vh_number << std::endl; + + CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); + + int count(0); + for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++){ + typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; + if ((!v_it->is_exterior()) && d == -1){ + d = count; + count++; + os_points << v_it->point() << " 0" << std::endl; + } + } + + os_faces << S.number_of_facets() << std::endl; + for(Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; + os_faces << 3 << " "; + os_faces << vertex_index_map[c->vertex(i1)] + 1 << " "; + os_faces << vertex_index_map[c->vertex(i2)] + 1 << " "; + os_faces << vertex_index_map[c->vertex(i3)] + 1 << " "; + os_faces << " 0 0 0 0" << std::endl; + } + + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + os_faces << 3 << " "; + os_faces << vertex_index_map[n->vertex(i1)] + 1 << " "; + os_faces << vertex_index_map[n->vertex(i2)] + 1 << " "; + os_faces << vertex_index_map[n->vertex(i3)] + 1 << " "; + os_faces << " 0 0 0 0" << std::endl; + } + } + + std::cout << "-- medit result written." << std::endl; +} + +//--------------------------------------------------------------------- + +template +void +write_to_file_gv(char* foutput, const Surface& S) +{ + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Vertex Vertex; + typedef typename Surface::Cell_handle Cell_handle; + Triangulation_3& T = S.triangulation(); + + char foutput_tmp[100]; + std::strcpy(foutput_tmp, foutput); + + strcat(foutput_tmp, ".off"); + std::ofstream os(foutput_tmp, std::ios::out); + + if(os.fail()) + std::cerr << "+++unable to open file for output" << std::endl; + else + std::cout << ">> file for output : " << foutput_tmp << std::endl; + + os.clear(); + + CGAL::set_ascii_mode(os); + + int _vh_number = std::count_if(T.finite_vertices_begin(), + T.finite_vertices_end(), + Is_not_exterior()); + // Header. + os << "OFF" << std::endl + << _vh_number << " " << S.number_of_facets() << " " << 0 << std::endl; + + CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); + + int count(0); + for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++){ + typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; + if ((!v_it->is_exterior()) && d == -1){ + d = count; + count++; + os << v_it->point() << " \n"; + } + } + + for(Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; + os << 3 << " "; + os << vertex_index_map[c->vertex(i1)] << " "; + os << vertex_index_map[c->vertex(i2)] << " "; + os << vertex_index_map[c->vertex(i3)] << " "; + os << 0 << std::endl; // without color. + // os << 4 << drand48() << drand48() << drand48() << 1.0; // random + // color + } + + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + os << 3 << " "; + os << vertex_index_map[n->vertex(i1)] << " "; + os << vertex_index_map[n->vertex(i2)] << " "; + os << vertex_index_map[n->vertex(i3)] << " "; + os << 0 << std::endl; // without color. + // os << 4 << drand48() << drand48() << drand48() << 1.0; // random + // color + } + } + + std::cout << "-- oogl result written." << std::endl; +} + +//--------------------------------------------------------------------- +template +void +write_to_file_ply(char* foutput, const Surface& S) +{ + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Cell_handle Cell_handle; + Triangulation_3& T = S.triangulation(); + char foutput_tmp[100]; + std::strcpy(foutput_tmp, foutput); + + strcat(foutput_tmp, ".ply"); + std::ofstream os(foutput_tmp, std::ios::out | std::ios::binary); + + if(os.fail()) + std::cerr << "+++unable to open file for output" << std::endl; + else + std::cout << ">> file for output : " << foutput_tmp << std::endl; + + os.clear(); + + CGAL::set_ascii_mode(os); + + // Header. + os << "ply" << std::endl + << "format binary_little_endian 1.0" << std::endl + << "comment generated by ply_writer" << std::endl + << "element vertex " << S.number_of_vertices() << std::endl + << "property float x" << std::endl + << "property float y" << std::endl + << "property float z" << std::endl + << "element face " << S.number_of_facets() << std::endl + << "property list uchar int vertex_indices" << std::endl + << "end_header" << std::endl; + + CGAL::set_binary_mode(os); + + CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); + + int count(0); + for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++){ + typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; + if ((!v_it->is_exterior()) && d == -1){ + d = count; + count++; + os << v_it->point() << std::endl; + } + } + + for(Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; + char three = '3'; + CGAL::write(os, three, CGAL::io_Read_write()); + CGAL::write(os,vertex_index_map[c->vertex(i1)], CGAL::io_Read_write()); + CGAL::write(os,vertex_index_map[c->vertex(i2)], CGAL::io_Read_write()); + CGAL::write(os,vertex_index_map[c->vertex(i3)], CGAL::io_Read_write()); + os << std::endl; // without color. + // os << 4 << drand48() << drand48() << drand48() << 1.0; // random + // color + } + + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + char three = '3'; + CGAL::write(os, three, CGAL::io_Read_write()); + CGAL::write(os,vertex_index_map[n->vertex(i1)], CGAL::io_Read_write()); + CGAL::write(os,vertex_index_map[n->vertex(i2)], CGAL::io_Read_write()); + CGAL::write(os,vertex_index_map[n->vertex(i3)], CGAL::io_Read_write()); + os << std::endl; // without color. + // os << 4 << drand48() << drand48() << drand48() << 1.0; // random + // color + } + } + + //std::cout << "-- ply result written." << std::endl; +} + +//--------------------------------------------------------------------- +template +void +write_to_file_iv_border_edges(const Surface& S, std::ofstream& os) +{ + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_edges_iterator Finite_edges_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Cell_handle Cell_handle; + typedef typename Surface::Edge_like Edge_like; + typedef typename Surface::Border_elt Border_elt; + + Triangulation_3& T = S.triangulation(); + typedef std::pair indiced_vh; + std::map _vh_vect; + int _vh_bord_count = 0; + + for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++) + if (v_it->is_on_border()) + { + _vh_vect.insert(indiced_vh (v_it, _vh_bord_count)); + _vh_bord_count++; + } + + typedef const Point* Const_point_star; + std::vector points_tab(_vh_bord_count); + for (typename std::map::iterator vh_it = _vh_vect.begin(); + vh_it != _vh_vect.end(); vh_it++) + points_tab[vh_it->second] = &vh_it->first->point(); + + os << " Separator {" << std::endl << +" Switch {" << std::endl << +" whichChild 0" << std::endl << +" Separator {" << std::endl << +" BaseColor {" << std::endl << +" rgb 1 0 0" << std::endl << +" }" << std::endl << +" Coordinate3 {" << std::endl << +" point [ "; + bool first(true); + for(int vh_i=0; vh_i<_vh_bord_count; vh_i++) + { + if (!first) os << "," << std::endl << +" "; + else + first=false; + os << *points_tab[vh_i]; + } + os << " ]" << std::endl << +" }" << std::endl << +" IndexedLineSet {" << std::endl << +" coordIndex [ "; + + first=true; + for(Finite_edges_iterator e_it=T.finite_edges_begin(); + e_it!=T.finite_edges_end(); + e_it++) + { + Cell_handle c = (*e_it).first; + int i1 = (*e_it).second, i2 = (*e_it).third; + Edge_like key(c->vertex(i1), c->vertex(i2)); + Border_elt result; + + if (S.is_border_elt(key, result)) + { + if (!first) + os << "," << std::endl << " "; + else + first=false; + os << _vh_vect.find(c->vertex(i1))->second << ", "; + os << _vh_vect.find(c->vertex(i2))->second << ", "; + os << -1; + } + } + os << " ]" << std::endl << +" }}" << std::endl << +" }}" << std::endl; +} + +//--------------------------------------------------------------------- +template +void +write_to_file_iv_remaining_points(const Surface& S, std::ofstream& os) +{ + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Cell_handle Cell_handle; + Triangulation_3& T = S.triangulation(); + typedef std::pair indiced_vh; + std::map _vh_vect; + int _vh_bord_count(0); + + for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++) + if (v_it->is_exterior()) + { + _vh_vect.insert(indiced_vh (v_it, _vh_bord_count)); + _vh_bord_count++; + } + + typedef const Point* Const_point_star; + std::vector points_tab(_vh_bord_count); + for (typename std::map::iterator vh_it = _vh_vect.begin(); + vh_it != _vh_vect.end(); vh_it++) + points_tab[vh_it->second] = &vh_it->first->point(); + + os << " Separator {" << std::endl << +" Switch {" << std::endl << +" whichChild 0" << std::endl << +" Separator {" << std::endl << +" BaseColor {" << std::endl << +" rgb 0 0 1" << std::endl << +" }" << std::endl << +" Coordinate3 {" << std::endl << +" point [ "; + bool first(true); + for(int vh_i=0; vh_i<_vh_bord_count; vh_i++) + { + if (!first) os << "," << std::endl << +" "; + else + first=false; + os << *points_tab[vh_i]; + } + os << " ]" << std::endl << +" }" << std::endl << +" PointSet {" << std::endl << +" startIndex 0" << std::endl << +" numPoints -1" << std::endl << +" }"; + + os << " }" << std::endl << +" }}" << std::endl; + +} + +//--------------------------------------------------------------------- +// attention cette procedure produit un fichier tres sale... trop de sommets... + +// !!!! bizarre : ca a l'air de buggue pour hand.xyz (seg fault...) +template +void +write_to_file_iv_border_facets(const Surface& S, std::ofstream& os) +{ + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Cell_handle Cell_handle; + typedef typename Surface::Edge_like Edge_like; + typedef typename Surface::Border_elt Border_elt; + + Triangulation_3& T = S.triangulation(); + typedef std::pair indiced_vh; + std::map _vh_vect; + int _vh_bord_count(0); + + for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++) +// if (v_it->number_of_incident_border() > 0) + { + _vh_vect.insert(indiced_vh (v_it, _vh_bord_count)); + _vh_bord_count++; + } + + typedef const Point* Const_point_star; + std::vector points_tab(_vh_bord_count); + for (typename std::map::iterator vh_it = _vh_vect.begin(); + vh_it != _vh_vect.end(); vh_it++) + points_tab[vh_it->second] = &vh_it->first->point(); + + os << " Separator {" << std::endl << +" Switch {" << std::endl << +" whichChild 0" << std::endl << +" Separator {" << std::endl << +" ShapeHints {" << std::endl << +" vertexOrdering CLOCKWISE" << std::endl << +" shapeType UNKNOWN_SHAPE_TYPE" << std::endl << +" faceType CONVEX" << std::endl << +" creaseAngle 1.0" << std::endl << +" }" << std::endl << +" BaseColor {" << std::endl << +" rgb 0 0 1" << std::endl << +" }" << std::endl << +" Coordinate3 {" << std::endl << +" point [ "; + bool first(true); + for(int vh_i=0; vh_i<_vh_bord_count; vh_i++) + { + if (!first) os << "," << std::endl << +" "; + else + first=false; + os << *points_tab[vh_i]; + } + os << " ]" << std::endl << +" }" << std::endl << +" IndexedFaceSet {" << std::endl << +" coordIndex [ "; + + first=true; + for(Finite_facets_iterator f_it=T.finite_facets_begin(); + f_it!=T.finite_facets_end(); + f_it++) + { + Cell_handle c = (*f_it).first; + int index = (*f_it).second; + int i1 = (index+1) & 3; + int i2 = (index+2) & 3; + int i3 = (index+3) & 3; + Edge_like key12(c->vertex(i1), c->vertex(i2)); + Edge_like key13(c->vertex(i1), c->vertex(i3)); + Edge_like key32(c->vertex(i3), c->vertex(i2)); + Border_elt result; + + // les trois aretes sur le bord... +// if (is_border_elt(key12, result)&& +// is_border_elt(key13, result)&& +// is_border_elt(key32, result)) + + // au moins 2 aretes sur le bord... +// if (((is_border_elt(key12, result)&& +// is_border_elt(key13, result)))|| +// ((is_border_elt(key32, result)&& +// is_border_elt(key13, result)))|| +// ((is_border_elt(key12, result)&& +// is_border_elt(key32, result)))) + + // une arete sur le bord... + if ((is_border_elt(key12, result)|| + is_border_elt(key13, result)|| + is_border_elt(key32, result))&& + (c->is_selected_facet(index)|| + c->neighbor(index)->is_selected_facet(c->neighbor(index)->index(c)))) + + // au moins 2 aretes sur le bord... +// if (((is_border_elt(key12, result)&& +// is_border_elt(key13, result)))|| +// ((is_border_elt(key32, result)&& +// is_border_elt(key13, result)))|| +// ((is_border_elt(key12, result)&& +// is_border_elt(key32, result)))) + { + if (!first) + os << "," << std::endl << " "; + else + first=false; + os << _vh_vect.find(c->vertex(i1))->second << ", "; + os << _vh_vect.find(c->vertex(i2))->second << ", "; + os << _vh_vect.find(c->vertex(i3))->second << ", "; + + os << -1; + } + } + os << " ]" << std::endl << +" }}" << std::endl << +" }}" << std::endl; +} + +//--------------------------------------------------------------------- +template +void +write_to_file_iv(char* foutput, const Surface& S, + const bool& boundary) +{ + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Cell_handle Cell_handle; + Triangulation_3& T = S.triangulation(); + char foutput_tmp[100]; + std::strcpy(foutput_tmp, foutput); + + strcat(foutput_tmp, ".iv"); + std::ofstream os(foutput_tmp, std::ios::out); + + if(os.fail()) + std::cerr << "+++unable to open file for output" << std::endl; + else + std::cout << ">> file for output : " << foutput_tmp << std::endl; + + os.clear(); + + CGAL::set_ascii_mode(os); + + // Header. + os << +"#Inventor V2.1 ascii" << std::endl << +"Separator {" << std::endl << +" PerspectiveCamera {" << std::endl << +" position 0 0 2.41421" << std::endl << +" nearDistance 1.41421" << std::endl << +" farDistance 3.41421" << std::endl << +" focalDistance 2.41421" << std::endl << +" }" << std::endl << +" Group {" << std::endl << +" Rotation {" << std::endl << +" }" << std::endl << +" DirectionalLight {" << std::endl << +" direction 0.2 -0.2 -0.979796" << std::endl << +" }" << std::endl << +" ResetTransform {" << std::endl << +" } }" << std::endl << +" Separator {" << std::endl << +" Switch {" << std::endl << +" whichChild 0" << std::endl << +" Separator {" << std::endl << +" ShapeHints {" << std::endl << +" vertexOrdering CLOCKWISE" << std::endl << +" shapeType UNKNOWN_SHAPE_TYPE" << std::endl << +" faceType CONVEX" << std::endl << +" creaseAngle 1.0" << std::endl << +" }" << std::endl << +" BaseColor {" << std::endl << +" rgb 0.6 0.6 0.48" << std::endl << +" }" << std::endl << +" Coordinate3 {" << std::endl << +" point [ "; + + CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); + + int count(0); + for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++){ + typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; + if ((!v_it->is_exterior()) && d == -1){ + d = count; + count++; + os << v_it->point() << " ,\n"; + } + } + os << " ]" << std::endl << +" }" << std::endl << +" IndexedFaceSet {" << std::endl << +" coordIndex [ "; + + for(Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; + os << vertex_index_map[c->vertex(i1)] << ", "; + os << vertex_index_map[c->vertex(i2)] << ", "; + os << vertex_index_map[c->vertex(i3)] << ", "; + os << -1; + } + + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + os << vertex_index_map[n->vertex(i1)] << ", "; + os << vertex_index_map[n->vertex(i2)] << ", "; + os << vertex_index_map[n->vertex(i3)] << ", "; + os << -1; + } + } + + + os << " ]\n" + " }\n" + " }}\n" + " }\n"; + + if (boundary) + { + // pour visualiser les boundaries restant a la fin... + write_to_file_iv_border_edges(S, os); + + // pour visualiser les facettes eventuellement candidates... + // write_to_file_iv_border_facets(S, os); + + // pour afficher les points non selectionnes, ~bruit??? + // write_to_file_iv_remaining_points(S, os); + } + + os << "}" << std::endl; + + std::cout << "-- Inventor result written." << std::endl; +} + + +template +void +write_boundaries(std::ostream& os, const Surface& S) +{ + + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Boundary_iterator Boundary_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Vertex Vertex; + typedef typename Surface::Cell_handle Cell_handle; + + + CGAL::Random random; + for(Boundary_iterator it = S.boundaries_begin(); + it != S.boundaries_end(); + ++it) { + double blue = random.get_double(0,1); + os << + "Shape {\n" + "appearance Appearance {\n" + "material Material { emissiveColor 1 0 " << blue << "}}\n" + "geometry\n" + "IndexedLineSet {\n" + "coord Coordinate {\n" + "point [ " << std::endl; + unsigned int count = 0; + Vertex_handle first = *it; + do { + os << (*it)->point() << std::endl; + ++it; + count++; + } while(*it != first); + os << "]\n" + "}\n" + "coordIndex [\n"; + + for(unsigned int i = 0; i < count; i++){ + os << i << ", "; + } + os << "0, -1\n"; + os << "]\n" + "}#IndexedLineSet\n" + "}# Shape\n"; + } +} + + + + +template +void +write_to_file_vrml2(char* foutput, const Surface& S, + const bool& boundary, double red, double green, double blue, bool no_header) +{ + + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Cell_handle Cell_handle; + Triangulation_3& T = S.triangulation(); + + typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; + + typedef CGAL::Triangulation_data_structure_2 > TDS; + + TDS tds; + + TDS::Vertex_handle inf = AFSR::orient(tds, S); + + char foutput_tmp[100]; + std::strcpy(foutput_tmp, foutput); + + strcat(foutput_tmp, ".wrl"); + std::ofstream os(foutput_tmp, std::ios::out); + + if(os.fail()) + std::cerr << "+++unable to open file for output" << std::endl; + else + std::cout << ">> file for output : " << foutput_tmp << std::endl; + + os.clear(); + + CGAL::set_ascii_mode(os); + + if(! no_header){ + // Header. + os << + "#VRML V2.0 utf8\n" + "Background {skyColor .1 .5 .5}\n" + "Group {\n" + "children [\n" << std::endl; + }; + + afsr_vrml_output(tds, os, red, green, blue, inf, true); + + if (boundary){ + write_boundaries(os, S); + } + + typename Surface::Outlier_iterator pit = S.outliers_begin(); + + if(pit != S.outliers_end()) { + os << "Shape {\n" + "geometry PointSet {\n" + "coord Coordinate { point [\n"; + + for(; pit != S.outliers_end(); pit++){ + os << pit->x() << " " << pit->y() << " " << pit->z() << ",\n"; + } + os << "] } }\n" + "appearance Appearance {\n" + " material Material {\n" + " emissiveColor 1 0.1 0\n" + " }\n" + "}\n" + "} # Shape\n"; + } + + if(! no_header){ + os << "] # children\n" + "} # Group\n"; + } + std::cout << "-- wrl result written." << std::endl; +} + + + +template +void +write_to_file_stl(char* foutput, const Surface& S) +{ + + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Cell_handle Cell_handle; + Triangulation_3& T = S.triangulation(); + + + char foutput_tmp[100]; + std::strcpy(foutput_tmp, foutput); + + strcat(foutput_tmp, ".stl"); + std::ofstream os(foutput_tmp, std::ios::out); + + if(os.fail()) + std::cerr << "+++unable to open file for output" << std::endl; + else + std::cout << ">> file for output : " << foutput_tmp << std::endl; + + os.clear(); + + CGAL::set_ascii_mode(os); + + // Header. + os << "solid" << std::endl; + + for(Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + + bool selected = false; + if(c->is_selected_facet(ci)){ + selected = true; + } else { + n = c->neighbor(ci); + ni = n->index(c); + if(n->is_selected_facet(ni)) { + selected = true; + c = n; + ci = ni; + } + } + + if(selected){ + int i1, i2 ,i3; + + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; + + Point p = c->vertex(i1)->point(); + Point q = c->vertex(i2)->point(); + Point r = c->vertex(i3)->point(); + // compute normal + Vector n = CGAL::cross_product( q-p, r-p); + Vector norm = n / sqrt( n * n); + os << "outer loop" << std::endl; + os << "facet normal " << norm << std::endl; + os << "vertex " << p << std::endl; + os << "vertex " << q << std::endl; + os << "vertex " << r << std::endl; + os << "endloop\nendfacet" << std::endl; + } + + } + + os << "endsolid" << std::endl; + + std::cout << "-- stl result written." << std::endl; +} + + +//--------------------------------------------------------------------- +template +void +write_to_file(char* foutput, const Surface& S, + const bool& boundary, const int& out_format, + double red, double green, double blue, bool no_header) +{ + switch(out_format) + { + case -2: + // no output file... + return; + case -1: + write_to_file_iv(foutput, S, boundary); + write_to_file_vrml2(foutput, S, boundary, red, green, blue, no_header); + write_to_file_gv(foutput, S); + write_to_file_medit(foutput, S); + //write_to_file_ply(foutput, S); + return; + case 0: + write_to_file_vrml2(foutput, S, boundary, red, green, blue, no_header); + return; + case 1: + write_to_file_gv(foutput, S); + return; + case 2: + write_to_file_medit(foutput, S); + return; + case 3: + write_to_file_ply(foutput, S); + return; + case 4: + write_to_file_iv(foutput, S, boundary); + return; + case 5: + write_to_file_stl(foutput, S); + return; + } +} + +} // namespace CGAL + + +#endif // CGAL_IO_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h b/Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h new file mode 100755 index 00000000000..8fbb59d7739 --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h @@ -0,0 +1,94 @@ +// Copyright (c) 1997 INRIA Sophia-Antipolis (France). +// All rights reserved. +// +// This file is part of CGAL (www.cgal.org); you may redistribute it under +// the terms of the Q Public License version 1.0. +// See the file LICENSE.QPL distributed with CGAL. +// +// Licensees holding a valid commercial license may use this file in +// accordance with the commercial license agreement provided with the software. +// +// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE +// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +// +// $Source: /CVSROOT/CGAL/Packages/Triangulation_2/include/CGAL/Triangulation_vertex_base_2.h,v $ +// $Revision$ $Date$ +// $Name: current_submission $ +// +// Author(s) : Mariette Yvinec + + +#ifndef CGAL_TVB_3_2_H +#define CGAL_TVB_3_2_H + +#include +#include + +namespace CGAL { + +template < typename GT, + typename Vb = Triangulation_ds_vertex_base_2<> > +class Tvb_3_2 + : public Vb + +{ + typedef typename Vb::Triangulation_data_structure Tds; +public: + typedef GT Geom_traits; + typedef typename GT::Point_3 Point; + typedef Tds Triangulation_data_structure; + typedef typename Tds::Face_handle Face_handle; + typedef typename Tds::Vertex_handle Vertex_handle; + + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef Tvb_3_2 Other; + }; + +private: + Point _p; + +public: + Tvb_3_2 () : Vb() {} + Tvb_3_2(const Point & p) : Vb(), _p(p) {} + Tvb_3_2(const Point & p, Face_handle f) + : Vb(f), _p(p) {} + Tvb_3_2(Face_handle f) : Vb(f) {} + + void set_point(const Point & p) { _p = p; } + const Point& point() const { return _p; } + + // the non const version of point() is undocument + // but needed to make the point iterator works + // using Lutz projection scheme + Point& point() { return _p; } + + //the following trivial is_valid to allow + // the user of derived face base classes + // to add their own purpose checking + bool is_valid(bool /* verbose */ = false, int /* level */ = 0) const + {return true;} +}; + +template < class GT, class Vb > +std::istream& +operator>>(std::istream &is, Tvb_3_2 &v) + // non combinatorial information. Default = point +{ + return is >> static_cast(v) >> v.point(); +} + +template < class GT, class Vb > +std::ostream& +operator<<(std::ostream &os, const Tvb_3_2 &v) + // non combinatorial information. Default = point +{ + return os << static_cast(v) << v.point(); +} + + + +} //namespace CGAL + +#endif //CGAL_TVB_3_2_H From e7900a02a37cc665959d7783913e65b9f6e1c3bc Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 6 Mar 2013 18:08:37 +0100 Subject: [PATCH 003/114] made two private functions public, so that we can modify a TDS_2 --- Triangulation_2/include/CGAL/Triangulation_data_structure_2.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h index ee5831b3dbf..5d064f1515a 100644 --- a/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h @@ -301,7 +301,9 @@ public: Face_handle f1, Face_handle f2, Face_handle f3); + void set_adjacency(Face_handle f0, int i0, Face_handle f1, int i1) const; + void delete_face(Face_handle); void delete_vertex(Vertex_handle); @@ -342,10 +344,12 @@ public: // HELPING private: typedef std::pair Vh_pair; +public: void set_adjacency(Face_handle fh, int ih, std::map< Vh_pair, Edge>& edge_map); void reorient_faces(); +private: bool dim_down_precondition(Face_handle f, int i); public: From d17c5a763a1bf0cea221431e6d573978e26d86d9 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 6 Mar 2013 18:09:58 +0100 Subject: [PATCH 004/114] re-add and fix OFF-output; size_t and static_cast --- .../extract.cpp | 11 ++++++---- .../include/CGAL/AFSR_cell_base_3.h | 4 ++-- .../Advancing_front_surface_reconstruction.h | 10 ++++----- .../Advancing_front_surface_reconstruction.h | 22 +++++++------------ 4 files changed, 22 insertions(+), 25 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 2bf5dd81adc..4a58a06c27b 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -60,7 +60,7 @@ bool file_input(const Options& opt, std::vector& points) { const char* finput = opt.finname; - int number_of_points = opt.number_of_points; + std::size_t number_of_points = opt.number_of_points; bool xyz = opt.xyz; std::ios::openmode mode = (opt.binary) ? std::ios::binary : std::ios::in; @@ -78,17 +78,19 @@ file_input(const Options& opt, std::vector& points) else std::cout << "Input from file : " << finput << std::endl; - int n; + std::size_t n; if(! xyz){ is >> n; std::cout << " reading " << n << " points" << std::endl; points.reserve(n); - CGAL::copy_n(std::istream_iterator(is), n, std::back_inserter(points)); + CGAL::cpp11::copy_n(std::istream_iterator(is), n, std::back_inserter(points)); } else { // we do not know beforehand how many points we will read std::istream_iterator it(is), eof; + char ignore[256]; while(it!= eof){ points.push_back(*it); + is.getline(ignore,256); it++; } n = points.size(); @@ -478,7 +480,8 @@ int main(int argc, char* argv[]) std::cout << "Total time: " << timer.time() << " sec." << std::endl; - write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); + // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); + write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header); std::cout << " " << S.number_of_outliers() diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h index 7274c0263c1..e08b57c609c 100755 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h @@ -179,12 +179,12 @@ facet_number(int i) inline bool is_selected_facet(const int& i) { - return selected_facet & (1 << i); + return (selected_facet & (1 << i)) != 0; } inline bool has_facet_on_surface(const int& i) { - return selected_facet & (1 << i); + return (selected_facet & (1 << i)) != 0; } #ifdef AFSR_LAZY diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index b07feecc4ea..7137fe42a31 100755 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -238,7 +238,7 @@ public: : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), - NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), _vh_number(T.number_of_vertices()), _facet_number(0), + NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), _postprocessing_counter(0), _size_before_postprocessing(0), area(opt.area), perimeter(opt.perimeter), abs_area(opt.abs_area), abs_perimeter(opt.abs_perimeter), total_area(0), total_perimeter(0), _number_of_connected_components(0) @@ -321,7 +321,7 @@ public: int number_of_outliers() const { - return outliers.size(); + return static_cast(outliers.size()); } typedef typename std::list::const_iterator Outlier_iterator; @@ -1060,7 +1060,7 @@ public: void ordered_map_erase(const criteria& value, const IO_edge_type* pkey) { - int number_of_conflict = _ordered_border.count(value); + std::size_t number_of_conflict = _ordered_border.count(value); if (number_of_conflict == 1) { _ordered_border.erase(_ordered_border.find(value)); @@ -1073,7 +1073,7 @@ public: _ordered_border.find(value); // si ca foire jamais on peut s'areter des que l'elt // est trouve!!! - for(int jj=0; (jjsecond) == ((long) pkey)) { @@ -1908,7 +1908,7 @@ public: L_v.push_back(v_it); } - unsigned int itmp, L_v_size_mem; + std::size_t itmp, L_v_size_mem; L_v_size_mem = L_v.size(); if ((vh_on_border_inserted != 0)&& // pour ne post-traiter que les bords (L_v.size() < .1 * _size_before_postprocessing)) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h index 31cc943795b..9cd8e11558f 100755 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -59,9 +59,9 @@ write_to_file_medit(char* foutput, const Surface& S) CGAL::set_ascii_mode(os_faces); // af: what is the relationship to _vh_number in Extract_surface - int _vh_number = std::count_if(T.finite_vertices_begin(), - T.finite_vertices_end(), - Is_not_exterior()); + std::size_t _vh_number = std::count_if(T.finite_vertices_begin(), + T.finite_vertices_end(), + Is_not_exterior()); os_points << _vh_number << std::endl; @@ -147,9 +147,9 @@ write_to_file_gv(char* foutput, const Surface& S) CGAL::set_ascii_mode(os); - int _vh_number = std::count_if(T.finite_vertices_begin(), - T.finite_vertices_end(), - Is_not_exterior()); + std::size_t _vh_number = std::count_if(T.finite_vertices_begin(), + T.finite_vertices_end(), + Is_not_exterior()); // Header. os << "OFF" << std::endl << _vh_number << " " << S.number_of_facets() << " " << 0 << std::endl; @@ -186,10 +186,7 @@ write_to_file_gv(char* foutput, const Surface& S) os << 3 << " "; os << vertex_index_map[c->vertex(i1)] << " "; os << vertex_index_map[c->vertex(i2)] << " "; - os << vertex_index_map[c->vertex(i3)] << " "; - os << 0 << std::endl; // without color. - // os << 4 << drand48() << drand48() << drand48() << 1.0; // random - // color + os << vertex_index_map[c->vertex(i3)] << "\n"; } if (n->is_selected_facet(ni)) @@ -200,10 +197,7 @@ write_to_file_gv(char* foutput, const Surface& S) os << 3 << " "; os << vertex_index_map[n->vertex(i1)] << " "; os << vertex_index_map[n->vertex(i2)] << " "; - os << vertex_index_map[n->vertex(i3)] << " "; - os << 0 << std::endl; // without color. - // os << 4 << drand48() << drand48() << drand48() << 1.0; // random - // color + os << vertex_index_map[n->vertex(i3)] << "\n"; } } From 1ee52525ab686536eabc0731361d9762a54b2580 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 7 Mar 2013 17:44:31 +0100 Subject: [PATCH 005/114] No need for the hierarchy. Makes it simpler and faster --- .../extract.cpp | 152 +++++++----------- .../include/CGAL/AFSR_options.h | 44 +++-- .../include/CGAL/AFSR_vertex_base_with_id_3.h | 11 ++ .../Advancing_front_surface_reconstruction.h | 4 +- .../CGAL/Triangulation_data_structure_2.h | 4 +- 5 files changed, 95 insertions(+), 120 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 4a58a06c27b..55d44c3dd59 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -11,13 +11,13 @@ #include #include +#include // Kernel #include #include #include -#include #include #include @@ -37,17 +37,15 @@ typedef Kernel::Vector_3 Vector; typedef Kernel::Point_2 Point_2; typedef CGAL::AFSR_vertex_base_with_id_3 LVb; -typedef CGAL::Triangulation_hierarchy_vertex_base_3 HVb; typedef CGAL::Triangulation_cell_base_3 Cb; typedef CGAL::AFSR_cell_base_3 LCb; - -typedef CGAL::Triangulation_data_structure_3 Tds; +typedef CGAL::Triangulation_data_structure_3 Tds; -typedef CGAL::Delaunay_triangulation_3 Delaunay_Triangulation_3; -typedef CGAL::Triangulation_hierarchy_3 Triangulation_3; +typedef CGAL::Delaunay_triangulation_3 Triangulation_3; + typedef Triangulation_3::Vertex_handle Vertex_handle; typedef CGAL::Advancing_front_surface_reconstruction Surface; @@ -56,11 +54,19 @@ typedef CGAL::AFSR_options Options; //--------------------------------------------------------------------- +struct Auto_count : public std::unary_function >{ + mutable int i; + Auto_count() : i(0){} + std::pair operator()(const Point& p) const { + return std::make_pair(p,i++); + } +}; + + bool file_input(const Options& opt, std::vector& points) { const char* finput = opt.finname; - std::size_t number_of_points = opt.number_of_points; bool xyz = opt.xyz; std::ios::openmode mode = (opt.binary) ? std::ios::binary : std::ios::in; @@ -76,12 +82,12 @@ file_input(const Options& opt, std::vector& points) return false; } else - std::cout << "Input from file : " << finput << std::endl; + std::cerr << "Input from file : " << finput << std::endl; std::size_t n; if(! xyz){ is >> n; - std::cout << " reading " << n << " points" << std::endl; + std::cerr << " reading " << n << " points" << std::endl; points.reserve(n); CGAL::cpp11::copy_n(std::istream_iterator(is), n, std::back_inserter(points)); } else { @@ -90,22 +96,12 @@ file_input(const Options& opt, std::vector& points) char ignore[256]; while(it!= eof){ points.push_back(*it); - is.getline(ignore,256); + is.getline(ignore,256); // ignore what comes after 3 doubles in a line it++; } n = points.size(); } - - if ( (number_of_points > 0 ) && (number_of_points < n )) - { - points.erase(points.begin()+number_of_points, points.begin()+n); - - std::cout << std::endl - << " and randomize a sub-sample of " << number_of_points - << " points." << - std::endl << std::endl; - } return true; } @@ -117,12 +113,11 @@ void usage(char* program) << program << " - surface extension -" << std::endl << std::endl; std::cerr << std::endl << "OPTIONS" << std::endl - << " -shuffle : random shuffle" << std::endl << " -xyz : input data in xyz format" << std::endl << " -no_border -nb : " << std::endl << " -in fname : reads points from file ./fname" << std::endl << " -out fname : writes points to file ./fname" << std::endl - << " -out_format -of : choose file format for output (iv, wrl, oogl, medit," << std::endl + << " -out_format -of : choose file format for output (iv, wrl, off, medit," << std::endl << " ply, stl, all, none)" << std::endl << " -rgb r g b : color of the surface" << std::endl << " -no_header : The Vrml header and footer are not written" << std::endl @@ -130,8 +125,6 @@ void usage(char* program) << " -perimeter p : No faces larger than perimeter * average_perimeter" << std::endl << " -abs_area a : No faces larger than abs_area" << std::endl << " -abs_perimeter p : No faces with perimeter longer than abs_perimeter" << std::endl - << " -number_of_points n : set a number of points for a sub-sample" << std::endl - << "\n Options for internal use" << std::endl << " -sect_in fname : reads points from sections file ./fname" << std::endl @@ -156,51 +149,45 @@ parse(int argc, char* argv[], Options &opt) --argc; argv++; if(argc == 0) - std::cout << "nothing ???" << std::endl; + std::cerr << "nothing ???" << std::endl; while ((argc > 0) && (argv[0][0] == '-')){ if ((!std::strcmp(argv[0], "-D")) || (!std::strcmp(argv[0], "-Delaunay"))) { opt.Delaunay = true; argv++; argc--; - std::cout << "-D "; + std::cerr << "-D "; } else if ((!std::strcmp(argv[0], "-c")) || (!std::strcmp(argv[0], "-contours"))) { opt.contour = true; argv++; argc--; - std::cout << "-c "; - } - else if ((!std::strcmp(argv[0], "-s")) || (!std::strcmp(argv[0], "-shuffle"))) { - opt.shuffle = true; - argv++; - argc--; - std::cout << "-s "; + std::cerr << "-c "; } else if ((!std::strcmp(argv[0], "-b")) || (!std::strcmp(argv[0], "-binary"))) { opt.binary = true; argv++; argc--; - std::cout << "-b "; + std::cerr << "-b "; } else if ((!std::strcmp(argv[0], "-x")) || (!std::strcmp(argv[0], "-xyz"))) { opt.xyz = true; argv++; argc--; - std::cout << "-x "; + std::cerr << "-x "; } else if ((!std::strcmp(argv[0], "-nb")) || (!std::strcmp(argv[0], "-no_border"))) { opt.K = HUGE_VAL; opt.K_init = opt.K; argv++; argc--; - std::cout << "-nb "; + std::cerr << "-nb "; } else if ((!std::strcmp(argv[0], "-nh")) || (!std::strcmp(argv[0], "-no_header"))) { opt.no_header = true; argv++; argc--; - std::cout << "-nh "; + std::cerr << "-nh "; } else if ((!std::strcmp(argv[0], "-d")) || (!std::strcmp(argv[0], "-delta"))){ if (sscanf(argv[1], "%lf", &opt.delta) != 1) { @@ -209,7 +196,7 @@ parse(int argc, char* argv[], Options &opt) } argv += 2; argc -= 2; - std::cout << "-d " << opt.delta << " "; + std::cerr << "-d " << opt.delta << " "; } else if ((!std::strcmp(argv[0], "-a")) || (!std::strcmp(argv[0], "-area"))){ if (sscanf(argv[1], "%lf", &opt.area) != 1) { @@ -218,7 +205,7 @@ parse(int argc, char* argv[], Options &opt) } argv += 2; argc -= 2; - std::cout << "-a " << opt.area << " "; + std::cerr << "-a " << opt.area << " "; } else if ((!std::strcmp(argv[0], "-pe")) || (!std::strcmp(argv[0], "-perimeter"))){ if (sscanf(argv[1], "%lf", &opt.perimeter) != 1) { @@ -227,7 +214,7 @@ parse(int argc, char* argv[], Options &opt) } argv += 2; argc -= 2; - std::cout << "-perimeter " << opt.perimeter << " "; + std::cerr << "-perimeter " << opt.perimeter << " "; } else if ((!std::strcmp(argv[0], "-aa")) || (!std::strcmp(argv[0], "-abs_area"))){ if (sscanf(argv[1], "%lf", &opt.abs_area) != 1) { @@ -236,7 +223,7 @@ parse(int argc, char* argv[], Options &opt) } argv += 2; argc -= 2; - std::cout << "-abs_area " << opt.abs_area << " "; + std::cerr << "-abs_area " << opt.abs_area << " "; } else if ((!std::strcmp(argv[0], "-ae")) || (!std::strcmp(argv[0], "-abs_perimeter"))){ if (sscanf(argv[1], "%lf", &opt.abs_perimeter) != 1) { @@ -245,7 +232,7 @@ parse(int argc, char* argv[], Options &opt) } argv += 2; argc -= 2; - std::cout << "-abs_perimeter " << opt.abs_perimeter << " "; + std::cerr << "-abs_perimeter " << opt.abs_perimeter << " "; } else if ((!std::strcmp(argv[0], "-ki"))){ if ((sscanf(argv[1], "%lf", &opt.K_init) != 1)|| @@ -255,7 +242,7 @@ parse(int argc, char* argv[], Options &opt) } argv += 3; argc -= 3; - std::cout << "-ki " << opt.K_init << " " << opt.K << " "; + std::cerr << "-ki " << opt.K_init << " " << opt.K << " "; } else if ((!std::strcmp(argv[0], "-rgb"))){ if ((sscanf(argv[1], "%lf", &opt.red) != 1)|| @@ -266,7 +253,7 @@ parse(int argc, char* argv[], Options &opt) } argv += 4; argc -= 4; - std::cout << "-rgb " << opt.red << " " << opt.green << " " << opt.blue << " " ; + std::cerr << "-rgb " << opt.red << " " << opt.green << " " << opt.blue << " " ; } else if ((!std::strcmp(argv[0], "-ks"))){ if (sscanf(argv[1], "%lf", &opt.K_step) != 1) { @@ -275,7 +262,7 @@ parse(int argc, char* argv[], Options &opt) } argv += 2; argc -= 2; - std::cout << "-ks " << opt.K_step << " "; + std::cerr << "-ks " << opt.K_step << " "; } else if ((!std::strcmp(argv[0], "-k"))){ if (sscanf(argv[1], "%lf", &opt.K) != 1) { @@ -285,17 +272,8 @@ parse(int argc, char* argv[], Options &opt) opt.K_init = opt.K; argv += 2; argc -= 2; - std::cout << "-k " << opt.K_init << " "; + std::cerr << "-k " << opt.K_init << " "; } - else if ((!std::strcmp(argv[0], "-n")) || (!std::strcmp(argv[0], "-number_of_points"))){ - if (sscanf(argv[1], "%d", &opt.number_of_points) != 1) { - std::cerr << "Argument for the number of points must be a number" - << std::endl; - } - argv += 2; - argc -= 2; - std::cout << "-n " << opt.number_of_points << " "; - } else if ((!std::strcmp(argv[0], "-m")) || (!std::strcmp(argv[0], "-max_of_connected_components"))){ if (sscanf(argv[1], "%d", &opt.max_connected_comp) != 1) { std::cerr << "Argument for the number of connected components must be a number" @@ -310,7 +288,7 @@ parse(int argc, char* argv[], Options &opt) */ argv += 2; argc -= 2; - std::cout << "-m " << opt.max_connected_comp << " "; + std::cerr << "-m " << opt.max_connected_comp << " "; } else if ((!std::strcmp(argv[0], "-p")) || (!std::strcmp(argv[0], "-post"))){ if (sscanf(argv[1], "%d", &opt.NB_BORDER_MAX) != 1) { @@ -319,14 +297,14 @@ parse(int argc, char* argv[], Options &opt) } argv += 2; argc -= 2; - std::cout << "-p " << opt.NB_BORDER_MAX << " "; + std::cerr << "-p " << opt.NB_BORDER_MAX << " "; } else if ((!std::strcmp(argv[0], "-i")) || (!std::strcmp(argv[0], "-in"))) { std::strcpy(opt.finname, argv[1]); opt.file_input = true; argv += 2; argc -= 2; - std::cout << "-i " << opt.finname << " "; + std::cerr << "-i " << opt.finname << " "; } else if ((!std::strcmp(argv[0], "-s")) || (!std::strcmp(argv[0], "-sect_in"))) { std::strcpy(opt.finname, argv[1]); @@ -334,19 +312,19 @@ parse(int argc, char* argv[], Options &opt) opt.file_input = true; argv += 2; argc -= 2; - std::cout << "-s " << opt.finname << " "; + std::cerr << "-s " << opt.finname << " "; } else if ((!std::strcmp(argv[0], "-o")) || (!std::strcmp(argv[0], "-out"))) { std::strcpy(opt.foutname, argv[1]); opt.file_output = true; argv += 2; argc -= 2; - std::cout << "-o " << opt.foutname << " "; + std::cerr << "-o " << opt.foutname << " "; } else if ((!std::strcmp(argv[0], "-of")) || (!std::strcmp(argv[0], "-out_format"))) { if (!std::strcmp(argv[1], "wrl")) opt.out_format = 0; - else if (!std::strcmp(argv[1], "oogl")) + else if (!std::strcmp(argv[1], "off")) opt.out_format = 1; else if (!std::strcmp(argv[1], "medit")) opt.out_format = 2; @@ -361,9 +339,9 @@ parse(int argc, char* argv[], Options &opt) else if (!std::strcmp(argv[1], "none")) opt.out_format = -2; else - std::cout << "unrecognized file format." << std::endl; + std::cerr << "unrecognized file format." << std::endl; opt.file_output = true; - std::cout << "-of " << argv[1] << " "; + std::cerr << "-of " << argv[1] << " "; argv += 2; argc -= 2; } @@ -396,57 +374,44 @@ int main(int argc, char* argv[]) timer.start(); //parse command line Options opt; - std::cout << "Option line for this execution is :" << std::endl; + std::cerr << "Option line for this execution is :" << std::endl; if (!parse(argc, argv, opt)) exit(0); - std::cout << std::endl << std::endl; + std::cerr << std::endl << std::endl; - Triangulation_3 dt; - std::vector points; file_input(opt, points); - std::cout << "Time for reading " << timer.time() << " sec." << std::endl; + std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; - - std::vector index(points.size()); - for(int i = 0; i < points.size(); i++){ - index[i] = i; - } - if(opt.shuffle){ - std::cout << "Random shuffling" << std::endl; - std::random_shuffle(index.begin(), index.end()); - } - - std::cout << "Compute Delaunay Tetrahedrization " << std::endl; + std::cerr << "Compute Delaunay Tetrahedrization " << std::endl; CGAL::Timer t1; t1.start(); - for(int i =0; i < points.size(); i++){ - Vertex_handle vh = dt.insert(points[index[i]]); - vh->id() = index[i]; - } + Triangulation_3 dt( boost::make_transform_iterator(points.begin(),Auto_count()), + boost::make_transform_iterator(points.end(), Auto_count() ) ); t1.stop(); - std::cout << " Inserted " << dt.number_of_vertices() << " points, " + std::cerr << " Inserted " << dt.number_of_vertices() << " points, " << dt.number_of_cells() << " cells computed in " << t1.time() << " sec." << std::endl; if (dt.dimension() < 3) { - std::cout << "-- 2D sample of points ???" << std::endl; + std::cerr << "-- 2D sample of points ???" << std::endl; exit(0); } - index.clear(); points.clear(); { Surface S(dt, opt); const Surface::TDS_2& tds_2 = S.tds_2(); - + int count = 0; for(Surface::TDS_2::Face_iterator fit = tds_2.faces_begin(); fit != tds_2.faces_end(); ++fit){ + if( fit->is_on_surface()){ + count++; Surface::Facet facet = fit->facet(); Surface::Cell_handle ch = facet.first; int fi = facet.second; @@ -478,24 +443,25 @@ int main(int argc, char* argv[]) } + std::cerr << "count = " << count << std::endl; - std::cout << "Total time: " << timer.time() << " sec." << std::endl; + std::cerr << "Total time: " << timer.time() << " sec." << std::endl; // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header); - std::cout << " " << S.number_of_outliers() + std::cerr << " " << S.number_of_outliers() << " outliers." << std::endl; - std::cout << " Reconstructed surface: " << S.number_of_facets() << + std::cerr << " Reconstructed surface: " << S.number_of_facets() << " facets, " << S.number_of_vertices() << " vertices." << std::endl; - std::cout << " " << S.number_of_border_edges() << + std::cerr << " " << S.number_of_border_edges() << " border edges." << std::endl; - std::cout << " number of connected components <= " + std::cerr << " number of connected components <= " << (std::max)(1, S.number_of_connected_components()-1) << std::endl << std::endl; } total.stop(); - std::cout << "Total = " << total.time() << " sec." << std::endl; + std::cerr << "Total = " << total.time() << " sec." << std::endl; return 0; } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h index faa18effc01..3fda69a12c2 100755 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h @@ -8,8 +8,8 @@ class AFSR_options { public: AFSR_options() : file_input(true), file_output(false), - Delaunay(false), contour(false), shuffle(false), binary(false), xyz(false), - Section_file(false), number_of_points(-1), max_connected_comp(-1), + Delaunay(false), contour(false), binary(false), xyz(false), + Section_file(false), max_connected_comp(-1), delta(.86), K_init(1.1), K_step(.1), K(5), out_format(0), NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false), area(0), perimeter(0), abs_area(0), abs_perimeter(0) @@ -18,27 +18,25 @@ public: std::strcpy(foutname,"foutput"); } - char program[100]; - char finname[100]; - char foutname[100]; - bool file_input; - bool file_output; - bool Delaunay; - bool contour; - bool shuffle; - bool binary; - bool xyz; - bool Section_file; - int number_of_points; - int max_connected_comp; - double delta; - double K_init; - double K_step; - double K; - int out_format; - int NB_BORDER_MAX; - double red, green, blue; - bool no_header; + char program[100]; + char finname[100]; + char foutname[100]; + bool file_input; + bool file_output; + bool Delaunay; + bool contour; + bool binary; + bool xyz; + bool Section_file; + int max_connected_comp; + double delta; + double K_init; + double K_step; + double K; + int out_format; + int NB_BORDER_MAX; + double red, green, blue; + bool no_header; double area, perimeter, abs_area, abs_perimeter; }; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h index 81c60fce4cb..f5f279f7c35 100755 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h @@ -63,6 +63,8 @@ public: //-------------------- DATA MEMBERS --------------------------------- + typedef int Info; // so that we are a model of TriangulationVertexBaseWithInfo_3 + private: int _id; int _mark; @@ -232,6 +234,15 @@ public: return _id; } + int& info() + { + return _id; + } + + const int& info() const + { + return _id; + } inline void re_init() { if (_incident_border != NULL) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 7137fe42a31..66f7c3aa48d 100755 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -1368,7 +1368,7 @@ public: { ear1_valid = test_merge(ear1_e, result_ear1, v1, get_smallest_radius_delaunay_sphere(ear1_c, - ear1.second)); + ear1.second)) != 0; } if (is_border_ear2&&(e2.first < STANDBY_CANDIDATE)&& @@ -1377,7 +1377,7 @@ public: { ear2_valid = test_merge(ear2_e, result_ear2, v2, get_smallest_radius_delaunay_sphere(ear2_c, - ear2.second)); + ear2.second)) != 0; } if ((!ear1_valid)&&(!ear2_valid)) diff --git a/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h index 5d064f1515a..5a0ca860f1e 100644 --- a/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h @@ -2157,9 +2157,9 @@ reorient_faces() std::set oriented_set; std::stack st; Face_iterator fit = faces_begin(); - int nf = std::distance(faces_begin(),faces_end()); + std::ptrdiff_t nf = std::distance(faces_begin(),faces_end()); - while (static_cast(oriented_set.size()) != nf) { + while (oriented_set.size() != nf) { while ( oriented_set.find(fit) != oriented_set.end()){ ++fit; // find a germ for non oriented components } From bb56196953c72b672d2142c893786716086c981a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 8 Mar 2013 11:49:30 +0100 Subject: [PATCH 006/114] print the average spacing --- .../extract.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 55d44c3dd59..2591f405401 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -15,7 +15,7 @@ // Kernel #include - +#include #include #include @@ -382,7 +382,9 @@ int main(int argc, char* argv[]) std::vector points; file_input(opt, points); - + double avgsp = CGAL::compute_average_spacing(points.begin(), points.end(), 5); + std::cerr << "average spacing " << avgsp << std::endl; + std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; std::cerr << "Compute Delaunay Tetrahedrization " << std::endl; @@ -406,6 +408,9 @@ int main(int argc, char* argv[]) { Surface S(dt, opt); + +#if 0 + const Surface::TDS_2& tds_2 = S.tds_2(); int count = 0; for(Surface::TDS_2::Face_iterator fit = tds_2.faces_begin(); fit != tds_2.faces_end(); ++fit){ @@ -444,6 +449,8 @@ int main(int argc, char* argv[]) } std::cerr << "count = " << count << std::endl; +#endif + std::cerr << "Total time: " << timer.time() << " sec." << std::endl; // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); From 13e5aedb2aaf8e6b1477872925e681fd2b8f40db Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 12 Mar 2013 12:47:43 +0100 Subject: [PATCH 007/114] Add a routine to write index triples of the result --- .../extract.cpp | 9 ++-- .../Advancing_front_surface_reconstruction.h | 48 +++++++++++++++++++ 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 2591f405401..77eaeeea985 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -15,7 +15,6 @@ // Kernel #include -#include #include #include @@ -382,8 +381,6 @@ int main(int argc, char* argv[]) std::vector points; file_input(opt, points); - double avgsp = CGAL::compute_average_spacing(points.begin(), points.end(), 5); - std::cerr << "average spacing " << avgsp << std::endl; std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; @@ -454,8 +451,10 @@ int main(int argc, char* argv[]) std::cerr << "Total time: " << timer.time() << " sec." << std::endl; // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); - write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header); - + // write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header); + std::vector > triples; + write_triple_indices(std::back_inserter(triples), S); + std::cerr << triples.size() << std::endl; std::cerr << " " << S.number_of_outliers() << " outliers." << std::endl; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h index 9cd8e11558f..8943afce312 100755 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -204,6 +204,54 @@ write_to_file_gv(char* foutput, const Surface& S) std::cout << "-- oogl result written." << std::endl; } + +template +OutputIterator +write_triple_indices(OutputIterator out, const Surface& S) +{ + typedef typename Surface::Triangulation_3 Triangulation_3; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Vertex Vertex; + typedef typename Surface::Cell_handle Cell_handle; + Triangulation_3& T = S.triangulation(); + + + for(Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; + *out++ = CGAL::Triple(c->vertex(i1)->id(), + c->vertex(i2)->id(), + c->vertex(i3)->id()); + } + + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + + *out++ = CGAL::Triple(n->vertex(i1)->id(), + n->vertex(i2)->id(), + n->vertex(i3)->id()); + } + } + return out; +} + //--------------------------------------------------------------------- template void From 9510bb6cf5e1caf96e6c5d7a2f1489bab0897e7b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 12 Mar 2013 13:08:55 +0100 Subject: [PATCH 008/114] Add reconstruction_test --- .../extract.cpp | 80 +++++++------------ 1 file changed, 30 insertions(+), 50 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 77eaeeea985..9efb3c1cb5b 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -32,8 +32,6 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; -typedef Kernel::Vector_3 Vector; -typedef Kernel::Point_2 Point_2; typedef CGAL::AFSR_vertex_base_with_id_3 LVb; @@ -41,8 +39,6 @@ typedef CGAL::Triangulation_cell_base_3 Cb; typedef CGAL::AFSR_cell_base_3 LCb; typedef CGAL::Triangulation_data_structure_3 Tds; - - typedef CGAL::Delaunay_triangulation_3 Triangulation_3; typedef Triangulation_3::Vertex_handle Vertex_handle; @@ -364,6 +360,29 @@ parse(int argc, char* argv[], Options &opt) return true; } +template +void reconstruction_test(PointIterator point_begin, PointIterator + point_end, TripleOutputIterator out, bool filter_input_points=false, + double perimeter=0) +{ + Options opt; + opt.abs_perimeter = perimeter; + std::cerr << "Compute Delaunay Tetrahedrization " << std::endl; + CGAL::Timer t1; + t1.start(); + + Triangulation_3 dt( boost::make_transform_iterator(point_begin, Auto_count()), + boost::make_transform_iterator(point_end, Auto_count() ) ); + t1.stop(); + std::cerr << " Inserted " << dt.number_of_vertices() << " points, " + << dt.number_of_cells() << " cells computed in " + << t1.time() << " sec." << std::endl; + + Surface S(dt, opt); + + write_triple_indices(out, S); +} + //___________________________________________ int main(int argc, char* argv[]) @@ -383,7 +402,10 @@ int main(int argc, char* argv[]) file_input(opt, points); std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; - + std::vector > triples; + reconstruction_test(points.begin(), points.end(), std::back_inserter(triples)); + std::cerr << triples.size() << std::endl; +#if 0 std::cerr << "Compute Delaunay Tetrahedrization " << std::endl; CGAL::Timer t1; t1.start(); @@ -402,51 +424,8 @@ int main(int argc, char* argv[]) points.clear(); - { - Surface S(dt, opt); - - -#if 0 - - const Surface::TDS_2& tds_2 = S.tds_2(); - int count = 0; - for(Surface::TDS_2::Face_iterator fit = tds_2.faces_begin(); fit != tds_2.faces_end(); ++fit){ - - if( fit->is_on_surface()){ - count++; - Surface::Facet facet = fit->facet(); - Surface::Cell_handle ch = facet.first; - int fi = facet.second; - int i,j,k; - Surface::Vertex_handle vh3 = ch->vertex(Triangulation_3::vertex_triple_index(fi,0)); - for(i=0; i<3 ; i++){ - if(fit->vertex(i)->vertex_3()== vh3){ - break; - } - } - vh3 = ch->vertex(Triangulation_3::vertex_triple_index(fi,1)); - for(j=0; j<3; j++){ - if(fit->vertex(j)->vertex_3()== vh3){ - break; - } - } - vh3 = ch->vertex(Triangulation_3::vertex_triple_index(fi,2)); - for(k=0; k<3 ; k++){ - if (fit->vertex(k)->vertex_3()== vh3){ - break; - } - } - - if((i+j+k) != 3){ - std::cerr << "i = " << i << "; j = " << j << "; k = " << k << std::endl; - } - - } - - } - std::cerr << "count = " << count << std::endl; -#endif + Surface S(dt, opt); std::cerr << "Total time: " << timer.time() << " sec." << std::endl; @@ -465,7 +444,8 @@ int main(int argc, char* argv[]) std::cerr << " number of connected components <= " << (std::max)(1, S.number_of_connected_components()-1) << std::endl << std::endl; - } + +#endif total.stop(); std::cerr << "Total = " << total.time() << " sec." << std::endl; return 0; From 79fac9b3105279e17c8942a7af745c8642a9caec Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 12 Mar 2013 14:27:25 +0100 Subject: [PATCH 009/114] write out the triples --- .../extract.cpp | 23 +++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 9efb3c1cb5b..58512ce81f3 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -378,8 +378,19 @@ void reconstruction_test(PointIterator point_begin, PointIterator << dt.number_of_cells() << " cells computed in " << t1.time() << " sec." << std::endl; + t1.reset(); + t1.start(); Surface S(dt, opt); - + t1.stop(); + std::cerr << "Reconstruction takes " << t1.time() << " sec.\n"; + std::cerr << " " << S.number_of_outliers() << " outliers.\n"; + std::cerr << " Reconstructed surface: " << S.number_of_facets() << + " facets, " << S.number_of_vertices() << " vertices.\n"; + std::cerr << " " << S.number_of_border_edges() << + " border edges.\n"; + std::cerr << " number of connected components <= " + << (std::max)(1, S.number_of_connected_components()-1) + << std::endl; write_triple_indices(out, S); } @@ -404,7 +415,15 @@ int main(int argc, char* argv[]) std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; std::vector > triples; reconstruction_test(points.begin(), points.end(), std::back_inserter(triples)); - std::cerr << triples.size() << std::endl; + + + std::cout << triples.size() << std::endl; + for(int i = 0; i < triples.size(); ++i){ + std::cout << "3 " << triples[i].first << " " << triples[i].second << " " << triples[i].third << " " << std::endl; + } + + + #if 0 std::cerr << "Compute Delaunay Tetrahedrization " << std::endl; CGAL::Timer t1; From f76d13782b91e7b5a34d7dd95116a5b99d74ee0c Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 12 Mar 2013 18:35:42 +0100 Subject: [PATCH 010/114] switch back to main --- .../extract.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 58512ce81f3..71759c57a26 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -32,6 +32,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; +typedef Kernel::Vector_3 Vector; typedef CGAL::AFSR_vertex_base_with_id_3 LVb; @@ -412,6 +413,7 @@ int main(int argc, char* argv[]) file_input(opt, points); +#if 0 std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; std::vector > triples; reconstruction_test(points.begin(), points.end(), std::back_inserter(triples)); @@ -422,9 +424,8 @@ int main(int argc, char* argv[]) std::cout << "3 " << triples[i].first << " " << triples[i].second << " " << triples[i].third << " " << std::endl; } +#else - -#if 0 std::cerr << "Compute Delaunay Tetrahedrization " << std::endl; CGAL::Timer t1; t1.start(); @@ -446,13 +447,9 @@ int main(int argc, char* argv[]) Surface S(dt, opt); - std::cerr << "Total time: " << timer.time() << " sec." << std::endl; // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); - // write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header); - std::vector > triples; - write_triple_indices(std::back_inserter(triples), S); - std::cerr << triples.size() << std::endl; + write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header); std::cerr << " " << S.number_of_outliers() << " outliers." << std::endl; From ebeff549eb198a3efd33768ffc02a6cb82bc9976 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Mar 2013 12:22:38 +0100 Subject: [PATCH 011/114] allocate storage when generating the first face; cleanup --- .../demo/Polyhedron/Scene_polygon_soup_item.cpp | 14 ++++++++------ .../demo/Polyhedron/Scene_polygon_soup_item.h | 8 ++++---- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index 8ef721674d0..04604a5eb7c 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -546,17 +546,19 @@ Scene_polygon_soup_item::bbox() const { } void -Scene_polygon_soup_item::new_vertex(const double& x, - const double& y, - const double& z) +Scene_polygon_soup_item::new_vertex(double x, + double y, + double z) { + if(!soup) + soup = new Polygon_soup; soup->points.push_back(Point_3(x, y, z)); } void -Scene_polygon_soup_item::new_triangle(const std::size_t i, - const std::size_t j, - const std::size_t k) +Scene_polygon_soup_item::new_triangle(std::size_t i, + std::size_t j, + std::size_t k) { Polygon_soup::Polygon_3 new_polygon(3); new_polygon[0] = i; diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h index 648056d1e3f..62fe4139ff7 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.h @@ -34,10 +34,10 @@ public: bool isFinite() const { return true; } bool isEmpty() const; Bbox bbox() const; - - void new_vertex(const double&, const double&, const double&); - void new_triangle(const std::size_t, const std::size_t, const std::size_t); - + + void new_vertex(double, double, double); + void new_triangle(std::size_t, std::size_t, std::size_t); + public slots: void shuffle_orientations(); bool orient(); From d427177d3af1662d206f927fe51c2f8b65afb7ef Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 13 Mar 2013 12:24:11 +0100 Subject: [PATCH 012/114] add a plugin for the advancing front reconstruction --- .../extract.cpp | 6 +- .../Advancing_front_surface_reconstruction.h | 12 +- Polyhedron/demo/Polyhedron/CMakeLists.txt | 6 +- ...Polyhedron_demo_advancing_front_plugin.cpp | 121 ++++++++++++++++++ .../Polyhedron_demo_advancing_front_plugin.ui | 113 ++++++++++++++++ 5 files changed, 246 insertions(+), 12 deletions(-) create mode 100755 Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp create mode 100755 Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 71759c57a26..7284f0a4dae 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -2,14 +2,10 @@ #define BLIND -#include #include #include #include -#include -#include #include -#include #include @@ -415,7 +411,7 @@ int main(int argc, char* argv[]) #if 0 std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; - std::vector > triples; + std::vector > triples; reconstruction_test(points.begin(), points.end(), std::back_inserter(triples)); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h index 8943afce312..4f9bc906e0e 100755 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -233,9 +233,9 @@ write_triple_indices(OutputIterator out, const Surface& S) i1 = (ci+1) & 3; i2 = (ci+2) & 3; i3 = (ci+3) & 3; - *out++ = CGAL::Triple(c->vertex(i1)->id(), - c->vertex(i2)->id(), - c->vertex(i3)->id()); + *out++ = CGAL::Triple(c->vertex(i1)->id(), + c->vertex(i2)->id(), + c->vertex(i3)->id()); } if (n->is_selected_facet(ni)) @@ -244,9 +244,9 @@ write_triple_indices(OutputIterator out, const Surface& S) i2 = (ni+2) & 3; i3 = (ni+3) & 3; - *out++ = CGAL::Triple(n->vertex(i1)->id(), - n->vertex(i2)->id(), - n->vertex(i3)->id()); + *out++ = CGAL::Triple(n->vertex(i1)->id(), + n->vertex(i2)->id(), + n->vertex(i3)->id()); } } return out; diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index f9f4cd29ec7..a1a62564ca3 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -28,7 +28,7 @@ foreach(DEP_PKG AABB_tree STL_Extension GraphicsView Surface_mesher Filtered_ker endforeach() # Include this package's headers first -include_directories( BEFORE ./ ./include ../../include ./CGAL_demo) +include_directories( BEFORE ./ ./include ../../include ./CGAL_demo ../../../Advancing_front_surface_reconstruction/include) add_subdirectory( implicit_functions ) @@ -334,6 +334,10 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) polyhedron_demo_plugin(pca_plugin Polyhedron_demo_pca_plugin) target_link_libraries(pca_plugin scene_polyhedron_item scene_basic_objects) + qt4_wrap_ui( advancing_frontUI_FILES Polyhedron_demo_advancing_front_plugin.ui) + polyhedron_demo_plugin(advancing_front_plugin Polyhedron_demo_advancing_front_plugin Polyhedron_demo_advancing_front_plugin_impl.cpp ${advancing_frontUI_FILES}) + target_link_libraries(advancing_front_plugin scene_polygon_soup_item scene_points_with_normal_item) + if(EIGEN3_FOUND OR TAUCS_FOUND) polyhedron_demo_plugin(parameterization_plugin Polyhedron_demo_parameterization_plugin) target_link_libraries(parameterization_plugin scene_polyhedron_item scene_textured_polyhedron_item ) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp new file mode 100755 index 00000000000..d51aee9cd90 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp @@ -0,0 +1,121 @@ +#include "config.h" +#include "Scene_points_with_normal_item.h" +#include "Polyhedron_demo_plugin_helper.h" +#include "Polyhedron_demo_plugin_interface.h" +#include + + +#include +#include +#include +#include +#include +#include + +#include "ui_Polyhedron_demo_advancing_front_plugin.h" + +// Poisson reconstruction method: +// Reconstructs a surface mesh from a point set and writes facet indices into polygon soup. +void advancing_front_reconstruct(const Point_set& points, + double sm_perimeter, + double sm_area, + Scene_polygon_soup_item*); + +class Polyhedron_demo_advancing_front_plugin : + public QObject, + public Polyhedron_demo_plugin_helper +{ + Q_OBJECT + Q_INTERFACES(Polyhedron_demo_plugin_interface) + QAction* actionAdvancingFrontReconstruction; + +public: + void init(QMainWindow* mainWindow, Scene_interface* scene_interface) { + + actionAdvancingFrontReconstruction = new QAction(tr("Advancing Front reconstruction"), mainWindow); + actionAdvancingFrontReconstruction->setObjectName("actionAdvancingFrontReconstruction"); + + Polyhedron_demo_plugin_helper::init(mainWindow, scene_interface); + } + + //! Applicate for Point_sets with normals. + bool applicable() const { + return qobject_cast(scene->item(scene->mainSelectionIndex())); + } + + QList actions() const { + return QList() << actionAdvancingFrontReconstruction; + } + +public slots: + void on_actionAdvancingFrontReconstruction_triggered(); +}; // end class Polyhedron_demo_advancing_front_plugin + + +class Polyhedron_demo_advancing_front_plugin_dialog : public QDialog, private Ui::AdvancingFrontDialog +{ + Q_OBJECT + public: + Polyhedron_demo_advancing_front_plugin_dialog(QWidget* /*parent*/ = 0) + { + setupUi(this); + + } + + double trianglePerimeter() const { return m_inputPerimeter->value(); } + double triangleArea() const { return m_inputArea->value(); } +}; + +void Polyhedron_demo_advancing_front_plugin::on_actionAdvancingFrontReconstruction_triggered() +{ + const Scene_interface::Item_id index = scene->mainSelectionIndex(); + + Scene_points_with_normal_item* point_set_item = + qobject_cast(scene->item(index)); + + if(point_set_item) + { + // Gets point set + Point_set* points = point_set_item->point_set(); + if(!points) return; + + // Gets options + Polyhedron_demo_advancing_front_plugin_dialog dialog; + if(!dialog.exec()) + return; + const double sm_perimeter = dialog.trianglePerimeter(); + const double sm_area = dialog.triangleArea(); + + + QApplication::setOverrideCursor(Qt::WaitCursor); + + // Add polyhedron to scene + Scene_polygon_soup_item* new_item = new Scene_polygon_soup_item(); + + for(Point_set::iterator it = points->begin(); it!= points->end(); ++it){ + new_item->new_vertex(it->x(), it->y(), it->z()); + } + + // Reconstruct point set as a polyhedron + advancing_front_reconstruct(*points, sm_perimeter, sm_area, new_item); + + + new_item->setName(tr("%1 Advancing Front (%2 %3)") + .arg(point_set_item->name()) + .arg(sm_perimeter) + .arg(sm_area)); + new_item->setColor(Qt::lightGray); + scene->addItem(new_item); + + // Hide point set + point_set_item->setVisible(false); + scene->itemChanged(index); + + + QApplication::restoreOverrideCursor(); + } +} + +Q_EXPORT_PLUGIN2(Polyhedron_demo_advancing_front_plugin, Polyhedron_demo_advancing_front_plugin) + +#include "Polyhedron_demo_advancing_front_plugin.moc" diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui new file mode 100755 index 00000000000..b66834514ab --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui @@ -0,0 +1,113 @@ + + + AdvancingFrontDialog + + + + 0 + 0 + 376 + 170 + + + + Advancing front reconstruction + + + + + + Min triangle perimeter: + + + + + + + * average spacing + + + 0.000000000000000 + + + 30.000000000000000 + + + 0.000000000000000 + + + + + + + Max triangle area: + + + + + + + * average spacing^2 + + + 0 + + + 0.000000000000000 + + + 20.000000000000000 + + + 1.000000000000000 + + + 0.000000000000000 + + + + + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + buttonBox + accepted() + AdvancingFrontDialog + accept() + + + 177 + 123 + + + 53 + 125 + + + + + buttonBox + rejected() + AdvancingFrontDialog + reject() + + + 257 + 119 + + + 257 + 143 + + + + + From afbc49226446cd930765c6d0d88f7192154bccd2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 6 Mar 2013 18:23:03 +0100 Subject: [PATCH 013/114] bugfix: missing connection of delete/reset for point set selection These actions can be done thanks to the context menu --- ...n_demo_point_set_simplification_plugin.cpp | 4 +- .../Scene_points_with_normal_item.cpp | 38 +++++++++++++++++++ .../Scene_points_with_normal_item.h | 18 ++++++--- 3 files changed, 53 insertions(+), 7 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp index 76104db70bb..6accc0716df 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_point_set_simplification_plugin.cpp @@ -131,8 +131,8 @@ void Polyhedron_demo_point_set_simplification_plugin::on_actionSimplify_triggere if (nb_points_to_remove > 0) { QMessageBox::information(NULL, - tr("Points selected from removal"), - tr("%1 point(s) are selected for removal.\nYou may remove them with the \"Delete selection\" menu item.") + tr("Points selected for removal"), + tr("%1 point(s) are selected for removal.\nYou may delete or reset the selection using the item context menu.") .arg(nb_points_to_remove)); } } diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index e3837b56f56..42a7488602f 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -13,6 +13,7 @@ #include #include +#include #include #include @@ -85,6 +86,7 @@ void Scene_points_with_normal_item::deleteSelection() std::cerr << "done: " << task_timer.time() << " seconds, " << (memory>>20) << " Mb allocated" << std::endl; + emit itemChanged(); } // Reset selection mark @@ -92,6 +94,7 @@ void Scene_points_with_normal_item::resetSelection() { // Un-select all points m_points->select(m_points->begin(), m_points->end(), false); + emit itemChanged(); } // Loads point set from .OFF file @@ -245,6 +248,41 @@ void Scene_points_with_normal_item::computes_local_spacing(int k) m_points->set_radii_uptodate(true); } +QMenu* Scene_points_with_normal_item::contextMenu() +{ + const char* prop_name = "Menu modified by Scene_points_with_normal_item."; + + QMenu* menu = Scene_item::contextMenu(); + + // Use dynamic properties: + // http://doc.trolltech.com/lastest/qobject.html#property + bool menuChanged = menu->property(prop_name).toBool(); + + if(!menuChanged) { + actionDeleteSelection = menu->addAction(tr("Delete Selection")); + actionDeleteSelection->setObjectName("actionDeleteSelection"); + connect(actionDeleteSelection, SIGNAL(triggered()),this, SLOT(deleteSelection())); + + actionResetSelection = menu->addAction(tr("Reset Selection")); + actionResetSelection->setObjectName("actionResetSelection"); + connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection())); + menu->setProperty(prop_name, true); + } + + if (isSelectionEmpty()) + { + actionDeleteSelection->setDisabled(true); + actionResetSelection->setDisabled(true); + } + else + { + actionDeleteSelection->setDisabled(false); + actionResetSelection->setDisabled(false); + } + + return menu; +} + void Scene_points_with_normal_item::setRenderingMode(RenderingMode m) { Scene_item_with_display_list::setRenderingMode(m); diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h index 1e6239aca88..f8dbc6b4b07 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h @@ -14,6 +14,8 @@ typedef Point_set_3 Point_set; typedef Point_set::UI_point UI_point; // type of points in Point_set_3 +class QMenu; +class QAction; // This class represents a point set in the OpenGL scene class SCENE_POINTS_WITH_NORMAL_ITEM_EXPORT Scene_points_with_normal_item @@ -30,10 +32,9 @@ public: // Is selection empty? virtual bool isSelectionEmpty() const; - // Delete selection - virtual void deleteSelection(); - // Reset selection mark - void resetSelection(); + + // Function to override the context menu + QMenu* contextMenu(); // IO bool read_off_point_set(std::istream& in); @@ -66,10 +67,17 @@ public: // computes the local point spacing (aka radius) of each point void computes_local_spacing(int k); +public slots: + // Delete selection + virtual void deleteSelection(); + // Reset selection mark + void resetSelection(); + // Data private: Point_set* m_points; - + QAction* actionDeleteSelection; + QAction* actionResetSelection; }; // end class Scene_points_with_normal_item From dac79ec1d467eb64e8249d6af808af66621077d4 Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Wed, 13 Mar 2013 14:34:19 +0100 Subject: [PATCH 014/114] Optimise the drawing of Scene_polyhedron_item when only one color is used (cherry picked from commit 187e826d90fe37345291db0ba8a045b9bace8742) --- Polyhedron/demo/Polyhedron/include/CGAL/gl_render.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/include/CGAL/gl_render.h b/Polyhedron/demo/Polyhedron/include/CGAL/gl_render.h index 225a8ea71ed..2697095fe70 100644 --- a/Polyhedron/demo/Polyhedron/include/CGAL/gl_render.h +++ b/Polyhedron/demo/Polyhedron/include/CGAL/gl_render.h @@ -35,12 +35,18 @@ void gl_render_facets(Polyhedron& polyhedron, const std::vector& colors) GLint shading; ::glGetIntegerv(GL_SHADE_MODEL, &shading); + int patch_id = 0; + Facet_iterator f; for(f = polyhedron.facets_begin(); f != polyhedron.facets_end(); f++) { - CGALglcolor(colors[f->patch_id()]); + const int this_patch_id = f->patch_id(); + if(patch_id != this_patch_id) { + CGALglcolor(colors[this_patch_id]); + patch_id = this_patch_id; + } ::glBegin(GL_POLYGON); // If Flat shading: 1 normal per polygon From 7b70385147efd6535bed45f0a48eb7c89ba0e44a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Wed, 6 Mar 2013 18:41:01 +0100 Subject: [PATCH 015/114] add an option to switch the two-pass on (cherry picked from commit a9a49ffabdbcc893025374f8b796d710c69d00bd) --- Installation/changes.html | 3 ++- .../Polyhedron/Polyhedron_demo_poisson_plugin.cpp | 7 +++++-- .../Polyhedron/Polyhedron_demo_poisson_plugin.ui | 13 ++++++++++--- .../Polyhedron_demo_poisson_plugin_impl.cpp | 9 +++++---- 4 files changed, 22 insertions(+), 10 deletions(-) diff --git a/Installation/changes.html b/Installation/changes.html index b91a3ff7edf..7f80f522e3e 100755 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -196,7 +196,8 @@ David A. Wheeler's 'SLOCCount', restricted to the include/CGAL/

Surface Reconstruction from Point Sets

  • Performance improvements and addition of an option to better - reconstruct undersampled zones. + reconstruct undersampled zones. The poisson reconstruction plugin + has an option to switch it on.

2D Voronoi Diagram Adaptor

diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp index 66466a59d88..4dff15b0416 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.cpp @@ -19,7 +19,8 @@ Polyhedron* poisson_reconstruct(const Point_set& points, Kernel::FT sm_angle, // Min triangle angle (degrees). Kernel::FT sm_radius, // Max triangle size w.r.t. point set average spacing. Kernel::FT sm_distance, // Approximation error w.r.t. point set average spacing. - const QString& solver); // solver name + const QString& solver, // solver name + bool use_two_passes); class Polyhedron_demo_poisson_plugin : public QObject, @@ -73,6 +74,7 @@ class Polyhedron_demo_poisson_plugin_dialog : public QDialog, private Ui::Poisso double triangleAngle() const { return m_inputAngle->value(); } double triangleRadius() const { return m_inputRadius->value(); } double triangleError() const { return m_inputDistance->value(); } + bool use_two_passes() const { return m_inputTwoPasses->isChecked(); } QString solver() const { return m_inputSolver->currentText(); } }; @@ -97,11 +99,12 @@ void Polyhedron_demo_poisson_plugin::on_actionPoissonReconstruction_triggered() const double sm_radius = dialog.triangleRadius(); const double sm_distance = dialog.triangleError(); const QString sm_solver = dialog.solver(); + bool use_two_passes = dialog.use_two_passes(); QApplication::setOverrideCursor(Qt::WaitCursor); // Reconstruct point set as a polyhedron - Polyhedron* pRemesh = poisson_reconstruct(*points, sm_angle, sm_radius, sm_distance, sm_solver); + Polyhedron* pRemesh = poisson_reconstruct(*points, sm_angle, sm_radius, sm_distance, sm_solver, use_two_passes); if(pRemesh) { // Add polyhedron to scene diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.ui b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.ui index 3682ceb5131..1e736e3adaf 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.ui +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin.ui @@ -6,8 +6,8 @@ 0 0 - 376 - 170 + 390 + 312 @@ -109,13 +109,20 @@ - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + Uses two passes + + + diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin_impl.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin_impl.cpp index 06468f5f197..e9fc508a481 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin_impl.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_poisson_plugin_impl.cpp @@ -50,7 +50,8 @@ Polyhedron* poisson_reconstruct(const Point_set& points, Kernel::FT sm_angle, // Min triangle angle (degrees). Kernel::FT sm_radius, // Max triangle size w.r.t. point set average spacing. Kernel::FT sm_distance, // Approximation error w.r.t. point set average spacing. - const QString& solver_name) // solver name + const QString& solver_name, + bool use_two_passes) // solver name { CGAL::Timer task_timer; task_timer.start(); @@ -107,7 +108,7 @@ Polyhedron* poisson_reconstruct(const Point_set& points, unlink("taucs-ooc.0"); // make sure TAUCS ooc file does not exist CGAL::Taucs_symmetric_solver_traits solver(OOC_SUPERNODAL_CHOLESKY_FACTORIZATION); - ok = function.compute_implicit_function(solver); + ok = function.compute_implicit_function(solver, use_two_passes); } #endif @@ -115,14 +116,14 @@ Polyhedron* poisson_reconstruct(const Point_set& points, if(solver_name=="Eigen - built-in simplicial LDLt") { CGAL::Eigen_solver_traits::EigenType> > solver; - ok = function.compute_implicit_function(solver); + ok = function.compute_implicit_function(solver, use_two_passes); } if(solver_name=="Eigen - built-in CG") { CGAL::Eigen_solver_traits::EigenType> > solver; solver.solver().setTolerance(1e-6); solver.solver().setMaxIterations(1000); - ok = function.compute_implicit_function(solver); + ok = function.compute_implicit_function(solver, use_two_passes); } #endif From 1d1dabf516d16b8ebf2237e21d64a7c5873f5f43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Apr 2013 11:47:01 +0200 Subject: [PATCH 016/114] remove executable property from include files --- .../include/CGAL/AFSR/Surface_face_base_2.h | 0 .../include/CGAL/AFSR/Surface_vertex_base_2.h | 0 .../include/CGAL/AFSR/construct_surface_2.h | 0 Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h | 0 .../include/CGAL/AFSR_cell_base_3.h | 0 .../include/CGAL/AFSR_options.h | 0 .../include/CGAL/AFSR_vertex_base_3.h | 0 .../include/CGAL/AFSR_vertex_base_with_id_3.h | 0 .../include/CGAL/Advancing_front_surface_reconstruction.h | 0 .../include/CGAL/IO/AFSR_vrml.h | 0 .../include/CGAL/IO/Advancing_front_surface_reconstruction.h | 0 Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h | 0 12 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h b/Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h old mode 100755 new mode 100644 From f3c1e0c9a0877ff182a6469b10f3f37af0367038 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Apr 2013 11:49:48 +0200 Subject: [PATCH 017/114] add layout for package info --- .../Advancing_front_surface_reconstruction/copyright | 1 + .../Advancing_front_surface_reconstruction/description.txt | 1 + .../Advancing_front_surface_reconstruction/license.txt | 1 + .../Advancing_front_surface_reconstruction/maintainer | 1 + 4 files changed, 4 insertions(+) create mode 100644 Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/copyright create mode 100644 Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/description.txt create mode 100644 Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/license.txt create mode 100644 Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/maintainer diff --git a/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/copyright b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/copyright new file mode 100644 index 00000000000..434d5723b62 --- /dev/null +++ b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/copyright @@ -0,0 +1 @@ +INRIA Sophia-Antipolis (France) diff --git a/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/description.txt b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/description.txt new file mode 100644 index 00000000000..0d961765618 --- /dev/null +++ b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/description.txt @@ -0,0 +1 @@ +Surface reconstruction using an advancing front method. diff --git a/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/license.txt b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/license.txt new file mode 100644 index 00000000000..8bb8efcb72b --- /dev/null +++ b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/license.txt @@ -0,0 +1 @@ +GPL (v3 or later) diff --git a/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/maintainer b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/maintainer new file mode 100644 index 00000000000..4f45ddcd216 --- /dev/null +++ b/Advancing_front_surface_reconstruction/package_info/Advancing_front_surface_reconstruction/maintainer @@ -0,0 +1 @@ +Andreas Fabri From 4a6bd62c924171de214b873e8bc11d6d139ba9d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Apr 2013 19:31:43 +0200 Subject: [PATCH 018/114] remove compilation errors and warnings when using g++ --- .../include/CGAL/AFSR/Surface_vertex_base_2.h | 2 +- .../include/CGAL/AFSR/construct_surface_2.h | 4 +-- .../include/CGAL/AFSR/orient.h | 2 +- .../include/CGAL/AFSR_cell_base_3.h | 28 ++++++++++--------- .../Advancing_front_surface_reconstruction.h | 15 +++++----- .../Advancing_front_surface_reconstruction.h | 10 ++++--- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h index d33628cf794..d274a07cef7 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h @@ -61,7 +61,7 @@ public: return _vertex; } - const Point& point() const { return vertex->point(); } + const Point& point() const { return _vertex->point(); } }; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h index 079cce8232c..b9384598472 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h @@ -43,7 +43,7 @@ construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstructionset_vertex(Triangulation::Vertex_handle(v_it)); + vh->set_vertex(typename Triangulation::Vertex_handle(v_it)); i++; } } @@ -105,7 +105,7 @@ construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstructionvertex(TDS::cw(ih)), fh->vertex(TDS::ccw(ih))); - fn->set_facet(std::make_pair(Triangulation::Cell_handle(),0)); + fn->set_facet(std::make_pair( typename Triangulation::Cell_handle(),0)); fn->set_is_on_surface(false); vinf->set_face(fn); tds.set_adjacency(fn, 0, fh, ih); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h index fe0e9f5938a..c74232afe88 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h @@ -117,4 +117,4 @@ orient(TDS& tds, const Advancing_front_surface_reconstruction #include #include +#include namespace CGAL { -class AFSR_options; - // This iterator allows to visit all contours. It has the particularity // that it visits the entry point of the contour twice. This allows to // detect that the traversal of the border is finished. One more increment @@ -238,22 +237,22 @@ public: : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), - NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), - _postprocessing_counter(0), _size_before_postprocessing(0), area(opt.area), perimeter(opt.perimeter), - abs_area(opt.abs_area), abs_perimeter(opt.abs_perimeter), - total_area(0), total_perimeter(0), _number_of_connected_components(0) + NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), area(opt.area), perimeter(opt.perimeter), + abs_area(opt.abs_area), abs_perimeter(opt.abs_perimeter), total_area(0), total_perimeter(0), + _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), + _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0) { bool re_init = false; do { _number_of_connected_components++; - if (re_init = init(re_init)) + if ( (re_init = init(re_init)) ) { std::cerr << "Growing connected component " << _number_of_connected_components << std::endl; extend(opt.K_init, opt.K_step, opt.K); - if ((number_of_facets() > T.number_of_vertices())&& + if ((number_of_facets() > static_cast(T.number_of_vertices()))&& (opt.NB_BORDER_MAX > 0)) // en principe 2*nb_sommets = nb_facettes: y a encore de la marge!!! { diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h index 4f9bc906e0e..0e5af821295 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -377,7 +377,7 @@ write_to_file_iv_border_edges(const Surface& S, std::ofstream& os) _vh_bord_count++; } - typedef const Point* Const_point_star; + typedef const typename Triangulation_3::Point* Const_point_star; std::vector points_tab(_vh_bord_count); for (typename std::map::iterator vh_it = _vh_vect.begin(); vh_it != _vh_vect.end(); vh_it++) @@ -455,7 +455,7 @@ write_to_file_iv_remaining_points(const Surface& S, std::ofstream& os) _vh_bord_count++; } - typedef const Point* Const_point_star; + typedef const typename Triangulation_3::Point* Const_point_star; std::vector points_tab(_vh_bord_count); for (typename std::map::iterator vh_it = _vh_vect.begin(); vh_it != _vh_vect.end(); vh_it++) @@ -521,7 +521,7 @@ write_to_file_iv_border_facets(const Surface& S, std::ofstream& os) _vh_bord_count++; } - typedef const Point* Const_point_star; + typedef const typename Triangulation_3::PoinPoint* Const_point_star; std::vector points_tab(_vh_bord_count); for (typename std::map::iterator vh_it = _vh_vect.begin(); vh_it != _vh_vect.end(); vh_it++) @@ -813,7 +813,7 @@ write_to_file_vrml2(char* foutput, const Surface& S, typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; typedef typename Surface::Vertex_handle Vertex_handle; typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation(); + //Triangulation_3& T = S.triangulation(); typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; @@ -891,6 +891,8 @@ write_to_file_stl(char* foutput, const Surface& S) typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; typedef typename Surface::Vertex_handle Vertex_handle; typedef typename Surface::Cell_handle Cell_handle; + typedef typename Triangulation_3::Point Point; + typedef typename CGAL::Kernel_traits::Kernel::Vector_3 Vector; Triangulation_3& T = S.triangulation(); From 2143378f58456e346230f911871ceed5e73ca054 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Apr 2013 19:33:47 +0200 Subject: [PATCH 019/114] remove a warning and simplify the implementation --- .../include/CGAL/Triangulation_data_structure_2.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h b/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h index 5a0ca860f1e..2150345458f 100644 --- a/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h +++ b/Triangulation_2/include/CGAL/Triangulation_data_structure_2.h @@ -2159,22 +2159,22 @@ reorient_faces() Face_iterator fit = faces_begin(); std::ptrdiff_t nf = std::distance(faces_begin(),faces_end()); - while (oriented_set.size() != nf) { - while ( oriented_set.find(fit) != oriented_set.end()){ + while (0 != nf) { + while ( !oriented_set.insert(fit).second ){ ++fit; // find a germ for non oriented components } // orient component - oriented_set.insert(fit); + --nf; st.push(fit); while ( ! st.empty()) { Face_handle fh = st.top(); st.pop(); for(int ih = 0 ; ih < 3 ; ++ih){ Face_handle fn = fh->neighbor(ih); - if (oriented_set.find(fn) == oriented_set.end()){ + if (oriented_set.insert(fn).second){ int in = fn->index(fh); if (fn->vertex(cw(in)) != fh->vertex(ccw(ih))) fn->reorient(); - oriented_set.insert(fn); + --nf; st.push(fn); } } From 17f17382ebc24c967e82ba95f1c557b1d1d7c070 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 28 Nov 2013 14:44:33 +0100 Subject: [PATCH 020/114] cleanup and add doxygen version of the manual --- ...Advancing_front_surface_reconstruction.txt | 36 +++++ .../Advancing_front_surface_reconstruction.h | 152 ++++++++++++++++++ ...front_surface_reconstruction_cell_base_3.h | 22 +++ ...ont_surface_reconstruction_vertex_base_3.h | 23 +++ .../PackageDescription.txt | 27 ++++ .../examples.txt | 4 + .../AFSR_cell_base_3.tex | 4 +- ...Advancing_front_surface_reconstruction.tex | 2 +- .../extract.cpp | 2 +- .../include/CGAL/AFSR/Surface_face_base_2.h | 1 - .../include/CGAL/AFSR/construct_surface_2.h | 2 +- .../Advancing_front_surface_reconstruction.h | 20 +++ Documentation/doc/packages.txt | 1 + 13 files changed, 290 insertions(+), 6 deletions(-) create mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt create mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h create mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h create mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h create mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt create mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt new file mode 100644 index 00000000000..cee26494920 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -0,0 +1,36 @@ + +namespace CGAL { +/*! + +\mainpage User Manual +\anchor Chapter_Advancing_Front_Surface_Reconstruction +\anchor I1ChapterAdvancingFrontSurfaceReconstruction +\cgalAutoToc +\author Tran Kai Frank Da and David Cohen-Steiner + +\image html afsr.png + +Assume we are given a set \f$ S\f$ of points in 3D and we'd like to + + +\section AFSR_Definitions Definitions + +We distinguish + +\section AFSR_Examples Examples + +\subsection AFSR_Example_function Example for Global Function + +The basic +\cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp} + + +\subsection AFSR_Example_class Example for Class + +A + +\cgalExample{Advancing_front_surface_reconstruction/reconstruction_class.cpp} + +*/ +} /* namespace CGAL */ + diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h new file mode 100644 index 00000000000..e06b4c26dd0 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -0,0 +1,152 @@ + +namespace CGAL { + +/*! +\ingroup PkgAdvancingFrontSurfaceReconstruction + +The class `Advancing_front_surface_reconstruction` + +\tparam Dt must be a `Delaunay_triangulation_3` with +`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` +blended into the vertex and cell type. + + +\cgalHeading{Implementation} + +The .. +*/ +template< typename Dt> +class Advancing_front_surface_reconstruction { +public: + +/// \name Types +/// @{ + +/*! + The type of the 2D triangulation data structure describing the reconstructed surface. + The type `TDS_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the + method `vertex_3()` that returns a `Triangulation_3::Vertex_handle` to the associated 3D vertex + The type `TDS_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the + method `facet()` that returns the associated `Triangulation_3::Facet`, and a method `bool is_on_surface()` + for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. + In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite + vertex of the 3D triangulation. +*/ + typedef Hidden_type TDS_2; + +/*! +The type of the 3D triangulation. + +*/ + typedef Dt Triangulation_3; + + +/*! + A bidirectional iterator which allows to enumerate all points that were removed + from the 3D Delaunay triangulation during the surface reconstruction. The value type + of the iterator is `Triangulation_3::Point_3`. +*/ +typedef Hidden_type Outlier_iterator; + +/*! + A forward iterator which allows to visit all boundaries. It + visits the entry point of each boundary twice. This allows to + detect that the traversal of a boundary is finished. One more increment + brings us to the vertex on the next boundary. + The value type of the iterator is `Triangulation_3::Vertex_handle`. +*/ +typedef Hidden_type Boundary_iterator; + + +/// @} + +/// \name Creation +/// @{ + +/*! +Initializes from a 3D Delaunay triangulation of a point set. +*/ +Advancing_front_surface_reconstruction(Dt& dt); + + +/// @} + +/// \name Operations +/// @{ + +/*! +calls the surface reconstruction function with the default parameters. +*/ + void operator()(); + +/*! +returns the reconstructed surface. +*/ +const TDS_2& +tds_2(); + +/*! +returns the underlying 3D Delaunay triangulation. +*/ +const Triangulation_3_& +triangulation_3(); + + + + +/*! +An iterator over the outliers. +*/ +Outlier_iterator outliers_begin(); + +/*! +Past-the-end iterator. +*/ +Outlier_iterator outliers_end(); + +/*! +An iterator over the boundary vertices. +*/ +Boundary_iterator boundary_begin(); + +/*! +Past-the-end iterator. +*/ +Boundary_iterator boundary_end(); + +/// @} + +/// \name Predicates +/// @{ + +/*! +returns `true` if the reconstructed surface has boundaries. +*/ +bool +has_boundaries() const; + + +/*! +returns `true` if the facet is on the surface. +*/ +bool +has_on_surface(Triangulation_3::Facet f) const; + +/*! +returns `true` if the facet f is on the surface. +*/ +bool +has_on_surface(TDS_2::Face_handle f2) const; + +/*! +returns `true` if the facet f is on the surface. +*/ +bool +has_on_surface(TDS_2::Vertex_handle v2) const; +/// @} + + + + +}; /* end Advancing_front_surface_reconstruction */ +} /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h new file mode 100644 index 00000000000..3b902c4e79d --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h @@ -0,0 +1,22 @@ + +namespace CGAL { + +/*! +\ingroup PkgAdvancingFrontSurfaceReconstruction + +The class `Advancing_front_surface_reconstruction_cell_base_3` is the default +cell type for the class `Advancing_front_surface_reconstruction`. + +\tparam Traits has to be a model of `DelaunayTriangulationTraits_3`. + +\tparam Cb has to be a model of `TriangulationCellBase_3`. + +*/ +template< typename Traits, typename Cb = Triangulation_cell_base_3 > +class Advancing_front_surface_reconstruction_cell_base_3 : public Cb { +public: + +/// @} + +}; /* end Advancing_front_surface_reconstruction_cell_base_3 */ +} /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h new file mode 100644 index 00000000000..49414059b97 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -0,0 +1,23 @@ + +namespace CGAL { + +/*! +\ingroup PkgAdvancingFrontSurfaceReconstruction + +The class `Advancing_front_surface_reconstruction_vertex_base_3` is the default +vertex type for the class `Advancing_front_surface_reconstruction`. + +\tparam Traits has to be a model of `DelaunayTriangulationTraits_3`. + +\tparam Vb has to be a model of `TriangulationVertexBase_3`. + + +*/ + template< typename Traits, typename Vb = Triangulation_vertex_base_3 > +class Advancing_front_surface_reconstruction_vertex_base_3 : public Vb { +public: + +/// @} + +}; /* end Advancing_front_surface_reconstruction_vertex_base_3 */ +} /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt new file mode 100644 index 00000000000..2f53214e304 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -0,0 +1,27 @@ +/// \defgroup PkgAdvancingFrontSurfaceReconstruction Advancing Front Surface Reconstruction Reference +/// \defgroup PkgAdvancingFrontSurfaceReconstructionConcepts Concepts +/// \ingroup PkgAdvancingFrontSurfaceReconstruction + +/*! +\addtogroup PkgAdvancingFrontSurfaceReconstruction + +\cgalPkgDescriptionBegin{Advancing Front Surface Reconstruction,PkgAdvancingFrontSurfaceReconstructionSummary} +\cgalPkgPicture{afsr-detail.png} +\cgalPkgSummaryBegin +\cgalPkgAuthors{Tran Kai Frank Da, David Cohen-Steiner} +\cgalPkgDesc{This package offers a surface reconstruction algorithm.} +\cgalPkgManuals{Chapter_Advancing_Front_Surface_Reconstruction,PkgAdvancingFrontSurfaceReconstruction} +\cgalPkgSummaryEnd +\cgalPkgShortInfoBegin +\cgalPkgSince{2.1} +\cgalPkgDependsOn{\ref PkgTriangulation3Summary} +\cgalPkgBib{cgal:dc-afsr} +\cgalPkgLicense{\ref licensesGPL "GPL"} +\cgalPkgShortInfoEnd +\cgalPkgDescriptionEnd + +This chapter presents a ... The description is based on +the articles \cite toto. + +*/ + diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt new file mode 100644 index 00000000000..2f14a4e739c --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt @@ -0,0 +1,4 @@ +/*! +\example Advancing_front_surface_reconstruction/reconstruction_fct.cpp +\example Advancing_front_surface_reconstruction/reconstruction_class.cpp +*/ diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex index b78473321b2..d7cc8686c18 100755 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex @@ -6,7 +6,7 @@ of the 3D Delaunay triagulation. It mainly provides storage and methods used by Advancing front surface reconstruction algorithm. -\ccInclude{CGAL/AFSR_cell_base_2.h} +\ccInclude{CGAL/AFSR_cell_base_3.h} \ccInheritsFrom @@ -23,7 +23,7 @@ Advancing front surface reconstruction algorithm. %\ccOperations -%\ccMemberFunction{bool has_facet_on_surface() const;}{Returns \ccc{true}, iff the facet is on the surface.} +%\ccMemberFunction{bool has_facet_on_surface(int i) const;}{Returns \ccc{true}, iff the facet is on the surface.} %\ccSeeAlso diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex index 16deda0cf40..6f405227aab 100755 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex +++ b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex @@ -30,7 +30,7 @@ or \ccc{CGAL::AFSR_vertex_base_with_id_3} and \ccc{CGAL::AFSR_cell_base_3} must \ccNestedType{Boundary_iterator}{This forward iterator allows to visit all contours. It visits the entry point of the contour twice. This allows to detect that the traversal of the border is finished. One more increment - brings us to the vertex on the next boundary. The value type of the iterator is \ccc{Triangulation_3::Vertex}.} + brings us to the vertex on the next boundary. The value type of the iterator is \ccc{Triangulation_3::Vertex_handle}.} \ccNestedType{Outlier_iterator}{This bidirectional iterator allows to enumerate all points that were removed from the 3D Delaunay triangulation during the surface reconstruction. The value type diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 7284f0a4dae..5543d0d0e41 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -409,7 +409,7 @@ int main(int argc, char* argv[]) file_input(opt, points); -#if 0 +#if 1 std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; std::vector > triples; reconstruction_test(points.begin(), points.end(), std::back_inserter(triples)); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h index 739dcd1261e..d59bf2048c6 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h @@ -72,7 +72,6 @@ public: void reorient() { - Fb::reorient(); if( is_on_surface()){ _facet = std::make_pair(_facet.first->neighbor(_facet.second), diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h index b9384598472..6ee1003ceb7 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h @@ -98,6 +98,7 @@ construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstructionset_vertex(T.infinite_vertex()); std::map inf_edge_map; while (!edge_map.empty()) { Face_handle fh = edge_map.begin()->second.first; @@ -115,7 +116,6 @@ construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction OutputIterator write_triple_indices(OutputIterator out, const Surface& S) { + std::cerr << "write triple indices" << std::endl; +#if 1 + typedef typename Surface::TDS_2 TDS_2; + typedef typename TDS_2::Face_iterator Face_iterator; + typedef typename Surface::Cell_handle Cell_handle; + + const TDS_2& tds = S.tds_2(); + + for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ + + if(fit->is_on_surface()){ + *out++ = CGAL::Triple(fit->vertex(0)->vertex_3()->id(), + fit->vertex(1)->vertex_3()->id(), + fit->vertex(2)->vertex_3()->id()); + } + } + return out; + +#else typedef typename Surface::Triangulation_3 Triangulation_3; typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; @@ -250,6 +269,7 @@ write_triple_indices(OutputIterator out, const Surface& S) } } return out; +#endif } //--------------------------------------------------------------------- diff --git a/Documentation/doc/packages.txt b/Documentation/doc/packages.txt index abd0419a096..186294d3654 100644 --- a/Documentation/doc/packages.txt +++ b/Documentation/doc/packages.txt @@ -90,6 +90,7 @@ h1 { \package_listing{Surface_reconstruction_points_3} \package_listing{Skin_surface_3} \package_listing{Mesh_3} +\package_listing{Advancing_front_surface_reconstruction} \section PartGeometryProcessing Geometry Processing From ce47c6e33118f55f5aaec5f29b177937b8e31d20 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 28 Nov 2013 15:16:20 +0100 Subject: [PATCH 021/114] Hook the Advancing Front Surface Reconstruction inot the manual --- .../Advancing_front_surface_reconstruction/Doxyfile.in | 9 +++++++++ .../Advancing_front_surface_reconstruction/dependencies | 9 +++++++++ Documentation/doc/Documentation/Doxyfile.in | 1 + Documentation/doc/Documentation/dependencies | 1 + 4 files changed, 20 insertions(+) create mode 100755 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in create mode 100755 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in new file mode 100755 index 00000000000..da8f676b361 --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in @@ -0,0 +1,9 @@ +@INCLUDE = ${CGAL_DOC_PACKAGE_DEFAULTS} + +PROJECT_NAME = "CGAL ${CGAL_CREATED_VERSION_NUM} - Advancing Front Surface Reconstruction" + + +INPUT = ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/ + + + diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies new file mode 100755 index 00000000000..160ff7cc8ce --- /dev/null +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies @@ -0,0 +1,9 @@ +Manual +Kernel_23 +STL_Extension +Algebraic_foundations +Circulator +Stream_support +Triangulation_2 +Triangulation_3 +Number_types diff --git a/Documentation/doc/Documentation/Doxyfile.in b/Documentation/doc/Documentation/Doxyfile.in index 7f312d0b9fb..1bf320f1c59 100644 --- a/Documentation/doc/Documentation/Doxyfile.in +++ b/Documentation/doc/Documentation/Doxyfile.in @@ -111,3 +111,4 @@ IMAGE_PATH = ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/fig \ ${CMAKE_SOURCE_DIR}/Surface_reconstruction_points_3/doc/Surface_reconstruction_points_3/fig \ ${CMAKE_SOURCE_DIR}/Stream_lines_2/doc/Stream_lines_2/fig \ ${CMAKE_SOURCE_DIR}/Stream_support/doc/Stream_support/fig \ + ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig \ diff --git a/Documentation/doc/Documentation/dependencies b/Documentation/doc/Documentation/dependencies index 0c39215e2e6..b50453f9f99 100644 --- a/Documentation/doc/Documentation/dependencies +++ b/Documentation/doc/Documentation/dependencies @@ -78,3 +78,4 @@ Surface_mesh_parameterization Surface_reconstruction_points_3 Stream_lines_2 Stream_support +Advancing_front_surface_reconstruction From a46452da00610541172fd3625f50a2454b3584fd Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 28 Nov 2013 16:11:03 +0100 Subject: [PATCH 022/114] synchronize manual and code --- .../Advancing_front_surface_reconstruction.h | 28 +++++++++++++++---- .../Advancing_front_surface_reconstruction.h | 14 +++++++++- 2 files changed, 36 insertions(+), 6 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index e06b4c26dd0..eff4710076e 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -25,9 +25,9 @@ public: /*! The type of the 2D triangulation data structure describing the reconstructed surface. The type `TDS_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the - method `vertex_3()` that returns a `Triangulation_3::Vertex_handle` to the associated 3D vertex + method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex The type `TDS_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the - method `facet()` that returns the associated `Triangulation_3::Facet`, and a method `bool is_on_surface()` + method `facet()` that returns the associated `Facet`, and a method `bool is_on_surface()` for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite vertex of the 3D triangulation. @@ -40,6 +40,24 @@ The type of the 3D triangulation. */ typedef Dt Triangulation_3; +/*! +The vertex handle type of the 3D triangulation. + +*/ + typedef typename Triangulation_3::Vertex_handle Vertex_handle; + +/*! +The cell handle type of the 3D triangulation. + +*/ + typedef typename Triangulation_3::Cell_handle Cell_handle; + +/*! +The facet type of the 3D triangulation. + +*/ + typedef typename Triangulation_3::Facet Facet; + /*! A bidirectional iterator which allows to enumerate all points that were removed @@ -107,12 +125,12 @@ Outlier_iterator outliers_end(); /*! An iterator over the boundary vertices. */ -Boundary_iterator boundary_begin(); +Boundary_iterator boundaries_begin(); /*! Past-the-end iterator. */ -Boundary_iterator boundary_end(); +Boundary_iterator boundaries_end(); /// @} @@ -130,7 +148,7 @@ has_boundaries() const; returns `true` if the facet is on the surface. */ bool -has_on_surface(Triangulation_3::Facet f) const; +has_on_surface(Facet f) const; /*! returns `true` if the facet f is on the surface. diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index af2a490c356..7ca257acb8f 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -285,11 +285,23 @@ public: return _tds_2; } - bool is_on_surface(const typename TDS_2::Vertex_handle vh) const + bool has_on_surface(typename TDS_2::Vertex_handle vh) const { return vh != _tds_2_inf; } + + bool has_on_surface(typename TDS_2::Face_handle fh) const + { + return fh->is_on_surface(); + } + + + bool has_on_surface(Facet fh) const + { + return fh.first->has_facet_on_surface(fh.second); + } + int number_of_connected_components() const From b9dca246d2069514d148953ac3dc27aa6d21bcb4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 28 Nov 2013 16:28:43 +0100 Subject: [PATCH 023/114] synchronize manual and code --- .../extract.cpp | 10 +++---- ...ront_surface_reconstruction_cell_base_3.h} | 22 +++++++------- ...nt_surface_reconstruction_vertex_base_3.h} | 30 +++++++++---------- 3 files changed, 31 insertions(+), 31 deletions(-) rename Advancing_front_surface_reconstruction/include/CGAL/{AFSR_cell_base_3.h => Advancing_front_surface_reconstruction_cell_base_3.h} (84%) rename Advancing_front_surface_reconstruction/include/CGAL/{AFSR_vertex_base_with_id_3.h => Advancing_front_surface_reconstruction_vertex_base_3.h} (89%) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 5543d0d0e41..2e26898da5d 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -14,9 +14,9 @@ #include #include -#include +#include #include -#include +#include #include #include #include @@ -30,10 +30,8 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; typedef Kernel::Vector_3 Vector; -typedef CGAL::AFSR_vertex_base_with_id_3 LVb; - -typedef CGAL::Triangulation_cell_base_3 Cb; -typedef CGAL::AFSR_cell_base_3 LCb; +typedef CGAL::Advancing_front_surface_reconstruction_vertex_base_3 LVb; +typedef CGAL::Advancing_front_surface_reconstruction_cell_base_3 LCb; typedef CGAL::Triangulation_data_structure_3 Tds; typedef CGAL::Delaunay_triangulation_3 Triangulation_3; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h similarity index 84% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h rename to Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h index 0c279cda67c..a86e1ae46d9 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_cell_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h @@ -1,17 +1,19 @@ -#ifndef CGAL_AFSR_CELL_BASE_3_H -#define CGAL_AFSR_CELL_BASE_3_H +#ifndef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_CELL_BASE_3_H +#define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_CELL_BASE_3_H + +#include namespace CGAL { -template < class CellBase > -class AFSR_cell_base_3 : public CellBase + template < class Kernel, class CellBase = Triangulation_cell_base_3 > +class Advancing_front_surface_reconstruction_cell_base_3 : public CellBase { public: template < typename TDS2 > struct Rebind_TDS { typedef typename CellBase::template Rebind_TDS::Other Cb2; - typedef AFSR_cell_base_3 Other; + typedef Advancing_front_surface_reconstruction_cell_base_3 Other; }; typedef typename CellBase::Vertex_handle Vertex_handle; @@ -39,7 +41,7 @@ private: public: - AFSR_cell_base_3() + Advancing_front_surface_reconstruction_cell_base_3() : CellBase(), _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY @@ -53,7 +55,7 @@ public: #endif } - AFSR_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) + Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) : CellBase( v0, v1, v2, v3), _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY @@ -67,7 +69,7 @@ public: #endif } - AFSR_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, + Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) : CellBase(v0, v1, v2, v3, n0, n1, n2, n3), @@ -85,7 +87,7 @@ public: //-------------------- DESTRUCTOR ----------------------------------- - inline ~AFSR_cell_base_3() + inline ~Advancing_front_surface_reconstruction_cell_base_3() { if (_smallest_radius_facet_tab != NULL) delete[] _smallest_radius_facet_tab; @@ -221,4 +223,4 @@ public: } // namespace CGAL -#endif // CGAL_AFSR_CELL_BASE_3_H +#endif // CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_CELL_BASE_3_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h similarity index 89% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h rename to Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index f5f279f7c35..5566700f504 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_with_id_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -1,5 +1,5 @@ -#ifndef CGAL_AFSR_VERTEX_BASE_WITH_ID_3_H -#define CGAL_AFSR_VERTEX_BASE_WITH_ID_3_H +#ifndef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_WITH_ID_3_H +#define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_WITH_ID_3_H #include @@ -15,14 +15,14 @@ namespace CGAL { template > -class AFSR_vertex_base_with_id_3 : public VertexBase +class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase { public: template < typename TDS2 > struct Rebind_TDS { typedef typename VertexBase::template Rebind_TDS::Other Vb2; - typedef AFSR_vertex_base_with_id_3 Other; + typedef Advancing_front_surface_reconstruction_vertex_base_3 Other; }; @@ -155,7 +155,7 @@ public: } - AFSR_vertex_base_with_id_3() + Advancing_front_surface_reconstruction_vertex_base_3() : VertexBase(), _mark(-1), _post_mark(-1), ie_first(interior_edges.end()), ie_last(interior_edges.end()), @@ -164,7 +164,7 @@ public: _incident_border = new_border(); } - AFSR_vertex_base_with_id_3(const Point & p) + Advancing_front_surface_reconstruction_vertex_base_3(const Point & p) : VertexBase(p), _mark(-1), _post_mark(-1), ie_first(interior_edges.end()), ie_last(interior_edges.end()), @@ -173,7 +173,7 @@ public: _incident_border = new_border(); } - AFSR_vertex_base_with_id_3(const Point & p, Cell_handle f) + Advancing_front_surface_reconstruction_vertex_base_3(const Point & p, Cell_handle f) : VertexBase(p, f), _mark(-1), _post_mark(-1), ie_first(interior_edges.end()), ie_last(interior_edges.end()), @@ -182,7 +182,7 @@ public: _incident_border = new_border(); } - AFSR_vertex_base_with_id_3(Cell_handle f) + Advancing_front_surface_reconstruction_vertex_base_3(Cell_handle f) : VertexBase(f), _mark(-1), _post_mark(-1), ie_first(interior_edges.end()), ie_last(interior_edges.end()), @@ -191,7 +191,7 @@ public: _incident_border = new_border(); } - AFSR_vertex_base_with_id_3(const AFSR_vertex_base_with_id_3& other) + Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other) : VertexBase(), _mark(-1), _post_mark(-1), ie_first(interior_edges.end()), ie_last(interior_edges.end()), @@ -201,7 +201,7 @@ public: } //-------------------- DESTRUCTOR ----------------------------------- - ~AFSR_vertex_base_with_id_3() + ~Advancing_front_surface_reconstruction_vertex_base_3() { if (_incident_border != NULL) { @@ -538,20 +538,20 @@ public: template -boost::object_pool::Next_border_elt> AFSR_vertex_base_with_id_3::nbe_pool; +boost::object_pool::Next_border_elt> Advancing_front_surface_reconstruction_vertex_base_3::nbe_pool; template -boost::object_pool::Intern_successors_type> AFSR_vertex_base_with_id_3::ist_pool; +boost::object_pool::Intern_successors_type> Advancing_front_surface_reconstruction_vertex_base_3::ist_pool; template -std::list::Vertex_handle> AFSR_vertex_base_with_id_3::interior_edges; +std::list::Vertex_handle> Advancing_front_surface_reconstruction_vertex_base_3::interior_edges; template -std::list::Incidence_request_elt> AFSR_vertex_base_with_id_3::incidence_requests; +std::list::Incidence_request_elt> Advancing_front_surface_reconstruction_vertex_base_3::incidence_requests; } // namespace CGAL -#endif // CGALAFSR_VERTEX_BASE_3_H +#endif // CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_3_H From 18a7c0d01aa45b77ba31e84b0818d6527985208a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 28 Nov 2013 19:23:15 +0100 Subject: [PATCH 024/114] Add global function and example --- .../CMakeLists.txt | 1 + .../extract.cpp | 4 --- .../reconstruction_fct.cpp | 36 +++++++++++++++++++ .../Advancing_front_surface_reconstruction.h | 12 +++++++ ...ont_surface_reconstruction_vertex_base_3.h | 1 + 5 files changed, 50 insertions(+), 4 deletions(-) create mode 100755 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt index 1ff756f5b94..70054a257b9 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt @@ -24,6 +24,7 @@ if ( CGAL_FOUND ) # include_directories (BEFORE ../../../../../trunk/Triangulation_2/include) create_single_source_cgal_program( "extract.cpp" ) + create_single_source_cgal_program( "reconstruction_fct.cpp" ) else() diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 2e26898da5d..a33dd694b47 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -14,9 +14,6 @@ #include #include -#include -#include -#include #include #include #include @@ -28,7 +25,6 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point; -typedef Kernel::Vector_3 Vector; typedef CGAL::Advancing_front_surface_reconstruction_vertex_base_3 LVb; typedef CGAL::Advancing_front_surface_reconstruction_cell_base_3 LCb; diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp new file mode 100755 index 00000000000..959a3640831 --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -0,0 +1,36 @@ + + +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point_3; +typedef std::vector V; + +typedef CGAL::Triple Facet; +typedef std::vector F; + +namespace std { +std::ostream& +operator<<(std::ostream& os, const Facet f) +{ + os << "3 " << f.first << " " << f.second << " " << f.third << std::endl; + return os; +} + +} + +int main() +{ + V points; + F facets; + + std::copy(std::istream_iterator(std::cin), std::istream_iterator(), std::back_inserter(points)); + CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), std::back_inserter(facets)); + std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n"; + std::copy(points.begin(), points.end(), std::ostream_iterator(std::cout, "\n")); + std::copy(facets.begin(), facets.end(), std::ostream_iterator(std::cout)); + return 0; +} diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 7ca257acb8f..3b83d9e86a8 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -12,6 +12,10 @@ #include #include #include + +#include +#include + #include #include #include @@ -1962,6 +1966,14 @@ public: }; // class Advancing_front_surface_reconstruction +template +IndexTripleIterator +advancing_front_surface_reconstruction(PointIterator b, PointIterator e, IndexTripleIterator out) +{ + return out; +} + + } // namespace CGAL #endif // CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index 5566700f504..64706bd045d 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -2,6 +2,7 @@ #define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_WITH_ID_3_H #include +#include #include From 7f1834c35255de7a56eb8211ec1d06281a8cd015 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 29 Nov 2013 14:46:13 +0100 Subject: [PATCH 025/114] Add simple example --- .../extract.cpp | 2 + .../reconstruction_fct.cpp | 35 ++++++++++----- .../include/CGAL/AFSR/construct_surface_2.h | 1 + .../include/CGAL/AFSR/write_triple_indices.h | 38 ++++++++++++++++ .../Advancing_front_surface_reconstruction.h | 44 ++++++++++++++----- ...front_surface_reconstruction_cell_base_3.h | 2 +- .../Advancing_front_surface_reconstruction.h | 4 +- 7 files changed, 101 insertions(+), 25 deletions(-) create mode 100755 Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index a33dd694b47..fcd71da2ace 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -16,8 +16,10 @@ #include #include +#include #include +#include diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index 959a3640831..ecc855a2b7e 100755 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -4,22 +4,22 @@ #include #include #include +#include typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; typedef std::vector V; -typedef CGAL::Triple Facet; +typedef CGAL::cpp11::tuple Facet; typedef std::vector F; namespace std { -std::ostream& -operator<<(std::ostream& os, const Facet f) -{ - os << "3 " << f.first << " " << f.second << " " << f.third << std::endl; - return os; -} - + std::ostream& + operator<<(std::ostream& os, const Facet& f) + { + os << "3 " << get<0>(f) << " " << get<1>(f) << " " << get<2>(f); + return os; + } } int main() @@ -27,10 +27,21 @@ int main() V points; F facets; - std::copy(std::istream_iterator(std::cin), std::istream_iterator(), std::back_inserter(points)); - CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), std::back_inserter(facets)); + std::copy(std::istream_iterator(std::cin), + std::istream_iterator(), + std::back_inserter(points)); + + CGAL::advancing_front_surface_reconstruction(points.begin(), + points.end(), + std::back_inserter(facets)); + std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n"; - std::copy(points.begin(), points.end(), std::ostream_iterator(std::cout, "\n")); - std::copy(facets.begin(), facets.end(), std::ostream_iterator(std::cout)); + std::copy(points.begin(), + points.end(), + std::ostream_iterator(std::cout, "\n")); + std::copy(facets.begin(), + facets.end(), + std::ostream_iterator(std::cout, "\n")); + return 0; } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h index 6ee1003ceb7..203e2aabc5f 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h @@ -1,4 +1,5 @@ #ifndef CGAL_AFSR_CONSTRUCT_SURFACE_2 +#define CGAL_AFSR_CONSTRUCT_SURFACE_2 namespace CGAL { diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h new file mode 100755 index 00000000000..333a1dd32bf --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h @@ -0,0 +1,38 @@ +#ifndef CGAL_AFSR_WRITE_TRIPLE_INDICES_H +#define CGAL_AFSR_WRITE_TRIPLE_INDICES_H + +#include + +namespace CGAL { + +template +class Advancing_front_surface_reconstruction; + + + + template +OutputIterator + write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S) +{ + typedef Advancing_front_surface_reconstruction Surface; + typedef typename Surface::TDS_2 TDS_2; + typedef typename TDS_2::Face_iterator Face_iterator; + typedef typename Surface::Cell_handle Cell_handle; + + const TDS_2& tds = S.tds_2(); + + for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ + + if(fit->is_on_surface()){ + *out++ = CGAL::cpp11::tuple(fit->vertex(0)->vertex_3()->id(), + fit->vertex(1)->vertex_3()->id(), + fit->vertex(2)->vertex_3()->id()); + } + } + return out; +} + +} + + +#endif diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 3b83d9e86a8..0a3fc353449 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -4,9 +4,10 @@ // In order to activate lazy evaluation: // #define LAZY -#include -#include -#include +#include +#include +#include + #include #include #include @@ -21,7 +22,7 @@ #include #include #include - +#include namespace CGAL { // This iterator allows to visit all contours. It has the particularity @@ -217,10 +218,6 @@ private: const double abs_perimeter; double total_area; double total_perimeter; - //--------------------------------------------------------------------- - - CGAL::Timer t1; - //--------------------------------------------------------------------- //Pour une visu correcte //pour retenir les facettes selectionnees @@ -237,7 +234,7 @@ private: int _number_of_connected_components; public: - Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt) + Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options()) : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), @@ -1528,7 +1525,6 @@ public: K = K_init; // valeur d'initialisation de K pour commencer prudemment... Vertex_handle v1, v2; - t1.start(); if (_ordered_border.empty()) return; do { @@ -1596,7 +1592,6 @@ public: // faire des betises auparavant... } while((!_ordered_border.empty())&&(K <= K_max)&&(min_K != HUGE_VAL)); - t1.stop(); #ifdef VERBOSE if ((min_K < HUGE_VAL)&&(!_ordered_border.empty())) { @@ -1966,10 +1961,37 @@ public: }; // class Advancing_front_surface_reconstruction +namespace AFSR { + + template +struct Auto_count : public std::unary_function >{ + mutable int i; + Auto_count() : i(0){} + std::pair operator()(const T& p) const { + return std::make_pair(p,i++); + } + }; +} + template IndexTripleIterator advancing_front_surface_reconstruction(PointIterator b, PointIterator e, IndexTripleIterator out) { + typedef Exact_predicates_inexact_constructions_kernel Kernel; + typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; + typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; + + typedef Triangulation_data_structure_3 Tds; + typedef Delaunay_triangulation_3 Triangulation_3; + + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Kernel::Point_3 Point_3; + + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), + boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + + Reconstruction R(dt); + write_triple_indices(out, R); return out; } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h index a86e1ae46d9..e79d316b74c 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h @@ -13,7 +13,7 @@ public: template < typename TDS2 > struct Rebind_TDS { typedef typename CellBase::template Rebind_TDS::Other Cb2; - typedef Advancing_front_surface_reconstruction_cell_base_3 Other; + typedef Advancing_front_surface_reconstruction_cell_base_3 Other; }; typedef typename CellBase::Vertex_handle Vertex_handle; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h index 4adca6f951a..6bd8ff5e70e 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -204,7 +204,7 @@ write_to_file_gv(char* foutput, const Surface& S) std::cout << "-- oogl result written." << std::endl; } - + /* template OutputIterator write_triple_indices(OutputIterator out, const Surface& S) @@ -271,6 +271,8 @@ write_triple_indices(OutputIterator out, const Surface& S) return out; #endif } +*/ + //--------------------------------------------------------------------- template From 5e2e4080034b9be11d4cd0d9d7e173220bd00b9f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 29 Nov 2013 16:03:56 +0100 Subject: [PATCH 026/114] Add an example that uses the reconstruction class --- .../CMakeLists.txt | 1 + .../reconstruction_class.cpp | 43 +++++++++++++++++++ .../reconstruction_fct.cpp | 6 +-- .../Advancing_front_surface_reconstruction.h | 21 +++++++-- 4 files changed, 64 insertions(+), 7 deletions(-) create mode 100755 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt index 70054a257b9..cfee6716cee 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt @@ -25,6 +25,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "extract.cpp" ) create_single_source_cgal_program( "reconstruction_fct.cpp" ) + create_single_source_cgal_program( "reconstruction_class.cpp" ) else() diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp new file mode 100755 index 00000000000..b25b6aff530 --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp @@ -0,0 +1,43 @@ +#include +#include +#include +#include +#include +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; +typedef Reconstruction::Triangulation_3 Triangulation_3; +typedef Reconstruction::TDS_2 TDS_2; +typedef K::Point_3 Point_3; + +int main() +{ + + std::istream_iterator begin(std::cin); + std::istream_iterator end; + + Triangulation_3 dt(begin,end); + + Reconstruction reconstruction(dt); + + reconstruction(); + + const TDS_2& tds = reconstruction.tds_2(); + + if(! reconstruction.has_boundaries()){ + for(TDS_2::Face_iterator fit = tds.faces_begin(); + fit != tds.faces_end(); + ++fit){ + Triangulation_3::Facet f = fit->facet(); + Triangulation_3::Cell_handle ch = f.first; + int ci = f.second; + for(int i = 0; i < 4; i++){ + if(ci != i){ + std:: cout << ch->vertex(i)->point() << " "; + } + } + std::cout << std::endl; + } + } + + return 0; +} diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index ecc855a2b7e..18b9a189c3e 100755 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -8,10 +8,8 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; -typedef std::vector V; typedef CGAL::cpp11::tuple Facet; -typedef std::vector F; namespace std { std::ostream& @@ -24,8 +22,8 @@ namespace std { int main() { - V points; - F facets; + std::vector points; + std::vector facets; std::copy(std::istream_iterator(std::cin), std::istream_iterator(), diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 0a3fc353449..a8534cd26d5 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -133,7 +133,8 @@ public: }; -template + template , Advancing_front_surface_reconstruction_cell_base_3 > > > class Advancing_front_surface_reconstruction { public: @@ -234,7 +235,7 @@ private: int _number_of_connected_components; public: - Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options()) + Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options()) : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), @@ -242,7 +243,13 @@ public: abs_area(opt.abs_area), abs_perimeter(opt.abs_perimeter), total_area(0), total_perimeter(0), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0) - { + + {} + + + void operator()(const AFSR_options& opt = AFSR_options()) + { + bool re_init = false; do { @@ -285,7 +292,15 @@ public: { return _tds_2; } + + bool + has_boundaries() const + { + return _tds_2_inf->vertex_3() == triangulation().infinite_vertex(); + } + + bool has_on_surface(typename TDS_2::Vertex_handle vh) const { return vh != _tds_2_inf; From 0976c34cf65c33b6c093766a179e5dda2eee0028 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 29 Nov 2013 16:23:06 +0100 Subject: [PATCH 027/114] Explain the examples --- .../Advancing_front_surface_reconstruction.txt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index cee26494920..d710eb31a2a 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -21,13 +21,23 @@ We distinguish \subsection AFSR_Example_function Example for Global Function -The basic +The global function `advancing_front_surface_reconstruction/reconstruction()` +takes an iterator range of points as input and writes for each face of the +reconstructed surface a triple of point indices into an output iterator. +In the example we write the surface in the OFF format to `std::cout`. + \cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp} \subsection AFSR_Example_class Example for Class -A +When using the class `Advancing_front_surface_reconstruction/reconstruction` +you can access a 2D triangulation data structure describing the surface. +You can explore the surface by going from faces to neighboring faces, +and you can also go to the underlying 3D Delaunay triangulation. + +In the example we write the surface in the STL (Stereo Lithography) format +to `std::cout`. \cgalExample{Advancing_front_surface_reconstruction/reconstruction_class.cpp} From ea6d94957789f460192d900027d2c098676c5cca Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 2 Dec 2013 15:36:33 +0100 Subject: [PATCH 028/114] wip on the user manual --- ...Advancing_front_surface_reconstruction.txt | 137 +++++++++++++++++- .../PackageDescription.txt | 9 +- .../fig/valid.png | Bin 0 -> 84499 bytes 3 files changed, 139 insertions(+), 7 deletions(-) create mode 100755 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index d710eb31a2a..19a86e3127b 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -10,18 +10,145 @@ namespace CGAL { \image html afsr.png -Assume we are given a set \f$ S\f$ of points in 3D and we'd like to +Surface reconstruction from an unstructured point set is to find +a surface that approximates these points. Several techniques have +been applied to this problem. Among them are variational +methods \cgalCite{}, tensor voting \cgalCite{}, implicit surface \cgalCite{}, +and Delaunay triangulations. + +For Delaunay based algorithms the output surface +usually is the union of some triangles selected in the Delaunay +triangulation of the input points. Such algorithms can be volume oriented +which output the boundary of selected tetrahedra, or surface +oriented, that is they explicitely select triangles. + +In most surface oriented Delaunay-based algorithms triangles are +selected independently, that is in parallel \cgalCite{}. + +The surface oriented Delaunay-based surface reconstruction algorithm +presented in this chapter selects triangles sequentially, that is by +using previous selected triangles to select a new one. It adds the +most *plausible* triangle first, and only adds triangles in a way +that the surface remains an orientable manifold. + +Two other examples of this greedy approach are the ball pivoting +algorithm and Boyer and Petitjean's algorithm \cgalCite{}. In both +algorithms a triangulated surface is incrementally grown starting from +a seed triangle. Ball pivoting is fast, but the quality of the +reconstruction depends on user defined parameters corresponding to the +sampling density. The Boyer Petitjean approach can handle non-uniform +sampling, but fails when near cocircular points are encountered, and +it does not provide any guarantee on the topology of the surface. + +In +the next sections we describe the algorithm in detail, and give +examples. -\section AFSR_Definitions Definitions +\section AFSR_Definitions The Algorithm + +\subsection AFSR_Topology Topological Constraints + +Any triangle \f$t\f$ considered as next potential candidate has to share an +edge \f$e\f$ with the boundary of the current reconstruction. Let \f$b\f$ +be the vertex of \f$t\f$ opposite to \f$e\f$. There are four +possible situations where \f$t\f$ may be added to the surface. +- extension, if \f$b\f$ is not yet on the surface. +- hole filling, if \f$b\f$ is on the boundary and both neighbors of \f$b\f$ on the boundary are on edge \f$e\f$. +- ear filling, if \f$b\f$ is on the boundary and one neighbor of \f$b\f$ on the boundary is on edge \f$e\f$. +- glueing, if \f$b\f$ is on the boundary and no neighbor of \f$b\f$ on the boundary is on edge \f$e\f$. + +\cgalFigureBegin{figAFSRvalid,valid.png} +Valid candidates. +\cgalFigureEnd + +While the first three operations would never induce a non-manifold edge or vertex, +we only can perform glueing, if triangle \f$t\f$ has a *twin* facet, that is a +triangle with an edge on the boundary and incident to \f$b\f$, and the +third vertex on edge \f$e\f$. + +We call a triangle on which the above operations can be applied *valid*. + +\subsection AFSR_Selection Selection Criteria + +Valid triangles for an edge on the boundary are compared through what +we call their *radius*. The radius of a triangle \f$t\f$ is the radius of +the smallest sphere passing through the vertices of \f$t\f$ and enclosing no +sample point. In other words, the radius \f$r_t\f$ is the distance +from any vertex of \f$t\f$ to the Voronoi edge dual to \f$t\f$. + +While the radius is a good criterion in the case of 2D smooth curve +reconstruction \cgalCite{}, we need another criterion for 3D surface +reconstruction, namely the dihedral angle between triangles on the +surface, that is the angle between the normals of the triangles. + +We denote by \f$ \beta_t\f$ the angle between the normal of a triangle +\f$ t\f$ incident on a boundary edge \f$ e \f$ and the normal of the +triangle on the surface incident to \f$ e \f$. + +The *candidate* triangle of an edge \f$ e \f$ is the triangle +with the smallest radius, that is valid for \f$ e \f$ +and that has \f$ \beta_t < \alpha_\mathrm{sliver} \f$. +There may be no such triangle. In the implementation +of the algorithm \f$ \alpha_\mathrm{sliver} = 5\pi/6 \f$. + + +We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if +\f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$ +\beta \f$ can be chosen by the user and is by default \f$ \pi/6\f$. + +\subsection AFSR_Algorithm The Algorithm + +The algorithm takes as input a reference to a Delaunay triangulation. + +The Delaunay triangle with the smallest radius is the starting point +for the greedy algorithm. The algorithm maintains a priority queue of +candidate triangles, that is of triangles incident to the boundary +edges. The priority is the plausibility. While this priority queue +is not empty, the algorithm adds the most plausible candidate into the +surface, and inserts new candidates into the priority queue in case +there are new boundary edges. + + +\subsection AFSR_Boundaries Dealing with Multiple Components, Boundaries and Sharp Edges + +By construction the output of the algorithm is a connected orientable +manifold with or without boundary. To cope with multiple components we +merely look for a new seed facet among facets disjoint from the +surface. In case of noisy data or outliers, the user has to filter out +small surface components. + +It is impossible to handle all kinds of boundaries and non uniform sampling +at the same time. A void can either be an undersampled zone of the surface, +or a hole. + +As we do not want the algorithm to rely on a uniformity condition on +the sampling it will fill holes cut off from "flat" regions of the +surface. However, in many cases a boundary component cannot be cloded +by adding a spanning disk such that the resulting disk is well +sampled. Typically, closing a boundary component due to a transversal +clipping of the operation, would yield large dihedral angles at +boundary edges. Moreover, if the boundary is sufficiently well +sampled, the radii of the two triangles incident on a boundary edge +would be very different. These heuristic facts can be used for +boundary detection. + +We discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$ +such that \f$ p(t) < 0\f$, and \f$ r_t > K r_{t'}\f$ where \f$ t'\f$ is +the triangle on the surface incident on \f$ e \f$. The parameter \f$ K \f$ +can be chosen by the user. + + +Note that this heuristic implies that +where the sampling is too sparse with respect to curvature, it must +be sufficiently uniform for our algorithm to work. -We distinguish \section AFSR_Examples Examples \subsection AFSR_Example_function Example for Global Function -The global function `advancing_front_surface_reconstruction/reconstruction()` +The global function `advancing_front_surface_reconstruction()` takes an iterator range of points as input and writes for each face of the reconstructed surface a triple of point indices into an output iterator. In the example we write the surface in the OFF format to `std::cout`. @@ -31,7 +158,7 @@ In the example we write the surface in the OFF format to `std::cout`. \subsection AFSR_Example_class Example for Class -When using the class `Advancing_front_surface_reconstruction/reconstruction` +When using the class `Advancing_front_surface_reconstruction` you can access a 2D triangulation data structure describing the surface. You can explore the surface by going from faces to neighboring faces, and you can also go to the underlying 3D Delaunay triangulation. diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt index 2f53214e304..6a71220a90e 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -20,8 +20,13 @@ \cgalPkgShortInfoEnd \cgalPkgDescriptionEnd -This chapter presents a ... The description is based on -the articles \cite toto. +This chapter presents a greedy algorithm for surface reconstruction from +unorganized point sets. Starting from a seed facet, a piecewise linear +surface is grown by adding Delaunay triangles one by one. The most +plausible triangles are added first, in a way that avoids the appearance +of topolgical singularities. The output is thus guranteed to be a +piecewise linear orientable manifold, possibly with boundary. + */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png new file mode 100755 index 0000000000000000000000000000000000000000..97f747c6d8b3133f1c80cadf4f2fdd6fb2928d2d GIT binary patch literal 84499 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 YH^?tC{8|6 Date: Mon, 2 Dec 2013 17:08:10 +0100 Subject: [PATCH 029/114] wip user manual --- ...Advancing_front_surface_reconstruction.txt | 24 ++++++++-------- .../Advancing_front_surface_reconstruction.h | 28 ++++++++++++++----- .../PackageDescription.txt | 2 +- 3 files changed, 35 insertions(+), 19 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 19a86e3127b..7598ad22fff 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -13,7 +13,7 @@ namespace CGAL { Surface reconstruction from an unstructured point set is to find a surface that approximates these points. Several techniques have been applied to this problem. Among them are variational -methods \cgalCite{}, tensor voting \cgalCite{}, implicit surface \cgalCite{}, +methods \cgalCite{todo}, tensor voting \cgalCite{todo}, implicit surface \cgalCite{todo}, and Delaunay triangulations. For Delaunay based algorithms the output surface @@ -23,7 +23,7 @@ which output the boundary of selected tetrahedra, or surface oriented, that is they explicitely select triangles. In most surface oriented Delaunay-based algorithms triangles are -selected independently, that is in parallel \cgalCite{}. +selected independently, that is in parallel \cgalCite{todo}. The surface oriented Delaunay-based surface reconstruction algorithm presented in this chapter selects triangles sequentially, that is by @@ -32,7 +32,7 @@ most *plausible* triangle first, and only adds triangles in a way that the surface remains an orientable manifold. Two other examples of this greedy approach are the ball pivoting -algorithm and Boyer and Petitjean's algorithm \cgalCite{}. In both +algorithm and Boyer and Petitjean's algorithm \cgalCite{todo}. In both algorithms a triangulated surface is incrementally grown starting from a seed triangle. Ball pivoting is fast, but the quality of the reconstruction depends on user defined parameters corresponding to the @@ -45,7 +45,7 @@ the next sections we describe the algorithm in detail, and give examples. -\section AFSR_Definitions The Algorithm +\section AFSR_Definitions Definitions and the Algorithm \subsection AFSR_Topology Topological Constraints @@ -78,7 +78,7 @@ sample point. In other words, the radius \f$r_t\f$ is the distance from any vertex of \f$t\f$ to the Voronoi edge dual to \f$t\f$. While the radius is a good criterion in the case of 2D smooth curve -reconstruction \cgalCite{}, we need another criterion for 3D surface +reconstruction \cgalCite{todo}, we need another criterion for 3D surface reconstruction, namely the dihedral angle between triangles on the surface, that is the angle between the normals of the triangles. @@ -99,14 +99,16 @@ We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if \subsection AFSR_Algorithm The Algorithm -The algorithm takes as input a reference to a Delaunay triangulation. - +The first step of the algorithm is the construction of a 3D Delaunay +triangulation of the point set. The Delaunay triangle with the smallest radius is the starting point -for the greedy algorithm. The algorithm maintains a priority queue of +for the greedy algorithm. + +The algorithm maintains a priority queue of candidate triangles, that is of triangles incident to the boundary edges. The priority is the plausibility. While this priority queue is not empty, the algorithm adds the most plausible candidate into the -surface, and inserts new candidates into the priority queue in case +surface, and inserts new candidate triangles into the priority queue in case there are new boundary edges. @@ -136,7 +138,7 @@ boundary detection. We discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$ such that \f$ p(t) < 0\f$, and \f$ r_t > K r_{t'}\f$ where \f$ t'\f$ is the triangle on the surface incident on \f$ e \f$. The parameter \f$ K \f$ -can be chosen by the user. +can be chosen by the user and is by default 5. Note that this heuristic implies that @@ -156,7 +158,7 @@ In the example we write the surface in the OFF format to `std::cout`. \cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp} -\subsection AFSR_Example_class Example for Class +\subsection AFSR_Example_class Example for the Reconstruction Class When using the class `Advancing_front_surface_reconstruction` you can access a 2D triangulation data structure describing the surface. diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index eff4710076e..96b1bf12b30 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -7,14 +7,10 @@ namespace CGAL { The class `Advancing_front_surface_reconstruction` \tparam Dt must be a `Delaunay_triangulation_3` with -`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` -blended into the vertex and cell type. +`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, and the geometeic traits class must be the `Exact_predicates_inexact_constructions_kernel`. - -\cgalHeading{Implementation} - -The .. */ + template< typename Dt> class Advancing_front_surface_reconstruction { public: @@ -95,7 +91,7 @@ Advancing_front_surface_reconstruction(Dt& dt); /*! calls the surface reconstruction function with the default parameters. */ - void operator()(); + void operator()(double K=5, double beta= 0.18); /*! returns the reconstructed surface. @@ -167,4 +163,22 @@ has_on_surface(TDS_2::Vertex_handle v2) const; }; /* end Advancing_front_surface_reconstruction */ + + +/*! +\ingroup PkgAdvancingFrontSurfaceReconstruction + +For a sequence of points computes a sequence of index triples +describing the faces of the reconstructed surface. + +\tparam PointInputIterator must be an input iterator with 3D points from the `Exact_predicates_inexact_constructions_kernel` as value type. +\tparam IndicesOutputIterator must be an output iterator to which +`CGAL::cpp11::tuple` can be assigned. + + +*/ + template + void advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double K=5, double beta= 0.18 ); + + } /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt index 6a71220a90e..eefaac1df3a 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -13,7 +13,7 @@ \cgalPkgManuals{Chapter_Advancing_Front_Surface_Reconstruction,PkgAdvancingFrontSurfaceReconstruction} \cgalPkgSummaryEnd \cgalPkgShortInfoBegin -\cgalPkgSince{2.1} +\cgalPkgSince{4.4} \cgalPkgDependsOn{\ref PkgTriangulation3Summary} \cgalPkgBib{cgal:dc-afsr} \cgalPkgLicense{\ref licensesGPL "GPL"} From 50ca0d4b32e0a14984394b4e7bf9916921ee781a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 4 Dec 2013 14:11:22 +0100 Subject: [PATCH 030/114] Turn class static containers in the vertex class into a container in the reconstruction class As a consequence we had to move vertex member functions in the reconstruction class --- .../Advancing_front_surface_reconstruction.h | 338 +++++++++++-- ...ont_surface_reconstruction_vertex_base_3.h | 454 +++--------------- 2 files changed, 381 insertions(+), 411 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index a8534cd26d5..5ccfbee1dcb 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -23,6 +23,7 @@ #include #include #include + namespace CGAL { // This iterator allows to visit all contours. It has the particularity @@ -166,7 +167,7 @@ public: typedef typename Triangulation_3::Finite_facets_iterator Finite_facets_iterator; typedef typename Triangulation_3::Finite_vertices_iterator Finite_vertices_iterator; typedef typename Triangulation_3::Finite_edges_iterator Finite_edges_iterator; - + typedef typename Triangulation_3::All_cells_iterator All_cells_iterator; typedef typename Triangulation_3::All_facets_iterator All_facets_iterator; typedef typename Triangulation_3::All_vertices_iterator All_vertices_iterator; @@ -178,6 +179,7 @@ public: typedef typename Triangulation_3::Vertex::Radius_edge_type Radius_edge_type; typedef typename Triangulation_3::Vertex::Border_elt Border_elt; typedef typename Triangulation_3::Vertex::Next_border_elt Next_border_elt; + typedef typename Triangulation_3::Vertex::Intern_successors_type Intern_successors_type; typedef typename Triangulation_3::Vertex::Radius_ptr_type Radius_ptr_type; typedef typename Triangulation_3::Vertex::Incidence_request_iterator Incidence_request_iterator; @@ -234,6 +236,276 @@ private: int _number_of_connected_components; + std::list interior_edges; + std::list< Incidence_request_elt > incidence_requests; + + + std::list nbe_pool; + std::list ist_pool; + + + Intern_successors_type* new_border() + { + nbe_pool.push_back(Next_border_elt()); + + Next_border_elt* p1 = & nbe_pool.back(); + nbe_pool.push_back(Next_border_elt()); + Next_border_elt* p2 = & nbe_pool.back(); + + Intern_successors_type ist(p1,p2); + ist_pool.push_back(ist); + + Intern_successors_type* ret = &ist_pool.back(); + + ret->first->first = NULL; + ret->second->first = NULL; + return ret; + } + + + inline bool is_on_border(Vertex_handle vh, const int& i) const + { + if (vh->m_incident_border == NULL) return false; //vh is interior + if (vh->m_incident_border->first->first != NULL) + { + if (vh->m_incident_border->second->first != NULL) + return ((vh->m_incident_border->first->second.second == i)|| + (vh->m_incident_border->second->second.second == i)); + return (vh->m_incident_border->first->second.second == i); + } + return false; //vh is still exterior + } + + + void remove_border_edge(Vertex_handle w, Vertex_handle v) + { + if (w->m_incident_border != NULL) + { + if (w->m_incident_border->second->first == v) + { + w->m_incident_border->second->first = NULL; + set_interior_edge(w,v); + return; + } + if (w->m_incident_border->first->first == v) + { + if (w->m_incident_border->second->first != NULL) + { + Next_border_elt* tmp = w->m_incident_border->first; + w->m_incident_border->first = w->m_incident_border->second; + w->m_incident_border->second = tmp; + w->m_incident_border->second->first = NULL; + set_interior_edge(w,v); + return; + } + else + { + w->m_incident_border->first->first = NULL; + set_interior_edge(w,v); + return; + } + } + } + } + + + inline bool is_interior_edge(Vertex_handle w, Vertex_handle v) const + { + + bool r1; + if(w->m_ie_first == interior_edges.end()){ + r1 = false; + }else { + typename std::list::iterator b(w->m_ie_first), e(w->m_ie_last); + e++; + typename std::list::iterator r = std::find(b, e, v); + r1 = ( r != e); + } + + return r1; + } + + //------------------------------------------------------------------- + // pour gerer certaines aretes interieures: a savoir celle encore connectee au + // bord (en fait seule, les aretes interieures reliant 2 bords nous + // interressent...) + + inline void set_interior_edge(Vertex_handle w, Vertex_handle v) + { + if(w->m_ie_last == interior_edges.end()){ // empty set + assert(w->m_ie_first == w->m_ie_last); + w->m_ie_last = interior_edges.insert(w->m_ie_last, v); + w->m_ie_first = w->m_ie_last; + } else { + typename std::list::iterator e(w->m_ie_last); + e++; +#ifdef DEBUG + typename std::list::iterator r = std::find(w->m_ie_first, e, v); + assert(r == e); +#endif + w->m_ie_last = interior_edges.insert(e, v); + } + } + + + inline void remove_interior_edge(Vertex_handle w, Vertex_handle v) + { + if(w->m_ie_first == interior_edges.end()){ + assert(w->m_ie_last == w->m_ie_first); + } else if(w->m_ie_first == w->m_ie_last){ // there is only one element + if(*(w->m_ie_first) == v){ + interior_edges.erase(w->m_ie_first); + w->m_ie_last = interior_edges.end(); + w->m_ie_first = w->m_ie_last; + } + } else { + typename std::list::iterator b(w->m_ie_first), e(w->m_ie_last); + e++; + typename std::list::iterator r = std::find(b, e, v); + if(r != e){ + if(r == w->m_ie_first){ + w->m_ie_first++; + } + if(r == w->m_ie_last){ + w->m_ie_last--; + } + interior_edges.erase(r); + } + } + } + + + //------------------------------------------------------------------- + + inline void set_incidence_request(Vertex_handle w, const Incidence_request_elt& ir) + { + if(w->m_ir_last == incidence_requests.end()){ + assert(w->m_ir_first == w->m_ir_last); + w->m_ir_last = incidence_requests.insert(w->m_ir_last, ir); + w->m_ir_first = w->m_ir_last; + } else { + typename std::list::iterator e(w->m_ir_last); + e++; + w->m_ir_last = incidence_requests.insert(e, ir); + } + } + + inline bool is_incidence_requested(Vertex_handle w) const + { + if(w->m_ir_last == incidence_requests.end()){ + assert(w->m_ir_first == incidence_requests.end()); + } + return (w->m_ir_last != incidence_requests.end()); + } + + inline Incidence_request_iterator incidence_request_begin(Vertex_handle w) + { + return w->m_ir_first; + } + + inline Incidence_request_iterator get_incidence_request_end(Vertex_handle w) + { + if(w->m_ir_last != incidence_requests.end()){ + assert(w->m_ir_first != incidence_requests.end()); + Incidence_request_iterator it(w->m_ir_last); + it++; + return it; + } + return w->m_ir_last; + } + + inline void erase_incidence_request(Vertex_handle w) + { + if(w->m_ir_last != incidence_requests.end()){ + assert(w->m_ir_first != incidence_requests.end()); + w->m_ir_last++; + incidence_requests.erase(w->m_ir_first, w->m_ir_last); + w->m_ir_first = incidence_requests.end(); + w->m_ir_last = incidence_requests.end(); + } + } + + + void re_init(Vertex_handle w) + { + if (w->m_incident_border != NULL) + { + w->delete_border(); + } + + if(w->m_ir_first != incidence_requests.end()){ + assert(w->m_ir_last != incidence_requests.end()); + typename std::list< Incidence_request_elt >::iterator b(w->m_ir_first), e(w->m_ir_last); + e++; + incidence_requests.erase(b, e); + w->m_ir_first = incidence_requests.end(); + w->m_ir_last = incidence_requests.end(); + } + + w->m_incident_border = new_border(); + w->m_mark = -1; + w->m_post_mark = -1; + } + + + + inline void dec_mark(Vertex_handle w) + { + w->m_mark--; + if(w->m_mark == 0) + { + w->delete_border(); + erase_incidence_request(w); + } + } + + + + void initialize_vertices_and_cells() + { + for(All_vertices_iterator fit = T.all_vertices_begin(); + fit != T.all_vertices_end(); + ++fit){ + fit->m_ie_first = fit->m_ie_last = interior_edges.end(); + fit->m_ir_first = fit->m_ir_last = incidence_requests.end(); + fit->m_incident_border = new_border(); + } + } + + //-------------------- DESTRUCTOR ----------------------------------- + + void clear_vertex(Vertex_handle w) + { + if (w->m_incident_border != NULL) + { + w->delete_border(); + } + if(w->m_ir_first != incidence_requests.end()){ + assert(w->m_ir_last != incidence_requests.end()); + typename std::list< Incidence_request_elt >::iterator b(w->m_ir_first), e(w->m_ir_last); + e++; + incidence_requests.erase(b, e); + } + + if(w->m_ie_first != interior_edges.end()){ + assert(w->m_ie_last != interior_edges.end()); + typename std::list::iterator b(w->m_ie_first), e(w->m_ie_last); + e++; + interior_edges.erase(b, e); + } + } + + + void clear_vertices() + { + for (All_vertices_iterator vit = T.all_vertices_begin(); + vit != T.all_vertices_end(); + ++vit){ + clear_vertex(vit); + } + } + + public: Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options()) : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), @@ -249,7 +521,7 @@ public: void operator()(const AFSR_options& opt = AFSR_options()) { - + initialize_vertices_and_cells(); bool re_init = false; do { @@ -257,7 +529,7 @@ public: if ( (re_init = init(re_init)) ) { - std::cerr << "Growing connected component " << _number_of_connected_components << std::endl; + //std::cerr << "Growing connected component " << _number_of_connected_components << std::endl; extend(opt.K_init, opt.K_step, opt.K); if ((number_of_facets() > static_cast(T.number_of_vertices()))&& @@ -274,10 +546,9 @@ public: (opt.max_connected_comp < 0))); _tds_2_inf = AFSR::construct_surface(_tds_2, *this); - } - ~Advancing_front_surface_reconstruction() - {} + clear_vertices(); + } typedef Triangulation_data_structure_2, @@ -384,7 +655,7 @@ public: - Next_border_elt* get_border_elt(const Vertex_handle& v1, const Vertex_handle& v2) + Next_border_elt* get_border_elt(const Vertex_handle& v1, const Vertex_handle& v2) const { return v1->get_border_elt(v2); } @@ -415,14 +686,14 @@ public: bool is_border_elt(Edge_like& key, Border_elt& result) const { - Next_border_elt* it12 = key.first->get_border_elt(key.second); + Next_border_elt* it12 = get_border_elt(key.first, key.second); if (it12 != NULL) { result = it12->second; return true; } - Next_border_elt* it21 = key.second->get_border_elt(key.first); + Next_border_elt* it21 = get_border_elt(key.second, key.first); if (it21 != NULL) { result = it21->second; @@ -434,13 +705,13 @@ public: //--------------------------------------------------------------------- bool is_border_elt(Edge_like& key) const { - Next_border_elt* it12 = key.first->get_border_elt(key.second); + Next_border_elt* it12 = get_border_elt(key.first, key.second); if (it12 != NULL) { return true; } - Next_border_elt* it21 = key.second->get_border_elt(key.first); + Next_border_elt* it21 = get_border_elt(key.second, key.first); if (it21 != NULL) { std::swap(key.first, key.second); @@ -452,7 +723,7 @@ public: bool is_ordered_border_elt(const Edge_like& key, Border_elt& result) const { - Next_border_elt* it12 = key.first->get_border_elt(key.second); + Next_border_elt* it12 = get_border_elt(key.first, key.second); if (it12 != NULL) { result = it12->second; @@ -466,7 +737,7 @@ public: void remove_border_elt(const Edge_like& ordered_key) { - ordered_key.first->remove_border_edge(ordered_key.second); + remove_border_edge(ordered_key.first, ordered_key.second); } //--------------------------------------------------------------------- @@ -476,7 +747,7 @@ public: { Vertex_handle v1 = e.first; - Next_border_elt* it12 = v1->get_border_elt(e.second); + Next_border_elt* it12 = get_border_elt(v1, e.second); if (it12 != NULL) { ptr = &it12->second.first.second; @@ -491,7 +762,7 @@ public: const Edge_like& e) { Incidence_request_elt incident_elt(value, e); - v->set_incidence_request(incident_elt); + set_incidence_request(v, incident_elt); } //--------------------------------------------------------------------- @@ -501,8 +772,8 @@ public: // bord (en fait seule, les aretes interieures reliant 2 bords nous // interressent...) { - return (key.first->is_interior_edge(key.second)|| - key.second->is_interior_edge(key.first)); + return (is_interior_edge(key.first, key.second)|| + is_interior_edge(key.second, key.first)); } //--------------------------------------------------------------------- @@ -1129,10 +1400,10 @@ public: void dequeue_incidence_request(const Vertex_handle& v) { - if (v->is_incidence_requested()) + if (is_incidence_requested(v)) { - for(Incidence_request_iterator v_it = v->incidence_request_begin(); - v_it != v->get_incidence_request_end(); + for(Incidence_request_iterator v_it = incidence_request_begin(v); + v_it != get_incidence_request_end(v); v_it++) { IO_edge_type* ptr; @@ -1140,7 +1411,7 @@ public: if (is_ordered_border_elt(v_it->second, ptr)) _ordered_border.insert(Radius_ptr_type(v_it->first, ptr)); } - v->erase_incidence_request(); + erase_incidence_request(v); } } @@ -1166,7 +1437,7 @@ public: p2 = set_border_elt(ordered_el1.first, v2, Border_elt(e2,result1.second)); - v1->dec_mark(); + dec_mark(v1); _ordered_border.insert(Radius_ptr_type(e2.first, p2)); @@ -1256,9 +1527,9 @@ public: force_merge(ordered_el1, result1); force_merge(ordered_el2, result2); - v1->dec_mark(); - v2->dec_mark(); - c->vertex(i)->dec_mark(); + dec_mark(v1); + dec_mark(v2); + dec_mark(c->vertex(i)); select_facet(c, edge_Efacet.second); @@ -1729,9 +2000,9 @@ public: Vertex_handle vh_int = c->vertex(i3); ordered_map_erase(border_elt.second.first.first, get_border_IO_elt(vh, vh_succ)); - vh->remove_border_edge(vh_succ); + remove_border_edge(vh, vh_succ); // 1- a virer au cas ou car vh va etre detruit - vh_succ->remove_interior_edge(vh); + remove_interior_edge(vh_succ, vh); bool while_cond(true); do { @@ -1746,7 +2017,7 @@ public: if (!vh_int->is_on_border()) { - vh_int->re_init(); + re_init(vh_int); vh_int->inc_mark(); } @@ -1758,17 +2029,17 @@ public: if (is_ordered_border_elt(Edge_like(vh_int, vh), result)) { ordered_map_erase(result.first.first, get_border_IO_elt(vh_int, vh)); - vh_int->remove_border_edge(vh); + remove_border_edge(vh_int, vh); // 1- a virer au cas ou car vh va etre detruit - vh_int->remove_interior_edge(vh); + remove_interior_edge(vh_int, vh); while_cond = false; } // a titre preventif... on essaye de s'assurer de marquer les aretes // interieures au sens large... // 2- a virer a tout pris pour que maintenir le sens de interior edge - vh_int->remove_interior_edge(vh_succ); - vh_succ->remove_interior_edge(vh_int); + remove_interior_edge(vh_int, vh_succ); + remove_interior_edge(vh_succ, vh_int); IO_edge_type* p32 = set_border_elt(vh_int, vh_succ, Border_elt(rad_elt_32, border_index)); @@ -1901,7 +2172,7 @@ public: v_it != T.finite_vertices_end(); v_it++) { - v_it->erase_incidence_request(); + erase_incidence_request(v_it); if ((v_it->is_on_border())&& (!v_it->is_post_marked(_postprocessing_counter))) { @@ -2006,6 +2277,7 @@ advancing_front_surface_reconstruction(PointIterator b, PointIterator e, IndexTr boost::make_transform_iterator(e, AFSR::Auto_count() ) ); Reconstruction R(dt); + R(); write_triple_indices(out, R); return out; } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index 64706bd045d..f3210b6167c 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -7,14 +7,13 @@ #include #include -#include -#include -#include namespace CGAL { + template class Advancing_front_surface_reconstruction; + template > class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase { @@ -27,6 +26,7 @@ public: }; + template friend class Advancing_front_surface_reconstruction; typedef VertexBase Base; @@ -45,7 +45,6 @@ public: typedef std::pair< Radius_edge_type, int > Border_elt; typedef std::pair< Vertex_handle, Border_elt > Next_border_elt; -private: //par convention je remplis d'abord first et si necessaire second... typedef std::pair< Next_border_elt*, Next_border_elt*> Intern_successors_type; @@ -60,498 +59,197 @@ public: typedef std::list< Incidence_request_elt > Incidence_request_type; typedef typename Incidence_request_type::iterator Incidence_request_iterator; - // typedef std::set< void* > Interior_edge_set_type; //-------------------- DATA MEMBERS --------------------------------- typedef int Info; // so that we are a model of TriangulationVertexBaseWithInfo_3 private: - int _id; - int _mark; - int _post_mark; - Intern_successors_type* _incident_border; + int m_id; + int m_mark; + int m_post_mark; + Intern_successors_type* m_incident_border; - // Instead of having a set per vertex, there is a global list. - static std::list interior_edges; + // Instead of having a set per vertex, there is a global list + // in the surface reconstruction class // and two iterators per vertex in this list - // Note that ie_last is not past the end - // ie_first == ie_last == interior_edge.end() iff the set is empty - typename std::list::iterator ie_first, ie_last; + // Note that m_ie_last is not past the end + // m_ie_first == m_ie_last == interior_edge.end() iff the set is empty + typename std::list::iterator m_ie_first, m_ie_last; // We do the same for the incidence requests - static std::list< Incidence_request_elt > incidence_requests; - typename std::list< Incidence_request_elt >::iterator ir_first, ir_last; - - static std::list bbb; - static boost::object_pool nbe_pool; - static boost::object_pool ist_pool; - - + typename std::list< Incidence_request_elt >::iterator m_ir_first, m_ir_last; //-------------------- CONSTRUCTORS --------------------------------- - public: - Intern_successors_type* new_border() - { - Intern_successors_type* ret; - /* - std::allocator nbea; - std::allocator ista; - Next_border_elt nbe; - Next_border_elt* p1 = nbea.allocate(1); - Next_border_elt* p2 = nbea.allocate(1); - nbea.construct(p1, nbe); - nbea.construct(p1, nbe); - - ret = ista.allocate(1); - ista.construct(ret, std::make_pair(p1, p2)); - */ - - Next_border_elt* p1 = nbe_pool.malloc(); - Next_border_elt* p2 = nbe_pool.malloc(); - ret = ist_pool.malloc(); - - Intern_successors_type ist(p1,p2); - *ret = ist; - - - /* - ret = new Intern_successors_type(new Next_border_elt(), - new Next_border_elt()); - */ - ret->first->first = NULL; - ret->second->first = NULL; - return ret; - } - - - void delete_border() - { - /* - std::allocator nbea; - std::allocator ista; - nbea.destroy(_incident_border->first); - nbea.destroy(_incident_border->second); - nbea.deallocate(_incident_border->first, 1); - nbea.deallocate(_incident_border->second, 1); - ista.destroy(_incident_border); - ista.deallocate(_incident_border, 1); - */ - /* - delete _incident_border->first; - delete _incident_border->second; - */ - //nbe_pool.free(_incident_border->first); - //nbe_pool.free(_incident_border->second); - //delete _incident_border; - - _incident_border = NULL; - - - } - - Advancing_front_surface_reconstruction_vertex_base_3() - : VertexBase(), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new_border(); - } + : VertexBase(), m_mark(-1), + m_post_mark(-1) + {} Advancing_front_surface_reconstruction_vertex_base_3(const Point & p) - : VertexBase(p), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new_border(); - } + : VertexBase(p), m_mark(-1), + m_post_mark(-1) + {} Advancing_front_surface_reconstruction_vertex_base_3(const Point & p, Cell_handle f) - : VertexBase(p, f), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new_border(); - } + : VertexBase(p, f), m_mark(-1), + m_post_mark(-1) + {} Advancing_front_surface_reconstruction_vertex_base_3(Cell_handle f) - : VertexBase(f), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new_border(); - } + : VertexBase(f), m_mark(-1), + m_post_mark(-1) + {} Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other) - : VertexBase(), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new_border(); - } - //-------------------- DESTRUCTOR ----------------------------------- - - ~Advancing_front_surface_reconstruction_vertex_base_3() - { - if (_incident_border != NULL) - { - delete_border(); - } - if(ir_first != incidence_requests.end()){ - assert(ir_last != incidence_requests.end()); - typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last); - e++; - incidence_requests.erase(b, e); - } - - if(ie_first != interior_edges.end()){ - assert(ie_last != interior_edges.end()); - typename std::list::iterator b(ie_first), e(ie_last); - e++; - interior_edges.erase(b, e); - } - } + : VertexBase(), m_mark(-1), + m_post_mark(-1) + {} //-------------------- MEMBER FUNCTIONS ----------------------------- +public: + int& id() { - return _id; + return m_id; } const int& id() const { - return _id; + return m_id; } int& info() { - return _id; + return m_id; } const int& info() const { - return _id; + return m_id; } - inline void re_init() - { - if (_incident_border != NULL) - { - delete_border(); - //delete _incident_border->first; - //delete _incident_border->second; - //delete _incident_border; - } - - if(ir_first != incidence_requests.end()){ - assert(ir_last != incidence_requests.end()); - typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last); - e++; - incidence_requests.erase(b, e); - ir_first = incidence_requests.end(); - ir_last = incidence_requests.end(); - } - - _incident_border = new_border(); - _mark = -1; - _post_mark = -1; - } + //------------------------------------------------------------------- +private: + + void delete_border() + { + m_incident_border = NULL; + } - inline bool is_on_border(const int& i) const - { - if (_incident_border == NULL) return false; //vh is interior - if (_incident_border->first->first != NULL) - { - if (_incident_border->second->first != NULL) - return ((_incident_border->first->second.second == i)|| - (_incident_border->second->second.second == i)); - return (_incident_border->first->second.second == i); - } - return false; //vh is still exterior - } inline Next_border_elt* get_next_on_border(const int& i) const { - if (_incident_border == NULL) return NULL; //vh is interior - if (_incident_border->first->first != NULL) - if (_incident_border->first->second.second == i) - return _incident_border->first; - if (_incident_border->second->first != NULL) - if (_incident_border->second->second.second == i) - return _incident_border->second; + if (m_incident_border == NULL) return NULL; //vh is interior + if (m_incident_border->first->first != NULL) + if (m_incident_border->first->second.second == i) + return m_incident_border->first; + if (m_incident_border->second->first != NULL) + if (m_incident_border->second->second.second == i) + return m_incident_border->second; return NULL; } - inline void remove_border_edge(Vertex_handle v) - { - if (_incident_border != NULL) - { - if (_incident_border->second->first == v) - { - _incident_border->second->first = NULL; - set_interior_edge(v); - return; - } - if (_incident_border->first->first == v) - { - if (_incident_border->second->first != NULL) - { - Next_border_elt* tmp = _incident_border->first; - _incident_border->first = _incident_border->second; - _incident_border->second = tmp; - _incident_border->second->first = NULL; - set_interior_edge(v); - return; - } - else - { - _incident_border->first->first = NULL; - set_interior_edge(v); - return; - } - } - } - } + inline bool is_border_edge(Vertex_handle v) const { - if (_incident_border == NULL) return false; - return ((_incident_border->first->first == v)|| - (_incident_border->second->first == v)); + if (m_incident_border == NULL) return false; + return ((m_incident_border->first->first == v)|| + (m_incident_border->second->first == v)); } inline Next_border_elt* get_border_elt(Vertex_handle v) const { - if (_incident_border == NULL) return NULL; - if (_incident_border->first->first == v) return _incident_border->first; - if (_incident_border->second->first == v) return _incident_border->second; + if (m_incident_border == NULL) return NULL; + if (m_incident_border->first->first == v) return m_incident_border->first; + if (m_incident_border->second->first == v) return m_incident_border->second; return NULL; } inline Next_border_elt* first_incident() const { - if (_incident_border == NULL) return NULL; - return _incident_border->first; + if (m_incident_border == NULL) return NULL; + return m_incident_border->first; } inline Next_border_elt* second_incident() const { - if (_incident_border == NULL) return NULL; - return _incident_border->second; + if (m_incident_border == NULL) return NULL; + return m_incident_border->second; } inline void set_next_border_elt(const Next_border_elt& elt) { - if (_incident_border->first->first == NULL) - *_incident_border->first = elt; + if (m_incident_border->first->first == NULL) + *m_incident_border->first = elt; else { - if (_incident_border->second->first != NULL) + if (m_incident_border->second->first != NULL) std::cerr << "+++probleme de MAJ du bord " << std::endl; - *_incident_border->second = elt; + *m_incident_border->second = elt; } } + + //------------------------------------------------------------------- - // pour gerer certaines aretes interieures: a savoir celle encore connectee au - // bord (en fait seule, les aretes interieures reliant 2 bords nous - // interressent...) - inline bool is_interior_edge(Vertex_handle v) const - { - - bool r1; - if(ie_first == interior_edges.end()){ - r1 = false; - }else { - typename std::list::iterator b(ie_first), e(ie_last); - e++; - typename std::list::iterator r = std::find(b, e, v); - r1 = ( r != e); - } - - return r1; - } - - inline void set_interior_edge(Vertex_handle v) - { - if(ie_last == interior_edges.end()){ // empty set - assert(ie_first == ie_last); - ie_last = interior_edges.insert(ie_last, v); - ie_first = ie_last; - } else { - typename std::list::iterator e(ie_last); - e++; -#ifdef DEBUG - typename std::list::iterator r = std::find(ie_first, e, v); - assert(r == e); -#endif - ie_last = interior_edges.insert(e, v); - } - } - - inline void remove_interior_edge(Vertex_handle v) - { - if(ie_first == interior_edges.end()){ - assert(ie_last == ie_first); - } else if(ie_first == ie_last){ // there is only one element - if(*ie_first == v){ - interior_edges.erase(ie_first); - ie_last = interior_edges.end(); - ie_first = ie_last; - } - } else { - typename std::list::iterator b(ie_first), e(ie_last); - e++; - typename std::list::iterator r = std::find(b, e, v); - if(r != e){ - if(r == ie_first){ - ie_first++; - } - if(r == ie_last){ - ie_last--; - } - interior_edges.erase(r); - } - } - } - - //------------------------------------------------------------------- - - inline void set_incidence_request(const Incidence_request_elt& ir) - { - if(ir_last == incidence_requests.end()){ - assert(ir_first == ir_last); - ir_last = incidence_requests.insert(ir_last, ir); - ir_first = ir_last; - } else { - typename std::list::iterator e(ir_last); - e++; - ir_last = incidence_requests.insert(e, ir); - } - } - - inline bool is_incidence_requested() const - { - if(ir_last == incidence_requests.end()){ - assert(ir_first == incidence_requests.end()); - } - return (ir_last != incidence_requests.end()); - } - - inline Incidence_request_iterator incidence_request_begin() - { - return ir_first; - } - - inline Incidence_request_iterator get_incidence_request_end() - { - if(ir_last != incidence_requests.end()){ - assert(ir_first != incidence_requests.end()); - Incidence_request_iterator it(ir_last); - it++; - return it; - } - return ir_last; - } - - inline void erase_incidence_request() - { - if(ir_last != incidence_requests.end()){ - assert(ir_first != incidence_requests.end()); - ir_last++; - incidence_requests.erase(ir_first, ir_last); - ir_first = incidence_requests.end(); - ir_last = incidence_requests.end(); - } - } - - - //------------------------------------------------------------------- +public: inline bool is_on_border() const { - return (_mark > 0); + return (m_mark > 0); } inline bool not_interior() const { - return (_mark != 0); + return (m_mark != 0); } inline int number_of_incident_border() const { - return _mark; + return m_mark; } inline bool is_exterior() const { - return (_mark < 0); + return (m_mark < 0); } //------------------------------------------------------------------- +private: inline void inc_mark() { - if (_mark==-1) - _mark=1; + if (m_mark==-1) + m_mark=1; else - _mark++; - } - - inline void dec_mark() - { - _mark--; - if(_mark == 0) - { - delete_border(); - erase_incidence_request(); - } + m_mark++; } //------------------------------------------------------------------- inline void set_post_mark(const int& i) { - _post_mark = i; + m_post_mark = i; } inline bool is_post_marked(const int& i) { - return (_post_mark == i); + return (m_post_mark == i); } }; - -template -boost::object_pool::Next_border_elt> Advancing_front_surface_reconstruction_vertex_base_3::nbe_pool; - -template -boost::object_pool::Intern_successors_type> Advancing_front_surface_reconstruction_vertex_base_3::ist_pool; - - - -template -std::list::Vertex_handle> Advancing_front_surface_reconstruction_vertex_base_3::interior_edges; - -template -std::list::Incidence_request_elt> Advancing_front_surface_reconstruction_vertex_base_3::incidence_requests; - } // namespace CGAL #endif // CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_3_H From 537077436368b5cff90d4dcd2d8e27cb9be9a139 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 4 Dec 2013 14:26:14 +0100 Subject: [PATCH 031/114] No need for get_ prefix --- .../Advancing_front_surface_reconstruction.h | 96 +++++++++---------- ...front_surface_reconstruction_cell_base_3.h | 6 +- ...ont_surface_reconstruction_vertex_base_3.h | 4 +- 3 files changed, 53 insertions(+), 53 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 5ccfbee1dcb..06368a85ec4 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -403,7 +403,7 @@ private: return w->m_ir_first; } - inline Incidence_request_iterator get_incidence_request_end(Vertex_handle w) + inline Incidence_request_iterator incidence_request_end(Vertex_handle w) { if(w->m_ir_last != incidence_requests.end()){ assert(w->m_ir_first != incidence_requests.end()); @@ -638,7 +638,7 @@ public: Boundary_iterator boundaries_begin() const { - return Boundary_iterator(*this, get_next_mark()); + return Boundary_iterator(*this, next_mark()); } Boundary_iterator boundaries_end() const @@ -647,7 +647,7 @@ public: } - int get_next_mark() const + int next_mark() const { _postprocessing_counter++; return _postprocessing_counter; @@ -655,45 +655,45 @@ public: - Next_border_elt* get_border_elt(const Vertex_handle& v1, const Vertex_handle& v2) const + Next_border_elt* border_elt(const Vertex_handle& v1, const Vertex_handle& v2) const { - return v1->get_border_elt(v2); + return v1->border_elt(v2); } //public - IO_edge_type* get_border_IO_elt(const Vertex_handle& v1, const Vertex_handle& v2) + IO_edge_type* border_IO_elt(const Vertex_handle& v1, const Vertex_handle& v2) { - return &get_border_elt(v1,v2)->second.first.second; + return &border_elt(v1,v2)->second.first.second; } IO_edge_type* set_border_elt(const Vertex_handle& v1, const Vertex_handle& v2, const Border_elt& e) { v1->set_next_border_elt(Next_border_elt (v2, e)); - return get_border_IO_elt(v1, v2); + return border_IO_elt(v1, v2); } IO_edge_type* set_again_border_elt(const Vertex_handle& v1, const Vertex_handle& v2, const Border_elt& e) { - get_border_elt(v1,v2)->second = e; - return get_border_IO_elt(v1, v2); + border_elt(v1,v2)->second = e; + return border_IO_elt(v1, v2); } //--------------------------------------------------------------------- bool is_border_elt(Edge_like& key, Border_elt& result) const { - Next_border_elt* it12 = get_border_elt(key.first, key.second); + Next_border_elt* it12 = border_elt(key.first, key.second); if (it12 != NULL) { result = it12->second; return true; } - Next_border_elt* it21 = get_border_elt(key.second, key.first); + Next_border_elt* it21 = border_elt(key.second, key.first); if (it21 != NULL) { result = it21->second; @@ -705,13 +705,13 @@ public: //--------------------------------------------------------------------- bool is_border_elt(Edge_like& key) const { - Next_border_elt* it12 = get_border_elt(key.first, key.second); + Next_border_elt* it12 = border_elt(key.first, key.second); if (it12 != NULL) { return true; } - Next_border_elt* it21 = get_border_elt(key.second, key.first); + Next_border_elt* it21 = border_elt(key.second, key.first); if (it21 != NULL) { std::swap(key.first, key.second); @@ -723,7 +723,7 @@ public: bool is_ordered_border_elt(const Edge_like& key, Border_elt& result) const { - Next_border_elt* it12 = get_border_elt(key.first, key.second); + Next_border_elt* it12 = border_elt(key.first, key.second); if (it12 != NULL) { result = it12->second; @@ -747,7 +747,7 @@ public: { Vertex_handle v1 = e.first; - Next_border_elt* it12 = get_border_elt(v1, e.second); + Next_border_elt* it12 = border_elt(v1, e.second); if (it12 != NULL) { ptr = &it12->second.first.second; @@ -780,30 +780,30 @@ public: #ifdef AFSR_LAZY - coord_type get_lazy_squared_radius(const Cell_handle& c) + coord_type lazy_squared_radius(const Cell_handle& c) { - if (c->get_lazy_squared_radius() != NULL) - return *(c->get_lazy_squared_radius()); + if (c->lazy_squared_radius() != NULL) + return *(c->lazy_squared_radius()); c->set_lazy_squared_radius (squared_radius(c->vertex(0)->point(), c->vertex(1)->point(), c->vertex(2)->point(), c->vertex(3)->point())); - return *(c->get_lazy_squared_radius()); + return *(c->lazy_squared_radius()); } - Point get_lazy_circumcenter(const Cell_handle& c) + Point lazy_circumcenter(const Cell_handle& c) { - if (c->get_lazy_circumcenter() != NULL) - return *(c->get_lazy_circumcenter()); + if (c->lazy_circumcenter() != NULL) + return *(c->lazy_circumcenter()); c->set_lazy_circumcenter (circumcenter(c->vertex(0)->point(), c->vertex(1)->point(), c->vertex(2)->point(), c->vertex(3)->point())); - return *(c->get_lazy_circumcenter()); + return *(c->lazy_circumcenter()); } #endif //NOLAZY @@ -932,15 +932,15 @@ public: //===================================================================== - coord_type get_smallest_radius_delaunay_sphere(const Cell_handle& c, - const int& index) const + coord_type smallest_radius_delaunay_sphere(const Cell_handle& c, + const int& index) const { int i1, i2, i3; Cell_handle n = c->neighbor(index); // lazy evaluation ... - coord_type value = c->get_smallest_radius(index); - if ((value >= 0)&&(n->get_smallest_radius(n->index(c)) == value)) + coord_type value = c->smallest_radius(index); + if ((value >= 0)&&(n->smallest_radius(n->index(c)) == value)) return value; const Point& cp0 = c->vertex(index)->point(); @@ -993,7 +993,7 @@ public: facet_sphere.squared_radius()) { #ifdef AFSR_LAZY - value = get_lazy_squared_radius(cc); + value = lazy_squared_radius(cc); #else value = squared_radius(pp0, pp1, pp2, pp3); #endif @@ -1005,8 +1005,8 @@ public: { Point cc, cn; #ifdef AFSR_LAZY - cc = get_lazy_circumcenter(c); - cn = get_lazy_circumcenter(n); + cc = lazy_circumcenter(c); + cn = lazy_circumcenter(n); #else cc = circumcenter(cp0, cp1, cp2, cp3); cn = circumcenter(np0, np1, np2, np3); @@ -1134,7 +1134,7 @@ public: if(tmp != HUGE_VAL){ - tmp = get_smallest_radius_delaunay_sphere(neigh, n_ind); + tmp = smallest_radius_delaunay_sphere(neigh, n_ind); } Edge_like el1(neigh->vertex(n_i1),neigh->vertex(n_i3)), @@ -1207,7 +1207,7 @@ public: else { //on refuse une trop grande non-uniformite - coord_type tmp = get_smallest_radius_delaunay_sphere(c, i); + coord_type tmp = smallest_radius_delaunay_sphere(c, i); if (min_valueA <= K * tmp) value = - min_valueP; else @@ -1247,8 +1247,8 @@ public: facet_it != T.finite_facets_end(); facet_it++) { - coord_type value = get_smallest_radius_delaunay_sphere((*facet_it).first, - (*facet_it).second); + coord_type value = smallest_radius_delaunay_sphere((*facet_it).first, + (*facet_it).second); if (value < min_value) { min_facet = *facet_it; @@ -1266,7 +1266,7 @@ public: if (c->vertex((index+2) & 3)->is_exterior()) if (c->vertex((index+3) & 3)->is_exterior()) { - coord_type value = get_smallest_radius_delaunay_sphere(c, index); + coord_type value = smallest_radius_delaunay_sphere(c, index); coord_type pe=0; if(abs_perimeter != 0){ pe = compute_perimeter(c->vertex((index+1)&3)->point(), @@ -1346,7 +1346,7 @@ public: if (v1*v2 > SLIVER_ANGULUS*norm) return 1; // label bonne pliure sinon: - if (ear_alpha <= K*get_smallest_radius_delaunay_sphere(neigh, n_ind)) + if (ear_alpha <= K*smallest_radius_delaunay_sphere(neigh, n_ind)) return 2; // label alpha coherent... return 0; //sinon oreille a rejeter... @@ -1389,7 +1389,7 @@ public: force_merge(const Edge_like& ordered_key, const Border_elt& result) { criteria value = result.first.first; - IO_edge_type* pkey = get_border_IO_elt(ordered_key.first, ordered_key.second); + IO_edge_type* pkey = border_IO_elt(ordered_key.first, ordered_key.second); ordered_map_erase(value, pkey); @@ -1403,7 +1403,7 @@ public: if (is_incidence_requested(v)) { for(Incidence_request_iterator v_it = incidence_request_begin(v); - v_it != get_incidence_request_end(v); + v_it != incidence_request_end(v); v_it++) { IO_edge_type* ptr; @@ -1665,8 +1665,8 @@ public: (result12.second==result_ear1.second)) { ear1_valid = test_merge(ear1_e, result_ear1, v1, - get_smallest_radius_delaunay_sphere(ear1_c, - ear1.second)) != 0; + smallest_radius_delaunay_sphere(ear1_c, + ear1.second)) != 0; } if (is_border_ear2&&(e2.first < STANDBY_CANDIDATE)&& @@ -1674,8 +1674,8 @@ public: (result12.second==result_ear2.second)) { ear2_valid = test_merge(ear2_e, result_ear2, v2, - get_smallest_radius_delaunay_sphere(ear2_c, - ear2.second)) != 0; + smallest_radius_delaunay_sphere(ear2_c, + ear2.second)) != 0; } if ((!ear1_valid)&&(!ear2_valid)) @@ -1935,7 +1935,7 @@ public: { Edge_incident_facet ei_facet(Edge(neigh, i1, i2), n_ind); - *get_border_IO_elt(key.first, key.second) = + *border_IO_elt(key.first, key.second) = IO_edge_type(ei_facet, ei_facet); } key = Edge_like(neigh->vertex(i1), neigh->vertex(i3)); @@ -1943,7 +1943,7 @@ public: { Edge_incident_facet ei_facet(Edge(neigh, i1, i3), n_ind); - *get_border_IO_elt(key.first, key.second) = + *border_IO_elt(key.first, key.second) = IO_edge_type(ei_facet, ei_facet); } key = Edge_like(neigh->vertex(i3), neigh->vertex(i2)); @@ -1951,7 +1951,7 @@ public: { Edge_incident_facet ei_facet(Edge(neigh, i3, i2), n_ind); - *get_border_IO_elt(key.first, key.second) = + *border_IO_elt(key.first, key.second) = IO_edge_type(ei_facet, ei_facet); } } @@ -1999,7 +1999,7 @@ public: int i3 = 6 - index - i1 - i2; Vertex_handle vh_int = c->vertex(i3); ordered_map_erase(border_elt.second.first.first, - get_border_IO_elt(vh, vh_succ)); + border_IO_elt(vh, vh_succ)); remove_border_edge(vh, vh_succ); // 1- a virer au cas ou car vh va etre detruit remove_interior_edge(vh_succ, vh); @@ -2028,7 +2028,7 @@ public: Border_elt result; if (is_ordered_border_elt(Edge_like(vh_int, vh), result)) { - ordered_map_erase(result.first.first, get_border_IO_elt(vh_int, vh)); + ordered_map_erase(result.first.first, border_IO_elt(vh_int, vh)); remove_border_edge(vh_int, vh); // 1- a virer au cas ou car vh va etre detruit remove_interior_edge(vh_int, vh); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h index e79d316b74c..376cf4b1236 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h @@ -121,7 +121,7 @@ public: //------------------------------------------------------------------- - inline coord_type get_smallest_radius(const int& i) + inline coord_type smallest_radius(const int& i) { if (_smallest_radius_facet_tab == NULL) return -1; @@ -195,7 +195,7 @@ public: //------------------------------------------------------------------- - inline D_Point* get_lazy_circumcenter() + inline D_Point* lazy_circumcenter() { return _circumcenter; } @@ -207,7 +207,7 @@ public: //------------------------------------------------------------------- - inline coord_type* get_lazy_squared_radius() + inline coord_type* lazy_squared_radius() { return _squared_radius; } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index f3210b6167c..aa87cd97461 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -145,7 +145,7 @@ private: } - inline Next_border_elt* get_next_on_border(const int& i) const + inline Next_border_elt* next_on_border(const int& i) const { if (m_incident_border == NULL) return NULL; //vh is interior if (m_incident_border->first->first != NULL) @@ -167,7 +167,7 @@ private: (m_incident_border->second->first == v)); } - inline Next_border_elt* get_border_elt(Vertex_handle v) const + inline Next_border_elt* border_elt(Vertex_handle v) const { if (m_incident_border == NULL) return NULL; if (m_incident_border->first->first == v) return m_incident_border->first; From da83251018146fe405e8ccd5296a158e1c0dd571 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 9 Dec 2013 15:16:48 +0100 Subject: [PATCH 032/114] Add bibtex entries and citations --- ...Advancing_front_surface_reconstruction.txt | 16 ++++++++------- Documentation/biblio/cgal_manual.bib | 20 +++++++++++++++++++ 2 files changed, 29 insertions(+), 7 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 7598ad22fff..4364ccd02d8 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -13,17 +13,17 @@ namespace CGAL { Surface reconstruction from an unstructured point set is to find a surface that approximates these points. Several techniques have been applied to this problem. Among them are variational -methods \cgalCite{todo}, tensor voting \cgalCite{todo}, implicit surface \cgalCite{todo}, +methods \cgalCite{s-lsm-96,zomk-insru-00}, tensor voting \cgalCite{cgal:ml-cfsg-00}, implicit surface \cgalCite{hddhjmss-pssr-94,bc-ssrnn-00}, and Delaunay triangulations. For Delaunay based algorithms the output surface usually is the union of some triangles selected in the Delaunay triangulation of the input points. Such algorithms can be volume oriented -which output the boundary of selected tetrahedra, or surface +which output the boundary of selected tetrahedra \cgalCite{abe-cbscc-97,ack-pcubm-01}, or surface oriented, that is they explicitely select triangles. In most surface oriented Delaunay-based algorithms triangles are -selected independently, that is in parallel \cgalCite{todo}. +selected independently, that is in parallel \cgalCite{agj-lcsr-00,ab-srvf-98}. The surface oriented Delaunay-based surface reconstruction algorithm presented in this chapter selects triangles sequentially, that is by @@ -32,7 +32,7 @@ most *plausible* triangle first, and only adds triangles in a way that the surface remains an orientable manifold. Two other examples of this greedy approach are the ball pivoting -algorithm and Boyer and Petitjean's algorithm \cgalCite{todo}. In both +algorithm and Boyer and Petitjean's algorithm \cgalCite{bmrst-bpasr-99, pb-rnrps-01}. In both algorithms a triangulated surface is incrementally grown starting from a seed triangle. Ball pivoting is fast, but the quality of the reconstruction depends on user defined parameters corresponding to the @@ -40,13 +40,15 @@ sampling density. The Boyer Petitjean approach can handle non-uniform sampling, but fails when near cocircular points are encountered, and it does not provide any guarantee on the topology of the surface. -In -the next sections we describe the algorithm in detail, and give +In the next sections we describe the algorithm, and give examples. \section AFSR_Definitions Definitions and the Algorithm +A detailed desciption of the algorithm and the underlying theory can be found +in \cgalCite{cgal:csd-gdbsra-04}. + \subsection AFSR_Topology Topological Constraints Any triangle \f$t\f$ considered as next potential candidate has to share an @@ -78,7 +80,7 @@ sample point. In other words, the radius \f$r_t\f$ is the distance from any vertex of \f$t\f$ to the Voronoi edge dual to \f$t\f$. While the radius is a good criterion in the case of 2D smooth curve -reconstruction \cgalCite{todo}, we need another criterion for 3D surface +reconstruction \cgalCite{b-cccda-94}, we need another criterion for 3D surface reconstruction, namely the dihedral angle between triangles on the surface, that is the angle between the normals of the triangles. diff --git a/Documentation/biblio/cgal_manual.bib b/Documentation/biblio/cgal_manual.bib index 2285b00840a..c909b095ce4 100644 --- a/Documentation/biblio/cgal_manual.bib +++ b/Documentation/biblio/cgal_manual.bib @@ -387,6 +387,16 @@ note="Conference version: Symp. on Geometry Processing 2003" year="2005" } + +@article{ cgal:csd-gdbsra-04 + , author = "David Cohen-Steiner and Tran Kai Frank Da" + , title = "A greedy Delaunay-based surface reconstruction algorithm" + , journal = "The Visual Computer" + , volume = 20 + , pages = "4--16" + , year = 2004 +} + @inproceedings{ cgal:csm-rdtnc-03, author="D. Cohen-Steiner and J.-M. Morvan", title="Restricted {Delaunay} triangulations and normal cycle", @@ -1260,6 +1270,16 @@ ABSTRACT = {We present the first complete, exact and efficient C++ implementatio update = "09.11 penarand" } +@article{cgal:ml-cfsg-00 +, author = "G. Medioni and M. Lee and C. Tang" +, title = "A Computational Framework for Segmentation and Grouping" +, journal = "Elsevier Science + +, year = 2000 +, pages = "" +, update = "12.13 afabri" +} + @book{ cgal:m-cst-93 ,author = {Robert B. Murray} ,title = "{C{\tt ++}} Strategies and Tactics" From 256b8a534791b467e95ba7833281d9ee05581d11 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 10 Dec 2013 10:57:01 +0100 Subject: [PATCH 033/114] Add an example that writes the result in a Polyhedron --- .../CMakeLists.txt | 1 + .../reconstruction_polyhedron.cpp | 32 +++++++++++++++++++ .../Advancing_front_surface_reconstruction.h | 21 ++++++++++++ 3 files changed, 54 insertions(+) create mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt index cfee6716cee..6467152a14f 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt @@ -26,6 +26,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "extract.cpp" ) create_single_source_cgal_program( "reconstruction_fct.cpp" ) create_single_source_cgal_program( "reconstruction_class.cpp" ) + create_single_source_cgal_program( "reconstruction_polyhedron.cpp" ) else() diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp new file mode 100644 index 00000000000..4b6da452bf0 --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp @@ -0,0 +1,32 @@ + + +#include +#include +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point_3; + +typedef CGAL::Polyhedron_3 Polyhedron; + + +int main() +{ + std::vector points; + Polyhedron P; + + std::copy(std::istream_iterator(std::cin), + std::istream_iterator(), + std::back_inserter(points)); + + CGAL::advancing_front_surface_reconstruction(points.begin(), + points.end(), + P); + + std::cout << P << std::endl; + + return 0; +} diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 06368a85ec4..338c94043c4 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -2281,6 +2282,26 @@ advancing_front_surface_reconstruction(PointIterator b, PointIterator e, IndexTr write_triple_indices(out, R); return out; } +template +void +advancing_front_surface_reconstruction(PointIterator b, PointIterator e, Polyhedron_3& polyhedron) +{ + typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; + typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; + + typedef Triangulation_data_structure_3 Tds; + typedef Delaunay_triangulation_3 Triangulation_3; + + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Kernel::Point_3 Point_3; + + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), + boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + + Reconstruction R(dt); + R(); + AFSR::construct_polyhedron(polyhedron, R); +} } // namespace CGAL From e52911e7a2183cc38663419fd898a230c2c6f2e3 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 10 Dec 2013 12:10:20 +0100 Subject: [PATCH 034/114] Add the advancing front reconstruction to the demo --- ...Advancing_front_surface_reconstruction.txt | 2 +- Polyhedron/demo/Polyhedron/CMakeLists.txt | 2 +- ...Polyhedron_demo_advancing_front_plugin.cpp | 20 +++++------- ...edron_demo_advancing_front_plugin_impl.cpp | 32 +++++++++++++++++++ .../Scene_points_with_normal_item.cpp | 4 +-- 5 files changed, 43 insertions(+), 17 deletions(-) mode change 100755 => 100644 Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp create mode 100644 Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin_impl.cpp diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 4364ccd02d8..8be1e1919b6 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -46,7 +46,7 @@ examples. \section AFSR_Definitions Definitions and the Algorithm -A detailed desciption of the algorithm and the underlying theory can be found +A detailed description of the algorithm and the underlying theory can be found in \cgalCite{cgal:csd-gdbsra-04}. \subsection AFSR_Topology Topological Constraints diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index 20534d7cd0c..4f2be8333d2 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -335,7 +335,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) target_link_libraries(pca_plugin scene_polyhedron_item scene_basic_objects) qt4_wrap_ui( advancing_frontUI_FILES Polyhedron_demo_advancing_front_plugin.ui) - polyhedron_demo_plugin(advancing_front_plugin Polyhedron_demo_advancing_front_plugin Polyhedron_demo_advancing_front_plugin_impl.cpp ${advancing_frontUI_FILES}) + polyhedron_demo_plugin(advancing_front_plugin Polyhedron_demo_advancing_front_plugin Polyhedron_demo_advancing_front_plugin_impl ${advancing_frontUI_FILES}) target_link_libraries(advancing_front_plugin scene_polygon_soup_item scene_points_with_normal_item) if(EIGEN3_FOUND OR TAUCS_FOUND) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp old mode 100755 new mode 100644 index d51aee9cd90..837e1598425 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp @@ -2,7 +2,7 @@ #include "Scene_points_with_normal_item.h" #include "Polyhedron_demo_plugin_helper.h" #include "Polyhedron_demo_plugin_interface.h" -#include +#include #include @@ -14,12 +14,10 @@ #include "ui_Polyhedron_demo_advancing_front_plugin.h" -// Poisson reconstruction method: // Reconstructs a surface mesh from a point set and writes facet indices into polygon soup. -void advancing_front_reconstruct(const Point_set& points, - double sm_perimeter, - double sm_area, - Scene_polygon_soup_item*); +Polyhedron* advancing_front_reconstruct(const Point_set& points, + double sm_perimeter, + double sm_area); class Polyhedron_demo_advancing_front_plugin : public QObject, @@ -90,14 +88,11 @@ void Polyhedron_demo_advancing_front_plugin::on_actionAdvancingFrontReconstructi QApplication::setOverrideCursor(Qt::WaitCursor); // Add polyhedron to scene - Scene_polygon_soup_item* new_item = new Scene_polygon_soup_item(); - for(Point_set::iterator it = points->begin(); it!= points->end(); ++it){ - new_item->new_vertex(it->x(), it->y(), it->z()); - } - // Reconstruct point set as a polyhedron - advancing_front_reconstruct(*points, sm_perimeter, sm_area, new_item); + Polyhedron *poly = advancing_front_reconstruct(*points, sm_perimeter, sm_area); + + Scene_polyhedron_item* new_item = new Scene_polyhedron_item(poly); new_item->setName(tr("%1 Advancing Front (%2 %3)") @@ -113,6 +108,7 @@ void Polyhedron_demo_advancing_front_plugin::on_actionAdvancingFrontReconstructi QApplication::restoreOverrideCursor(); + } } diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin_impl.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin_impl.cpp new file mode 100644 index 00000000000..c4eba4540d7 --- /dev/null +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin_impl.cpp @@ -0,0 +1,32 @@ +#include "config.h" +#include "Scene_points_with_normal_item.h" +#include "Polyhedron_demo_plugin_helper.h" +#include "Polyhedron_demo_plugin_interface.h" +#include + +#include "Kernel_type.h" +#include "Polyhedron_type.h" +#include "Scene_points_with_normal_item.h" + +#include + +Polyhedron* +advancing_front_reconstruct(const Point_set& points, + double sm_perimeter, + double sm_area) +{ + typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; + typedef Reconstruction::Triangulation_3 Triangulation_3; + Polyhedron* output_mesh = new Polyhedron; + + Triangulation_3 dt(points.begin(), points.end()); + + Reconstruction reconstruction(dt); + + reconstruction(); + + CGAL::AFSR::construct_polyhedron(*output_mesh, reconstruction); + + return output_mesh; +} + diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index bb7587e934b..54c96186aec 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -275,14 +275,12 @@ QMenu* Scene_points_with_normal_item::contextMenu() actionResetSelection = menu->addAction(tr("Reset Selection")); actionResetSelection->setObjectName("actionResetSelection"); connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection())); -<<<<<<< HEAD actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points")); actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints"); connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates())); -======= ->>>>>>> old + menu->setProperty(prop_name, true); } From 058a51915bbbc70af06bc1e53f4116e149e5e506 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 4 Mar 2014 18:09:19 +0100 Subject: [PATCH 035/114] Add construct_polyhedron.h --- .../include/CGAL/AFSR/construct_polyhedron.h | 74 +++++++++++++++++++ 1 file changed, 74 insertions(+) create mode 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h new file mode 100644 index 00000000000..295241c6094 --- /dev/null +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h @@ -0,0 +1,74 @@ +#ifndef CGAL_AFSR_CONSTRUCT_POLYHEDRON_2 +#define CGAL_AFSR_CONSTRUCT_POLYHEDRON_2 + +#include +#include + +namespace CGAL { + +template +class Advancing_front_polyhedron_reconstruction; + +namespace AFSR { + + template +class Construct_polyhedron: public CGAL::Modifier_base { + + const Surface& s; + +public: + Construct_polyhedron(Surface& s) + : s(s) + {} + + void operator()( HDS& hds) + { + CGAL::Polyhedron_incremental_builder_3 B( hds, true); + B.begin_surface( s.number_of_vertices(), s.number_of_facets(), 6* s.number_of_facets()); + typedef typename HDS::Vertex Vertex; + typedef typename Vertex::Point Point; + + typedef typename Surface::TDS_2 TDS_2; + typedef typename TDS_2::Face_iterator Face_iterator; + typedef typename TDS_2::Vertex_iterator Vertex_iterator; + typedef typename Surface::Cell_handle Cell_handle; + + const TDS_2& tds = s.tds_2(); + + int index = 0; + Vertex_iterator end = tds.vertices_end(); + + for(Vertex_iterator vit = tds.vertices_begin(); vit != end; ++vit){ + if(vit->vertex_3() != s.triangulation().infinite_vertex()){ + B.add_vertex(vit->point()); + vit->vertex_3()->id() = index++; + } + } + + for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ + + if(fit->is_on_surface()){ + B.begin_facet(); + for(int i=0; i < 3; i++){ + B.add_vertex_to_facet(fit->vertex(i)->vertex_3()->id()); + } + B.end_facet(); + } + } + B.end_surface(); + } + +}; + +template +void +construct_polyhedron(Polyhedron& P, Surface& surface) +{ + typedef Polyhedron::HalfedgeDS HalfedgeDS; + Construct_polyhedron builder(surface); + P.delegate(builder); +} + +} // namespace AFSR +} // namespace CGAL +#endif // CGAL_AFSR_CONSTRUCT_POLYHEDRON_2 From c9ae94fc2b153d37a1fd89da90e1e47cb787c00f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 4 Mar 2014 18:33:59 +0100 Subject: [PATCH 036/114] fixes so that extract.cpp compiles --- .../extract.cpp | 11 +++++------ ...ncing_front_surface_reconstruction_vertex_base_3.h | 5 +++-- .../Point_set_2/CGAL/nearest_neighbor_delaunay_2.h | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index fcd71da2ace..bdc1ccf23ad 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -103,8 +103,8 @@ void usage(char* program) std::cerr << std::endl << "OPTIONS" << std::endl << " -xyz : input data in xyz format" << std::endl << " -no_border -nb : " << std::endl - << " -in fname : reads points from file ./fname" << std::endl - << " -out fname : writes points to file ./fname" << std::endl + << " -in fname : reads points from file fname" << std::endl + << " -out fname : writes points to file fname" << std::endl << " -out_format -of : choose file format for output (iv, wrl, off, medit," << std::endl << " ply, stl, all, none)" << std::endl << " -rgb r g b : color of the surface" << std::endl @@ -115,7 +115,6 @@ void usage(char* program) << " -abs_perimeter p : No faces with perimeter longer than abs_perimeter" << std::endl << "\n Options for internal use" << std::endl - << " -sect_in fname : reads points from sections file ./fname" << std::endl << " -binary : binary I/O" << std::endl << " -delta x : set the delta constant" << std::endl << " -ki x y : set the K interval (default : [1.1 5])" << std::endl @@ -405,15 +404,15 @@ int main(int argc, char* argv[]) file_input(opt, points); -#if 1 +#if 0 std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; - std::vector > triples; + std::vector > triples; reconstruction_test(points.begin(), points.end(), std::back_inserter(triples)); std::cout << triples.size() << std::endl; for(int i = 0; i < triples.size(); ++i){ - std::cout << "3 " << triples[i].first << " " << triples[i].second << " " << triples[i].third << " " << std::endl; + std::cout << "3 " << get<0>(triples[i]) << " " << get<1>(triples[i]) << " " << get<2>(triples[i]) << " " << std::endl; } #else diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index aa87cd97461..a8ca2fd0f97 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -175,12 +175,13 @@ private: return NULL; } +public: inline Next_border_elt* first_incident() const { if (m_incident_border == NULL) return NULL; return m_incident_border->first; } - +private: inline Next_border_elt* second_incident() const { if (m_incident_border == NULL) return NULL; @@ -238,7 +239,7 @@ private: } //------------------------------------------------------------------- - +public: inline void set_post_mark(const int& i) { m_post_mark = i; diff --git a/Point_set_2/doc/Point_set_2/CGAL/nearest_neighbor_delaunay_2.h b/Point_set_2/doc/Point_set_2/CGAL/nearest_neighbor_delaunay_2.h index a453d178c28..d56276e9e75 100644 --- a/Point_set_2/doc/Point_set_2/CGAL/nearest_neighbor_delaunay_2.h +++ b/Point_set_2/doc/Point_set_2/CGAL/nearest_neighbor_delaunay_2.h @@ -27,7 +27,7 @@ Dt::Vertex_handle nearest_neighbor(const Dt& delau, Dt::Vertex_handle v); namespace CGAL { /*! -\ingroup PkgPointSet2NeighborSearch + \ingroup PkgPointSet2NeighborSearch computes the `k` nearest neighbors of `p` in `delau`, and places the handles to the corresponding vertices as a sequence of objects of type From b967bec8af874f48ea8db45b056fdf4f627b0136 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 5 Mar 2014 13:15:51 +0100 Subject: [PATCH 037/114] do the reconstruction --- .../examples/Advancing_front_surface_reconstruction/extract.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index bdc1ccf23ad..a56866a511c 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -437,6 +437,7 @@ int main(int argc, char* argv[]) Surface S(dt, opt); + S(); std::cerr << "Total time: " << timer.time() << " sec." << std::endl; // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); From 1ebe7a903c9a8eea935603b92149df52fe58580a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 12 Mar 2014 16:32:38 +0100 Subject: [PATCH 038/114] increase precision and fix multiple \cgalCite --- .../Advancing_front_surface_reconstruction.txt | 8 ++++---- .../CGAL/IO/Advancing_front_surface_reconstruction.h | 4 ++++ 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 8be1e1919b6..a1f7f5b2d19 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -13,17 +13,17 @@ namespace CGAL { Surface reconstruction from an unstructured point set is to find a surface that approximates these points. Several techniques have been applied to this problem. Among them are variational -methods \cgalCite{s-lsm-96,zomk-insru-00}, tensor voting \cgalCite{cgal:ml-cfsg-00}, implicit surface \cgalCite{hddhjmss-pssr-94,bc-ssrnn-00}, +methods \cgalCite{s-lsm-96}\cgalCite{zomk-insru-00}, tensor voting \cgalCite{cgal:ml-cfsg-00}, implicit surface \cgalCite{hddhjmss-pssr-94}\cgalCite{bc-ssrnn-00}, and Delaunay triangulations. For Delaunay based algorithms the output surface usually is the union of some triangles selected in the Delaunay triangulation of the input points. Such algorithms can be volume oriented -which output the boundary of selected tetrahedra \cgalCite{abe-cbscc-97,ack-pcubm-01}, or surface +which output the boundary of selected tetrahedra \cgalCite{abe-cbscc-97}\cgalCite{ack-pcubm-01}, or surface oriented, that is they explicitely select triangles. In most surface oriented Delaunay-based algorithms triangles are -selected independently, that is in parallel \cgalCite{agj-lcsr-00,ab-srvf-98}. +selected independently, that is in parallel \cgalCite{agj-lcsr-00}\cgalCite{ab-srvf-98}. The surface oriented Delaunay-based surface reconstruction algorithm presented in this chapter selects triangles sequentially, that is by @@ -32,7 +32,7 @@ most *plausible* triangle first, and only adds triangles in a way that the surface remains an orientable manifold. Two other examples of this greedy approach are the ball pivoting -algorithm and Boyer and Petitjean's algorithm \cgalCite{bmrst-bpasr-99, pb-rnrps-01}. In both +algorithm and Boyer and Petitjean's algorithm \cgalCite{bmrst-bpasr-99}\cgalCite{pb-rnrps-01}. In both algorithms a triangulated surface is incrementally grown starting from a seed triangle. Ball pivoting is fast, but the quality of the reconstruction depends on user defined parameters corresponding to the diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h index 6bd8ff5e70e..7dd03b2bd3a 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -143,6 +143,7 @@ write_to_file_gv(char* foutput, const Surface& S) else std::cout << ">> file for output : " << foutput_tmp << std::endl; + os.precision(17); os.clear(); CGAL::set_ascii_mode(os); @@ -660,6 +661,7 @@ write_to_file_iv(char* foutput, const Surface& S, else std::cout << ">> file for output : " << foutput_tmp << std::endl; + os.precision(17); os.clear(); CGAL::set_ascii_mode(os); @@ -856,6 +858,7 @@ write_to_file_vrml2(char* foutput, const Surface& S, else std::cout << ">> file for output : " << foutput_tmp << std::endl; + os.precision(17); os.clear(); CGAL::set_ascii_mode(os); @@ -929,6 +932,7 @@ write_to_file_stl(char* foutput, const Surface& S) else std::cout << ">> file for output : " << foutput_tmp << std::endl; + os.precision(17); os.clear(); CGAL::set_ascii_mode(os); From 3441d513d4a9fbe5536a56935930abfc882ccd4d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 14 Aug 2014 10:57:32 +0200 Subject: [PATCH 039/114] add missing typename --- .../include/CGAL/AFSR/construct_polyhedron.h | 2 +- .../include/CGAL/Advancing_front_surface_reconstruction.h | 2 +- .../demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui | 0 3 files changed, 2 insertions(+), 2 deletions(-) mode change 100755 => 100644 Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h index 295241c6094..74afdc5c9ed 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h @@ -64,7 +64,7 @@ template void construct_polyhedron(Polyhedron& P, Surface& surface) { - typedef Polyhedron::HalfedgeDS HalfedgeDS; + typedef typename Polyhedron::HalfedgeDS HalfedgeDS; Construct_polyhedron builder(surface); P.delegate(builder); } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 338c94043c4..0d851fbfe39 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2293,7 +2293,7 @@ advancing_front_surface_reconstruction(PointIterator b, PointIterator e, Polyhed typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; - typedef Kernel::Point_3 Point_3; + typedef typename Kernel::Point_3 Point_3; Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), boost::make_transform_iterator(e, AFSR::Auto_count() ) ); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui old mode 100755 new mode 100644 From 84482e11dc0c13102ab11304b7c30213ce5fbf72 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 8 Sep 2014 11:15:46 +0200 Subject: [PATCH 040/114] typo --- .../CGAL/Advancing_front_surface_reconstruction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 96b1bf12b30..5167b90b1f7 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -7,7 +7,7 @@ namespace CGAL { The class `Advancing_front_surface_reconstruction` \tparam Dt must be a `Delaunay_triangulation_3` with -`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, and the geometeic traits class must be the `Exact_predicates_inexact_constructions_kernel`. +`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, and the geometric traits class must be the `Exact_predicates_inexact_constructions_kernel`. */ From ca015dd85f4b402a4ca41c0ad706caf8b4497eda Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 17 Oct 2014 13:12:37 +0200 Subject: [PATCH 041/114] polish for the submission --- ...Advancing_front_surface_reconstruction.txt | 35 ++++++++++-------- .../Advancing_front_surface_reconstruction.h | 6 +++ .../PackageDescription.txt | 15 +++----- .../fig/afsr-detail.png | Bin 0 -> 2513 bytes 4 files changed, 31 insertions(+), 25 deletions(-) create mode 100755 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index a1f7f5b2d19..454b9259c8f 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -8,7 +8,6 @@ namespace CGAL { \cgalAutoToc \author Tran Kai Frank Da and David Cohen-Steiner -\image html afsr.png Surface reconstruction from an unstructured point set is to find a surface that approximates these points. Several techniques have @@ -49,6 +48,24 @@ examples. A detailed description of the algorithm and the underlying theory can be found in \cgalCite{cgal:csd-gdbsra-04}. + + +The first step of the algorithm is the construction of a 3D Delaunay +triangulation of the point set. +The Delaunay triangle with the smallest radius is the starting point +for the greedy algorithm. It is the initial surface and it has three +boundary edges. + +The algorithm maintains a priority queue of +candidate triangles, that is of triangles incident to the boundary +edges of the current surface. The priority is the \em plausibility. +While this priority queue +is not empty, the algorithm selects the most plausible candidate triangle and adds into the +surface, and inserts new candidate triangles into the priority queue in case +there are new boundary edges. As the algorithm creates a two-manifold surface +some candidate triangles can not be selected due to topological constraints which are explained next. + + \subsection AFSR_Topology Topological Constraints Any triangle \f$t\f$ considered as next potential candidate has to share an @@ -71,7 +88,7 @@ third vertex on edge \f$e\f$. We call a triangle on which the above operations can be applied *valid*. -\subsection AFSR_Selection Selection Criteria +\subsection AFSR_Selection Plausibility of a Candidate Triangle Valid triangles for an edge on the boundary are compared through what we call their *radius*. The radius of a triangle \f$t\f$ is the radius of @@ -99,20 +116,6 @@ We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if \f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$ \beta \f$ can be chosen by the user and is by default \f$ \pi/6\f$. -\subsection AFSR_Algorithm The Algorithm - -The first step of the algorithm is the construction of a 3D Delaunay -triangulation of the point set. -The Delaunay triangle with the smallest radius is the starting point -for the greedy algorithm. - -The algorithm maintains a priority queue of -candidate triangles, that is of triangles incident to the boundary -edges. The priority is the plausibility. While this priority queue -is not empty, the algorithm adds the most plausible candidate into the -surface, and inserts new candidate triangles into the priority queue in case -there are new boundary edges. - \subsection AFSR_Boundaries Dealing with Multiple Components, Boundaries and Sharp Edges diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 5167b90b1f7..7bb9fa1cd40 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -90,6 +90,10 @@ Advancing_front_surface_reconstruction(Dt& dt); /*! calls the surface reconstruction function with the default parameters. + +\param K described in Section \ref AFSR_Boundaries +\param beta described in Section \ref AFSR_Selection + */ void operator()(double K=5, double beta= 0.18); @@ -175,6 +179,8 @@ describing the faces of the reconstructed surface. \tparam IndicesOutputIterator must be an output iterator to which `CGAL::cpp11::tuple` can be assigned. +\param K described in Section \ref AFSR_Boundaries +\param beta described in Section \ref AFSR_Selection */ template diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt index eefaac1df3a..e8ab4401e8e 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -1,6 +1,4 @@ /// \defgroup PkgAdvancingFrontSurfaceReconstruction Advancing Front Surface Reconstruction Reference -/// \defgroup PkgAdvancingFrontSurfaceReconstructionConcepts Concepts -/// \ingroup PkgAdvancingFrontSurfaceReconstruction /*! \addtogroup PkgAdvancingFrontSurfaceReconstruction @@ -9,7 +7,11 @@ \cgalPkgPicture{afsr-detail.png} \cgalPkgSummaryBegin \cgalPkgAuthors{Tran Kai Frank Da, David Cohen-Steiner} -\cgalPkgDesc{This package offers a surface reconstruction algorithm.} +\cgalPkgDesc{This package provides a greedy algorithm for surface reconstruction from an +unorganized point set. Starting from a seed facet, a piecewise linear +surface is grown by adding Delaunay triangles one by one. The most +plausible triangles are added first, in a way that avoids the appearance +of topological singularities. } \cgalPkgManuals{Chapter_Advancing_Front_Surface_Reconstruction,PkgAdvancingFrontSurfaceReconstruction} \cgalPkgSummaryEnd \cgalPkgShortInfoBegin @@ -20,12 +22,7 @@ \cgalPkgShortInfoEnd \cgalPkgDescriptionEnd -This chapter presents a greedy algorithm for surface reconstruction from -unorganized point sets. Starting from a seed facet, a piecewise linear -surface is grown by adding Delaunay triangles one by one. The most -plausible triangles are added first, in a way that avoids the appearance -of topolgical singularities. The output is thus guranteed to be a -piecewise linear orientable manifold, possibly with boundary. + */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png new file mode 100755 index 0000000000000000000000000000000000000000..5fd4b3e6c2a067a0691dcc399f0d1a2b8f37731e GIT binary patch literal 2513 zcmV;?2`=`DP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGmbN~PnbOGLGA9w%&31&$|K~#8N?V3$; zEw>FuwGa=z+U&s7EW^{citHejs?0Kf`9MGvFZk0S39{K&It9z!Y!U!*p6n`@KYssk zJntsyBOovD!du-Z>UlFyZ*rON`}1{|A4$idlmuUdyg#4E-z1k24dtI6%7d>FWu)** zT+cT=k*D6FHhm=t;5mJLB9H98HuQ8|?Rm7PhqaDbH^!ZQ%C|KR9?p~cZckZ#EpC3O zr^hsXIbVw;@I+4!=on+YoNT_KapW@FX`J4!aiCq2z_UCZ-RrO+aC!DYo(^pk6SNPp zxYKgnUgBO(?6PZijm<_+mTmWPTz|bIYwWkDI^5Gi&0$i#!)ovE%GO(YC#Q5aHX}z# z;8;&bw6($z7)X1jr#pMXL>PJRSW=sCgD-f6KaH_g5~9}= z2jvV%n{#;O8GuVqHn2nzV$u^*#s^0F9b)qMFtP4z|7zj`K_g7`#2EI3d};+jRYtEm zd~k-e=wt(%Bq8jckWa0|pjrWG-$w6#7gW)i9u`VM40u8^wNeZ!8jyQjVc+ROUT&s= zt&$Lzo{&tfw1cV#T!gn}=Wl5*$7^tFF5Y&7?<}rlv_;8g|B;n_3Pbi{R(x4s!GMFBWr^b?lt&$K0Ps#D6 zo=``v6odNdnWlYnSK5@_k`UTcay*sf?g@3&N+YPNfXu1F<%X25%_(O|Lag(II%>rd z)ZQmDvrqDsO9qaB8zdpVJeAHa@`O@qr8lVCfXwc_B_YI9c#Q_&CtGS>>18;aZ~ zDHv)?LO4o7pr~3Ih;|a1M%_f?Q-eDt@xx9}sHs+Z!@jmT2HpL+k`Nm_ zp|V=B1U2ku2*~WsY?oBuY>|YR@r2@P#S+x>oFvWwWa^z9Bnh$F6N;;q%NRJ42Hp45 zO?>EOucWJ;MoEZ0p1L;Yf#Wjf2}9s4Nr=^+(1KcNMAzmt=%%k$)N2j_<`m0}pTslX|j>npW&BfBJ7_9U^+6Bxk# zR(L`$Y9)>K*EFzGMp(zP$HH4lLR@-6FKQ)?_E!$Nj&1tJZI`T<)c$%E1D+6Lo@(nc z=q~2D+jm}ax+H|VCv>D%5XD6fxpUg2P2~qQerqWlA;vxd;GO8ZN zPStpTB!sUgG!>s~D+p?Sbk@TMi>#DXTOSHXPv|R}$X|H{$b|ZtIa}oYB_Wh2^re)j zSDDQy^BEM&Bo!Cu!sV9fQ-Qd-)t!hB&k>LFiJ|5sGtrP40J_K=6RA3%9C<%8PuWo zK;09jcuPv37et(LoOoBrodf*rg?qx3qa~>kcZJ-qg!@3<6DnLK#fSb-BfbojiqCSD z9&lWqJn+qybAzNf+<}m;12dzUIje9?Rl`pb|9lNK;@*%R>kJQQ_@KfoPa983YQ$Y3 z?Q}9cBd_6l$4(H0DM@qBj4DTQ6zzjhKR@NjC}-wee#1a${YMotorD()@2vjWD{cs^qE8 zKtDULkn$yIk)9M1wdJ0cDg&MDX+B3JZ7>ueQR{DODbdx&hMsGXq@9K$Bq|{9-dHks zRbSWYCAUe6kf=5Hzf5ba8ydXL5TO6;CXctWXb|n3#)_e}TP4Zg&%k{g?QE7>zWt1G zmL!Hm`HiNL>avPs8#A0Ji6K!=Gpgme%lN{@FVGX be*gYI-?Vzi@XAmT00000NkvXXu0mjfJ?XW> literal 0 HcmV?d00001 From b2c0e0db7e857122cfdb97ef76890c919509aece Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 25 Aug 2014 16:51:08 +0200 Subject: [PATCH 042/114] Use the MathJaX CDN with https:// Otherwise, Firefox, when reading CGAL documentation pages through an https connection, will refuse to load MathJaX via the CDN. (cherry picked from commit 6f249606770bc8305c453fe810bbf900730014b7) --- Documentation/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/CMakeLists.txt b/Documentation/CMakeLists.txt index 0c19f9ce7f9..b6322f75848 100644 --- a/Documentation/CMakeLists.txt +++ b/Documentation/CMakeLists.txt @@ -108,7 +108,7 @@ find_package(PythonInterp 2.6.8) if(DOXYGEN_FOUND) # set up the directories and variables - set(CGAL_DOC_MATHJAX_LOCATION "http://cdn.mathjax.org/mathjax/latest" + set(CGAL_DOC_MATHJAX_LOCATION "https://cdn.mathjax.org/mathjax/latest" CACHE STRING "The location of MathJax to be used for the documentation.") set(CGAL_DOC_OUTPUT_DIR "${CMAKE_BINARY_DIR}/doc_output") From 3f36f26f21422400a9e53ce0487e16a626ba6de6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 17 Oct 2014 13:19:20 +0200 Subject: [PATCH 043/114] remove exe flag --- .../Doxyfile.in | 0 .../dependencies | 0 .../fig/valid.png | Bin .../reconstruction_class.cpp | 0 .../reconstruction_fct.cpp | 0 .../include/CGAL/AFSR/write_triple_indices.h | 0 6 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in mode change 100755 => 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies mode change 100755 => 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png mode change 100755 => 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp mode change 100755 => 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp mode change 100755 => 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/valid.png old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h old mode 100755 new mode 100644 From 622bc7a7db87418cb00a677e3be4d4ef8c4d39d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 17 Oct 2014 13:24:38 +0200 Subject: [PATCH 044/114] Hidden_type -> unspecified_type --- .../CGAL/Advancing_front_surface_reconstruction.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 7bb9fa1cd40..1fd52945198 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -28,7 +28,7 @@ public: In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite vertex of the 3D triangulation. */ - typedef Hidden_type TDS_2; + typedef unspecified_type TDS_2; /*! The type of the 3D triangulation. @@ -60,7 +60,7 @@ The facet type of the 3D triangulation. from the 3D Delaunay triangulation during the surface reconstruction. The value type of the iterator is `Triangulation_3::Point_3`. */ -typedef Hidden_type Outlier_iterator; +typedef unspecified_type Outlier_iterator; /*! A forward iterator which allows to visit all boundaries. It @@ -69,7 +69,7 @@ typedef Hidden_type Outlier_iterator; brings us to the vertex on the next boundary. The value type of the iterator is `Triangulation_3::Vertex_handle`. */ -typedef Hidden_type Boundary_iterator; +typedef unspecified_type Boundary_iterator; /// @} From c74a7ebebed8a3d17cddbd35de5a6de970ad02a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 17 Oct 2014 13:26:41 +0200 Subject: [PATCH 045/114] typos --- .../Advancing_front_surface_reconstruction.txt | 2 +- .../CGAL/Advancing_front_surface_reconstruction.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 454b9259c8f..cd9b0fbd3fc 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -131,7 +131,7 @@ or a hole. As we do not want the algorithm to rely on a uniformity condition on the sampling it will fill holes cut off from "flat" regions of the -surface. However, in many cases a boundary component cannot be cloded +surface. However, in many cases a boundary component cannot be closed by adding a spanning disk such that the resulting disk is well sampled. Typically, closing a boundary component due to a transversal clipping of the operation, would yield large dihedral angles at diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 1fd52945198..b98d71e327c 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -106,7 +106,7 @@ tds_2(); /*! returns the underlying 3D Delaunay triangulation. */ -const Triangulation_3_& +const Triangulation_3& triangulation_3(); From c9b7fb24bb5ac8fe2aabecf6ba8b80b4ebcf28a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 17 Oct 2014 14:23:24 +0200 Subject: [PATCH 046/114] remove tex files --- .../main.aux | 34 --------- .../main.tex | 13 ---- .../AFSR_cell_base_3.tex | 37 ---------- .../AFSR_options.tex | 14 ---- .../AFSR_vertex_base_3.tex | 33 --------- .../AFSR_vertex_base_with_id_3.tex | 31 -------- ...Advancing_front_surface_reconstruction.tex | 71 ------------------- .../Surface_face_base_2.tex | 39 ---------- .../Surface_vertex_base_2.tex | 29 -------- .../intro.tex | 16 ----- .../main.tex | 8 --- .../write_to_file_vrml2.tex | 18 ----- 12 files changed, 343 deletions(-) delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_options.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_face_base_2.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_vertex_base_2.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/intro.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/main.tex delete mode 100755 Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux deleted file mode 100755 index 01003caf766..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.aux +++ /dev/null @@ -1,34 +0,0 @@ -\relax -\@writefile{toc}{\contentsline {chapter}{\numberline {1}Advancing Front Surface Reconstuction}{1}} -\@writefile{lof}{\addvspace {10\p@ }} -\@writefile{lot}{\addvspace {10\p@ }} -\@writefile{lof}{\contentsline {xchapter}{Advancing Front Surface Reconstuction}{1}} -\@writefile{lot}{\contentsline {xchapter}{Advancing Front Surface Reconstuction}{1}} -\newlabel{chap:surface_reconstruction}{{1}{1}} -\@writefile{toc}{\contentsline {section}{\numberline {1.1}Introduction}{1}} -\@setckpt{Advancing_front_surface_reconstruction/main}{ -\setcounter{page}{2} -\setcounter{equation}{0} -\setcounter{enumi}{0} -\setcounter{enumii}{0} -\setcounter{enumiii}{0} -\setcounter{enumiv}{0} -\setcounter{footnote}{0} -\setcounter{mpfootnote}{0} -\setcounter{part}{0} -\setcounter{chapter}{1} -\setcounter{section}{1} -\setcounter{subsection}{0} -\setcounter{subsubsection}{0} -\setcounter{paragraph}{0} -\setcounter{subparagraph}{0} -\setcounter{figure}{0} -\setcounter{table}{0} -\setcounter{r@tfl@t}{0} -\setcounter{LT@tables}{0} -\setcounter{LT@chunks}{0} -\setcounter{mtc}{1} -\setcounter{minitocdepth}{2} -\setcounter{ptc}{0} -\setcounter{parttocdepth}{2} -} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.tex deleted file mode 100755 index 713ddc1e4fe..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction/main.tex +++ /dev/null @@ -1,13 +0,0 @@ -\chapter{Advancing Front Surface Reconstuction} -\label{chap:surface_reconstruction} -\ccChapterAuthor{Frank Da and David Cohen-Steiner} - - -\section{Introduction} - -This package offers an algorithm for surface reconstruction from an unorganized point set. -The algorithm selects facets of the 3D Delaunay triangulation of the points. - - - - diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex deleted file mode 100755 index d7cc8686c18..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex +++ /dev/null @@ -1,37 +0,0 @@ -\begin{ccRefClass}{AFSR_cell_base_3} - -\ccDefinition - The class \ccRefName\ is the cell class that must be blended in the cell parameter -of the 3D Delaunay triagulation. It mainly provides storage and methods used by the -Advancing front surface reconstruction algorithm. - - -\ccInclude{CGAL/AFSR_cell_base_3.h} - -\ccInheritsFrom - -\ccc{CellBase} - -%\ccTypes - -%\ccTypedef{typedef Kernel::FT FT;}{The number type.} - -%\ccCreation -%\ccCreationVariable{c} - -%\ccConstructor{AFSR_cell_base_3();}{Default constructor} - -%\ccOperations - -%\ccMemberFunction{bool has_facet_on_surface(int i) const;}{Returns \ccc{true}, iff the facet is on the surface.} - -%\ccSeeAlso - -%\ccRefIdfierPage{} - -\end{ccRefClass} - - - - - diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_options.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_options.tex deleted file mode 100755 index 06b2ffae373..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_options.tex +++ /dev/null @@ -1,14 +0,0 @@ -\begin{ccRefClass}{AFSR_options} - -\ccDefinition - -The class \ccRefName\ is used as a container of the options of the surface reconstruction algorithm. - -\ccInclude{CGAL/AFSR_options.h} - - -%\ccSeeAlso - -%\ccRefIdfierPage{} - -\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex deleted file mode 100755 index bffba82de7d..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex +++ /dev/null @@ -1,33 +0,0 @@ -\begin{ccRefClass}{AFSR_vertex_base_3} - -\ccDefinition - -The class \ccRefName\ is the vertex class that must be blended in the vertex parameter -of the 3D Delaunay triagulation. It mainly provides storage and methods used by the -Advancing front surface reconstruction algorithm. - -\ccInclude{CGAL/AFSR_vertex_base_3.h} - - -\ccInheritsFrom - -\ccc{VertexBase} - -%\ccTypes - -%\ccTypedef{typedef Kernel::FT FT;}{The number type.} - -%\ccCreation -%\ccCreationVariable{v} - -%\ccConstructor{Surface_vertex_base_2();}{Default constructor} - -%\ccOperations - -%\ccMemberFunction{Vertex_handle_3 vertex_3() const;}{Returns the vertex handle in the 3D Delaunay triangulation.} - -%\ccSeeAlso - -%\ccRefIdfierPage{} - -\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex deleted file mode 100755 index 276a2aef984..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex +++ /dev/null @@ -1,31 +0,0 @@ -\begin{ccRefClass}{AFSR_vertex_base_with_id_3} - -\ccDefinition - -The class \ccRefName\ is the vertex class that must be blended in the vertex parameter -of the 3D Delaunay triagulation. It mainly provides storage and methods used by the -Advancing front surface reconstruction algorithm. - -\ccInclude{CGAL/AFSR_vertex_base_with_id_3.h} - - - -%\ccTypes - -%\ccTypedef{typedef Kernel::FT FT;}{The number type.} - -%\ccCreation -\ccCreationVariable{v} - -%\ccConstructor{Surface_vertex_base_2();}{Default constructor} - -\ccOperations - -\ccMemberFunction{int& id() const;}{Returns a reference to an \ccc{int} that is not used or altered by the - surface reconstruction algorithm.} - -%\ccSeeAlso - -%\ccRefIdfierPage{} - -\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex deleted file mode 100755 index 6f405227aab..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex +++ /dev/null @@ -1,71 +0,0 @@ -\begin{ccRefClass}{Advancing_front_surface_reconstruction} - -\ccDefinition - -The class \ccRefName\ extracts a surface from a 3D Delaunay triangulation. - -\ccInclude{CGAL/Advancing_front_surface_reconstruction.h} - -\ccParameters - -The parameter for \ccc{Delaunay_3} must be a 3D Delaunay triangulation where \ccc{CGAL::AFSR_vertex_base_3} -or \ccc{CGAL::AFSR_vertex_base_with_id_3} and \ccc{CGAL::AFSR_cell_base_3} must be blended in the vertex and face class. - - - -\ccTypes - -\ccTypedef{typedef Delaunay_3 Triangulation_3;}{} -\ccTypedef{typedef CGAL::Triple Edge;}{For \ccc{(ch,i,j)}, this is the edge between vertices \ccc{i} and \ccc{j} in cell \ccc{*ch}.} - -\ccTypedef{typedef std::pair Edge_incident_facet;}{For \ccc{((ch,i,j),k)}, this is the facet adjacent to the edge \ccc{(,i,j)}, and - opposite to vertex \ccc{k}, in the cell \ccc{*ch}.} -\ccGlue -\ccNestedType{TDS_2}{The type of the 2D triangulation data structure describing the reconstructed surface.} -\ccNestedType{TDS_2::Vertex}{It is model of the concept \ccc{TriangulationDataStructure_2::Vertex} and has additionally the - method \ccc{vertex_3()} that returns a \ccc{Triangulation_3::Vertex_handle} to the associated 3D vertex.} -\ccNestedType{TDS_2::Face}{It is model of the concept \ccc{TriangulationDataStructure_2::Face} and has additionally the - method \ccc{facet()} that returns the associated \ccc{Triangulation_3::Facet}.} - -\ccNestedType{Boundary_iterator}{This forward iterator allows to visit all contours. It - visits the entry point of the contour twice. This allows to - detect that the traversal of the border is finished. One more increment - brings us to the vertex on the next boundary. The value type of the iterator is \ccc{Triangulation_3::Vertex_handle}.} - -\ccNestedType{Outlier_iterator}{This bidirectional iterator allows to enumerate all points that were removed - from the 3D Delaunay triangulation during the surface reconstruction. The value type - of the iterator is \ccc{Kernel::Point_3}.} - -\ccCreation -\ccCreationVariable{es} - -\ccConstructor{Advancing_front_surface_reconstruction(Delaunay_3& del, AFSR_options opt);}{} - -\ccOperations - -\ccMemberFunction{const TDS_2& tds_2() const;}{Returns a const reference to the reconstructed surface. } -\ccMemberFunction{bool is_on_surface(TDS_2::Vertex_handle vh;}{Returns true, iff the vertex is on the reconstructed surface.} - - -\ccMemberFunction{const Triangulation_3& triangulation() const;}{Returns a const reference to the 3D Delaunay triangulation.} - -\ccMemberFunction{Boundary_iterator boundaries_begin() const;}{} -\ccMemberFunction{Boundary_iterator boundaries_end() const;}{} - -\ccMemberFunction{Outlier_iterator outliers_begin() const;}{} -\ccMemberFunction{Outlier_iterator outliers_end() const;}{} - -\ccMemberFunction{bool has_on_surface(Triangulation_3::Facet f) const;} - {Returns \ccc{true}, iff the facet is on the reconstructed surface.} - -\ccMemberFunction{Edge_incident_facet next(const Edge_incident_facet& f) const;}{returns the next facet around the edge.} -\ccMemberFunction{Edge_incident_facet previous(const Edge_incident_facet& f) const;}{returns the previous facet around the edge.} - -\ccMemberFunction{Facet next_surface_facet(const Edge_incident_facet& f) const}{returns the next facet ariund the edge, - which is on the reconstructed surface.} - -%\ccSeeAlso - -%\ccRefIdfierPage{} - -\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_face_base_2.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_face_base_2.tex deleted file mode 100755 index d9328eba201..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_face_base_2.tex +++ /dev/null @@ -1,39 +0,0 @@ -\begin{ccRefClass}{AFSR::Surface_face_base_2} - -\ccDefinition - -The class \ccRefName\ is the face class used in the triangulation data structure -that describes the reconstructed surface. A face is either part of this -surface, or it is not part of the surface but adjacent to the boundary of the surface. - -The face class stores a facet of the 3D Delaunay triangulation, if it -is part of the surface. - -\ccInclude{CGAL/AFSR/Surface_face_base_2.h} - - -%\ccTypes - -%\ccTypedef{typedef Kernel::FT FT;}{The number type.} - -%\ccCreation -\ccCreationVariable{f} - -%\ccConstructor{Surface_face_base_2();}{Default constructor} - -\ccOperations - -\ccMemberFunction{Facet facet() const;}{Returns the facet in the 3D Delaunay triangulation.} - -\ccMemberFunction{bool is_on_surface() const;}{Returns \ccc{true}, iff the face is on the surface.} - -%\ccSeeAlso - -%\ccRefIdfierPage{} - -\end{ccRefClass} - - - - - diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_vertex_base_2.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_vertex_base_2.tex deleted file mode 100755 index 2a2845e231d..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/Surface_vertex_base_2.tex +++ /dev/null @@ -1,29 +0,0 @@ -\begin{ccRefClass}{AFSR::Surface_vertex_base_2} - -\ccDefinition - -The class \ccRefName\ is the vertex class used in the 2D triangulation data structure -that describes the reconstructed surface. It stores a vertex handle to its -correpsonding vertex in the 3D Delaunay triangulation. - -\ccInclude{CGAL/AFSR/Surface_vertex_base_2.h} - - -%\ccTypes - -%\ccTypedef{typedef Kernel::FT FT;}{The number type.} - -%\ccCreation -\ccCreationVariable{v} - -%\ccConstructor{Surface_vertex_base_2();}{Default constructor} - -\ccOperations - -\ccMemberFunction{Vertex_handle_3 vertex_3() const;}{Returns the vertex handle in the 3D Delaunay triangulation.} - -%\ccSeeAlso - -%\ccRefIdfierPage{} - -\end{ccRefClass} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/intro.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/intro.tex deleted file mode 100755 index ee184dd930d..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/intro.tex +++ /dev/null @@ -1,16 +0,0 @@ -\chapter{Advancing Front Surface Reconstruction} -\label{chap:surface_reconstruction_ref} -\ccChapterAuthor{Frank Da and David Cohen-Steiner} - - -\ccHeading{Classes} - -\ccRefIdfierPage{CGAL::Advancing_front_surface_reconstruction}\\ -\ccRefIdfierPage{CGAL::AFSR_options}\\ -\ccRefIdfierPage{CGAL::AFSR_face_base_3}\\ -\ccRefIdfierPage{CGAL::AFSR_vertex_base_3}\\ -\ccRefIdfierPage{CGAL::AFSR_vertex_base_with_id_3} - -\ccHeading{Functions} - -\ccRefIdfierPage{CGAL::write_to_file_vrml2} diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/main.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/main.tex deleted file mode 100755 index 1501aa839d0..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/main.tex +++ /dev/null @@ -1,8 +0,0 @@ - -\input{Advancing_front_surface_reconstruction_ref/intro.tex} - -\input{Advancing_front_surface_reconstruction_ref/Advancing_front_surface_reconstruction.tex} -\input{Advancing_front_surface_reconstruction_ref/AFSR_cell_base_3.tex} -\input{Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_3.tex} -\input{Advancing_front_surface_reconstruction_ref/AFSR_vertex_base_with_id_3.tex} -\input{Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex} \ No newline at end of file diff --git a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex b/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex deleted file mode 100755 index cc7ffd4a287..00000000000 --- a/Advancing_front_surface_reconstruction/doc_tex/Advancing_front_surface_reconstruction_ref/write_to_file_vrml2.tex +++ /dev/null @@ -1,18 +0,0 @@ -\begin{ccRefFunction}{write_to_file_vrml2} - -\ccDefinition - -The function \ccRefName\ writes the reconstructed surface to a file. - -\ccInclude{CGAL/IO/Advancing_front_surface_reconstruction.h} - -\ccFunction{template -void -write_to_file_vrml2(char* foutput, const Surface& S, - bool boundary, double red, double green, double blue, bool no_header);} -{Opens a file with the basename \ccc{foutput} and the file extension \ccc{.wrl}, and writes the -reconstructed surface to this file. If \ccc{boundary} is \ccc{true} the boundary is drawn. -The color of the facets is defined by \ccc{red}, \ccc{green}, and \ccc{blue}. If \ccc{no_header} is -\ccc{true}, the VRML header is not written.} - -\end{ccRefFunction} \ No newline at end of file From f886cd6588d0010b3247052eced09baa2e0b8eed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Fri, 17 Oct 2014 14:29:52 +0200 Subject: [PATCH 047/114] document parameters to avoid a warning --- .../CGAL/Advancing_front_surface_reconstruction.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index b98d71e327c..14980d883a0 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -179,12 +179,15 @@ describing the faces of the reconstructed surface. \tparam IndicesOutputIterator must be an output iterator to which `CGAL::cpp11::tuple` can be assigned. +\param begin iterator on the first point of the sequence +\param end past the end iterator the point sequence +\param out output iterator \param K described in Section \ref AFSR_Boundaries \param beta described in Section \ref AFSR_Selection */ template - void advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double K=5, double beta= 0.18 ); + void advancing_front_surface_reconstruction(PointInputIterator begin, PointInputIterator end, IndicesOutputIterator out, double K=5, double beta= 0.18 ); } /* end namespace CGAL */ From f70eb8a2b4b335013b8405ea20b26e1e9afd7a5b Mon Sep 17 00:00:00 2001 From: Laurent Rineau Date: Mon, 25 Aug 2014 16:51:08 +0200 Subject: [PATCH 048/114] Use the MathJaX CDN with https:// Otherwise, Firefox, when reading CGAL documentation pages through an https connection, will refuse to load MathJaX via the CDN. (cherry picked from commit 6f249606770bc8305c453fe810bbf900730014b7) --- Documentation/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Documentation/CMakeLists.txt b/Documentation/CMakeLists.txt index 0c19f9ce7f9..b6322f75848 100644 --- a/Documentation/CMakeLists.txt +++ b/Documentation/CMakeLists.txt @@ -108,7 +108,7 @@ find_package(PythonInterp 2.6.8) if(DOXYGEN_FOUND) # set up the directories and variables - set(CGAL_DOC_MATHJAX_LOCATION "http://cdn.mathjax.org/mathjax/latest" + set(CGAL_DOC_MATHJAX_LOCATION "https://cdn.mathjax.org/mathjax/latest" CACHE STRING "The location of MathJax to be used for the documentation.") set(CGAL_DOC_OUTPUT_DIR "${CMAKE_BINARY_DIR}/doc_output") From d3e13f50f11321c2718ca8afa2d327540bd99736 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Sun, 19 Oct 2014 22:03:26 +0200 Subject: [PATCH 049/114] fixes suggested by Sebastien --- .../Advancing_front_surface_reconstruction.txt | 4 ++-- .../CGAL/Advancing_front_surface_reconstruction.h | 6 +++--- .../doc/Advancing_front_surface_reconstruction/Doxyfile.in | 1 + 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 454b9259c8f..3d34133c5b3 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -141,8 +141,8 @@ would be very different. These heuristic facts can be used for boundary detection. We discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$ -such that \f$ p(t) < 0\f$, and \f$ r_t > K r_{t'}\f$ where \f$ t'\f$ is -the triangle on the surface incident on \f$ e \f$. The parameter \f$ K \f$ +such that \f$ p(t) < 0\f$, and \f$ r_t > k r_{t'}\f$ where \f$ t'\f$ is +the triangle on the surface incident on \f$ e \f$. The parameter \f$ k \f$ can be chosen by the user and is by default 5. diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 7bb9fa1cd40..002dddc2a8b 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -91,11 +91,11 @@ Advancing_front_surface_reconstruction(Dt& dt); /*! calls the surface reconstruction function with the default parameters. -\param K described in Section \ref AFSR_Boundaries +\param k described in Section \ref AFSR_Boundaries \param beta described in Section \ref AFSR_Selection */ - void operator()(double K=5, double beta= 0.18); + void operator()(double k=5, double beta= 0.18); /*! returns the reconstructed surface. @@ -184,7 +184,7 @@ describing the faces of the reconstructed surface. */ template - void advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double K=5, double beta= 0.18 ); + IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double k=5, double beta= 0.18 ); } /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in index da8f676b361..b440784ea24 100755 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in @@ -7,3 +7,4 @@ INPUT = ${CMAKE_SOURCE_DIR}/Advancing_front_surface_recons +MULTILINE_CPP_IS_BRIEF = YES \ No newline at end of file From 1504395c09e3e3e3277c03d58889db8b39aabbd2 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 20 Jan 2015 17:31:16 +0100 Subject: [PATCH 051/114] Add max_perimeter as argument to the global function --- .../include/CGAL/Advancing_front_surface_reconstruction.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 0d851fbfe39..1c9b3cf268d 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2284,7 +2284,7 @@ advancing_front_surface_reconstruction(PointIterator b, PointIterator e, IndexTr } template void -advancing_front_surface_reconstruction(PointIterator b, PointIterator e, Polyhedron_3& polyhedron) +advancing_front_surface_reconstruction(PointIterator b, PointIterator e, Polyhedron_3& polyhedron, double max_perimeter = 2) { typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; @@ -2297,8 +2297,10 @@ advancing_front_surface_reconstruction(PointIterator b, PointIterator e, Polyhed Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), boost::make_transform_iterator(e, AFSR::Auto_count() ) ); - - Reconstruction R(dt); + + AFSR_options opt; + opt.abs_perimeter = max_perimeter; + Reconstruction R(dt, opt); R(); AFSR::construct_polyhedron(polyhedron, R); } From 1b3b61158b3701b9ce1d4c7a74af5ebc1c157827 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 13 Mar 2015 16:17:27 +0100 Subject: [PATCH 052/114] Add most of Pierre's review --- ...Advancing_front_surface_reconstruction.txt | 192 +++++++++++------- .../Advancing_front_surface_reconstruction.h | 53 +++-- .../examples.txt | 1 + .../CMakeLists.txt | 1 + .../reconstruction_class.cpp | 13 +- 5 files changed, 158 insertions(+), 102 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index cc20dc36c12..0ae72e8ac9a 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -8,98 +8,105 @@ namespace CGAL { \cgalAutoToc \author Tran Kai Frank Da and David Cohen-Steiner +Surface reconstruction from an unstructured point cloud amounts to +generate a plausible surface that approximates well the input +points. This problem is ill-posed as many surfaces can be generated. A +wide range of approaches have been proposed to tackle this +problem. Among them are variational methods +\cgalCite{s-lsm-96}\cgalCite{zomk-insru-00}, tensor voting +\cgalCite{cgal:ml-cfsg-00}, implicit surface +\cgalCite{hddhjmss-pssr-94}\cgalCite{bc-ssrnn-00}, and Delaunay +triangulations. -Surface reconstruction from an unstructured point set is to find -a surface that approximates these points. Several techniques have -been applied to this problem. Among them are variational -methods \cgalCite{s-lsm-96}\cgalCite{zomk-insru-00}, tensor voting \cgalCite{cgal:ml-cfsg-00}, implicit surface \cgalCite{hddhjmss-pssr-94}\cgalCite{bc-ssrnn-00}, -and Delaunay triangulations. +For Delaunay based algorithms the output surface is commonly generated +as the union of some triangles selected in the 3D Delaunay +triangulation of the input points. Such algorithms are either +volume-based by generating as output the boundary of selected +tetrahedra \cgalCite{abe-cbscc-97}\cgalCite{ack-pcubm-01}, +or surface-based by selecting a set of triangles. -For Delaunay based algorithms the output surface -usually is the union of some triangles selected in the Delaunay -triangulation of the input points. Such algorithms can be volume oriented -which output the boundary of selected tetrahedra \cgalCite{abe-cbscc-97}\cgalCite{ack-pcubm-01}, or surface -oriented, that is they explicitely select triangles. -In most surface oriented Delaunay-based algorithms triangles are +In most surface based Delaunay algorithms the triangles are selected independently, that is in parallel \cgalCite{agj-lcsr-00}\cgalCite{ab-srvf-98}. -The surface oriented Delaunay-based surface reconstruction algorithm -presented in this chapter selects triangles sequentially, that is by -using previous selected triangles to select a new one. It adds the -most *plausible* triangle first, and only adds triangles in a way -that the surface remains an orientable manifold. - -Two other examples of this greedy approach are the ball pivoting -algorithm and Boyer and Petitjean's algorithm \cgalCite{bmrst-bpasr-99}\cgalCite{pb-rnrps-01}. In both -algorithms a triangulated surface is incrementally grown starting from -a seed triangle. Ball pivoting is fast, but the quality of the -reconstruction depends on user defined parameters corresponding to the -sampling density. The Boyer Petitjean approach can handle non-uniform -sampling, but fails when near cocircular points are encountered, and -it does not provide any guarantee on the topology of the surface. +This chapter presents a surface-based Delaunay surface +reconstruction algorithm by selecting the triangles sequentially, that +is by using previous selected triangles to select a new triangle for +advancing the front. At each advancing step the most plausible +triangle is selected, and the triangles are selected in a way that +generates an orientable manifold triangulated surface. -In the next sections we describe the algorithm, and give -examples. +Two other examples of this greedy approach are the ball pivoting +algorithm and Boyer-Petitjean's algorithm \cgalCite{bmrst-bpasr-99}\cgalCite{pb-rnrps-01}. In both algorithms +a triangulated surface is incrementally grown starting from a seed +triangle. Ball pivoting is fast, but the quality of the reconstruction +depends on user defined parameters corresponding to the sampling +density. The Boyer-Petitjean approach can handle non-uniform sampling, +but fails when near co-circular points are encountered, and it does +not provide any guarantee on the topology of the surface. + +We describe next the algorithm and provide examples. \section AFSR_Definitions Definitions and the Algorithm -A detailed description of the algorithm and the underlying theory can be found +A detailed description of the algorithm and the underlying theory are provided in \cgalCite{cgal:csd-gdbsra-04}. +The first step of the algorithm is the construction of a 3D Delaunay +triangulation of the point set. The Delaunay triangle with the +smallest radius is the starting point for the greedy algorithm. The +radius of a triangle \f$ t \f$ is the radius of the smallest sphere +passing through the vertices of \f$ t\f$ and enclosing no sample +point. In other words, the radius \f$ r_t\f$ is the distance from any +vertex of \f$ t\f$ to the Voronoi edge dual to \f$ t\f$. This triangle with +three boundary edges is the initial triangulated surface, and its +boundary is the advancing front. -The first step of the algorithm is the construction of a 3D Delaunay -triangulation of the point set. -The Delaunay triangle with the smallest radius is the starting point -for the greedy algorithm. It is the initial surface and it has three -boundary edges. - -The algorithm maintains a priority queue of -candidate triangles, that is of triangles incident to the boundary -edges of the current surface. The priority is the \em plausibility. -While this priority queue -is not empty, the algorithm selects the most plausible candidate triangle and adds into the -surface, and inserts new candidate triangles into the priority queue in case -there are new boundary edges. As the algorithm creates a two-manifold surface -some candidate triangles can not be selected due to topological constraints which are explained next. +The algorithm maintains a priority queue of candidate triangles, that +is of valid triangles incident to the boundary edges of the current +surface. The priority is the plausibility. While the priority queue is +not empty, the algorithm pops from the queue the most plausible +candidate triangle and adds it to the surface. New candidate triangles +are pushed to the priority queue when new boundary edges appear on the +advancing front. As the algorithm creates a two-manifold surface some +candidate triangles can not be selected due to topological constraints +which are explained next. \subsection AFSR_Topology Topological Constraints -Any triangle \f$t\f$ considered as next potential candidate has to share an -edge \f$e\f$ with the boundary of the current reconstruction. Let \f$b\f$ +Any triangle \f$t\f$ considered as next potential candidate shares an +edge \f$e\f$ with the front of the current reconstruction. Let \f$b\f$ be the vertex of \f$t\f$ opposite to \f$e\f$. There are four -possible situations where \f$t\f$ may be added to the surface. +configurations where \f$t\f$ is added to the surface. + - extension, if \f$b\f$ is not yet on the surface. -- hole filling, if \f$b\f$ is on the boundary and both neighbors of \f$b\f$ on the boundary are on edge \f$e\f$. -- ear filling, if \f$b\f$ is on the boundary and one neighbor of \f$b\f$ on the boundary is on edge \f$e\f$. -- glueing, if \f$b\f$ is on the boundary and no neighbor of \f$b\f$ on the boundary is on edge \f$e\f$. +- hole filling, if \f$b\f$ is on the front and both neighbors of \f$b\f$ on the front are on edge \f$e\f$. +- ear filling, if \f$b\f$ is on the front and one neighbor of \f$b\f$ on the front is on edge \f$e\f$. +- glueing, if \f$b\f$ is on the front and no neighbor of \f$b\f$ on the front is on edge \f$e\f$. \cgalFigureBegin{figAFSRvalid,valid.png} Valid candidates. \cgalFigureEnd -While the first three operations would never induce a non-manifold edge or vertex, -we only can perform glueing, if triangle \f$t\f$ has a *twin* facet, that is a -triangle with an edge on the boundary and incident to \f$b\f$, and the +While the first three operations never induce a non-manifold edge or vertex, +we only can perform gluing, if triangle \f$t\f$ has a *twin* facet, that is a +triangle with an edge on the front and incident to \f$b\f$, and the third vertex on edge \f$e\f$. -We call a triangle on which the above operations can be applied *valid*. +A triangle is said *valid* when the above operations can be applied. \subsection AFSR_Selection Plausibility of a Candidate Triangle -Valid triangles for an edge on the boundary are compared through what -we call their *radius*. The radius of a triangle \f$t\f$ is the radius of -the smallest sphere passing through the vertices of \f$t\f$ and enclosing no -sample point. In other words, the radius \f$r_t\f$ is the distance -from any vertex of \f$t\f$ to the Voronoi edge dual to \f$t\f$. +Valid triangles for an edge on the front are compared through their +radius. While the radius is a good criterion in the case of 2D smooth +curve reconstruction \cgalCite{b-cccda-94}, we need another criterion +for 3D surface reconstruction, namely the dihedral angle between +triangles on the surface, that is the angle between the normals of the +triangles. -While the radius is a good criterion in the case of 2D smooth curve -reconstruction \cgalCite{b-cccda-94}, we need another criterion for 3D surface -reconstruction, namely the dihedral angle between triangles on the -surface, that is the angle between the normals of the triangles. We denote by \f$ \beta_t\f$ the angle between the normal of a triangle \f$ t\f$ incident on a boundary edge \f$ e \f$ and the normal of the @@ -114,7 +121,7 @@ of the algorithm \f$ \alpha_\mathrm{sliver} = 5\pi/6 \f$. We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if \f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$ -\beta \f$ can be chosen by the user and is by default \f$ \pi/6\f$. +\beta \f$ can be specified by the user and is set by default \f$ \pi/6\f$. \subsection AFSR_Boundaries Dealing with Multiple Components, Boundaries and Sharp Edges @@ -122,11 +129,11 @@ We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if By construction the output of the algorithm is a connected orientable manifold with or without boundary. To cope with multiple components we merely look for a new seed facet among facets disjoint from the -surface. In case of noisy data or outliers, the user has to filter out +surface. In case of noisy data or outliers, the user must filter out small surface components. It is impossible to handle all kinds of boundaries and non uniform sampling -at the same time. A void can either be an undersampled zone of the surface, +at the same time, as a void can either be an undersampled area of the surface, or a hole. As we do not want the algorithm to rely on a uniformity condition on @@ -140,10 +147,10 @@ sampled, the radii of the two triangles incident on a boundary edge would be very different. These heuristic facts can be used for boundary detection. -We discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$ +More specifically, we discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$ such that \f$ p(t) < 0\f$, and \f$ r_t > k r_{t'}\f$ where \f$ t'\f$ is the triangle on the surface incident on \f$ e \f$. The parameter \f$ k \f$ -can be chosen by the user and is by default 5. +is specified by the user and is set by default to 5. Note that this heuristic implies that @@ -157,24 +164,61 @@ be sufficiently uniform for our algorithm to work. The global function `advancing_front_surface_reconstruction()` takes an iterator range of points as input and writes for each face of the -reconstructed surface a triple of point indices into an output iterator. -In the example we write the surface in the OFF format to `std::cout`. +reconstructed surface a triplet of point indices into an output iterator. +The following example writes the output triangulated surface to `std::cout` +in accordance to the OFF format. \cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp} \subsection AFSR_Example_class Example for the Reconstruction Class -When using the class `Advancing_front_surface_reconstruction` -you can access a 2D triangulation data structure describing the surface. -You can explore the surface by going from faces to neighboring faces, -and you can also go to the underlying 3D Delaunay triangulation. +The class `Advancing_front_surface_reconstruction` provides +access to a 2D triangulation data structure describing the output surface. +The latter can be explored by hopping from a face to its neighboring faces. -In the example we write the surface in the STL (Stereo Lithography) format -to `std::cout`. +The type of the 2D triangulation data structure describing the +reconstructed surface is the nested type +\link Advancing_front_surface_reconstruction::TDS_2 `TDS_2`\endlink. + +The type `TDS_2::Vertex` is model of the +concept `TriangulationDataStructure_2::Vertex` and has additionally +the method `vertex_3()` that returns an `Advancing_front_surface_reconstruction::Vertex_handle` to the +associated 3D vertex. + + The type `TDS_2::Face` is model of the concept +`TriangulationDataStructure_2::Face` and has additionally the method +`facet()` that returns the associated `Advancing_front_surface_reconstruction::Facet`, and a method `is_on_surface()` for testing if a face is part of the reconstructed +surface. + +In case the surface +has boundaries, the 2D surface has one vertex which is associated to +the infinite vertex of the 3D triangulation. + + +The underlying 3D Delaunay triangulation can be accessed as well, +using the API of the class `Delaunay_triangulation_3`. + +The following example writes the surface to `std::cout` in accordance +to the STL (Stereo Lithography) format. \cgalExample{Advancing_front_surface_reconstruction/reconstruction_class.cpp} + +\subsection AFSR_Example_boundaries Example for Outliers and Boundaries + +Input points which are not on +a surface are outliers. The member function \link Advancing_front_surface_reconstruction::outliers() `outliers()`\endlink +returns an iterator range of those points. + +Boundary edges can be traversed with the member function \link Advancing_front_surface_reconstruction::boundaries() `boundaries()`\endlink +It returns an iterator range type \link Advancing_front_surface_reconstruction::Boundary_range `Boundary_range`\endlink whose iterators have the value type +\link Advancing_front_surface_reconstruction::Vertex_on_boundary_range `Vertex_on_boundary_range`\endlink. This is again an iterator range whose iterators have the value type +\link Advancing_front_surface_reconstruction::Vertex_handle `Vertex_handle`\endlink. + +\cgalExample{Advancing_front_surface_reconstruction/boundaries.cpp} + + */ } /* namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 2112aeb7402..09b95b888fd 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -21,7 +21,7 @@ public: /*! The type of the 2D triangulation data structure describing the reconstructed surface. The type `TDS_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the - method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex + method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex. The type `TDS_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the method `facet()` that returns the associated `Facet`, and a method `bool is_on_surface()` for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. @@ -30,6 +30,7 @@ public: */ typedef unspecified_type TDS_2; + /*! The type of the 3D triangulation. @@ -37,6 +38,11 @@ The type of the 3D triangulation. typedef Dt Triangulation_3; /*! +The point type. + +*/ + typedef typename Triangulation_3::Point Point; +/*! The vertex handle type of the 3D triangulation. */ @@ -56,20 +62,33 @@ The facet type of the 3D triangulation. /*! - A bidirectional iterator which allows to enumerate all points that were removed + A bidirectional iterator range which enables to enumerate all points that were removed from the 3D Delaunay triangulation during the surface reconstruction. The value type - of the iterator is `Triangulation_3::Point_3`. + of the iterator is `Point`. */ -typedef unspecified_type Outlier_iterator; +typedef unspecified_type Outlier_range; +#if 0 /*! - A forward iterator which allows to visit all boundaries. It + A forward iterator which enables to visit all boundaries. It visits the entry point of each boundary twice. This allows to detect that the traversal of a boundary is finished. One more increment brings us to the vertex on the next boundary. - The value type of the iterator is `Triangulation_3::Vertex_handle`. + The value type of the iterator is `Vertex_handle`. */ -typedef unspecified_type Boundary_iterator; + +#endif + /*! + A bidirectional iterator range which enables to visit all boundaries. + The value type of the iterator is `Vertex_on_boundary_range`. + */ +typedef unspecified_type Boundary_range; + + /*! + A bidirectional iterator range which enables to visit all vertices on a boundary. + The value type of the iterator is `Vertex_handle` + */ +typedef unspecified_type Vertex_on_boundary_range; /// @} @@ -95,7 +114,7 @@ calls the surface reconstruction function with the default parameters. \param beta described in Section \ref AFSR_Selection */ - void operator()(double k=5, double beta= 0.18); + void run(double k=5, double beta= 0.18); /*! returns the reconstructed surface. @@ -113,24 +132,16 @@ triangulation_3(); /*! -An iterator over the outliers. +returns an iterator range over the outliers. */ -Outlier_iterator outliers_begin(); +Outlier_range outliers(); + /*! -Past-the-end iterator. +returns an iterator range over the boundaries. */ -Outlier_iterator outliers_end(); +Boundary_range boundaries(); -/*! -An iterator over the boundary vertices. -*/ -Boundary_iterator boundaries_begin(); - -/*! -Past-the-end iterator. -*/ -Boundary_iterator boundaries_end(); /// @} diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt index 2f14a4e739c..8e5c59fceeb 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt @@ -1,4 +1,5 @@ /*! \example Advancing_front_surface_reconstruction/reconstruction_fct.cpp \example Advancing_front_surface_reconstruction/reconstruction_class.cpp +\example Advancing_front_surface_reconstruction/boundaries.cpp */ diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt index 6467152a14f..a0cc57bb9f6 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt @@ -27,6 +27,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "reconstruction_fct.cpp" ) create_single_source_cgal_program( "reconstruction_class.cpp" ) create_single_source_cgal_program( "reconstruction_polyhedron.cpp" ) + create_single_source_cgal_program( "boundaries.cpp" ) else() diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp index b25b6aff530..acf8569770c 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp @@ -2,7 +2,6 @@ #include #include #include -#include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; typedef Reconstruction::Triangulation_3 Triangulation_3; @@ -19,14 +18,14 @@ int main() Reconstruction reconstruction(dt); - reconstruction(); + reconstruction.run(); const TDS_2& tds = reconstruction.tds_2(); - if(! reconstruction.has_boundaries()){ - for(TDS_2::Face_iterator fit = tds.faces_begin(); - fit != tds.faces_end(); - ++fit){ + for(TDS_2::Face_iterator fit = tds.faces_begin(); + fit != tds.faces_end(); + ++fit){ + if(fit->is_on_surface()){ Triangulation_3::Facet f = fit->facet(); Triangulation_3::Cell_handle ch = f.first; int ci = f.second; @@ -38,6 +37,6 @@ int main() std::cout << std::endl; } } - + return 0; } From fa8b9e6a26f658965cf08e76c50573b6a55a6556 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 13 Mar 2015 16:40:08 +0100 Subject: [PATCH 053/114] Add most of Pierre's review --- .../Advancing_front_surface_reconstruction.txt | 18 +++++++++++++++--- .../PackageDescription.txt | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 0ae72e8ac9a..e1a73a26fab 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -121,7 +121,7 @@ of the algorithm \f$ \alpha_\mathrm{sliver} = 5\pi/6 \f$. We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if \f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$ -\beta \f$ can be specified by the user and is set by default \f$ \pi/6\f$. +\beta \f$ can be specified by the user and is set by default to \f$ \pi/6\f$. \subsection AFSR_Boundaries Dealing with Multiple Components, Boundaries and Sharp Edges @@ -160,6 +160,15 @@ be sufficiently uniform for our algorithm to work. \section AFSR_Examples Examples +The first of the following three examples presents a free function for doing surface +reconstruction. For a sequence of points he function produces a sequence +of triplets of indices describing the triangles of the surface. +The second example presents a class that enables to traverse the +surface represented in a 2D triangulation data structure where +the faces are connected with the facets of underlying 3D Delaunay triangulation. +The third example shows how to get outliers and the boundaries of +the surface. + \subsection AFSR_Example_function Example for Global Function The global function `advancing_front_surface_reconstruction()` @@ -175,7 +184,9 @@ in accordance to the OFF format. The class `Advancing_front_surface_reconstruction` provides access to a 2D triangulation data structure describing the output surface. -The latter can be explored by hopping from a face to its neighboring faces. +The latter can be explored by hopping from a face to its neighboring faces, +and by hopping from faces of the 2D triangulation data structure to +corresponding facets of the underlying 3D Delaunay triangulation. The type of the 2D triangulation data structure describing the reconstructed surface is the nested type @@ -188,7 +199,8 @@ associated 3D vertex. The type `TDS_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the method -`facet()` that returns the associated `Advancing_front_surface_reconstruction::Facet`, and a method `is_on_surface()` for testing if a face is part of the reconstructed +`facet()` that returns the associated `Advancing_front_surface_reconstruction::Facet`, +and a method `is_on_surface()` for testing if a face is part of the reconstructed surface. In case the surface diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt index e8ab4401e8e..0742df993a9 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -15,7 +15,7 @@ of topological singularities. } \cgalPkgManuals{Chapter_Advancing_Front_Surface_Reconstruction,PkgAdvancingFrontSurfaceReconstruction} \cgalPkgSummaryEnd \cgalPkgShortInfoBegin -\cgalPkgSince{4.4} +\cgalPkgSince{4.7} \cgalPkgDependsOn{\ref PkgTriangulation3Summary} \cgalPkgBib{cgal:dc-afsr} \cgalPkgLicense{\ref licensesGPL "GPL"} From f645e803b4fd9a86c8567fea89e39547b749e9cf Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 13 Mar 2015 17:46:54 +0100 Subject: [PATCH 054/114] typo --- .../Advancing_front_surface_reconstruction.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index e1a73a26fab..b62ee6e532c 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -161,7 +161,7 @@ be sufficiently uniform for our algorithm to work. \section AFSR_Examples Examples The first of the following three examples presents a free function for doing surface -reconstruction. For a sequence of points he function produces a sequence +reconstruction. For a sequence of points the function produces a sequence of triplets of indices describing the triangles of the surface. The second example presents a class that enables to traverse the surface represented in a 2D triangulation data structure where From 95581a84b23f58b4fae18d17a482793b65fa3894 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 28 Apr 2015 16:06:32 +0200 Subject: [PATCH 055/114] Explain the plausibility with an image --- ...Advancing_front_surface_reconstruction.txt | 20 ++++++++++++++++++ .../fig/wedges.png | Bin 0 -> 6297 bytes 2 files changed, 20 insertions(+) create mode 100755 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/wedges.png diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index b62ee6e532c..f8d39241fd6 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -123,6 +123,20 @@ We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if \f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$ \beta \f$ can be specified by the user and is set by default to \f$ \pi/6\f$. +Let's have a look at the figure below. +\cgalFigureBegin{figAFSRplausible,wedges.png} +Plausibility. Triangle `t'` and incidident triangles sharing edge `e` seen from the side. +\cgalFigureEnd + + \f$ \alpha_\mathrm{sliver}\f$ corresponds to the red wedge. The algorithm will never select triangle `t1` +even if it is the only candidate triangle. + +\f$\beta\f$ corresponds to the green wedge. If there is a candidate triangle in this zone, +the one with the smallest radius is the most plausible. + +If there is no candidate triangle in the green wedge, the triangle with the smallest +angle between its normal and the normal of `t'` is chosen. In the figure above +this would be triangle `t4`. \subsection AFSR_Boundaries Dealing with Multiple Components, Boundaries and Sharp Edges @@ -152,6 +166,12 @@ such that \f$ p(t) < 0\f$, and \f$ r_t > k r_{t'}\f$ where \f$ t'\f$ is the triangle on the surface incident on \f$ e \f$. The parameter \f$ k \f$ is specified by the user and is set by default to 5. +For the example given in \cgalFigureRef{figAFSRplausible}, we said that if there +was no triangle `t3` in the green wedge, triangle `t4` would be chosen as it has +the smallest angle between its normal and the normal of triangle `t'`. +However, in case its radius was \f$ k \f$ times larger than the radius of triangle `t'`, +triangle `t2` would be chosen, assuming that its radius is not \f$ k \f$ times larger. + Note that this heuristic implies that where the sampling is too sparse with respect to curvature, it must diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/wedges.png b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/wedges.png new file mode 100755 index 0000000000000000000000000000000000000000..b92a29a54a624b1ac47a2915565dd56532053593 GIT binary patch literal 6297 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 Date: Tue, 28 Apr 2015 16:22:04 +0200 Subject: [PATCH 056/114] fix value of beta --- .../CGAL/Advancing_front_surface_reconstruction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 09b95b888fd..29302a21248 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -114,7 +114,7 @@ calls the surface reconstruction function with the default parameters. \param beta described in Section \ref AFSR_Selection */ - void run(double k=5, double beta= 0.18); + void run(double k=5, double beta= 0.52); /*! returns the reconstructed surface. From 8fa4a1e9c768fc751526e09ea0225f3eff6cf79a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 29 Apr 2015 09:12:57 +0200 Subject: [PATCH 057/114] polish --- ...Advancing_front_surface_reconstruction.txt | 8 +++---- .../Advancing_front_surface_reconstruction.h | 24 ++++++++++++------- 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index f8d39241fd6..ebe14c442e5 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -162,15 +162,15 @@ would be very different. These heuristic facts can be used for boundary detection. More specifically, we discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$ -such that \f$ p(t) < 0\f$, and \f$ r_t > k r_{t'}\f$ where \f$ t'\f$ is -the triangle on the surface incident on \f$ e \f$. The parameter \f$ k \f$ +such that \f$ p(t) < 0\f$, and \f$ r_t > \mathrm{radius\_ratio\_bound} \times r_{t'}\f$ where \f$ t'\f$ is +the triangle on the surface incident on \f$ e \f$. The parameter \f$\mathrm{radius\_ratio\_bound}\f$ is specified by the user and is set by default to 5. For the example given in \cgalFigureRef{figAFSRplausible}, we said that if there was no triangle `t3` in the green wedge, triangle `t4` would be chosen as it has the smallest angle between its normal and the normal of triangle `t'`. -However, in case its radius was \f$ k \f$ times larger than the radius of triangle `t'`, -triangle `t2` would be chosen, assuming that its radius is not \f$ k \f$ times larger. +However, in case its radius was \f$\mathrm{radius\_ratio\_bound}\f$ times larger than the radius of triangle `t'`, +triangle `t2` would be chosen, assuming that its radius is not \f$\mathrm{radius\_ratio\_bound}\f$ times larger. Note that this heuristic implies that diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 29302a21248..8003509269f 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -108,13 +108,16 @@ Advancing_front_surface_reconstruction(Dt& dt); /// @{ /*! -calls the surface reconstruction function with the default parameters. +runs the surface reconstruction function with the default parameters. -\param k described in Section \ref AFSR_Boundaries -\param beta described in Section \ref AFSR_Selection +\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge + are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. + Described in Section \ref AFSR_Boundaries +\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. + Described in Section \ref AFSR_Selection */ - void run(double k=5, double beta= 0.52); + void run(double radius_ratio_bound =5 , double beta = 0.52); /*! returns the reconstructed surface. @@ -190,15 +193,18 @@ describing the faces of the reconstructed surface. \tparam IndicesOutputIterator must be an output iterator to which `CGAL::cpp11::tuple` can be assigned. -\param begin iterator on the first point of the sequence -\param end past the end iterator the point sequence +\param b iterator on the first point of the sequence +\param e past the end iterator of the point sequence \param out output iterator -\param K described in Section \ref AFSR_Boundaries -\param beta described in Section \ref AFSR_Selection +\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge + are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. + Described in Section \ref AFSR_Boundaries +\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. + Described in Section \ref AFSR_Selection */ template - IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double k=5, double beta= 0.18 ); + IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double radius_ratio_bound = 5, double beta= 0.52 ); } /* end namespace CGAL */ From 457e9d5b00289fb1f8fe73a3313f27cf113dea4a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 4 May 2015 16:43:38 +0200 Subject: [PATCH 058/114] first changes after Guillaumes review --- ...Advancing_front_surface_reconstruction.txt | 6 +++--- .../Advancing_front_surface_reconstruction.h | 20 +++++++++---------- .../reconstruction_class.cpp | 2 +- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index ebe14c442e5..5de74e261e8 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -210,14 +210,14 @@ corresponding facets of the underlying 3D Delaunay triangulation. The type of the 2D triangulation data structure describing the reconstructed surface is the nested type -\link Advancing_front_surface_reconstruction::TDS_2 `TDS_2`\endlink. +\link Advancing_front_surface_reconstruction::Triangulation_data_structure_2 `Advancing_front_surface_reconstruction::Triangulation_data_structure_2`\endlink. -The type `TDS_2::Vertex` is model of the +The type `Advancing_front_surface_reconstruction::Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the method `vertex_3()` that returns an `Advancing_front_surface_reconstruction::Vertex_handle` to the associated 3D vertex. - The type `TDS_2::Face` is model of the concept + The type `Advancing_front_surface_reconstruction::Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the method `facet()` that returns the associated `Advancing_front_surface_reconstruction::Facet`, and a method `is_on_surface()` for testing if a face is part of the reconstructed diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 8003509269f..7250cf35bdd 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -20,15 +20,15 @@ public: /*! The type of the 2D triangulation data structure describing the reconstructed surface. - The type `TDS_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the + The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex. - The type `TDS_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the + The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the method `facet()` that returns the associated `Facet`, and a method `bool is_on_surface()` for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite vertex of the 3D triangulation. */ - typedef unspecified_type TDS_2; + typedef unspecified_type Triangulation_data_structure_2; /*! @@ -108,7 +108,7 @@ Advancing_front_surface_reconstruction(Dt& dt); /// @{ /*! -runs the surface reconstruction function with the default parameters. +runs the surface reconstruction function. \param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. @@ -122,8 +122,8 @@ runs the surface reconstruction function with the default parameters. /*! returns the reconstructed surface. */ -const TDS_2& -tds_2(); +const Triangulation_data_structure_2& +triangulation_data_structure_2() const; /*! returns the underlying 3D Delaunay triangulation. @@ -165,16 +165,16 @@ bool has_on_surface(Facet f) const; /*! -returns `true` if the facet f is on the surface. +returns `true` if the facet `f2` is on the surface. */ bool -has_on_surface(TDS_2::Face_handle f2) const; +has_on_surface(Triangulation_data_structure_2::Face_handle f2) const; /*! -returns `true` if the facet f is on the surface. +returns `true` if the vertex `v2` is on the surface. */ bool -has_on_surface(TDS_2::Vertex_handle v2) const; +has_on_surface(Triangulation_data_structure_2::Vertex_handle v2) const; /// @} diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp index acf8569770c..3c47e750ec0 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp @@ -5,7 +5,7 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; typedef Reconstruction::Triangulation_3 Triangulation_3; -typedef Reconstruction::TDS_2 TDS_2; +typedef Reconstruction::Triangulation_data_structure_2 TDS_2; typedef K::Point_3 Point_3; int main() From 267a93af97bd49cfbd1042f9f270d26cf01f291f Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 5 May 2015 13:03:41 +0200 Subject: [PATCH 059/114] changes after Guillaume's review --- .../CGAL/Advancing_front_surface_reconstruction.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 7250cf35bdd..0c82e35e114 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -4,7 +4,12 @@ namespace CGAL { /*! \ingroup PkgAdvancingFrontSurfaceReconstruction -The class `Advancing_front_surface_reconstruction` +The class `Advancing_front_surface_reconstruction` enables advanced users to provide the unstructured +point cloud in a 3D Delaunay triangulation. The reconstruction algorithm then marks vertices and faces +in the triangulation as being on the 2D surface embedded in 3D space, and constructs a 2D triangulation +data structure that describes the surface. The vertices and facets of the 2D triangulation data structure +store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the +2D as well as 3D neighborhood of vertices and facets of the surface. \tparam Dt must be a `Delaunay_triangulation_3` with `Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, and the geometric traits class must be the `Exact_predicates_inexact_constructions_kernel`. @@ -97,7 +102,7 @@ typedef unspecified_type Vertex_on_boundary_range; /// @{ /*! -Initializes from a 3D Delaunay triangulation of a point set. +Constructor for the unstructured point cloud given as 3D Delaunay triangulation. */ Advancing_front_surface_reconstruction(Dt& dt); From c36751959fa4c250b54714eb7f4626e24cdd8281 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 11 May 2015 17:10:11 +0200 Subject: [PATCH 060/114] Add example --- .../boundaries.cpp | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp new file mode 100644 index 00000000000..537a93491ca --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp @@ -0,0 +1,41 @@ +#include +#include +#include +#include + +typedef CGAL::Exact_predicates_inexact_constructions_kernel K; +typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; +typedef Reconstruction::Outlier_range Outlier_range; +typedef Reconstruction::Boundary_range Boundary_range; +typedef Reconstruction::Vertex_on_boundary_range Vertex_on_boundary_range; +typedef Reconstruction::Vertex_handle Vertex_handle; +typedef Kernel::Point_3 Point_3; + +int main() +{ + std::istream_iterator begin(std::cin); + std::istream_iterator end; + + Triangulation_3 dt(begin,end); + Reconstruction reconstruction(dt); + + reconstruction.run(); + + std::cout << "Outliers:\n"; + Outlier_range::iterator b,e; + // instead of boost::tie we might use BOOST_FOREACH + for(boost::tie(b,e) = reconstruction.outliers()){ + Point_3 p = *b; + std::cout << p << std::endl; + } + + std::cout << "Boundaries:\n"; + BOOST_FOREACH(Vertex_on_boundary_range it, reconstruction.boundaries()){ + std::cout << "boundary\n"; + // As we use BOOST_FOREACH we do not use the type Boundary_range + BOOST_FOREACH(Vertex_handle v, *it){ + std::cout << v->point() << std::endl; + } + } + return 0; +} From 9c30122060688608d99f4278987996f73d5a8589 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Jun 2015 15:19:15 +0200 Subject: [PATCH 061/114] Adapt the code to the accepted API --- .../boundaries.cpp | 25 +- .../data/half.xyz | 325 ++++++++++++++++++ .../extract.cpp | 2 +- .../reconstruction_class.cpp | 12 +- .../reconstruction_fct.cpp | 10 +- .../include/CGAL/AFSR/construct_polyhedron.h | 4 +- .../include/CGAL/AFSR/construct_surface_2.h | 2 +- .../include/CGAL/AFSR/orient.h | 2 +- .../include/CGAL/AFSR/write_triple_indices.h | 2 +- .../Advancing_front_surface_reconstruction.h | 225 ++++++++---- .../Advancing_front_surface_reconstruction.h | 28 +- 11 files changed, 526 insertions(+), 111 deletions(-) create mode 100755 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/half.xyz diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp index 537a93491ca..42ceaf8e63f 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp @@ -1,3 +1,4 @@ +#include #include #include #include @@ -5,37 +6,37 @@ typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; +typedef Reconstruction::Triangulation_3 Triangulation_3; typedef Reconstruction::Outlier_range Outlier_range; typedef Reconstruction::Boundary_range Boundary_range; typedef Reconstruction::Vertex_on_boundary_range Vertex_on_boundary_range; typedef Reconstruction::Vertex_handle Vertex_handle; -typedef Kernel::Point_3 Point_3; +typedef K::Point_3 Point_3; -int main() +int main(int argc, char* argv[]) { - std::istream_iterator begin(std::cin); + std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); + std::istream_iterator begin(in); std::istream_iterator end; - Triangulation_3 dt(begin,end); + Triangulation_3 dt(begin, end); Reconstruction reconstruction(dt); reconstruction.run(); - std::cout << "Outliers:\n"; - Outlier_range::iterator b,e; - // instead of boost::tie we might use BOOST_FOREACH - for(boost::tie(b,e) = reconstruction.outliers()){ - Point_3 p = *b; + std::cout << reconstruction.number_of_outliers() << " outliers:\n" << std::endl; + BOOST_FOREACH(const Point_3& p, reconstruction.outliers()){ std::cout << p << std::endl; } - std::cout << "Boundaries:\n"; - BOOST_FOREACH(Vertex_on_boundary_range it, reconstruction.boundaries()){ + std::cout << "Boundaries:" << std::endl ; + BOOST_FOREACH(const Vertex_on_boundary_range & vobr, reconstruction.boundaries()){ std::cout << "boundary\n"; // As we use BOOST_FOREACH we do not use the type Boundary_range - BOOST_FOREACH(Vertex_handle v, *it){ + BOOST_FOREACH(Vertex_handle v, vobr){ std::cout << v->point() << std::endl; } } + return 0; } diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/half.xyz b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/half.xyz new file mode 100755 index 00000000000..22721a18906 --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/half.xyz @@ -0,0 +1,325 @@ +-7.515480024991e-007 0.4928415052762 -1.734723475977e-018 +0.1362245936528 0.2204059209894 -0.4192549456997 +-0.3566293497428 0.2204059209894 -0.2590997754675 +-0.3566293497428 0.2204059209894 0.2590997754675 +0.3566293497428 -0.2204059209894 -0.2590997754675 +-0.1362245936528 -0.2204059209894 -0.4192549456997 +-0.4408118419787 -0.2204059209894 1.734723475977e-018 +7.515480024995e-007 -0.4928415052762 8.673617379884e-019 +0.1304938471362 0.4747717502931 0 +0.2574163248409 0.4195039861274 0 +0.3648848981566 0.3296449948398 0 +0.03997961642157 0.4744285141983 -0.1241 +0.0795435898012 0.4194849174555 -0.2448222222222 +0.1127521490808 0.3296439354692 -0.347001509329 +-0.1056956186181 0.4744094455264 -0.07636388888889 +-0.2082580899232 0.4194838580848 -0.1512841049383 +-0.2951937466481 0.3296438766152 -0.2144713266892 +-0.1053014650092 0.4744083861557 0.0769075617284 +-0.2082361925005 0.4194837992309 0.1513143089849 +-0.2951925301246 0.3296438733456 0.2144730046918 +0.04027120169883 0.4740650912069 0.1239115312071 +0.07955978898327 0.4194647272893 0.2448117517337 +0.4057914855631 0.2478389397683 -0.1245861111111 +0.3382717491979 0.2583549410982 -0.245688117284 +0.2435693606629 0.2475891554198 -0.3471802540174 +0.006912096818534 0.2478388809144 -0.4244420252794 +-0.1291490501767 0.2583549378286 -0.3976273347377 +-0.2549567859204 0.2475891519685 -0.3389332464941 +-0.4015346164662 0.2478388776447 -0.1377400612309 +-0.4180935898037 0.2583549376469 -6.055895727388e-005 +-0.4011314149817 0.2475891517768 0.1377367900668 +-0.2550845488815 0.2478388774631 0.3393151544533 +0.4715474070857 0.1170580478199 -0.07682700617284 +0.468102633727 4.489154554834e-005 -0.152037611454 +0.4266601101928 -0.1173339460802 -0.214804854829 +0.07264926058174 0.1170580445502 -0.4721859428322 +4.440336565236e-005 4.489136390043e-005 -0.4921631079351 +-0.07245809390484 -0.1173339460903 -0.472134336313 +-0.4266507759005 0.1170580443686 -0.2150022131499 +-0.4680750431056 4.489135380887e-005 -0.152122345175 +-0.4714381602825 -0.1173339460909 -0.07699290806528 +-0.3363035499236 0.1170580443585 0.3393230516623 +0.2188162897165 0.1170890622755 -0.4242178412527 +0.289253682762 4.661457086236e-005 -0.398159324514 +0.3356412857054 -0.1173940695833 -0.3392729974895 +-0.3358187173091 0.1170890620737 -0.3391936241729 +-0.2892982620727 4.661455964952e-005 -0.3981274235652 +-0.2189461638684 -0.1173940695844 -0.4240731503099 +-0.426378573036 0.1170890620625 0.2145810898443 +-0.4680599207242 4.661455902659e-005 0.1520989494358 +-0.4709811068325 -0.1173940695845 0.0771753356317 +0.2549872575249 -0.248327777254 -0.3390290429421 +0.1292592643069 -0.2583820987363 -0.397573835719 +-0.007139690180596 -0.2480762203231 -0.4237896176518 +-0.2436511531956 -0.2483277772541 -0.3472376720005 +-0.3381861751775 -0.2583820987363 -0.2457770928889 +-0.4052408987466 -0.2480762203231 -0.1241677778308 +-0.4055440527117 -0.2483277772541 0.1244125186462 +0.4180767837242 -0.2583820987363 6.030299350821e-005 +0.4008425690922 -0.2480762203225 -0.1377552404057 +0.1055711528638 -0.4747717502931 -0.07668888888889 +0.2082511751591 -0.4195039861274 -0.1513021604938 +0.2946533528622 -0.3291285502607 -0.2140964566283 +-0.04059822753268 -0.4744285141983 -0.123899382716 +-0.07957795708515 -0.4194849174555 -0.2448110768176 +-0.112563799673 -0.3291274908901 -0.3463718506761 +-0.1304037486658 -0.4744094455264 0.0003361454046639 +-0.2574113193703 -0.4194838580848 1.867474470355e-005 +-0.3642282284893 -0.3291274320362 1.463419778445e-005 +0.1782518543444 0.4386105093375 -0.1295317901235 +0.3040759062279 0.3614751872873 -0.1300503343621 +0.2173702560731 0.3609754803371 -0.2488374570743 +-0.06812086123992 0.4385892630703 -0.2095400120027 +-0.02971955976201 0.3614728852632 -0.3293601724206 +-0.1695110052039 0.3609741096017 -0.2836120109602 +-0.2203384092251 0.4385880827221 3.18820492303e-005 +-0.3224176917815 0.361472757373 -0.0735013427648 +-0.3221005460232 0.3609740334497 0.07355522689281 +-0.06808064815709 0.4385678891046 0.2095608418697 +-0.1695585311816 0.3614716320434 0.283930724489 +-0.02957205890907 0.3609717273766 0.3290751147583 +0.1782689534811 0.4385891974954 0.1295207379412 +0.4669085084433 -0.1267977790161 -0.07361031177914 +0.1516674242459 -0.00115896595775 -0.4667736786963 +0.214419939697 -0.1268536831645 -0.4218421599645 +0.07426629152944 -0.1267977790504 -0.4668042631267 +-0.3970412665771 -0.001158965980238 -0.2884886447813 +-0.3349540567162 -0.1268536831664 -0.3342668879748 +-0.4209964222559 -0.1267977790524 -0.2148786475953 +-0.4214192677113 -0.1268536831665 0.2152714897852 +0.3970309840215 0.001136860580719 -0.2884791549048 +0.3349440036867 0.1267981463303 -0.3342680384429 +0.421038236849 0.1267684348413 -0.2148825577428 +-0.1516615620267 0.001136860569378 -0.4667610010068 +-0.2144241320836 0.1267981459444 -0.4218329238876 +-0.07425716575118 0.1267684311762 -0.4668451297599 +-0.4907752350525 0.001136860568748 8.83510151191e-006 +-0.4674743740888 0.126798145923 0.07354806141617 +-0.4669446463565 0.1267684309725 -0.07363157122197 +0.06807728574472 -0.4386105093375 -0.2095473060509 +0.02971917239516 -0.3614600687079 -0.3292857603842 +0.1694859726663 -0.3609896105791 -0.2835908090121 +-0.1782828473697 -0.4385892630703 -0.1295003132991 +-0.3040055260641 -0.3614588262362 -0.1300284375042 +-0.2173593032536 -0.3609872429801 -0.2488070246215 +-0.1782462772615 -0.4385880827221 0.1295525974779 +-0.3038167909279 -0.3609871114469 0.1298222044149 +0.2203380200369 -0.4385891974954 -7.233207945732e-006 +0.3223478833819 -0.3614600029412 -0.07347782154124 +0.05962333333333 0.4873 -0.04331666666667 +0.1934666666667 0.4511666666667 -0.04381666666667 +0.1199233333333 0.4697 -0.08713333333333 +0.1014566666667 0.4511666666667 -0.1704666666667 +0.3136333333333 0.3776166666667 -0.04411666666667 +0.2509 0.41425 -0.08793333333333 +0.2370666666667 0.3958666666667 -0.1722333333333 +0.1611666666667 0.41425 -0.21145 +0.1388833333333 0.3776166666667 -0.2846333333333 +0.4092 0.27125 -0.04331666666667 +0.3631166666667 0.3201166666667 -0.08743333333333 +0.3547833333333 0.2953 -0.1707666666667 +0.2914666666667 0.3344166666667 -0.21175 +0.27205 0.2953 -0.2846333333333 +0.1953666666667 0.3201166666667 -0.3183 +0.16765 0.27125 -0.3757833333333 +-0.02277666666667 0.4873 -0.07008333333333 +0.01812333333333 0.4511666666667 -0.1975333333333 +-0.04581 0.4697 -0.1409666666667 +-0.1307666666667 0.4511666666667 -0.14915 +0.05496833333333 0.3776166666667 -0.3119 +-0.006081666666667 0.41425 -0.2657833333333 +-0.09054833333333 0.3958666666667 -0.2786666666667 +-0.1513 0.41425 -0.2186 +-0.2278 0.3776166666667 -0.2200333333333 +0.08525516666667 0.27125 -0.4025666666667 +0.02905683333333 0.3201166666667 -0.37235 +-0.0527765 0.2953 -0.3901833333333 +-0.1113316666667 0.3344166666667 -0.3426166666667 +-0.1866666666667 0.2953 -0.3466833333333 +-0.2423833333333 0.3201166666667 -0.2841666666667 +-0.3056 0.27125 -0.2755666666667 +-0.0737 0.4873 0 +-0.1822666666667 0.4511666666667 -0.07826666666667 +-0.1482333333333 0.4697 0 +-0.1822666666667 0.4511666666667 0.07826666666667 +-0.27965 0.3776166666667 -0.14865 +-0.25465 0.41425 -0.07633333333333 +-0.293 0.3958666666667 0 +-0.25465 0.41425 0.07633333333333 +-0.27965 0.3776166666667 0.14865 +-0.3565166666667 0.27125 -0.2054833333333 +-0.34515 0.3201166666667 -0.1427 +-0.3874 0.2953 -0.07038333333333 +-0.36025 0.3344166666667 0 +-0.3874 0.2953 0.07038333333333 +-0.34515 0.3201166666667 0.1427 +-0.3565166666667 0.27125 0.2054833333333 +-0.02277666666667 0.4873 0.07008333333333 +-0.1307666666667 0.4511666666667 0.14915 +-0.04581 0.4697 0.1409666666667 +0.01812333333333 0.4511666666667 0.1975333333333 +-0.2278 0.3776166666667 0.2200333333333 +-0.1513 0.41425 0.2186 +-0.09054833333333 0.3958666666667 0.2786666666667 +-0.006081666666667 0.41425 0.2657833333333 +0.05496833333333 0.3776166666667 0.3119 +-0.3056 0.27125 0.2755666666667 +-0.2423833333333 0.3201166666667 0.2841666666667 +-0.1866666666667 0.2953 0.3466833333333 +-0.1113316666667 0.3344166666667 0.3426166666667 +0.05962333333333 0.4873 0.04331666666667 +0.1014566666667 0.4511666666667 0.1704666666667 +0.1199233333333 0.4697 0.08713333333333 +0.1934666666667 0.4511666666667 0.04381666666667 +0.2509 0.41425 0.08793333333333 +0.3136333333333 0.3776166666667 0.04411666666667 +0.4850666666667 0.03875 -0.07826666666667 +0.4844166666667 -0.04251666666667 -0.07633333333333 +0.4628333333333 -0.08126666666667 -0.14865 +0.46025 -0.17265 0 +0.4374 -0.2144166666667 -0.07038333333333 +0.4407 -0.16555 -0.1427 +0.4020666666667 -0.1975666666667 -0.2054833333333 +0.1448833333333 0.1520333333333 -0.4458833333333 +0.2243333333333 0.03875 -0.4371333333333 +0.1503166666667 0.0775 -0.4626166666667 +0.07545 0.03875 -0.4855 +0.2844 -0.08126666666667 -0.3942166666667 +0.2223 -0.04251666666667 -0.4371 +0.1499166666667 -0.08503333333333 -0.4613833333333 +0.07708333333333 -0.04251666666667 -0.4843 +0.001633333333333 -0.08126666666667 -0.4861 +0.3196666666667 -0.1975666666667 -0.3188833333333 +0.2719 -0.16555 -0.3750166666667 +0.2021166666667 -0.2144166666667 -0.3942166666667 +0.1422333333333 -0.17265 -0.4377 +0.06822816666667 -0.2144166666667 -0.4377333333333 +0.0004615 -0.16555 -0.4632166666667 +-0.0711885 -0.1975666666667 -0.4458833333333 +-0.3792833333333 0.1520333333333 -0.2755666666667 +-0.3464 0.03875 -0.3484333333333 +-0.3935166666667 0.0775 -0.2859166666667 +-0.4384333333333 0.03875 -0.2217833333333 +-0.28705 -0.08126666666667 -0.3923 +-0.3470166666667 -0.04251666666667 -0.3464833333333 +-0.3924666666667 -0.08503333333333 -0.28515 +-0.4367666666667 -0.04251666666667 -0.2229666666667 +-0.4618166666667 -0.08126666666667 -0.1517666666667 +-0.2045 -0.1975666666667 -0.4025666666667 +-0.27265 -0.16555 -0.3744666666667 +-0.3124833333333 -0.2144166666667 -0.3140166666667 +-0.3723333333333 -0.17265 -0.2705166666667 +-0.3952166666667 -0.2144166666667 -0.20015 +-0.4404 -0.16555 -0.1435833333333 +-0.44605 -0.1975666666667 -0.07008333333333 +-0.3792833333333 0.1520333333333 0.2755666666667 +-0.4384333333333 0.03875 0.2217833333333 +-0.3935166666667 0.0775 0.2859166666667 +-0.4618166666667 -0.08126666666667 0.1517666666667 +-0.4367666666667 -0.04251666666667 0.2229666666667 +-0.44605 -0.1975666666667 0.07008333333333 +-0.4404 -0.16555 0.1435833333333 +-0.3952166666667 -0.2144166666667 0.20015 +0.3792833333333 -0.1520333333333 -0.2755666666667 +0.3464 -0.03875 -0.3484333333333 +0.3935166666667 -0.0775 -0.2859166666667 +0.4384333333333 -0.03875 -0.2217833333333 +0.28705 0.08126666666667 -0.3923 +0.3470166666667 0.04251666666667 -0.3464833333333 +0.3924666666667 0.08503333333333 -0.28515 +0.4367666666667 0.04251666666667 -0.2229666666667 +0.4618166666667 0.08126666666667 -0.1517666666667 +0.2045 0.1975666666667 -0.4025666666667 +0.27265 0.16555 -0.3744666666667 +0.3124833333333 0.2144166666667 -0.3140166666667 +0.3723333333333 0.17265 -0.2705166666667 +0.3952166666667 0.2144166666667 -0.20015 +0.4404 0.16555 -0.1435833333333 +0.44605 0.1975666666667 -0.07008333333333 +-0.1448833333333 -0.1520333333333 -0.4458833333333 +-0.2243333333333 -0.03875 -0.4371333333333 +-0.1503166666667 -0.0775 -0.4626166666667 +-0.07545 -0.03875 -0.4855 +-0.2844 0.08126666666667 -0.3942166666667 +-0.2223 0.04251666666667 -0.4371 +-0.1499166666667 0.08503333333333 -0.4613833333333 +-0.07708333333333 0.04251666666667 -0.4843 +-0.001633333333333 0.08126666666667 -0.4861 +-0.3196666666667 0.1975666666667 -0.3188833333333 +-0.2719 0.16555 -0.3750166666667 +-0.2021166666667 0.2144166666667 -0.3942166666667 +-0.1422333333333 0.17265 -0.4377 +-0.06822816666667 0.2144166666667 -0.4377333333333 +-0.0004615 0.16555 -0.4632166666667 +0.0711885 0.1975666666667 -0.4458833333333 +-0.4688333333333 -0.1520333333333 0 +-0.4850666666667 -0.03875 0.07826666666667 +-0.4864333333333 -0.0775 0 +-0.4850666666667 -0.03875 -0.07826666666667 +-0.4628333333333 0.08126666666667 0.14865 +-0.4844166666667 0.04251666666667 0.07633333333333 +-0.4851333333333 0.08503333333333 0 +-0.4844166666667 0.04251666666667 -0.07633333333333 +-0.4628333333333 0.08126666666667 -0.14865 +-0.4020666666667 0.1975666666667 0.2054833333333 +-0.4407 0.16555 0.1427 +-0.4374 0.2144166666667 0.07038333333333 +-0.46025 0.17265 0 +-0.4374 0.2144166666667 -0.07038333333333 +-0.4407 0.16555 -0.1427 +-0.4020666666667 0.1975666666667 -0.2054833333333 +-0.2719 0.16555 0.3750166666667 +-0.3196666666667 0.1975666666667 0.3188833333333 +0.02277666666667 -0.4873 -0.07008333333333 +-0.01812333333333 -0.4511666666667 -0.1975333333333 +0.04581 -0.4697 -0.1409666666667 +0.1307666666667 -0.4511666666667 -0.14915 +-0.05496833333333 -0.3776166666667 -0.3119 +0.006081666666667 -0.41425 -0.2657833333333 +0.09054833333333 -0.3958666666667 -0.2786666666667 +0.1513 -0.41425 -0.2186 +0.2278 -0.3776166666667 -0.2200333333333 +-0.08525516666667 -0.27125 -0.4025666666667 +-0.02905683333333 -0.3201166666667 -0.37235 +0.0527765 -0.2953 -0.3901833333333 +0.1113316666667 -0.3344166666667 -0.3426166666667 +0.1866666666667 -0.2953 -0.3466833333333 +0.2423833333333 -0.3201166666667 -0.2841666666667 +0.3056 -0.27125 -0.2755666666667 +-0.05962333333333 -0.4873 -0.04331666666667 +-0.1934666666667 -0.4511666666667 -0.04381666666667 +-0.1199233333333 -0.4697 -0.08713333333333 +-0.1014566666667 -0.4511666666667 -0.1704666666667 +-0.3136333333333 -0.3776166666667 -0.04411666666667 +-0.2509 -0.41425 -0.08793333333333 +-0.2370666666667 -0.3958666666667 -0.1722333333333 +-0.1611666666667 -0.41425 -0.21145 +-0.1388833333333 -0.3776166666667 -0.2846333333333 +-0.4092 -0.27125 -0.04331666666667 +-0.3631166666667 -0.3201166666667 -0.08743333333333 +-0.3547833333333 -0.2953 -0.1707666666667 +-0.2914666666667 -0.3344166666667 -0.21175 +-0.27205 -0.2953 -0.2846333333333 +-0.1953666666667 -0.3201166666667 -0.3183 +-0.16765 -0.27125 -0.3757833333333 +-0.05962333333333 -0.4873 0.04331666666667 +-0.1199233333333 -0.4697 0.08713333333333 +-0.1934666666667 -0.4511666666667 0.04381666666667 +-0.2370666666667 -0.3958666666667 0.1722333333333 +-0.2509 -0.41425 0.08793333333333 +-0.3136333333333 -0.3776166666667 0.04411666666667 +-0.3547833333333 -0.2953 0.1707666666667 +-0.3631166666667 -0.3201166666667 0.08743333333333 +-0.4092 -0.27125 0.04331666666667 +0.02277666666667 -0.4873 0.07008333333333 +0.0737 -0.4873 0 +0.1822666666667 -0.4511666666667 -0.07826666666667 +0.1482333333333 -0.4697 0 +0.27965 -0.3776166666667 -0.14865 +0.25465 -0.41425 -0.07633333333333 +0.293 -0.3958666666667 0 +0.3565166666667 -0.27125 -0.2054833333333 +0.34515 -0.3201166666667 -0.1427 +0.3874 -0.2953 -0.07038333333333 +0.36025 -0.3344166666667 0 diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index a56866a511c..5068f480a24 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -437,7 +437,7 @@ int main(int argc, char* argv[]) Surface S(dt, opt); - S(); + S.run(); std::cerr << "Total time: " << timer.time() << " sec." << std::endl; // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp index 3c47e750ec0..2214f938551 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp @@ -1,17 +1,19 @@ #include +#include #include #include #include + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; typedef Reconstruction::Triangulation_3 Triangulation_3; typedef Reconstruction::Triangulation_data_structure_2 TDS_2; typedef K::Point_3 Point_3; -int main() +int main(int argc, char* argv[]) { - - std::istream_iterator begin(std::cin); + std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); + std::istream_iterator begin(in); std::istream_iterator end; Triangulation_3 dt(begin,end); @@ -20,12 +22,12 @@ int main() reconstruction.run(); - const TDS_2& tds = reconstruction.tds_2(); + const TDS_2& tds = reconstruction.triangulation_data_structure_2(); for(TDS_2::Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ - if(fit->is_on_surface()){ + if(reconstruction.has_on_surface(fit)){ Triangulation_3::Facet f = fit->facet(); Triangulation_3::Cell_handle ch = f.first; int ci = f.second; diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index 18b9a189c3e..bd6f3424fe1 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -1,6 +1,5 @@ - - #include +#include #include #include #include @@ -20,12 +19,13 @@ namespace std { } } -int main() +int main(int argc, char* argv[]) { + std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); std::vector points; std::vector facets; - - std::copy(std::istream_iterator(std::cin), + + std::copy(std::istream_iterator(in), std::istream_iterator(), std::back_inserter(points)); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h index 74afdc5c9ed..f36005191c2 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h @@ -33,13 +33,13 @@ public: typedef typename TDS_2::Vertex_iterator Vertex_iterator; typedef typename Surface::Cell_handle Cell_handle; - const TDS_2& tds = s.tds_2(); + const TDS_2& tds = s.triangulation_data_structure_2(); int index = 0; Vertex_iterator end = tds.vertices_end(); for(Vertex_iterator vit = tds.vertices_begin(); vit != end; ++vit){ - if(vit->vertex_3() != s.triangulation().infinite_vertex()){ + if(vit->vertex_3() != s.triangulation_3().infinite_vertex()){ B.add_vertex(vit->point()); vit->vertex_3()->id() = index++; } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h index 203e2aabc5f..ad2a76dc1c0 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h @@ -20,7 +20,7 @@ construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction #include - +#include #include #include #include @@ -51,7 +51,7 @@ public: bool first, last; Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_, int m) - : S(S_), mark(m), first_vertex(S.triangulation().finite_vertices_begin()), pos(first_vertex) + : S(S_), mark(m), first_vertex(S.triangulation_3().finite_vertices_begin()), pos(first_vertex) { if (pos->number_of_incident_border() <= 0){ advance_to_next_boundary(); @@ -121,12 +121,13 @@ public: } do { first_vertex++; - } while((first_vertex != S.triangulation().finite_vertices_end()) && + } while((first_vertex != S.triangulation_3().finite_vertices_end()) && (! ((first_vertex->is_on_border()) && ! first_vertex->is_post_marked(mark)))); - if(first_vertex != S.triangulation().finite_vertices_end()) { + if(first_vertex != S.triangulation_3().finite_vertices_end()) { pos = first_vertex; pos->set_post_mark(mark); + assert(pos->is_on_border()); } else { pos = NULL; @@ -199,8 +200,17 @@ public: //===================================================================== //===================================================================== + + + typedef const std::list > Boundary_range; + typedef const std::list Vertex_on_boundary_range; + private: + mutable std::list > m_boundaries; + + Timer postprocess_timer, extend_timer, extend2_timer, init_timer; + Triangulation_3& T; Ordered_border_type _ordered_border; @@ -233,14 +243,14 @@ private: mutable int _postprocessing_counter; int _size_before_postprocessing; - std::list outliers; + std::list m_outliers; int _number_of_connected_components; std::list interior_edges; std::list< Incidence_request_elt > incidence_requests; - - + typename std::list< Incidence_request_elt >::iterator sentinel; + typename std::list::iterator ie_sentinel; std::list nbe_pool; std::list ist_pool; @@ -314,7 +324,7 @@ private: { bool r1; - if(w->m_ie_first == interior_edges.end()){ + if(w->m_ie_first == ie_sentinel){ r1 = false; }else { typename std::list::iterator b(w->m_ie_first), e(w->m_ie_last); @@ -333,7 +343,7 @@ private: inline void set_interior_edge(Vertex_handle w, Vertex_handle v) { - if(w->m_ie_last == interior_edges.end()){ // empty set + if(w->m_ie_last == ie_sentinel){ // empty set assert(w->m_ie_first == w->m_ie_last); w->m_ie_last = interior_edges.insert(w->m_ie_last, v); w->m_ie_first = w->m_ie_last; @@ -351,12 +361,12 @@ private: inline void remove_interior_edge(Vertex_handle w, Vertex_handle v) { - if(w->m_ie_first == interior_edges.end()){ + if(w->m_ie_first == ie_sentinel){ assert(w->m_ie_last == w->m_ie_first); } else if(w->m_ie_first == w->m_ie_last){ // there is only one element if(*(w->m_ie_first) == v){ interior_edges.erase(w->m_ie_first); - w->m_ie_last = interior_edges.end(); + w->m_ie_last = ie_sentinel; w->m_ie_first = w->m_ie_last; } } else { @@ -380,7 +390,7 @@ private: inline void set_incidence_request(Vertex_handle w, const Incidence_request_elt& ir) { - if(w->m_ir_last == incidence_requests.end()){ + if(w->m_ir_last == sentinel ){ assert(w->m_ir_first == w->m_ir_last); w->m_ir_last = incidence_requests.insert(w->m_ir_last, ir); w->m_ir_first = w->m_ir_last; @@ -393,10 +403,10 @@ private: inline bool is_incidence_requested(Vertex_handle w) const { - if(w->m_ir_last == incidence_requests.end()){ - assert(w->m_ir_first == incidence_requests.end()); + if(w->m_ir_last == sentinel ){ + assert(w->m_ir_first == sentinel ); } - return (w->m_ir_last != incidence_requests.end()); + return (w->m_ir_last != sentinel ); } inline Incidence_request_iterator incidence_request_begin(Vertex_handle w) @@ -406,8 +416,8 @@ private: inline Incidence_request_iterator incidence_request_end(Vertex_handle w) { - if(w->m_ir_last != incidence_requests.end()){ - assert(w->m_ir_first != incidence_requests.end()); + if(w->m_ir_last != sentinel ){ + assert(w->m_ir_first != sentinel ); Incidence_request_iterator it(w->m_ir_last); it++; return it; @@ -417,12 +427,12 @@ private: inline void erase_incidence_request(Vertex_handle w) { - if(w->m_ir_last != incidence_requests.end()){ - assert(w->m_ir_first != incidence_requests.end()); + if(w->m_ir_last != sentinel ){ + assert(w->m_ir_first != sentinel ); w->m_ir_last++; incidence_requests.erase(w->m_ir_first, w->m_ir_last); - w->m_ir_first = incidence_requests.end(); - w->m_ir_last = incidence_requests.end(); + w->m_ir_first = sentinel ; + w->m_ir_last = sentinel ; } } @@ -434,13 +444,13 @@ private: w->delete_border(); } - if(w->m_ir_first != incidence_requests.end()){ - assert(w->m_ir_last != incidence_requests.end()); + if(w->m_ir_first != sentinel ){ + assert(w->m_ir_last != sentinel ); typename std::list< Incidence_request_elt >::iterator b(w->m_ir_first), e(w->m_ir_last); e++; incidence_requests.erase(b, e); - w->m_ir_first = incidence_requests.end(); - w->m_ir_last = incidence_requests.end(); + w->m_ir_first = sentinel ; + w->m_ir_last = sentinel ; } w->m_incident_border = new_border(); @@ -464,11 +474,21 @@ private: void initialize_vertices_and_cells() { + + Incidence_request_elt ire; + incidence_requests.clear(); + incidence_requests.push_back(ire); + sentinel = incidence_requests.begin(); + + interior_edges.clear(); + interior_edges.push_back(Vertex_handle()); + ie_sentinel = interior_edges.begin(); + for(All_vertices_iterator fit = T.all_vertices_begin(); fit != T.all_vertices_end(); ++fit){ - fit->m_ie_first = fit->m_ie_last = interior_edges.end(); - fit->m_ir_first = fit->m_ir_last = incidence_requests.end(); + fit->m_ie_first = fit->m_ie_last = ie_sentinel; + fit->m_ir_first = fit->m_ir_last = sentinel ; fit->m_incident_border = new_border(); } } @@ -481,15 +501,15 @@ private: { w->delete_border(); } - if(w->m_ir_first != incidence_requests.end()){ - assert(w->m_ir_last != incidence_requests.end()); + if(w->m_ir_first != sentinel ){ + assert(w->m_ir_last != sentinel ); typename std::list< Incidence_request_elt >::iterator b(w->m_ir_first), e(w->m_ir_last); e++; incidence_requests.erase(b, e); } - if(w->m_ie_first != interior_edges.end()){ - assert(w->m_ie_last != interior_edges.end()); + if(w->m_ie_first != ie_sentinel){ + assert(w->m_ie_last != ie_sentinel); typename std::list::iterator b(w->m_ie_first), e(w->m_ie_last); e++; interior_edges.erase(b, e); @@ -519,8 +539,28 @@ public: {} + ~Advancing_front_surface_reconstruction() + { + /* + std::cerr << "postprocessing" << postprocess_timer.time() << std::endl; + std::cerr << "extend " << extend_timer.time() << std::endl; + std::cerr << "extend2 " << extend2_timer.time() << std::endl; + std::cerr << "init " << postprocess_timer.time() << std::endl; + std::cerr << "#outliers " << number_of_outliers() << std::endl; + */ + } - void operator()(const AFSR_options& opt = AFSR_options()) + void run(double radius_ratio_bound=5, double beta=0.52) + { + AFSR_options opt; + opt.K = radius_ratio_bound; + // TODO: what to do with beta + + run(opt); + } + + + void run(const AFSR_options opt) { initialize_vertices_and_cells(); bool re_init = false; @@ -531,14 +571,19 @@ public: if ( (re_init = init(re_init)) ) { //std::cerr << "Growing connected component " << _number_of_connected_components << std::endl; + extend_timer.start(); extend(opt.K_init, opt.K_step, opt.K); + extend_timer.stop(); if ((number_of_facets() > static_cast(T.number_of_vertices()))&& (opt.NB_BORDER_MAX > 0)) // en principe 2*nb_sommets = nb_facettes: y a encore de la marge!!! { while(postprocessing(opt.NB_BORDER_MAX)){ + extend2_timer.start(); extend(opt.K_init, opt.K_step, opt.K); + + extend2_timer.stop(); } } } @@ -548,6 +593,7 @@ public: _tds_2_inf = AFSR::construct_surface(_tds_2, *this); + boundaries(); clear_vertices(); } @@ -555,12 +601,13 @@ public: typedef Triangulation_data_structure_2, AFSR::Surface_face_base_2 > TDS_2; + typedef TDS_2 Triangulation_data_structure_2; mutable TDS_2 _tds_2; mutable typename TDS_2::Vertex_handle _tds_2_inf; - const TDS_2& tds_2() const + const TDS_2& triangulation_data_structure_2() const { return _tds_2; } @@ -569,7 +616,8 @@ public: bool has_boundaries() const { - return _tds_2_inf->vertex_3() == triangulation().infinite_vertex(); + return _tds_2_inf != typename TDS_2::Vertex_handle(); + // return _tds_2_inf->vertex_3() == triangulation_3().infinite_vertex(); } @@ -599,7 +647,7 @@ public: Triangulation_3& - triangulation() const + triangulation_3() const { return T; } @@ -620,19 +668,27 @@ public: int number_of_outliers() const { - return static_cast(outliers.size()); + return static_cast(m_outliers.size()); } + typedef std::list Outlier_range; + typedef typename std::list::const_iterator Outlier_iterator; - Outlier_iterator outliers_begin() const + const Outlier_range& outliers() const { - return outliers.begin(); + return m_outliers; } - Outlier_iterator outliers_end() const + + Outlier_iterator outliers_begin() const { - return outliers.end(); + return m_outliers.begin(); + } + + Outlier_iterator m_outliers_end() const + { + return m_outliers.end(); } typedef Advancing_front_surface_reconstruction_boundary_iterator Boundary_iterator; @@ -646,6 +702,25 @@ public: { return Boundary_iterator(*this); } + + const Boundary_range& boundaries() const + { + if(has_boundaries() && m_boundaries.empty()){ + Boundary_iterator b = boundaries_begin(); + Boundary_iterator e = boundaries_end(); + for(; b!= e; ++b){ + Vertex_handle v = *b; + std::list border; + m_boundaries.push_back(border); + do { + m_boundaries.back().push_back(*b); + ++b; + }while(*b != v); + } + } + + return m_boundaries; + } int next_mark() const @@ -1239,6 +1314,7 @@ public: bool init(const bool& re_init) { + init_timer.start(); Facet min_facet; coord_type min_value = HUGE_VAL; int i1, i2, i3; @@ -1316,8 +1392,10 @@ public: _ordered_border.insert(Radius_ptr_type (e31.first, p31)); select_facet(c_min, ind); + init_timer.stop(); return true; } + init_timer.stop(); return false; } @@ -1427,9 +1505,7 @@ public: { remove_border_elt(ordered_key); force_merge(ordered_el1, result1); - Radius_edge_type e2 = compute_value(edge_Ifacet_2); - IO_edge_type* p2; if (ordered_el1.first == v1) p2 = set_border_elt(v2, ordered_el1.second, @@ -1437,7 +1513,6 @@ public: else p2 = set_border_elt(ordered_el1.first, v2, Border_elt(e2,result1.second)); - dec_mark(v1); _ordered_border.insert(Radius_ptr_type(e2.first, p2)); @@ -1445,7 +1520,6 @@ public: //depiler les eventuelles requettes de connections avortees... zones etoilees, //en effet le bord a change donc on peut peut etre maintenant. dequeue_incidence_request(v2); - if (ordered_el1.first == v1) dequeue_incidence_request(ordered_el1.second); else @@ -1513,7 +1587,6 @@ public: is_border_el2 = is_border_elt(ordered_el2, result2); Radius_edge_type e1, e2; - if (c->vertex(i)->not_interior()) { if ((!is_interior_edge(ordered_el1))&& @@ -1536,7 +1609,6 @@ public: return FINAL_CASE; } - //--------------------------------------------------------------------- //on peut alors marquer v1 et on pourrait essayer de merger //sans faire de calcul inutile??? @@ -1551,7 +1623,6 @@ public: return EAR_CASE; } - //--------------------------------------------------------------------- //idem pour v2 if (is_border_el2) @@ -1560,13 +1631,11 @@ public: edge_Efacet.second); merge_ear(ordered_el2, result2, ordered_key, v2, v1, edge_Ifacet_1); - select_facet(c, edge_Efacet.second); return EAR_CASE; } - //--------------------------------------------------------------------- if ((!is_border_el1)&&(!is_border_el2)) { @@ -1580,7 +1649,7 @@ public: // if (c->vertex(i)->not_interior() deja teste en haut if(c->vertex(i)->is_exterior()) - { + { Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), edge_Efacet.second); @@ -1610,7 +1679,7 @@ public: else // c->vertex(i) is a border point (and now there's only 1 // border incident to a point... _mark<1 even if th orientation // may be such as one vh has 2 successorson the same border... - { + { // a ce niveau on peut tester si le recollement se fait en // maintenant la compatibilite d'orientation des bords (pour // surface orientable...) ou si elle est brisee... @@ -1660,7 +1729,6 @@ public: bool is_border_ear1 = is_ordered_border_elt(ear1_e, result_ear1); bool is_border_ear2 = is_ordered_border_elt(ear2_e, result_ear2); bool ear1_valid(false), ear2_valid(false); - if (is_border_ear1&&(e1.first < STANDBY_CANDIDATE)&& (e1.first <= value)&& (result12.second==result_ear1.second)) @@ -1669,7 +1737,6 @@ public: smallest_radius_delaunay_sphere(ear1_c, ear1.second)) != 0; } - if (is_border_ear2&&(e2.first < STANDBY_CANDIDATE)&& (e2.first <= value)&& (result12.second==result_ear2.second)) @@ -1678,7 +1745,6 @@ public: smallest_radius_delaunay_sphere(ear2_c, ear2.second)) != 0; } - if ((!ear1_valid)&&(!ear2_valid)) return NOT_VALID_CONNECTING_CASE; @@ -1754,9 +1820,7 @@ public: _ordered_border.insert(Radius_ptr_type(e2.first, p2)); } } - select_facet(c, edge_Efacet.second); - return CONNECTING_CASE; } } @@ -1812,12 +1876,15 @@ public: K = K_init; // valeur d'initialisation de K pour commencer prudemment... Vertex_handle v1, v2; - if (_ordered_border.empty()) return; + if (_ordered_border.empty()){ + return; + } do { min_K = HUGE_VAL; // pour retenir le prochain K necessaire pour progresser... do { + Ordered_border_iterator e_it = _ordered_border.begin(); criteria value = e_it->first; @@ -1841,9 +1908,7 @@ public: Radius_edge_type mem_e_it(e_it->first, *e_it->second); _ordered_border.erase(e_it); - Validation_case validate_result = validate(candidate, value); - if ((validate_result == NOT_VALID)|| (validate_result == NOT_VALID_CONNECTING_CASE)) { @@ -1971,16 +2036,17 @@ public: int ind = circ.second; Cell_handle neigh = ch->neighbor(ind); int n_ind = neigh->index(ch); - if (ch->is_selected_facet(ind)) + if (ch->is_selected_facet(ind)){ return Facet(ch, ind); - if (neigh->is_selected_facet(n_ind)) + } + if (neigh->is_selected_facet(n_ind)){ return Facet(neigh, n_ind); + } circ = next(circ); } while(circ.first.first != c); // si on passe par la, alors y a eu un probleme.... std::cerr << "+++probleme dans la MAJ avant remove..." << std::endl; - return Facet(c, start.second); } @@ -2109,7 +2175,7 @@ public: void store_outlier(const Point& p){ - outliers.push_back(p); + m_outliers.push_back(p); } void dec_vh_number() @@ -2159,7 +2225,9 @@ public: //--------------------------------------------------------------------- bool postprocessing(int NB_BORDER_MAX) - { + { + postprocess_timer.start(); + _postprocessing_counter++; std::list L_v; @@ -2228,6 +2296,7 @@ public: re_compute_values(); } else{ + postprocess_timer.stop(); return false; } // we stop if we removed more than 10% of points or after 20 rounds @@ -2235,6 +2304,7 @@ public: ((_size_before_postprocessing - T.number_of_vertices()) > .1 * _size_before_postprocessing)|| (_postprocessing_counter > 20)){ + postprocess_timer.stop(); return false; } @@ -2242,10 +2312,10 @@ public: // fin-- // if (_postprocessing_counter < 5) // return true; + postprocess_timer.stop(); return true; } - }; // class Advancing_front_surface_reconstruction namespace AFSR { @@ -2262,7 +2332,11 @@ struct Auto_count : public std::unary_function >{ template IndexTripleIterator -advancing_front_surface_reconstruction(PointIterator b, PointIterator e, IndexTripleIterator out) +advancing_front_surface_reconstruction(PointIterator b, + PointIterator e, + IndexTripleIterator out, + double radius_ratio_bound = 5, + double beta = 0.52 ) { typedef Exact_predicates_inexact_constructions_kernel Kernel; typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; @@ -2277,14 +2351,23 @@ advancing_front_surface_reconstruction(PointIterator b, PointIterator e, IndexTr Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), boost::make_transform_iterator(e, AFSR::Auto_count() ) ); - Reconstruction R(dt); - R(); + AFSR_options opt; + opt.K = radius_ratio_bound; + // TODO: What to do with beta??? + Reconstruction R(dt,opt); + R.run(opt); write_triple_indices(out, R); return out; } + template void -advancing_front_surface_reconstruction(PointIterator b, PointIterator e, Polyhedron_3& polyhedron, double max_perimeter = 2) +advancing_front_surface_reconstruction(PointIterator b, + PointIterator e, + Polyhedron_3& polyhedron, + double radius_ratio_bound = 5, + double beta = 0.52, + double max_perimeter = 0) { typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; @@ -2299,9 +2382,11 @@ advancing_front_surface_reconstruction(PointIterator b, PointIterator e, Polyhed boost::make_transform_iterator(e, AFSR::Auto_count() ) ); AFSR_options opt; + opt.K = radius_ratio_bound; + // TODO: What to do with beta??? opt.abs_perimeter = max_perimeter; Reconstruction R(dt, opt); - R(); + R.run(opt); AFSR::construct_polyhedron(polyhedron, R); } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h index 7dd03b2bd3a..6184c36b1d6 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -15,6 +15,8 @@ #include #include +#include + namespace CGAL { @@ -36,7 +38,7 @@ write_to_file_medit(char* foutput, const Surface& S) typedef typename Surface::Vertex Vertex; typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); char foutput_points[100]; char foutput_faces[100]; @@ -130,7 +132,7 @@ write_to_file_gv(char* foutput, const Surface& S) typedef typename Surface::Vertex_handle Vertex_handle; typedef typename Surface::Vertex Vertex; typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); char foutput_tmp[100]; std::strcpy(foutput_tmp, foutput); @@ -235,7 +237,7 @@ write_triple_indices(OutputIterator out, const Surface& S) typedef typename Surface::Vertex_handle Vertex_handle; typedef typename Surface::Vertex Vertex; typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); for(Finite_facets_iterator f_it = T.finite_facets_begin(); @@ -285,7 +287,7 @@ write_to_file_ply(char* foutput, const Surface& S) typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; typedef typename Surface::Vertex_handle Vertex_handle; typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); char foutput_tmp[100]; std::strcpy(foutput_tmp, foutput); @@ -386,7 +388,7 @@ write_to_file_iv_border_edges(const Surface& S, std::ofstream& os) typedef typename Surface::Edge_like Edge_like; typedef typename Surface::Border_elt Border_elt; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); typedef std::pair indiced_vh; std::map _vh_vect; int _vh_bord_count = 0; @@ -464,7 +466,7 @@ write_to_file_iv_remaining_points(const Surface& S, std::ofstream& os) typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; typedef typename Surface::Vertex_handle Vertex_handle; typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); typedef std::pair indiced_vh; std::map _vh_vect; int _vh_bord_count(0); @@ -530,7 +532,7 @@ write_to_file_iv_border_facets(const Surface& S, std::ofstream& os) typedef typename Surface::Edge_like Edge_like; typedef typename Surface::Border_elt Border_elt; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); typedef std::pair indiced_vh; std::map _vh_vect; int _vh_bord_count(0); @@ -649,7 +651,7 @@ write_to_file_iv(char* foutput, const Surface& S, typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; typedef typename Surface::Vertex_handle Vertex_handle; typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); char foutput_tmp[100]; std::strcpy(foutput_tmp, foutput); @@ -837,7 +839,7 @@ write_to_file_vrml2(char* foutput, const Surface& S, typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; typedef typename Surface::Vertex_handle Vertex_handle; typedef typename Surface::Cell_handle Cell_handle; - //Triangulation_3& T = S.triangulation(); + //Triangulation_3& T = S.triangulation_3(); typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; @@ -880,13 +882,13 @@ write_to_file_vrml2(char* foutput, const Surface& S, typename Surface::Outlier_iterator pit = S.outliers_begin(); - if(pit != S.outliers_end()) { + if(S.number_of_outliers()!= 0) { os << "Shape {\n" "geometry PointSet {\n" "coord Coordinate { point [\n"; - for(; pit != S.outliers_end(); pit++){ - os << pit->x() << " " << pit->y() << " " << pit->z() << ",\n"; + BOOST_FOREACH(const typename Surface::Point& p , S.outliers()){ + os << p.x() << " " << p.y() << " " << p.z() << ",\n"; } os << "] } }\n" "appearance Appearance {\n" @@ -918,7 +920,7 @@ write_to_file_stl(char* foutput, const Surface& S) typedef typename Surface::Cell_handle Cell_handle; typedef typename Triangulation_3::Point Point; typedef typename CGAL::Kernel_traits::Kernel::Vector_3 Vector; - Triangulation_3& T = S.triangulation(); + Triangulation_3& T = S.triangulation_3(); char foutput_tmp[100]; From 3e7b082ad363f3358e5d51cc8a60aa834de8a687 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Jun 2015 16:45:09 +0200 Subject: [PATCH 062/114] improve loop a little bit --- .../reconstruction_fct.cpp | 4 +- .../Advancing_front_surface_reconstruction.h | 47 +++++++++++++++---- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index bd6f3424fe1..8c0647f49b4 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -32,7 +32,7 @@ int main(int argc, char* argv[]) CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), std::back_inserter(facets)); - + std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n"; std::copy(points.begin(), points.end(), @@ -40,6 +40,6 @@ int main(int argc, char* argv[]) std::copy(facets.begin(), facets.end(), std::ostream_iterator(std::cout, "\n")); - + return 0; } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 043c64134f0..cc6dcf1ac64 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -190,9 +191,28 @@ public: typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; typedef CGAL::Triple< Vertex_handle, Vertex_handle, Vertex_handle > Facet_like; - +#if USE_MM typedef std::multimap< criteria, IO_edge_type*, std::less > Ordered_border_type; +#else + + struct LE { + + bool operator()(const Radius_ptr_type& p1, + const Radius_ptr_type p2) const + { + if(p1.first < p2.first) return true; + if(p1.first > p2.first) return false; + return p1.second < p2.second; + } + + }; + + + typedef std::set Ordered_border_type; +#endif + + typedef typename Ordered_border_type::iterator Ordered_border_iterator; enum Validation_case {NOT_VALID, NOT_VALID_CONNECTING_CASE, FINAL_CASE, @@ -213,7 +233,7 @@ private: Triangulation_3& T; - Ordered_border_type _ordered_border; + Ordered_border_type _ordered_border; int _number_of_border; const coord_type SLIVER_ANGULUS; // = sampling quality of the surface @@ -541,13 +561,13 @@ public: ~Advancing_front_surface_reconstruction() { - /* + std::cerr << "postprocessing" << postprocess_timer.time() << std::endl; std::cerr << "extend " << extend_timer.time() << std::endl; std::cerr << "extend2 " << extend2_timer.time() << std::endl; std::cerr << "init " << postprocess_timer.time() << std::endl; std::cerr << "#outliers " << number_of_outliers() << std::endl; - */ + } void run(double radius_ratio_bound=5, double beta=0.52) @@ -1319,10 +1339,11 @@ public: coord_type min_value = HUGE_VAL; int i1, i2, i3; - if (!re_init) + if (!re_init){ + Finite_facets_iterator end = T.finite_facets_end(); for(Finite_facets_iterator facet_it = T.finite_facets_begin(); - facet_it != T.finite_facets_end(); - facet_it++) + facet_it != end; + ++facet_it) { coord_type value = smallest_radius_delaunay_sphere((*facet_it).first, (*facet_it).second); @@ -1332,10 +1353,11 @@ public: min_value = value; } } - else //if (re_init) + }else{ //if (re_init) + Finite_facets_iterator end = T.finite_facets_end(); for(Finite_facets_iterator facet_it = T.finite_facets_begin(); - facet_it != T.finite_facets_end(); - facet_it++) + facet_it != end; + ++facet_it) { Cell_handle c = (*facet_it).first; int index = (*facet_it).second; @@ -1361,6 +1383,7 @@ public: } } } + } if (min_value != HUGE_VAL) { @@ -1437,6 +1460,7 @@ public: void ordered_map_erase(const criteria& value, const IO_edge_type* pkey) { +#if USE_MM std::size_t number_of_conflict = _ordered_border.count(value); if (number_of_conflict == 1) { @@ -1460,6 +1484,9 @@ public: elt_it++; } } +#else + _ordered_border.erase(Radius_ptr_type(value,(IO_edge_type*)pkey)); +#endif } //--------------------------------------------------------------------- From 37944b422e160e5ed7ea1cd8820410ee1f6e76e6 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 3 Jun 2015 17:31:15 +0200 Subject: [PATCH 063/114] fix comment --- .../include/CGAL/Advancing_front_surface_reconstruction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index cc6dcf1ac64..936d91c853d 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -1329,7 +1329,7 @@ public: //===================================================================== //===================================================================== - // The parameter re_init is true the first time only + // The parameter re_init is false the first time only // Returns true, iff it found a face where the next surface can grow bool init(const bool& re_init) From 7e3023fe60da1ae6cb3a0659c0bf72cce9776aa4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 4 Jun 2015 15:48:44 +0200 Subject: [PATCH 064/114] deal with border cases: 1, 2, 3 points, and coplanar point set --- .../reconstruction_fct.cpp | 2 +- .../include/CGAL/AFSR/write_triple_indices.h | 4 + .../Advancing_front_surface_reconstruction.h | 93 ++++++++----------- .../data/planar.xyz | 8 ++ .../data/point.xyz | 1 + .../data/segment.xyz | 2 + .../data/triangle.xyz | 3 + 7 files changed, 56 insertions(+), 57 deletions(-) create mode 100755 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/planar.xyz create mode 100755 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/point.xyz create mode 100755 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/segment.xyz create mode 100755 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index 8c0647f49b4..e697a437788 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -32,7 +32,7 @@ int main(int argc, char* argv[]) CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), std::back_inserter(facets)); - + std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n"; std::copy(points.begin(), points.end(), diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h index 22e024e71b8..926b98ba243 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h @@ -19,6 +19,10 @@ OutputIterator typedef typename TDS_2::Face_iterator Face_iterator; typedef typename Surface::Cell_handle Cell_handle; + if(S.triangulation_3().dimension() < 3){ + std::cerr << "not 3D\n"; + return out; + } const TDS_2& tds = S.triangulation_data_structure_2(); for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 936d91c853d..281784714b5 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -191,27 +191,7 @@ public: typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; typedef CGAL::Triple< Vertex_handle, Vertex_handle, Vertex_handle > Facet_like; -#if USE_MM - typedef std::multimap< criteria, IO_edge_type*, - std::less > Ordered_border_type; -#else - - struct LE { - - bool operator()(const Radius_ptr_type& p1, - const Radius_ptr_type p2) const - { - if(p1.first < p2.first) return true; - if(p1.first > p2.first) return false; - return p1.second < p2.second; - } - - }; - - - typedef std::set Ordered_border_type; -#endif - + typedef std::set Ordered_border_type; typedef typename Ordered_border_type::iterator Ordered_border_iterator; @@ -267,6 +247,8 @@ private: int _number_of_connected_components; + Vertex_handle added_vertex; + bool deal_with_2d; std::list interior_edges; std::list< Incidence_request_elt > incidence_requests; typename std::list< Incidence_request_elt >::iterator sentinel; @@ -555,19 +537,40 @@ public: NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), area(opt.area), perimeter(opt.perimeter), abs_area(opt.abs_area), abs_perimeter(opt.abs_perimeter), total_area(0), total_perimeter(0), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), - _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0) + _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), deal_with_2d(false) - {} + { + if(T.dimension() == 2){ + deal_with_2d = true; + Finite_vertices_iterator it = T.finite_vertices_begin(); + const Point& p = it->point(); + ++it; + const Point& q = it->point(); + do{ + ++it; + }while(collinear(p,q,it->point())); + const Point& r = it->point(); + Vector u = q-r; + Vector v = q-p; + Vector w = r-p; + Vector vw = cross_product(v,w); + double len = (std::max)(u*u,(std::max)(v*v,w*w)); + Point s = p + 10* len * (vw/(vw*vw)); + std::size_t n = T.number_of_vertices(); + added_vertex = T.insert(s); + + } + } ~Advancing_front_surface_reconstruction() { - + /* std::cerr << "postprocessing" << postprocess_timer.time() << std::endl; std::cerr << "extend " << extend_timer.time() << std::endl; std::cerr << "extend2 " << extend2_timer.time() << std::endl; std::cerr << "init " << postprocess_timer.time() << std::endl; std::cerr << "#outliers " << number_of_outliers() << std::endl; - + */ } void run(double radius_ratio_bound=5, double beta=0.52) @@ -582,6 +585,9 @@ public: void run(const AFSR_options opt) { + if(T.dimension() < 3){ + return; + } initialize_vertices_and_cells(); bool re_init = false; do @@ -637,7 +643,6 @@ public: has_boundaries() const { return _tds_2_inf != typename TDS_2::Vertex_handle(); - // return _tds_2_inf->vertex_3() == triangulation_3().infinite_vertex(); } @@ -672,10 +677,6 @@ public: return T; } - - - - int number_of_facets() const { return _facet_number; @@ -1033,6 +1034,12 @@ public: { int i1, i2, i3; + if(deal_with_2d && ( (c->vertex((index+1) & 3) == added_vertex) + || (c->vertex((index+2) & 3) == added_vertex) + || (c->vertex((index+3) & 3) == added_vertex) )) + { + return HUGE_VAL; + } Cell_handle n = c->neighbor(index); // lazy evaluation ... coord_type value = c->smallest_radius(index); @@ -1460,33 +1467,7 @@ public: void ordered_map_erase(const criteria& value, const IO_edge_type* pkey) { -#if USE_MM - std::size_t number_of_conflict = _ordered_border.count(value); - if (number_of_conflict == 1) - { - _ordered_border.erase(_ordered_border.find(value)); - - } - - else if (number_of_conflict > 1) - { - Ordered_border_iterator elt_it = - _ordered_border.find(value); - // si ca foire jamais on peut s'areter des que l'elt - // est trouve!!! - for(std::size_t jj=0; (jjsecond) == ((long) pkey)) - { - _ordered_border.erase(elt_it); - return; - } - elt_it++; - } - } -#else _ordered_border.erase(Radius_ptr_type(value,(IO_edge_type*)pkey)); -#endif } //--------------------------------------------------------------------- diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/planar.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/planar.xyz new file mode 100755 index 00000000000..6c068051642 --- /dev/null +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/planar.xyz @@ -0,0 +1,8 @@ +0 0 0 +1 0 0 +1 1 0 +0 1 0 +11 32 0 +355 43 0 +12 3 0 +134 456 0 diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/point.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/point.xyz new file mode 100755 index 00000000000..b85905ec0b9 --- /dev/null +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/point.xyz @@ -0,0 +1 @@ +1 2 3 diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/segment.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/segment.xyz new file mode 100755 index 00000000000..bd0247e4487 --- /dev/null +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/segment.xyz @@ -0,0 +1,2 @@ +0 0 0 +1 1 1 diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz new file mode 100755 index 00000000000..9e815aea7f5 --- /dev/null +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz @@ -0,0 +1,3 @@ +1 0 0 +111 0 0 +0 0 1111 From 36de1554b1a4ed006416f9a10d517cfc19dde360 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 5 Jun 2015 10:31:53 +0200 Subject: [PATCH 065/114] Add duplicate points to check that the indexing is correct --- .../CGAL/Advancing_front_surface_reconstruction.h | 10 ---------- .../data/triangle.xyz | 5 +++++ 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 281784714b5..008139dc676 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -985,16 +985,6 @@ public: void select_facet(const Cell_handle& c, const int& i) { - if(area!=0){ - total_area += compute_area(c->vertex((i+1)&3)->point(), - c->vertex((i+2)&3)->point(), - c->vertex((i+3)&3)->point()); - } - if(perimeter != 0){ - total_perimeter += compute_perimeter(c->vertex((i+1)&3)->point(), - c->vertex((i+2)&3)->point(), - c->vertex((i+3)&3)->point()); - } c->select_facet(i); _facet_number++; c->set_facet_number(i, _facet_number); diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz index 9e815aea7f5..0270ffab58f 100755 --- a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz @@ -1,3 +1,8 @@ 1 0 0 +1 0 0 +1 0 0 +111 0 0 111 0 0 0 0 1111 +1 0 0 +1 0 0 \ No newline at end of file From 6a724bb881f04968d952d3756ef3edc403254b32 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 5 Jun 2015 10:39:16 +0200 Subject: [PATCH 066/114] remove area filtering --- .../include/CGAL/AFSR_options.h | 6 ++-- .../Advancing_front_surface_reconstruction.h | 30 ++++--------------- 2 files changed, 8 insertions(+), 28 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h index 3fda69a12c2..53a8c11c1ae 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h @@ -11,8 +11,8 @@ public: Delaunay(false), contour(false), binary(false), xyz(false), Section_file(false), max_connected_comp(-1), delta(.86), K_init(1.1), K_step(.1), K(5), out_format(0), - NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false), area(0), perimeter(0), - abs_area(0), abs_perimeter(0) + NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false), perimeter(0), + abs_perimeter(0) { std::strcpy(finname,"finput"); std::strcpy(foutname,"foutput"); @@ -37,7 +37,7 @@ public: int NB_BORDER_MAX; double red, green, blue; bool no_header; - double area, perimeter, abs_area, abs_perimeter; + double perimeter, abs_perimeter; }; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 008139dc676..71ae079e932 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -226,11 +226,8 @@ private: const criteria STANDBY_CANDIDATE_BIS; const criteria NOT_VALID_CANDIDATE; - const double area; const double perimeter; - const double abs_area; const double abs_perimeter; - double total_area; double total_perimeter; //--------------------------------------------------------------------- //Pour une visu correcte @@ -534,8 +531,8 @@ public: : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), - NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), area(opt.area), perimeter(opt.perimeter), - abs_area(opt.abs_area), abs_perimeter(opt.abs_perimeter), total_area(0), total_perimeter(0), + NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), perimeter(opt.perimeter), + abs_perimeter(opt.abs_perimeter), total_perimeter(0), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), deal_with_2d(false) @@ -1128,12 +1125,7 @@ public: return value; } -//--------------------------------------------------------------------- - coord_type - compute_area(const Point& p1, const Point& p2, const Point& p3) const - { - return typename Kernel::Compute_area_3()(p1,p2,p3); - } + //--------------------------------------------------------------------- coord_type compute_perimeter(const Point& p1, const Point& p2, const Point& p3) const @@ -1191,32 +1183,20 @@ public: coord_type tmp=0; coord_type ar=0, pe=0; - // If the triangle has a very large area and a very high perimeter, + // If the triangle has a high perimeter, // we do not want to consider it as a good candidate. - if( (abs_area != 0) || ( (_facet_number > 1000) && (area != 0)) ){ - ar = compute_area(facet_it.first->vertex(n_i1)->point(), - facet_it.first->vertex(n_i2)->point(), - facet_it.first->vertex(n_i3)->point()); - } - if( (abs_perimeter != 0) || ( (_facet_number > 1000) && (perimeter != 0)) ){ pe = compute_perimeter(facet_it.first->vertex(n_i1)->point(), facet_it.first->vertex(n_i2)->point(), facet_it.first->vertex(n_i3)->point()); } - if( ((abs_area != 0)&&(ar > abs_area)) || ((abs_perimeter != 0) && (pe > abs_perimeter)) ){ + if((abs_perimeter != 0) && (pe > abs_perimeter)){ tmp = HUGE_VAL; } if((tmp != HUGE_VAL) && (_facet_number > 1000)){ - if(area != 0){ - coord_type avg_area = total_area/_facet_number; - if(ar > (area * avg_area)){ - tmp = HUGE_VAL; - } - } if((perimeter != 0) && (tmp != HUGE_VAL)){ coord_type avg_perimeter = total_perimeter/_facet_number; if(pe > (perimeter * avg_perimeter)){ From 7dd320c74b8c4d886a9cd2d9af58ec97415272e4 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 5 Jun 2015 11:54:30 +0200 Subject: [PATCH 067/114] Add a functor that allows to reject candidate faces --- .../reconstruction_fct.cpp | 23 +++- .../include/CGAL/AFSR/construct_polyhedron.h | 2 +- .../include/CGAL/AFSR/construct_surface_2.h | 6 +- .../include/CGAL/AFSR/orient.h | 4 +- .../include/CGAL/AFSR/write_triple_indices.h | 8 +- .../Advancing_front_surface_reconstruction.h | 108 +++++++++++------- ...ont_surface_reconstruction_vertex_base_3.h | 4 +- 7 files changed, 102 insertions(+), 53 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index e697a437788..479a4633dec 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -19,6 +19,25 @@ namespace std { } } +struct Perimeter { + + double bound; + + Perimeter(double bound) + : bound(bound) + {} + + bool operator()(const Point_3& p, const Point_3& q, const Point_3& r) const + { + double d = sqrt(squared_distance(p,q)); + if(d>bound) return true; + d += sqrt(squared_distance(p,r)) ; + if(d>bound) return true; + d+= sqrt(squared_distance(q,r)); + return d>bound; + } +}; + int main(int argc, char* argv[]) { std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); @@ -29,9 +48,11 @@ int main(int argc, char* argv[]) std::istream_iterator(), std::back_inserter(points)); + Perimeter perimeter(0.5); CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), - std::back_inserter(facets)); + std::back_inserter(facets), + perimeter); std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n"; std::copy(points.begin(), diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h index f36005191c2..511d9a335f3 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h @@ -6,7 +6,7 @@ namespace CGAL { -template + template class Advancing_front_polyhedron_reconstruction; namespace AFSR { diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h index ad2a76dc1c0..9a0a0196c8a 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h @@ -3,15 +3,15 @@ namespace CGAL { -template + template class Advancing_front_surface_reconstruction; namespace AFSR { -template + template typename TDS::Vertex_handle -construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface) +construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface) { typedef typename TDS::Vertex_handle Vertex_handle; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h index 4182d73c469..0e82534f628 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h @@ -4,9 +4,9 @@ namespace CGAL { namespace AFSR { -template + template typename TDS::Vertex_handle -orient(TDS& tds, const Advancing_front_surface_reconstruction& surface) + orient(TDS& tds, const Advancing_front_surface_reconstruction& surface) { typedef typename TDS::Vertex_handle Vertex_handle; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h index 926b98ba243..8c075ca6e00 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h @@ -5,16 +5,16 @@ namespace CGAL { -template + template class Advancing_front_surface_reconstruction; - template + template OutputIterator - write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S) + write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S) { - typedef Advancing_front_surface_reconstruction Surface; + typedef Advancing_front_surface_reconstruction Surface; typedef typename Surface::TDS_2 TDS_2; typedef typename TDS_2::Face_iterator Face_iterator; typedef typename Surface::Cell_handle Cell_handle; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 71ae079e932..290b43726ae 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -136,14 +136,25 @@ public: } }; + struct Always_false { + + template + bool operator()(const T&, const T&, const T&) const + { + return false; + } + + }; + template , Advancing_front_surface_reconstruction_cell_base_3 > > > + class Triangulation = Delaunay_triangulation_3, Advancing_front_surface_reconstruction_cell_base_3 > >, + class Reject = Always_false> class Advancing_front_surface_reconstruction { public: typedef Triangulation Triangulation_3; - typedef Advancing_front_surface_reconstruction Extract; + typedef Advancing_front_surface_reconstruction Extract; typedef typename Triangulation_3::Geom_traits Geom_traits; typedef typename Kernel::FT coord_type; @@ -205,7 +216,7 @@ public: typedef const std::list > Boundary_range; typedef const std::list Vertex_on_boundary_range; -private: +private: mutable std::list > m_boundaries; @@ -226,9 +237,6 @@ private: const criteria STANDBY_CANDIDATE_BIS; const criteria NOT_VALID_CANDIDATE; - const double perimeter; - const double abs_perimeter; - double total_perimeter; //--------------------------------------------------------------------- //Pour une visu correcte //pour retenir les facettes selectionnees @@ -246,6 +254,7 @@ private: Vertex_handle added_vertex; bool deal_with_2d; + Reject reject; std::list interior_edges; std::list< Incidence_request_elt > incidence_requests; typename std::list< Incidence_request_elt >::iterator sentinel; @@ -527,14 +536,16 @@ private: public: - Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options()) - : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), + Advancing_front_surface_reconstruction(Triangulation_3& T_, + const AFSR_options& opt = AFSR_options(), + Reject reject = Reject()) + : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), - NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), perimeter(opt.perimeter), - abs_perimeter(opt.abs_perimeter), total_perimeter(0), + NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), - _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), deal_with_2d(false) + _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), + deal_with_2d(false), reject(reject) { if(T.dimension() == 2){ @@ -1181,30 +1192,16 @@ public: int n_i3 = 6 - n_ind - n_i1 - n_i2; coord_type tmp=0; - coord_type ar=0, pe=0; // If the triangle has a high perimeter, // we do not want to consider it as a good candidate. - if( (abs_perimeter != 0) || ( (_facet_number > 1000) && (perimeter != 0)) ){ - pe = compute_perimeter(facet_it.first->vertex(n_i1)->point(), - facet_it.first->vertex(n_i2)->point(), - facet_it.first->vertex(n_i3)->point()); - } - - if((abs_perimeter != 0) && (pe > abs_perimeter)){ + if(reject(facet_it.first->vertex(n_i1)->point(), + facet_it.first->vertex(n_i2)->point(), + facet_it.first->vertex(n_i3)->point())){ tmp = HUGE_VAL; } - - if((tmp != HUGE_VAL) && (_facet_number > 1000)){ - if((perimeter != 0) && (tmp != HUGE_VAL)){ - coord_type avg_perimeter = total_perimeter/_facet_number; - if(pe > (perimeter * avg_perimeter)){ - tmp = HUGE_VAL; - } - } - } - + if(tmp != HUGE_VAL){ tmp = smallest_radius_delaunay_sphere(neigh, n_ind); @@ -1343,14 +1340,12 @@ public: if (c->vertex((index+3) & 3)->is_exterior()) { coord_type value = smallest_radius_delaunay_sphere(c, index); - coord_type pe=0; - if(abs_perimeter != 0){ - pe = compute_perimeter(c->vertex((index+1)&3)->point(), - c->vertex((index+2)&3)->point(), - c->vertex((index+3)&3)->point()); - if(pe > abs_perimeter){ - value = min_value; - } + + // we might not want the triangle, for example because it is too large + if(reject(c->vertex((index+1)&3)->point(), + c->vertex((index+2)&3)->point(), + c->vertex((index+3)&3)->point())){ + value = min_value; } if (value < min_value) @@ -2308,6 +2303,7 @@ struct Auto_count : public std::unary_function >{ }; } + template IndexTripleIterator advancing_front_surface_reconstruction(PointIterator b, @@ -2338,14 +2334,46 @@ advancing_front_surface_reconstruction(PointIterator b, return out; } + + template +IndexTripleIterator +advancing_front_surface_reconstruction(PointIterator b, + PointIterator e, + IndexTripleIterator out, + Filter filter, + double radius_ratio_bound = 5, + double beta = 0.52 ) +{ + typedef Exact_predicates_inexact_constructions_kernel Kernel; + typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; + typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; + + typedef Triangulation_data_structure_3 Tds; + typedef Delaunay_triangulation_3 Triangulation_3; + + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Kernel::Point_3 Point_3; + + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), + boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + + AFSR_options opt; + opt.K = radius_ratio_bound; + // TODO: What to do with beta??? + Reconstruction R(dt,opt, filter); + R.run(opt); + write_triple_indices(out, R); + return out; +} + + template void advancing_front_surface_reconstruction(PointIterator b, PointIterator e, Polyhedron_3& polyhedron, double radius_ratio_bound = 5, - double beta = 0.52, - double max_perimeter = 0) + double beta = 0.52) { typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; @@ -2362,7 +2390,7 @@ advancing_front_surface_reconstruction(PointIterator b, AFSR_options opt; opt.K = radius_ratio_bound; // TODO: What to do with beta??? - opt.abs_perimeter = max_perimeter; + //opt.abs_perimeter = max_perimeter; Reconstruction R(dt, opt); R.run(opt); AFSR::construct_polyhedron(polyhedron, R); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index a8ca2fd0f97..43d615e2f3a 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -12,7 +12,7 @@ namespace CGAL { - template class Advancing_front_surface_reconstruction; + template class Advancing_front_surface_reconstruction; template > class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase @@ -26,7 +26,7 @@ public: }; - template friend class Advancing_front_surface_reconstruction; + template friend class Advancing_front_surface_reconstruction; typedef VertexBase Base; From 89234432123d5ec2ed4d5f2ed6c370c078e089a0 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 5 Jun 2015 13:20:12 +0200 Subject: [PATCH 068/114] Explain the filter in the manual --- ...Advancing_front_surface_reconstruction.txt | 4 +++ .../Advancing_front_surface_reconstruction.h | 33 ++++++++++++++++++- .../include/CGAL/AFSR_options.h | 4 +-- .../Advancing_front_surface_reconstruction.h | 9 ----- 4 files changed, 37 insertions(+), 13 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 5de74e261e8..07bf8b8639d 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -197,6 +197,10 @@ reconstructed surface a triplet of point indices into an output iterator. The following example writes the output triangulated surface to `std::cout` in accordance to the OFF format. +The function has an overload with an additional argument that allows to filter triangles, +for example to avoid the generation of triangles with a perimeter larger +than a given bound. + \cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp} diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 0c82e35e114..2e821928623 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -11,12 +11,16 @@ data structure that describes the surface. The vertices and facets of the 2D tr store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the 2D as well as 3D neighborhood of vertices and facets of the surface. +\tparam Gt must be a model of `Kernel`. \tparam Dt must be a `Delaunay_triangulation_3` with `Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, and the geometric traits class must be the `Exact_predicates_inexact_constructions_kernel`. +\tparam Filter must be a functor with `bool operator()(Gt::Point_3,Gt::Point_3,Gt::Point_3)` that allows the user to filter candidate triangles, for example based on its size. + It defaults to a functor that always returns `false`. + */ -template< typename Dt> + template< typename Gt, typename Dt, typename Filter> class Advancing_front_surface_reconstruction { public: @@ -212,4 +216,31 @@ describing the faces of the reconstructed surface. IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double radius_ratio_bound = 5, double beta= 0.52 ); +/*! +\ingroup PkgAdvancingFrontSurfaceReconstruction + +For a sequence of points computes a sequence of index triples +describing the faces of the reconstructed surface. + +\tparam PointInputIterator must be an input iterator with 3D points from the `Exact_predicates_inexact_constructions_kernel` as value type. +\tparam IndicesOutputIterator must be an output iterator to which +`CGAL::cpp11::tuple` can be assigned. +\tparam Filter must be a functor with `bool operator()(Gt::Point_3,Gt::Point_3,Gt::Point_3)`. + +\param b iterator on the first point of the sequence +\param e past the end iterator of the point sequence +\param out output iterator +\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge + are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. + Described in Section \ref AFSR_Boundaries +\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. + Described in Section \ref AFSR_Selection +\param filter allows the user to filter candidate triangles, for example based on their size. + +*/ + template + IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, Filter filter, double radius_ratio_bound = 5, double beta= 0.52 ); + + + } /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h index 53a8c11c1ae..064a64a0942 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h @@ -11,8 +11,7 @@ public: Delaunay(false), contour(false), binary(false), xyz(false), Section_file(false), max_connected_comp(-1), delta(.86), K_init(1.1), K_step(.1), K(5), out_format(0), - NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false), perimeter(0), - abs_perimeter(0) + NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false) { std::strcpy(finname,"finput"); std::strcpy(foutname,"foutput"); @@ -37,7 +36,6 @@ public: int NB_BORDER_MAX; double red, green, blue; bool no_header; - double perimeter, abs_perimeter; }; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 290b43726ae..89dc328bc51 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -1137,14 +1137,6 @@ public: return value; } -//--------------------------------------------------------------------- - coord_type - compute_perimeter(const Point& p1, const Point& p2, const Point& p3) const - { - return sqrt(squared_distance(p1,p2)) - + sqrt(squared_distance(p2,p3)) - + sqrt(squared_distance(p3,p1)); - } //--------------------------------------------------------------------- // For a border edge e we determine the incident facet which has the highest @@ -2390,7 +2382,6 @@ advancing_front_surface_reconstruction(PointIterator b, AFSR_options opt; opt.K = radius_ratio_bound; // TODO: What to do with beta??? - //opt.abs_perimeter = max_perimeter; Reconstruction R(dt, opt); R.run(opt); AFSR::construct_polyhedron(polyhedron, R); From a99ff3c8222a561462f928e4af28678d64788542 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 5 Jun 2015 17:12:54 +0200 Subject: [PATCH 069/114] e claimed to write in the STL format but that was wrong --- .../reconstruction_class.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp index 2214f938551..8ef730cedad 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp @@ -9,6 +9,7 @@ typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; typedef Reconstruction::Triangulation_3 Triangulation_3; typedef Reconstruction::Triangulation_data_structure_2 TDS_2; typedef K::Point_3 Point_3; +typedef K::Vector_3 Vector_3; int main(int argc, char* argv[]) { @@ -24,6 +25,7 @@ int main(int argc, char* argv[]) const TDS_2& tds = reconstruction.triangulation_data_structure_2(); + std::cout << "solid produced with CGAL::Advancing_front_surface_reconstruction\n"; for(TDS_2::Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ @@ -31,14 +33,23 @@ int main(int argc, char* argv[]) Triangulation_3::Facet f = fit->facet(); Triangulation_3::Cell_handle ch = f.first; int ci = f.second; - for(int i = 0; i < 4; i++){ + Point_3 points[3]; + for(int i = 0, j = 0; i < 4; i++, j++){ if(ci != i){ - std:: cout << ch->vertex(i)->point() << " "; + points[j] = ch->vertex(i)->point(); } } - std::cout << std::endl; + std::cout << " facet normal " + << CGAL::unit_normal(points[0],points[1], points[2]) << "\n" + << " outer loop\n" + << " vertex " << points[0] << "\n" + << " vertex " << points[1] << "\n" + << " vertex " << points[2] << "\n" + << " endloop\n" + << " endfacet\n"; } } + std::cout << "endsolid" << std::endl; return 0; } From fb1c691ffa0bc90693a0a5edcc4d480b73e524a3 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 8 Jun 2015 14:29:46 +0200 Subject: [PATCH 070/114] get the demo compiled --- .../Advancing_front_surface_reconstruction.h | 17 ++++---- Polyhedron/demo/Polyhedron/CMakeLists.txt | 2 +- ...Polyhedron_demo_advancing_front_plugin.cpp | 42 +++++++++++++------ .../Polyhedron_demo_advancing_front_plugin.ui | 35 ++-------------- 4 files changed, 43 insertions(+), 53 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 89dc328bc51..c8a27921dab 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2359,13 +2359,14 @@ advancing_front_surface_reconstruction(PointIterator b, } -template + template void -advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, - Polyhedron_3& polyhedron, - double radius_ratio_bound = 5, - double beta = 0.52) +advancing_front_surface_reconstructionP(PointIterator b, + PointIterator e, + Polyhedron_3& polyhedron, + Filter filter, + double radius_ratio_bound = 5, + double beta = 0.52) { typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; @@ -2373,7 +2374,7 @@ advancing_front_surface_reconstruction(PointIterator b, typedef Triangulation_data_structure_3 Tds; typedef Delaunay_triangulation_3 Triangulation_3; - typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Advancing_front_surface_reconstruction Reconstruction; typedef typename Kernel::Point_3 Point_3; Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), @@ -2382,7 +2383,7 @@ advancing_front_surface_reconstruction(PointIterator b, AFSR_options opt; opt.K = radius_ratio_bound; // TODO: What to do with beta??? - Reconstruction R(dt, opt); + Reconstruction R(dt, opt,filter); R.run(opt); AFSR::construct_polyhedron(polyhedron, R); } diff --git a/Polyhedron/demo/Polyhedron/CMakeLists.txt b/Polyhedron/demo/Polyhedron/CMakeLists.txt index e038522e1ab..dc8e2493dfc 100644 --- a/Polyhedron/demo/Polyhedron/CMakeLists.txt +++ b/Polyhedron/demo/Polyhedron/CMakeLists.txt @@ -355,7 +355,7 @@ if(CGAL_Qt4_FOUND AND QT4_FOUND AND OPENGL_FOUND AND QGLVIEWER_FOUND) target_link_libraries(pca_plugin scene_polyhedron_item scene_basic_objects) qt4_wrap_ui( advancing_frontUI_FILES Polyhedron_demo_advancing_front_plugin.ui) - polyhedron_demo_plugin(advancing_front_plugin Polyhedron_demo_advancing_front_plugin Polyhedron_demo_advancing_front_plugin_impl ${advancing_frontUI_FILES}) + polyhedron_demo_plugin(advancing_front_plugin Polyhedron_demo_advancing_front_plugin ${advancing_frontUI_FILES}) target_link_libraries(advancing_front_plugin scene_polygon_soup_item scene_points_with_normal_item) if(EIGEN3_FOUND) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp index 837e1598425..350a8148368 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp @@ -3,7 +3,9 @@ #include "Polyhedron_demo_plugin_helper.h" #include "Polyhedron_demo_plugin_interface.h" #include - +#include "Kernel_type.h" +#include "Polyhedron_type.h" +#include #include #include @@ -14,10 +16,28 @@ #include "ui_Polyhedron_demo_advancing_front_plugin.h" -// Reconstructs a surface mesh from a point set and writes facet indices into polygon soup. -Polyhedron* advancing_front_reconstruct(const Point_set& points, - double sm_perimeter, - double sm_area); +struct Perimeter { + + double bound; + + Perimeter(double bound) + : bound(bound) + {} + + bool operator()(const Kernel::Point_3& p, const Kernel::Point_3& q, const Kernel::Point_3& r) const + { + if(bound == 0){ + return true; + } + double d = sqrt(squared_distance(p,q)); + if(d>bound) return true; + d += sqrt(squared_distance(p,r)) ; + if(d>bound) return true; + d+= sqrt(squared_distance(q,r)); + return d>bound; + } +}; + class Polyhedron_demo_advancing_front_plugin : public QObject, @@ -61,7 +81,6 @@ class Polyhedron_demo_advancing_front_plugin_dialog : public QDialog, private Ui } double trianglePerimeter() const { return m_inputPerimeter->value(); } - double triangleArea() const { return m_inputArea->value(); } }; void Polyhedron_demo_advancing_front_plugin::on_actionAdvancingFrontReconstruction_triggered() @@ -82,7 +101,6 @@ void Polyhedron_demo_advancing_front_plugin::on_actionAdvancingFrontReconstructi if(!dialog.exec()) return; const double sm_perimeter = dialog.trianglePerimeter(); - const double sm_area = dialog.triangleArea(); QApplication::setOverrideCursor(Qt::WaitCursor); @@ -90,15 +108,15 @@ void Polyhedron_demo_advancing_front_plugin::on_actionAdvancingFrontReconstructi // Add polyhedron to scene // Reconstruct point set as a polyhedron - Polyhedron *poly = advancing_front_reconstruct(*points, sm_perimeter, sm_area); - - Scene_polyhedron_item* new_item = new Scene_polyhedron_item(poly); + Scene_polyhedron_item* new_item = new Scene_polyhedron_item(Polyhedron()); + Polyhedron& P = * const_cast(new_item->polyhedron()); + Perimeter filter(sm_perimeter); + CGAL::advancing_front_surface_reconstructionP((points)->begin(), points->end(), P, filter); new_item->setName(tr("%1 Advancing Front (%2 %3)") .arg(point_set_item->name()) - .arg(sm_perimeter) - .arg(sm_area)); + .arg(sm_perimeter)); new_item->setColor(Qt::lightGray); scene->addItem(new_item); diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui index b66834514ab..a699faed2b8 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.ui @@ -17,14 +17,14 @@ - Min triangle perimeter: + Max triangle perimeter: - * average spacing + 0.000000000000000 @@ -37,36 +37,7 @@ - - - - Max triangle area: - - - - - - - * average spacing^2 - - - 0 - - - 0.000000000000000 - - - 20.000000000000000 - - - 1.000000000000000 - - - 0.000000000000000 - - - - + QDialogButtonBox::Cancel|QDialogButtonBox::Ok From 011adaef42cf637c5a1c4f4be33590cf2bfcc622 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 8 Jun 2015 15:05:23 +0200 Subject: [PATCH 071/114] the filter works the other way round --- .../demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp index 350a8148368..4db6d27379b 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp @@ -27,7 +27,7 @@ struct Perimeter { bool operator()(const Kernel::Point_3& p, const Kernel::Point_3& q, const Kernel::Point_3& r) const { if(bound == 0){ - return true; + return false; } double d = sqrt(squared_distance(p,q)); if(d>bound) return true; From a5aafc876b7e0f8c472ca6f8b0981484730df92e Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 8 Jun 2015 15:18:55 +0200 Subject: [PATCH 072/114] make applicable --- .../Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp index 4db6d27379b..3db1bfb534d 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp @@ -57,7 +57,7 @@ public: } //! Applicate for Point_sets with normals. - bool applicable() const { + bool applicable(QAction*) const { return qobject_cast(scene->item(scene->mainSelectionIndex())); } @@ -65,7 +65,7 @@ public: return QList() << actionAdvancingFrontReconstruction; } -public slots: +public Q_SLOTS: void on_actionAdvancingFrontReconstruction_triggered(); }; // end class Polyhedron_demo_advancing_front_plugin From cefc1b9c500f898dd62b5a56a8d3dca4fdf4833e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Jun 2015 09:34:33 +0200 Subject: [PATCH 073/114] add new plugin in testsuite --- Polyhedron/demo/Polyhedron/cgal_test_with_cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/Polyhedron/demo/Polyhedron/cgal_test_with_cmake b/Polyhedron/demo/Polyhedron/cgal_test_with_cmake index 1c208a31d85..6378b6b8a6a 100755 --- a/Polyhedron/demo/Polyhedron/cgal_test_with_cmake +++ b/Polyhedron/demo/Polyhedron/cgal_test_with_cmake @@ -162,6 +162,7 @@ else p_klein_function_plugin \ p_sphere_function_plugin \ p_tanglecube_function_plugin \ + advancing_front_plugin \ all do if ${MAKE_CMD} -f Makefile help | grep "$target" > /dev/null; then From 6964ebc4ff58d5e42079b838ad636d0bb47a201e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Jun 2015 09:50:24 +0200 Subject: [PATCH 074/114] fix warnings and compilation issues --- .../include/CGAL/AFSR/construct_polyhedron.h | 3 --- .../include/CGAL/AFSR/write_triple_indices.h | 5 ++--- .../include/CGAL/Advancing_front_surface_reconstruction.h | 6 +++--- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h index 511d9a335f3..01f23e45465 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h @@ -25,13 +25,10 @@ public: { CGAL::Polyhedron_incremental_builder_3 B( hds, true); B.begin_surface( s.number_of_vertices(), s.number_of_facets(), 6* s.number_of_facets()); - typedef typename HDS::Vertex Vertex; - typedef typename Vertex::Point Point; typedef typename Surface::TDS_2 TDS_2; typedef typename TDS_2::Face_iterator Face_iterator; typedef typename TDS_2::Vertex_iterator Vertex_iterator; - typedef typename Surface::Cell_handle Cell_handle; const TDS_2& tds = s.triangulation_data_structure_2(); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h index 8c075ca6e00..9e6f87b7f24 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h @@ -5,19 +5,18 @@ namespace CGAL { - template +template class Advancing_front_surface_reconstruction; - template +template OutputIterator write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S) { typedef Advancing_front_surface_reconstruction Surface; typedef typename Surface::TDS_2 TDS_2; typedef typename TDS_2::Face_iterator Face_iterator; - typedef typename Surface::Cell_handle Cell_handle; if(S.triangulation_3().dimension() < 3){ std::cerr << "not 3D\n"; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index c8a27921dab..0369ca4ddff 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -632,10 +632,10 @@ public: } - typedef Triangulation_data_structure_2, - AFSR::Surface_face_base_2 > TDS_2; + typedef CGAL::Triangulation_data_structure_2, + AFSR::Surface_face_base_2 > TDS_2; - typedef TDS_2 Triangulation_data_structure_2; + typedef TDS_2 Triangulation_data_structure_2; mutable TDS_2 _tds_2; From 43ee79850b3a30c8634c18ca90479df8e4590edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Jun 2015 09:56:48 +0200 Subject: [PATCH 075/114] remove warning --- .../include/CGAL/Advancing_front_surface_reconstruction.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 0369ca4ddff..e8aef309b26 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -564,9 +564,7 @@ public: Vector vw = cross_product(v,w); double len = (std::max)(u*u,(std::max)(v*v,w*w)); Point s = p + 10* len * (vw/(vw*vw)); - std::size_t n = T.number_of_vertices(); added_vertex = T.insert(s); - } } From 4c655134056824ef2be33433bb7a3694b7cd6a77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Tue, 9 Jun 2015 10:29:56 +0200 Subject: [PATCH 076/114] link more --- .../CGAL/Advancing_front_surface_reconstruction.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 2e821928623..5faddbee2b7 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -30,9 +30,9 @@ public: /*! The type of the 2D triangulation data structure describing the reconstructed surface. The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the - method `vertex_3()` that returns a `Vertex_handle` to the associated 3D vertex. + method `vertex_3()` that returns a `#Vertex_handle` to the associated 3D vertex. The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the - method `facet()` that returns the associated `Facet`, and a method `bool is_on_surface()` + method `facet()` that returns the associated `#Facet`, and a method `bool is_on_surface()` for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite vertex of the 3D triangulation. @@ -73,7 +73,7 @@ The facet type of the 3D triangulation. /*! A bidirectional iterator range which enables to enumerate all points that were removed from the 3D Delaunay triangulation during the surface reconstruction. The value type - of the iterator is `Point`. + of the iterator is `#Point`. */ typedef unspecified_type Outlier_range; @@ -83,7 +83,7 @@ typedef unspecified_type Outlier_range; visits the entry point of each boundary twice. This allows to detect that the traversal of a boundary is finished. One more increment brings us to the vertex on the next boundary. - The value type of the iterator is `Vertex_handle`. + The value type of the iterator is `#Vertex_handle`. */ #endif @@ -95,7 +95,7 @@ typedef unspecified_type Boundary_range; /*! A bidirectional iterator range which enables to visit all vertices on a boundary. - The value type of the iterator is `Vertex_handle` + The value type of the iterator is `#Vertex_handle` */ typedef unspecified_type Vertex_on_boundary_range; From 3f5cffe2c4d27f4799f71c0b52638657f04e4e32 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 9 Jun 2015 09:35:54 +0200 Subject: [PATCH 077/114] fix extract.cpp --- .../extract.cpp | 64 ++++++++----------- .../include/CGAL/AFSR_options.h | 1 + 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp index 5068f480a24..5ef99fa1139 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp @@ -36,9 +36,30 @@ typedef CGAL::Delaunay_triangulation_3 Triangulation_3; typedef Triangulation_3::Vertex_handle Vertex_handle; -typedef CGAL::Advancing_front_surface_reconstruction Surface; -typedef CGAL::AFSR_options Options; +struct Perimeter { + double bound; + + Perimeter(double bound) + : bound(bound) + {} + + bool operator()(const Point& p, const Point& q, const Point& r) const + { + if(bound == 0){ + return false; + } + double d = sqrt(squared_distance(p,q)); + if(d>bound) return true; + d += sqrt(squared_distance(p,r)) ; + if(d>bound) return true; + d+= sqrt(squared_distance(q,r)); + return d>bound; + } +}; + +typedef CGAL::Advancing_front_surface_reconstruction Surface; +typedef CGAL::AFSR_options Options; //--------------------------------------------------------------------- @@ -109,9 +130,7 @@ void usage(char* program) << " ply, stl, all, none)" << std::endl << " -rgb r g b : color of the surface" << std::endl << " -no_header : The Vrml header and footer are not written" << std::endl - << " -area a : No faces larger than area * average_area" << std::endl << " -perimeter p : No faces larger than perimeter * average_perimeter" << std::endl - << " -abs_area a : No faces larger than abs_area" << std::endl << " -abs_perimeter p : No faces with perimeter longer than abs_perimeter" << std::endl << "\n Options for internal use" << std::endl @@ -184,16 +203,7 @@ parse(int argc, char* argv[], Options &opt) argv += 2; argc -= 2; std::cerr << "-d " << opt.delta << " "; - } - else if ((!std::strcmp(argv[0], "-a")) || (!std::strcmp(argv[0], "-area"))){ - if (sscanf(argv[1], "%lf", &opt.area) != 1) { - std::cerr << "Argument for area must be a number" - << std::endl; - } - argv += 2; - argc -= 2; - std::cerr << "-a " << opt.area << " "; - } + } else if ((!std::strcmp(argv[0], "-pe")) || (!std::strcmp(argv[0], "-perimeter"))){ if (sscanf(argv[1], "%lf", &opt.perimeter) != 1) { std::cerr << "Argument for perimeter must be a number" @@ -202,25 +212,7 @@ parse(int argc, char* argv[], Options &opt) argv += 2; argc -= 2; std::cerr << "-perimeter " << opt.perimeter << " "; - } - else if ((!std::strcmp(argv[0], "-aa")) || (!std::strcmp(argv[0], "-abs_area"))){ - if (sscanf(argv[1], "%lf", &opt.abs_area) != 1) { - std::cerr << "Argument for abs_area must be a number" - << std::endl; - } - argv += 2; - argc -= 2; - std::cerr << "-abs_area " << opt.abs_area << " "; - } - else if ((!std::strcmp(argv[0], "-ae")) || (!std::strcmp(argv[0], "-abs_perimeter"))){ - if (sscanf(argv[1], "%lf", &opt.abs_perimeter) != 1) { - std::cerr << "Argument for abs_perimeter must be a number" - << std::endl; - } - argv += 2; - argc -= 2; - std::cerr << "-abs_perimeter " << opt.abs_perimeter << " "; - } + } else if ((!std::strcmp(argv[0], "-ki"))){ if ((sscanf(argv[1], "%lf", &opt.K_init) != 1)|| (sscanf(argv[2], "%lf", &opt.K) != 1)){ @@ -435,9 +427,9 @@ int main(int argc, char* argv[]) points.clear(); - - Surface S(dt, opt); - S.run(); + Perimeter filter(opt.perimeter); + Surface S(dt, opt, filter); + S.run(opt); std::cerr << "Total time: " << timer.time() << " sec." << std::endl; // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h index 064a64a0942..e7fb724d3f1 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h @@ -26,6 +26,7 @@ public: bool contour; bool binary; bool xyz; + double perimeter; bool Section_file; int max_connected_comp; double delta; From 8b4f2014f39423ca3761a39e876dc6f32696e62b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 9 Jun 2015 10:03:12 +0200 Subject: [PATCH 078/114] add license headers --- .../include/CGAL/AFSR/Surface_face_base_2.h | 19 +++++++++++++++++++ .../include/CGAL/AFSR/Surface_vertex_base_2.h | 14 ++++++++------ .../include/CGAL/AFSR/construct_polyhedron.h | 19 +++++++++++++++++++ .../include/CGAL/AFSR/construct_surface_2.h | 19 +++++++++++++++++++ .../include/CGAL/AFSR/orient.h | 19 +++++++++++++++++++ .../include/CGAL/AFSR/write_triple_indices.h | 19 +++++++++++++++++++ .../Advancing_front_surface_reconstruction.h | 19 +++++++++++++++++++ ...front_surface_reconstruction_cell_base_3.h | 19 +++++++++++++++++++ ...ont_surface_reconstruction_vertex_base_3.h | 19 +++++++++++++++++++ .../include/CGAL/IO/AFSR_vrml.h | 19 +++++++++++++++++++ .../Advancing_front_surface_reconstruction.h | 19 +++++++++++++++++++ 11 files changed, 198 insertions(+), 6 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h index d59bf2048c6..c52a1ce5d86 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_AFSR_SURFACE_FACE_BASE_2_H #define CGAL_AFSR_SURFACE_FACE_BASE_2_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h index d274a07cef7..6c15ca2185b 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h @@ -1,9 +1,10 @@ -// Copyright (c) 2005 GeometryFactory Sarl +// Copyright (c) 2015 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. +// This file is part of CGAL (www.cgal.org). +// You can redistribute it and/or modify it under the terms of the GNU +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. // // Licensees holding a valid commercial license may use this file in // accordance with the commercial license agreement provided with the software. @@ -11,9 +12,10 @@ // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. // +// $URL$ +// $Id$ // -// Author(s) : Andreas Fabri - +// Author(s) : Frank Da, David Cohen-Steiner, Andreas Fabri #ifndef CGAL_AFSR_SURFACE_VERTEX_BASE_2_H #define CGAL_AFSR_SURFACE_VERTEX_BASE_2_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h index 01f23e45465..4ee56548a60 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_AFSR_CONSTRUCT_POLYHEDRON_2 #define CGAL_AFSR_CONSTRUCT_POLYHEDRON_2 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h index 9a0a0196c8a..7147d11cb3b 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_AFSR_CONSTRUCT_SURFACE_2 #define CGAL_AFSR_CONSTRUCT_SURFACE_2 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h index 0e82534f628..f7ab995e178 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_AFSR_ORIENT namespace CGAL { diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h index 9e6f87b7f24..9a1899ad9ad 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_AFSR_WRITE_TRIPLE_INDICES_H #define CGAL_AFSR_WRITE_TRIPLE_INDICES_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index e8aef309b26..a2865382f2f 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H #define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h index 376cf4b1236..8fb77be47c8 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_CELL_BASE_3_H #define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_CELL_BASE_3_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index 43d615e2f3a..cf77c286548 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_WITH_ID_3_H #define CGAL_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_VERTEX_BASE_WITH_ID_3_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h index aa399136818..a145d7f48fb 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_AFSR_VRML_H #define CGAL_AFSR_VRML_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h index 6184c36b1d6..799310651f7 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h @@ -1,3 +1,22 @@ +// Copyright (c) 2015 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 +// General Public License as published by the Free Software Foundation, +// either version 3 of the License, or (at your option) any later version. +// +// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri + #ifndef CGAL_IO_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H #define CGAL_IO_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H From d7e2819f0c3d8e978d9ca96dbf8b9435f24f1b4c Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 9 Jun 2015 11:28:56 +0200 Subject: [PATCH 079/114] remove files --- .../CMakeLists.txt | 2 - .../reconstruction_polyhedron.cpp | 2 +- .../include/CGAL/AFSR_vertex_base_3.h | 473 -------- .../Advancing_front_surface_reconstruction.h | 29 + .../include/CGAL/IO/AFSR_vrml.h | 87 -- .../Advancing_front_surface_reconstruction.h | 1056 ----------------- .../include/CGAL/Tvb_3_2.h | 94 -- 7 files changed, 30 insertions(+), 1713 deletions(-) delete mode 100644 Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h delete mode 100644 Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h delete mode 100644 Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h delete mode 100644 Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt index a0cc57bb9f6..fb6a1a31263 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt @@ -21,9 +21,7 @@ if ( CGAL_FOUND ) include( CGAL_CreateSingleSourceCGALProgram ) include_directories (BEFORE ../../include) -# include_directories (BEFORE ../../../../../trunk/Triangulation_2/include) - create_single_source_cgal_program( "extract.cpp" ) create_single_source_cgal_program( "reconstruction_fct.cpp" ) create_single_source_cgal_program( "reconstruction_class.cpp" ) create_single_source_cgal_program( "reconstruction_polyhedron.cpp" ) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp index 4b6da452bf0..47ea0f09a60 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp @@ -22,7 +22,7 @@ int main() std::istream_iterator(), std::back_inserter(points)); - CGAL::advancing_front_surface_reconstruction(points.begin(), + CGAL::advancing_front_surface_reconstructionP(points.begin(), points.end(), P); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h deleted file mode 100644 index 1820698a372..00000000000 --- a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_vertex_base_3.h +++ /dev/null @@ -1,473 +0,0 @@ -#ifndef CGAL_AFSR_VERTEX_BASE_3_H -#define CGAL_AFSR_VERTEX_BASE_3_H - -#include - -#include -#include -#include - -#include - -namespace CGAL { - -template > -class AFSR_vertex_base_3 : public VertexBase -{ -public: - - template < typename TDS2 > - struct Rebind_TDS { - typedef typename VertexBase::template Rebind_TDS::Other Vb2; - typedef AFSR_vertex_base_3 Other; - }; - - - typedef VertexBase Base; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Cell_handle Cell_handle; - typedef typename VertexBase::Point Point; - typedef double coord_type; - - typedef Triple< Cell_handle, int, int > Edge; - typedef std::pair< Edge, int > Edge_incident_facet; - typedef std::pair< Edge_incident_facet, Edge_incident_facet > IO_edge_type; - - typedef coord_type criteria; - - typedef std::pair< criteria, IO_edge_type > Radius_edge_type; - typedef std::pair< Radius_edge_type, int > Border_elt; - typedef std::pair< Vertex_handle, Border_elt > Next_border_elt; - -private: - - //par convention je remplis d'abord first et si necessaire second... - typedef std::pair< Next_border_elt*, Next_border_elt*> Intern_successors_type; - -public: - - typedef std::pair< criteria, IO_edge_type* > Radius_ptr_type; - typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; - typedef std::pair< criteria, Edge_like > Incidence_request_elt; - typedef std::list< Incidence_request_elt > Incidence_request_type; - typedef typename Incidence_request_type::iterator Incidence_request_iterator; - - // typedef std::set< void* > Interior_edge_set_type; - - //-------------------- DATA MEMBERS --------------------------------- - -private: - - int _mark; - int _post_mark; - Intern_successors_type* _incident_border; - - // Instead of having a set per vertex, there is a global list. - static std::list interior_edges; - // and two iterators per vertex in this list - // Note that ie_last is not past the end - // ie_first == ie_last == interior_edge.end() iff the set is empty - typename std::list::iterator ie_first, ie_last; - - - // We do the same for the incidence requests - static std::list< Incidence_request_elt > incidence_requests; - typename std::list< Incidence_request_elt >::iterator ir_first, ir_last; - //-------------------- CONSTRUCTORS --------------------------------- - -public: - - AFSR_vertex_base_3() - : VertexBase(), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new Intern_successors_type(new Next_border_elt(), - new Next_border_elt()); - _incident_border->first->first = NULL; - _incident_border->second->first = NULL; - } - - AFSR_vertex_base_3(const Point & p) - : VertexBase(p), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new Intern_successors_type(new Next_border_elt(), - new Next_border_elt()); - _incident_border->first->first = NULL; - _incident_border->second->first = NULL; - } - - AFSR_vertex_base_3(const Point & p, Cell_handle f) - : VertexBase(p, f), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new Intern_successors_type(new Next_border_elt(), - new Next_border_elt()); - _incident_border->first->first = NULL; - _incident_border->second->first = NULL; - } - - AFSR_vertex_base_3(Cell_handle f) - : VertexBase(f), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new Intern_successors_type(new Next_border_elt(), - new Next_border_elt()); - _incident_border->first->first = NULL; - _incident_border->second->first = NULL; - } - - AFSR_vertex_base_3(const AFSR_vertex_base_3& other) - : VertexBase(), _mark(-1), - _post_mark(-1), - ie_first(interior_edges.end()), ie_last(interior_edges.end()), - ir_first(incidence_requests.end()), ir_last(incidence_requests.end()) - { - _incident_border = new Intern_successors_type(new Next_border_elt(), - new Next_border_elt()); - _incident_border->first->first = NULL; - _incident_border->second->first = NULL; - } - //-------------------- DESTRUCTOR ----------------------------------- - - ~AFSR_vertex_base_3() - { - if (_incident_border != NULL) - { - delete _incident_border->first; - delete _incident_border->second; - delete _incident_border; - } - if(ir_first != incidence_requests.end()){ - assert(ir_last != incidence_requests.end()); - typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last); - e++; - incidence_requests.erase(b, e); - } - - if(ie_first != interior_edges.end()){ - assert(ie_last != interior_edges.end()); - typename std::list::iterator b(ie_first), e(ie_last); - e++; - interior_edges.erase(b, e); - } - } - - //-------------------- MEMBER FUNCTIONS ----------------------------- - - inline void re_init() - { - if (_incident_border != NULL) - { - delete _incident_border->first; - delete _incident_border->second; - delete _incident_border; - } - - if(ir_first != incidence_requests.end()){ - assert(ir_last != incidence_requests.end()); - typename std::list< Incidence_request_elt >::iterator b(ir_first), e(ir_last); - e++; - incidence_requests.erase(b, e); - ir_first = incidence_requests.end(); - ir_last = incidence_requests.end(); - } - - _incident_border = new Intern_successors_type(new Next_border_elt(), - new Next_border_elt()); - _incident_border->first->first = NULL; - _incident_border->second->first = NULL; - _mark = -1; - _post_mark = -1; - } - - //------------------------------------------------------------------- - - inline bool is_on_border(const int& i) const - { - if (_incident_border == NULL) return false; //vh is interior - if (_incident_border->first->first != NULL) - { - if (_incident_border->second->first != NULL) - return ((_incident_border->first->second.second == i)|| - (_incident_border->second->second.second == i)); - return (_incident_border->first->second.second == i); - } - return false; //vh is still exterior - } - - inline Next_border_elt* get_next_on_border(const int& i) const - { - if (_incident_border == NULL) return NULL; //vh is interior - if (_incident_border->first->first != NULL) - if (_incident_border->first->second.second == i) - return _incident_border->first; - if (_incident_border->second->first != NULL) - if (_incident_border->second->second.second == i) - return _incident_border->second; - return NULL; - } - - - inline void remove_border_edge(Vertex_handle v) - { - if (_incident_border != NULL) - { - if (_incident_border->second->first == v) - { - _incident_border->second->first = NULL; - set_interior_edge(v); - return; - } - if (_incident_border->first->first == v) - { - if (_incident_border->second->first != NULL) - { - Next_border_elt* tmp = _incident_border->first; - _incident_border->first = _incident_border->second; - _incident_border->second = tmp; - _incident_border->second->first = NULL; - set_interior_edge(v); - return; - } - else - { - _incident_border->first->first = NULL; - set_interior_edge(v); - return; - } - } - } - } - - inline bool is_border_edge(Vertex_handle v) const - { - if (_incident_border == NULL) return false; - return ((_incident_border->first->first == v)|| - (_incident_border->second->first == v)); - } - - inline Next_border_elt* get_border_elt(Vertex_handle v) const - { - if (_incident_border == NULL) return NULL; - if (_incident_border->first->first == v) return _incident_border->first; - if (_incident_border->second->first == v) return _incident_border->second; - return NULL; - } - - inline Next_border_elt* first_incident() const - { - if (_incident_border == NULL) return NULL; - return _incident_border->first; - } - - inline Next_border_elt* second_incident() const - { - if (_incident_border == NULL) return NULL; - return _incident_border->second; - } - - - inline void set_next_border_elt(const Next_border_elt& elt) - { - if (_incident_border->first->first == NULL) - *_incident_border->first = elt; - else - { - if (_incident_border->second->first != NULL) - std::cerr << "+++probleme de MAJ du bord " << std::endl; - *_incident_border->second = elt; - } - } - - //------------------------------------------------------------------- - // pour gerer certaines aretes interieures: a savoir celle encore connectee au - // bord (en fait seule, les aretes interieures reliant 2 bords nous - // interressent...) - - inline bool is_interior_edge(Vertex_handle v) const - { - - bool r1; - if(ie_first == interior_edges.end()){ - r1 = false; - }else { - typename std::list::iterator b(ie_first), e(ie_last); - e++; - typename std::list::iterator r = std::find(b, e, v); - r1 = ( r != e); - } - - return r1; - } - - inline void set_interior_edge(Vertex_handle v) - { - if(ie_last == interior_edges.end()){ // empty set - assert(ie_first == ie_last); - ie_last = interior_edges.insert(ie_last, v); - ie_first = ie_last; - } else { - typename std::list::iterator e(ie_last); - e++; -#ifdef DEBUG - typename std::list::iterator r = std::find(ie_first, e, v); -#endif - assert(r == e); - ie_last = interior_edges.insert(e, v); - } - } - - inline void remove_interior_edge(Vertex_handle v) - { - if(ie_first == interior_edges.end()){ - assert(ie_last == ie_first); - } else if(ie_first == ie_last){ // there is only one element - if(*ie_first == v){ - interior_edges.erase(ie_first); - ie_last = interior_edges.end(); - ie_first = ie_last; - } - } else { - typename std::list::iterator b(ie_first), e(ie_last); - e++; - typename std::list::iterator r = std::find(b, e, v); - if(r != e){ - if(r == ie_first){ - ie_first++; - } - if(r == ie_last){ - ie_last--; - } - interior_edges.erase(r); - } - } - } - - //------------------------------------------------------------------- - - inline void set_incidence_request(const Incidence_request_elt& ir) - { - if(ir_last == incidence_requests.end()){ - assert(ir_first == ir_last); - ir_last = incidence_requests.insert(ir_last, ir); - ir_first = ir_last; - } else { - typename std::list::iterator e(ir_last); - e++; - ir_last = incidence_requests.insert(e, ir); - } - } - - inline bool is_incidence_requested() const - { - if(ir_last == incidence_requests.end()){ - assert(ir_first == incidence_requests.end()); - } - return (ir_last != incidence_requests.end()); - } - - inline Incidence_request_iterator incidence_request_begin() - { - return ir_first; - } - - inline Incidence_request_iterator get_incidence_request_end() - { - if(ir_last != incidence_requests.end()){ - assert(ir_first != incidence_requests.end()); - Incidence_request_iterator it(ir_last); - it++; - return it; - } - return ir_last; - } - - inline void erase_incidence_request() - { - if(ir_last != incidence_requests.end()){ - assert(ir_first != incidence_requests.end()); - ir_last++; - incidence_requests.erase(ir_first, ir_last); - ir_first = incidence_requests.end(); - ir_last = incidence_requests.end(); - } - } - - - //------------------------------------------------------------------- - - inline bool is_on_border() const - { - return (_mark > 0); - } - - inline bool not_interior() const - { - return (_mark != 0); - } - - inline int number_of_incident_border() const - { - return _mark; - } - - inline bool is_exterior() const - { - return (_mark < 0); - } - - //------------------------------------------------------------------- - - inline void inc_mark() - { - if (_mark==-1) - _mark=1; - else - _mark++; - } - - inline void dec_mark() - { - _mark--; - if(_mark == 0) - { - delete _incident_border->first; - delete _incident_border->second; - delete _incident_border; - _incident_border = NULL; - erase_incidence_request(); - } - } - - //------------------------------------------------------------------- - - inline void set_post_mark(const int& i) - { - _post_mark = i; - } - - inline bool is_post_marked(const int& i) - { - return (_post_mark == i); - } -}; - -template -std::list::Vertex_handle> AFSR_vertex_base_3::interior_edges; - -template -std::list::Incidence_request_elt> AFSR_vertex_base_3::incidence_requests; - -} // namespace CGAL - -#endif //CGAL_AFSR_VERTEX_BASE_3_H - diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index a2865382f2f..4bf12fc04e7 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2405,6 +2405,35 @@ advancing_front_surface_reconstructionP(PointIterator b, AFSR::construct_polyhedron(polyhedron, R); } +template +void +advancing_front_surface_reconstructionP(PointIterator b, + PointIterator e, + Polyhedron_3& polyhedron, + double radius_ratio_bound = 5, + double beta = 0.52) +{ + typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; + typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; + + typedef Triangulation_data_structure_3 Tds; + typedef Delaunay_triangulation_3 Triangulation_3; + + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef typename Kernel::Point_3 Point_3; + + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), + boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + + AFSR_options opt; + opt.K = radius_ratio_bound; + // TODO: What to do with beta??? + Reconstruction R(dt, opt); + R.run(opt); + AFSR::construct_polyhedron(polyhedron, R); +} + + } // namespace CGAL diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h deleted file mode 100644 index a145d7f48fb..00000000000 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/AFSR_vrml.h +++ /dev/null @@ -1,87 +0,0 @@ -// Copyright (c) 2015 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 -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri - -#ifndef CGAL_AFSR_VRML_H -#define CGAL_AFSR_VRML_H - -namespace CGAL { - -template < class Vb, class Fb> -void -afsr_vrml_output(const Triangulation_data_structure_2& tds, - std::ostream& os, double r, double g, double b, - typename Triangulation_data_structure_2::Vertex_handle v, bool skip_infinite) -{ - typedef typename Triangulation_data_structure_2::Vertex_handle Vertex_handle; - typedef typename Triangulation_data_structure_2::Vertex_iterator Vertex_iterator; - typedef typename Triangulation_data_structure_2::Face_iterator Face_iterator; - - // ouput to a vrml file style - // Point are assumed to be 3d points with a stream operator << - // if non NULL, v is the vertex to be output first - // if skip_inf is true, the point in the first vertex is not output - // and the faces incident to v are not output - // (it may be for instance the infinite vertex of the terrain) - - os << "#VRML V2.0 utf8" << std::endl; - os << "Shape {\n" - << "appearance Appearance {\n" - << "material Material { diffuseColor " << r << " " << g << " " << b << "}}\n"; - os << "\tgeometry IndexedFaceSet {" << std::endl; - os << "\t\tcoord Coordinate {" << std::endl; - os << "\t\t\tpoint [" << std::endl; - - std::map vmap; - Vertex_iterator vit; - Face_iterator fit; - - int inum = 0; - for( vit= tds.vertices_begin(); vit != tds.vertices_end() ; ++vit) { - if ( v != vit) { - vmap[vit] = inum++; - os << "\t\t\t\t" << *vit << ","<< std::endl; - } - } - - os << "\t\t\t]" << std::endl; - os << "\t\t}" << std::endl; - os << "\t\tsolid FALSE\n" - "\t\tcoordIndex [" << std::endl; - - // faces - for(fit= tds.faces_begin(); fit != tds.faces_end(); ++fit) { - if (!skip_infinite || !fit->has_vertex(v)) { - os << "\t\t\t"; - os << vmap[(*fit).vertex(0)] << ", "; - os << vmap[(*fit).vertex(1)] << ", "; - os << vmap[(*fit).vertex(2)] << ", "; - os << "-1, " << std::endl; - } - } - os << "\t\t]" << std::endl; - os << "\t}" << std::endl; - os << "}" << std::endl; - return; -} - - -} // namespace CGAL - -#endif - diff --git a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h deleted file mode 100644 index 799310651f7..00000000000 --- a/Advancing_front_surface_reconstruction/include/CGAL/IO/Advancing_front_surface_reconstruction.h +++ /dev/null @@ -1,1056 +0,0 @@ -// Copyright (c) 2015 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 -// General Public License as published by the Free Software Foundation, -// either version 3 of the License, or (at your option) any later version. -// -// 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) : Frank Da, David Cohen-Steiner, Andreas Fabri - -#ifndef CGAL_IO_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H -#define CGAL_IO_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H - - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace CGAL { - - -template -struct Is_not_exterior { - bool operator()(const Vertex& v)const { - return ! v.is_exterior(); - } -}; - -template -void -write_to_file_medit(char* foutput, const Surface& S) -{ - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Vertex Vertex; - typedef typename Surface::Cell_handle Cell_handle; - - Triangulation_3& T = S.triangulation_3(); - - char foutput_points[100]; - char foutput_faces[100]; - std::strcpy(foutput_points, foutput); - std::strcpy(foutput_faces, foutput); - strcat(foutput_points, ".points"); - strcat(foutput_faces, ".faces"); - std::ofstream os_points(foutput_points, std::ios::out); - std::ofstream os_faces(foutput_faces, std::ios::out); - if((os_points.fail())||(os_faces.fail())) - std::cerr << "+++unable to open file for output" << std::endl; - else - std::cout << ">> files for output : " << foutput_points - << ", " << foutput_faces << std::endl; - - os_points.clear(); - os_faces.clear(); - - CGAL::set_ascii_mode(os_points); - CGAL::set_ascii_mode(os_faces); - - // af: what is the relationship to _vh_number in Extract_surface - std::size_t _vh_number = std::count_if(T.finite_vertices_begin(), - T.finite_vertices_end(), - Is_not_exterior()); - - os_points << _vh_number << std::endl; - - CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); - - int count(0); - for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++){ - typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; - if ((!v_it->is_exterior()) && d == -1){ - d = count; - count++; - os_points << v_it->point() << " 0" << std::endl; - } - } - - os_faces << S.number_of_facets() << std::endl; - for(Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); - f_it++) - { - Cell_handle n, c = (*f_it).first; - int ni, ci = (*f_it).second; - n = c->neighbor(ci); - ni = n->index(c); - int i1, i2 ,i3; - - if (c->is_selected_facet(ci)) - { - i1 = (ci+1) & 3; - i2 = (ci+2) & 3; - i3 = (ci+3) & 3; - os_faces << 3 << " "; - os_faces << vertex_index_map[c->vertex(i1)] + 1 << " "; - os_faces << vertex_index_map[c->vertex(i2)] + 1 << " "; - os_faces << vertex_index_map[c->vertex(i3)] + 1 << " "; - os_faces << " 0 0 0 0" << std::endl; - } - - if (n->is_selected_facet(ni)) - { - i1 = (ni+1) & 3; - i2 = (ni+2) & 3; - i3 = (ni+3) & 3; - os_faces << 3 << " "; - os_faces << vertex_index_map[n->vertex(i1)] + 1 << " "; - os_faces << vertex_index_map[n->vertex(i2)] + 1 << " "; - os_faces << vertex_index_map[n->vertex(i3)] + 1 << " "; - os_faces << " 0 0 0 0" << std::endl; - } - } - - std::cout << "-- medit result written." << std::endl; -} - -//--------------------------------------------------------------------- - -template -void -write_to_file_gv(char* foutput, const Surface& S) -{ - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Vertex Vertex; - typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation_3(); - - char foutput_tmp[100]; - std::strcpy(foutput_tmp, foutput); - - strcat(foutput_tmp, ".off"); - std::ofstream os(foutput_tmp, std::ios::out); - - if(os.fail()) - std::cerr << "+++unable to open file for output" << std::endl; - else - std::cout << ">> file for output : " << foutput_tmp << std::endl; - - os.precision(17); - os.clear(); - - CGAL::set_ascii_mode(os); - - std::size_t _vh_number = std::count_if(T.finite_vertices_begin(), - T.finite_vertices_end(), - Is_not_exterior()); - // Header. - os << "OFF" << std::endl - << _vh_number << " " << S.number_of_facets() << " " << 0 << std::endl; - - CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); - - int count(0); - for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++){ - typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; - if ((!v_it->is_exterior()) && d == -1){ - d = count; - count++; - os << v_it->point() << " \n"; - } - } - - for(Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); - f_it++) - { - Cell_handle n, c = (*f_it).first; - int ni, ci = (*f_it).second; - n = c->neighbor(ci); - ni = n->index(c); - int i1, i2 ,i3; - - if (c->is_selected_facet(ci)) - { - i1 = (ci+1) & 3; - i2 = (ci+2) & 3; - i3 = (ci+3) & 3; - os << 3 << " "; - os << vertex_index_map[c->vertex(i1)] << " "; - os << vertex_index_map[c->vertex(i2)] << " "; - os << vertex_index_map[c->vertex(i3)] << "\n"; - } - - if (n->is_selected_facet(ni)) - { - i1 = (ni+1) & 3; - i2 = (ni+2) & 3; - i3 = (ni+3) & 3; - os << 3 << " "; - os << vertex_index_map[n->vertex(i1)] << " "; - os << vertex_index_map[n->vertex(i2)] << " "; - os << vertex_index_map[n->vertex(i3)] << "\n"; - } - } - - std::cout << "-- oogl result written." << std::endl; -} - - /* -template -OutputIterator -write_triple_indices(OutputIterator out, const Surface& S) -{ - std::cerr << "write triple indices" << std::endl; -#if 1 - typedef typename Surface::TDS_2 TDS_2; - typedef typename TDS_2::Face_iterator Face_iterator; - typedef typename Surface::Cell_handle Cell_handle; - - const TDS_2& tds = S.tds_2(); - - for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ - - if(fit->is_on_surface()){ - *out++ = CGAL::Triple(fit->vertex(0)->vertex_3()->id(), - fit->vertex(1)->vertex_3()->id(), - fit->vertex(2)->vertex_3()->id()); - } - } - return out; - -#else - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Vertex Vertex; - typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation_3(); - - - for(Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); - f_it++) - { - Cell_handle n, c = (*f_it).first; - int ni, ci = (*f_it).second; - n = c->neighbor(ci); - ni = n->index(c); - int i1, i2 ,i3; - - if (c->is_selected_facet(ci)) - { - i1 = (ci+1) & 3; - i2 = (ci+2) & 3; - i3 = (ci+3) & 3; - *out++ = CGAL::Triple(c->vertex(i1)->id(), - c->vertex(i2)->id(), - c->vertex(i3)->id()); - } - - if (n->is_selected_facet(ni)) - { - i1 = (ni+1) & 3; - i2 = (ni+2) & 3; - i3 = (ni+3) & 3; - - *out++ = CGAL::Triple(n->vertex(i1)->id(), - n->vertex(i2)->id(), - n->vertex(i3)->id()); - } - } - return out; -#endif -} -*/ - - -//--------------------------------------------------------------------- -template -void -write_to_file_ply(char* foutput, const Surface& S) -{ - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation_3(); - char foutput_tmp[100]; - std::strcpy(foutput_tmp, foutput); - - strcat(foutput_tmp, ".ply"); - std::ofstream os(foutput_tmp, std::ios::out | std::ios::binary); - - if(os.fail()) - std::cerr << "+++unable to open file for output" << std::endl; - else - std::cout << ">> file for output : " << foutput_tmp << std::endl; - - os.clear(); - - CGAL::set_ascii_mode(os); - - // Header. - os << "ply" << std::endl - << "format binary_little_endian 1.0" << std::endl - << "comment generated by ply_writer" << std::endl - << "element vertex " << S.number_of_vertices() << std::endl - << "property float x" << std::endl - << "property float y" << std::endl - << "property float z" << std::endl - << "element face " << S.number_of_facets() << std::endl - << "property list uchar int vertex_indices" << std::endl - << "end_header" << std::endl; - - CGAL::set_binary_mode(os); - - CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); - - int count(0); - for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++){ - typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; - if ((!v_it->is_exterior()) && d == -1){ - d = count; - count++; - os << v_it->point() << std::endl; - } - } - - for(Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); - f_it++) - { - Cell_handle n, c = (*f_it).first; - int ni, ci = (*f_it).second; - n = c->neighbor(ci); - ni = n->index(c); - int i1, i2 ,i3; - - if (c->is_selected_facet(ci)) - { - i1 = (ci+1) & 3; - i2 = (ci+2) & 3; - i3 = (ci+3) & 3; - char three = '3'; - CGAL::write(os, three, CGAL::io_Read_write()); - CGAL::write(os,vertex_index_map[c->vertex(i1)], CGAL::io_Read_write()); - CGAL::write(os,vertex_index_map[c->vertex(i2)], CGAL::io_Read_write()); - CGAL::write(os,vertex_index_map[c->vertex(i3)], CGAL::io_Read_write()); - os << std::endl; // without color. - // os << 4 << drand48() << drand48() << drand48() << 1.0; // random - // color - } - - if (n->is_selected_facet(ni)) - { - i1 = (ni+1) & 3; - i2 = (ni+2) & 3; - i3 = (ni+3) & 3; - char three = '3'; - CGAL::write(os, three, CGAL::io_Read_write()); - CGAL::write(os,vertex_index_map[n->vertex(i1)], CGAL::io_Read_write()); - CGAL::write(os,vertex_index_map[n->vertex(i2)], CGAL::io_Read_write()); - CGAL::write(os,vertex_index_map[n->vertex(i3)], CGAL::io_Read_write()); - os << std::endl; // without color. - // os << 4 << drand48() << drand48() << drand48() << 1.0; // random - // color - } - } - - //std::cout << "-- ply result written." << std::endl; -} - -//--------------------------------------------------------------------- -template -void -write_to_file_iv_border_edges(const Surface& S, std::ofstream& os) -{ - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_edges_iterator Finite_edges_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Cell_handle Cell_handle; - typedef typename Surface::Edge_like Edge_like; - typedef typename Surface::Border_elt Border_elt; - - Triangulation_3& T = S.triangulation_3(); - typedef std::pair indiced_vh; - std::map _vh_vect; - int _vh_bord_count = 0; - - for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++) - if (v_it->is_on_border()) - { - _vh_vect.insert(indiced_vh (v_it, _vh_bord_count)); - _vh_bord_count++; - } - - typedef const typename Triangulation_3::Point* Const_point_star; - std::vector points_tab(_vh_bord_count); - for (typename std::map::iterator vh_it = _vh_vect.begin(); - vh_it != _vh_vect.end(); vh_it++) - points_tab[vh_it->second] = &vh_it->first->point(); - - os << " Separator {" << std::endl << -" Switch {" << std::endl << -" whichChild 0" << std::endl << -" Separator {" << std::endl << -" BaseColor {" << std::endl << -" rgb 1 0 0" << std::endl << -" }" << std::endl << -" Coordinate3 {" << std::endl << -" point [ "; - bool first(true); - for(int vh_i=0; vh_i<_vh_bord_count; vh_i++) - { - if (!first) os << "," << std::endl << -" "; - else - first=false; - os << *points_tab[vh_i]; - } - os << " ]" << std::endl << -" }" << std::endl << -" IndexedLineSet {" << std::endl << -" coordIndex [ "; - - first=true; - for(Finite_edges_iterator e_it=T.finite_edges_begin(); - e_it!=T.finite_edges_end(); - e_it++) - { - Cell_handle c = (*e_it).first; - int i1 = (*e_it).second, i2 = (*e_it).third; - Edge_like key(c->vertex(i1), c->vertex(i2)); - Border_elt result; - - if (S.is_border_elt(key, result)) - { - if (!first) - os << "," << std::endl << " "; - else - first=false; - os << _vh_vect.find(c->vertex(i1))->second << ", "; - os << _vh_vect.find(c->vertex(i2))->second << ", "; - os << -1; - } - } - os << " ]" << std::endl << -" }}" << std::endl << -" }}" << std::endl; -} - -//--------------------------------------------------------------------- -template -void -write_to_file_iv_remaining_points(const Surface& S, std::ofstream& os) -{ - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation_3(); - typedef std::pair indiced_vh; - std::map _vh_vect; - int _vh_bord_count(0); - - for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++) - if (v_it->is_exterior()) - { - _vh_vect.insert(indiced_vh (v_it, _vh_bord_count)); - _vh_bord_count++; - } - - typedef const typename Triangulation_3::Point* Const_point_star; - std::vector points_tab(_vh_bord_count); - for (typename std::map::iterator vh_it = _vh_vect.begin(); - vh_it != _vh_vect.end(); vh_it++) - points_tab[vh_it->second] = &vh_it->first->point(); - - os << " Separator {" << std::endl << -" Switch {" << std::endl << -" whichChild 0" << std::endl << -" Separator {" << std::endl << -" BaseColor {" << std::endl << -" rgb 0 0 1" << std::endl << -" }" << std::endl << -" Coordinate3 {" << std::endl << -" point [ "; - bool first(true); - for(int vh_i=0; vh_i<_vh_bord_count; vh_i++) - { - if (!first) os << "," << std::endl << -" "; - else - first=false; - os << *points_tab[vh_i]; - } - os << " ]" << std::endl << -" }" << std::endl << -" PointSet {" << std::endl << -" startIndex 0" << std::endl << -" numPoints -1" << std::endl << -" }"; - - os << " }" << std::endl << -" }}" << std::endl; - -} - -//--------------------------------------------------------------------- -// attention cette procedure produit un fichier tres sale... trop de sommets... - -// !!!! bizarre : ca a l'air de buggue pour hand.xyz (seg fault...) -template -void -write_to_file_iv_border_facets(const Surface& S, std::ofstream& os) -{ - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Cell_handle Cell_handle; - typedef typename Surface::Edge_like Edge_like; - typedef typename Surface::Border_elt Border_elt; - - Triangulation_3& T = S.triangulation_3(); - typedef std::pair indiced_vh; - std::map _vh_vect; - int _vh_bord_count(0); - - for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++) -// if (v_it->number_of_incident_border() > 0) - { - _vh_vect.insert(indiced_vh (v_it, _vh_bord_count)); - _vh_bord_count++; - } - - typedef const typename Triangulation_3::PoinPoint* Const_point_star; - std::vector points_tab(_vh_bord_count); - for (typename std::map::iterator vh_it = _vh_vect.begin(); - vh_it != _vh_vect.end(); vh_it++) - points_tab[vh_it->second] = &vh_it->first->point(); - - os << " Separator {" << std::endl << -" Switch {" << std::endl << -" whichChild 0" << std::endl << -" Separator {" << std::endl << -" ShapeHints {" << std::endl << -" vertexOrdering CLOCKWISE" << std::endl << -" shapeType UNKNOWN_SHAPE_TYPE" << std::endl << -" faceType CONVEX" << std::endl << -" creaseAngle 1.0" << std::endl << -" }" << std::endl << -" BaseColor {" << std::endl << -" rgb 0 0 1" << std::endl << -" }" << std::endl << -" Coordinate3 {" << std::endl << -" point [ "; - bool first(true); - for(int vh_i=0; vh_i<_vh_bord_count; vh_i++) - { - if (!first) os << "," << std::endl << -" "; - else - first=false; - os << *points_tab[vh_i]; - } - os << " ]" << std::endl << -" }" << std::endl << -" IndexedFaceSet {" << std::endl << -" coordIndex [ "; - - first=true; - for(Finite_facets_iterator f_it=T.finite_facets_begin(); - f_it!=T.finite_facets_end(); - f_it++) - { - Cell_handle c = (*f_it).first; - int index = (*f_it).second; - int i1 = (index+1) & 3; - int i2 = (index+2) & 3; - int i3 = (index+3) & 3; - Edge_like key12(c->vertex(i1), c->vertex(i2)); - Edge_like key13(c->vertex(i1), c->vertex(i3)); - Edge_like key32(c->vertex(i3), c->vertex(i2)); - Border_elt result; - - // les trois aretes sur le bord... -// if (is_border_elt(key12, result)&& -// is_border_elt(key13, result)&& -// is_border_elt(key32, result)) - - // au moins 2 aretes sur le bord... -// if (((is_border_elt(key12, result)&& -// is_border_elt(key13, result)))|| -// ((is_border_elt(key32, result)&& -// is_border_elt(key13, result)))|| -// ((is_border_elt(key12, result)&& -// is_border_elt(key32, result)))) - - // une arete sur le bord... - if ((is_border_elt(key12, result)|| - is_border_elt(key13, result)|| - is_border_elt(key32, result))&& - (c->is_selected_facet(index)|| - c->neighbor(index)->is_selected_facet(c->neighbor(index)->index(c)))) - - // au moins 2 aretes sur le bord... -// if (((is_border_elt(key12, result)&& -// is_border_elt(key13, result)))|| -// ((is_border_elt(key32, result)&& -// is_border_elt(key13, result)))|| -// ((is_border_elt(key12, result)&& -// is_border_elt(key32, result)))) - { - if (!first) - os << "," << std::endl << " "; - else - first=false; - os << _vh_vect.find(c->vertex(i1))->second << ", "; - os << _vh_vect.find(c->vertex(i2))->second << ", "; - os << _vh_vect.find(c->vertex(i3))->second << ", "; - - os << -1; - } - } - os << " ]" << std::endl << -" }}" << std::endl << -" }}" << std::endl; -} - -//--------------------------------------------------------------------- -template -void -write_to_file_iv(char* foutput, const Surface& S, - const bool& boundary) -{ - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Cell_handle Cell_handle; - Triangulation_3& T = S.triangulation_3(); - char foutput_tmp[100]; - std::strcpy(foutput_tmp, foutput); - - strcat(foutput_tmp, ".iv"); - std::ofstream os(foutput_tmp, std::ios::out); - - if(os.fail()) - std::cerr << "+++unable to open file for output" << std::endl; - else - std::cout << ">> file for output : " << foutput_tmp << std::endl; - - os.precision(17); - os.clear(); - - CGAL::set_ascii_mode(os); - - // Header. - os << -"#Inventor V2.1 ascii" << std::endl << -"Separator {" << std::endl << -" PerspectiveCamera {" << std::endl << -" position 0 0 2.41421" << std::endl << -" nearDistance 1.41421" << std::endl << -" farDistance 3.41421" << std::endl << -" focalDistance 2.41421" << std::endl << -" }" << std::endl << -" Group {" << std::endl << -" Rotation {" << std::endl << -" }" << std::endl << -" DirectionalLight {" << std::endl << -" direction 0.2 -0.2 -0.979796" << std::endl << -" }" << std::endl << -" ResetTransform {" << std::endl << -" } }" << std::endl << -" Separator {" << std::endl << -" Switch {" << std::endl << -" whichChild 0" << std::endl << -" Separator {" << std::endl << -" ShapeHints {" << std::endl << -" vertexOrdering CLOCKWISE" << std::endl << -" shapeType UNKNOWN_SHAPE_TYPE" << std::endl << -" faceType CONVEX" << std::endl << -" creaseAngle 1.0" << std::endl << -" }" << std::endl << -" BaseColor {" << std::endl << -" rgb 0.6 0.6 0.48" << std::endl << -" }" << std::endl << -" Coordinate3 {" << std::endl << -" point [ "; - - CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); - - int count(0); - for (Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++){ - typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; - if ((!v_it->is_exterior()) && d == -1){ - d = count; - count++; - os << v_it->point() << " ,\n"; - } - } - os << " ]" << std::endl << -" }" << std::endl << -" IndexedFaceSet {" << std::endl << -" coordIndex [ "; - - for(Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); - f_it++) - { - Cell_handle n, c = (*f_it).first; - int ni, ci = (*f_it).second; - n = c->neighbor(ci); - ni = n->index(c); - int i1, i2 ,i3; - - if (c->is_selected_facet(ci)) - { - - i1 = (ci+1) & 3; - i2 = (ci+2) & 3; - i3 = (ci+3) & 3; - os << vertex_index_map[c->vertex(i1)] << ", "; - os << vertex_index_map[c->vertex(i2)] << ", "; - os << vertex_index_map[c->vertex(i3)] << ", "; - os << -1; - } - - if (n->is_selected_facet(ni)) - { - i1 = (ni+1) & 3; - i2 = (ni+2) & 3; - i3 = (ni+3) & 3; - os << vertex_index_map[n->vertex(i1)] << ", "; - os << vertex_index_map[n->vertex(i2)] << ", "; - os << vertex_index_map[n->vertex(i3)] << ", "; - os << -1; - } - } - - - os << " ]\n" - " }\n" - " }}\n" - " }\n"; - - if (boundary) - { - // pour visualiser les boundaries restant a la fin... - write_to_file_iv_border_edges(S, os); - - // pour visualiser les facettes eventuellement candidates... - // write_to_file_iv_border_facets(S, os); - - // pour afficher les points non selectionnes, ~bruit??? - // write_to_file_iv_remaining_points(S, os); - } - - os << "}" << std::endl; - - std::cout << "-- Inventor result written." << std::endl; -} - - -template -void -write_boundaries(std::ostream& os, const Surface& S) -{ - - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Boundary_iterator Boundary_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Vertex Vertex; - typedef typename Surface::Cell_handle Cell_handle; - - - CGAL::Random random; - for(Boundary_iterator it = S.boundaries_begin(); - it != S.boundaries_end(); - ++it) { - double blue = random.get_double(0,1); - os << - "Shape {\n" - "appearance Appearance {\n" - "material Material { emissiveColor 1 0 " << blue << "}}\n" - "geometry\n" - "IndexedLineSet {\n" - "coord Coordinate {\n" - "point [ " << std::endl; - unsigned int count = 0; - Vertex_handle first = *it; - do { - os << (*it)->point() << std::endl; - ++it; - count++; - } while(*it != first); - os << "]\n" - "}\n" - "coordIndex [\n"; - - for(unsigned int i = 0; i < count; i++){ - os << i << ", "; - } - os << "0, -1\n"; - os << "]\n" - "}#IndexedLineSet\n" - "}# Shape\n"; - } -} - - - - -template -void -write_to_file_vrml2(char* foutput, const Surface& S, - const bool& boundary, double red, double green, double blue, bool no_header) -{ - - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Cell_handle Cell_handle; - //Triangulation_3& T = S.triangulation_3(); - - typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; - - typedef CGAL::Triangulation_data_structure_2 > TDS; - - TDS tds; - - TDS::Vertex_handle inf = AFSR::orient(tds, S); - - char foutput_tmp[100]; - std::strcpy(foutput_tmp, foutput); - - strcat(foutput_tmp, ".wrl"); - std::ofstream os(foutput_tmp, std::ios::out); - - if(os.fail()) - std::cerr << "+++unable to open file for output" << std::endl; - else - std::cout << ">> file for output : " << foutput_tmp << std::endl; - - os.precision(17); - os.clear(); - - CGAL::set_ascii_mode(os); - - if(! no_header){ - // Header. - os << - "#VRML V2.0 utf8\n" - "Background {skyColor .1 .5 .5}\n" - "Group {\n" - "children [\n" << std::endl; - }; - - afsr_vrml_output(tds, os, red, green, blue, inf, true); - - if (boundary){ - write_boundaries(os, S); - } - - typename Surface::Outlier_iterator pit = S.outliers_begin(); - - if(S.number_of_outliers()!= 0) { - os << "Shape {\n" - "geometry PointSet {\n" - "coord Coordinate { point [\n"; - - BOOST_FOREACH(const typename Surface::Point& p , S.outliers()){ - os << p.x() << " " << p.y() << " " << p.z() << ",\n"; - } - os << "] } }\n" - "appearance Appearance {\n" - " material Material {\n" - " emissiveColor 1 0.1 0\n" - " }\n" - "}\n" - "} # Shape\n"; - } - - if(! no_header){ - os << "] # children\n" - "} # Group\n"; - } - std::cout << "-- wrl result written." << std::endl; -} - - - -template -void -write_to_file_stl(char* foutput, const Surface& S) -{ - - typedef typename Surface::Triangulation_3 Triangulation_3; - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Surface::Finite_facets_iterator Finite_facets_iterator; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Cell_handle Cell_handle; - typedef typename Triangulation_3::Point Point; - typedef typename CGAL::Kernel_traits::Kernel::Vector_3 Vector; - Triangulation_3& T = S.triangulation_3(); - - - char foutput_tmp[100]; - std::strcpy(foutput_tmp, foutput); - - strcat(foutput_tmp, ".stl"); - std::ofstream os(foutput_tmp, std::ios::out); - - if(os.fail()) - std::cerr << "+++unable to open file for output" << std::endl; - else - std::cout << ">> file for output : " << foutput_tmp << std::endl; - - os.precision(17); - os.clear(); - - CGAL::set_ascii_mode(os); - - // Header. - os << "solid" << std::endl; - - for(Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); - f_it++) - { - Cell_handle n, c = (*f_it).first; - int ni, ci = (*f_it).second; - - bool selected = false; - if(c->is_selected_facet(ci)){ - selected = true; - } else { - n = c->neighbor(ci); - ni = n->index(c); - if(n->is_selected_facet(ni)) { - selected = true; - c = n; - ci = ni; - } - } - - if(selected){ - int i1, i2 ,i3; - - i1 = (ci+1) & 3; - i2 = (ci+2) & 3; - i3 = (ci+3) & 3; - - Point p = c->vertex(i1)->point(); - Point q = c->vertex(i2)->point(); - Point r = c->vertex(i3)->point(); - // compute normal - Vector n = CGAL::cross_product( q-p, r-p); - Vector norm = n / sqrt( n * n); - os << "outer loop" << std::endl; - os << "facet normal " << norm << std::endl; - os << "vertex " << p << std::endl; - os << "vertex " << q << std::endl; - os << "vertex " << r << std::endl; - os << "endloop\nendfacet" << std::endl; - } - - } - - os << "endsolid" << std::endl; - - std::cout << "-- stl result written." << std::endl; -} - - -//--------------------------------------------------------------------- -template -void -write_to_file(char* foutput, const Surface& S, - const bool& boundary, const int& out_format, - double red, double green, double blue, bool no_header) -{ - switch(out_format) - { - case -2: - // no output file... - return; - case -1: - write_to_file_iv(foutput, S, boundary); - write_to_file_vrml2(foutput, S, boundary, red, green, blue, no_header); - write_to_file_gv(foutput, S); - write_to_file_medit(foutput, S); - //write_to_file_ply(foutput, S); - return; - case 0: - write_to_file_vrml2(foutput, S, boundary, red, green, blue, no_header); - return; - case 1: - write_to_file_gv(foutput, S); - return; - case 2: - write_to_file_medit(foutput, S); - return; - case 3: - write_to_file_ply(foutput, S); - return; - case 4: - write_to_file_iv(foutput, S, boundary); - return; - case 5: - write_to_file_stl(foutput, S); - return; - } -} - -} // namespace CGAL - - -#endif // CGAL_IO_ADVANCING_FRONT_SURFACE_RECONSTRUCTION_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h b/Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h deleted file mode 100644 index 8fbb59d7739..00000000000 --- a/Advancing_front_surface_reconstruction/include/CGAL/Tvb_3_2.h +++ /dev/null @@ -1,94 +0,0 @@ -// Copyright (c) 1997 INRIA Sophia-Antipolis (France). -// All rights reserved. -// -// This file is part of CGAL (www.cgal.org); you may redistribute it under -// the terms of the Q Public License version 1.0. -// See the file LICENSE.QPL distributed with CGAL. -// -// Licensees holding a valid commercial license may use this file in -// accordance with the commercial license agreement provided with the software. -// -// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -// -// $Source: /CVSROOT/CGAL/Packages/Triangulation_2/include/CGAL/Triangulation_vertex_base_2.h,v $ -// $Revision$ $Date$ -// $Name: current_submission $ -// -// Author(s) : Mariette Yvinec - - -#ifndef CGAL_TVB_3_2_H -#define CGAL_TVB_3_2_H - -#include -#include - -namespace CGAL { - -template < typename GT, - typename Vb = Triangulation_ds_vertex_base_2<> > -class Tvb_3_2 - : public Vb - -{ - typedef typename Vb::Triangulation_data_structure Tds; -public: - typedef GT Geom_traits; - typedef typename GT::Point_3 Point; - typedef Tds Triangulation_data_structure; - typedef typename Tds::Face_handle Face_handle; - typedef typename Tds::Vertex_handle Vertex_handle; - - template < typename TDS2 > - struct Rebind_TDS { - typedef typename Vb::template Rebind_TDS::Other Vb2; - typedef Tvb_3_2 Other; - }; - -private: - Point _p; - -public: - Tvb_3_2 () : Vb() {} - Tvb_3_2(const Point & p) : Vb(), _p(p) {} - Tvb_3_2(const Point & p, Face_handle f) - : Vb(f), _p(p) {} - Tvb_3_2(Face_handle f) : Vb(f) {} - - void set_point(const Point & p) { _p = p; } - const Point& point() const { return _p; } - - // the non const version of point() is undocument - // but needed to make the point iterator works - // using Lutz projection scheme - Point& point() { return _p; } - - //the following trivial is_valid to allow - // the user of derived face base classes - // to add their own purpose checking - bool is_valid(bool /* verbose */ = false, int /* level */ = 0) const - {return true;} -}; - -template < class GT, class Vb > -std::istream& -operator>>(std::istream &is, Tvb_3_2 &v) - // non combinatorial information. Default = point -{ - return is >> static_cast(v) >> v.point(); -} - -template < class GT, class Vb > -std::ostream& -operator<<(std::ostream &os, const Tvb_3_2 &v) - // non combinatorial information. Default = point -{ - return os << static_cast(v) << v.point(); -} - - - -} //namespace CGAL - -#endif //CGAL_TVB_3_2_H From 650eff46da49ba9bd7f015e6fb173fd881dcc745 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 9 Jun 2015 11:36:37 +0200 Subject: [PATCH 080/114] move files to internal/AFSR --- .../extract.cpp | 456 ------------------ .../Advancing_front_surface_reconstruction.h | 12 +- .../CGAL/{ => internal/AFSR}/AFSR_options.h | 0 .../{ => internal}/AFSR/Surface_face_base_2.h | 0 .../AFSR/Surface_vertex_base_2.h | 0 .../AFSR/construct_polyhedron.h | 0 .../{ => internal}/AFSR/construct_surface_2.h | 0 .../include/CGAL/{ => internal}/AFSR/orient.h | 0 .../AFSR/write_triple_indices.h | 0 9 files changed, 6 insertions(+), 462 deletions(-) delete mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp rename Advancing_front_surface_reconstruction/include/CGAL/{ => internal/AFSR}/AFSR_options.h (100%) rename Advancing_front_surface_reconstruction/include/CGAL/{ => internal}/AFSR/Surface_face_base_2.h (100%) rename Advancing_front_surface_reconstruction/include/CGAL/{ => internal}/AFSR/Surface_vertex_base_2.h (100%) rename Advancing_front_surface_reconstruction/include/CGAL/{ => internal}/AFSR/construct_polyhedron.h (100%) rename Advancing_front_surface_reconstruction/include/CGAL/{ => internal}/AFSR/construct_surface_2.h (100%) rename Advancing_front_surface_reconstruction/include/CGAL/{ => internal}/AFSR/orient.h (100%) rename Advancing_front_surface_reconstruction/include/CGAL/{ => internal}/AFSR/write_triple_indices.h (100%) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp deleted file mode 100644 index 5ef99fa1139..00000000000 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/extract.cpp +++ /dev/null @@ -1,456 +0,0 @@ -#define NOLAZY -#define BLIND - - -#include -#include -#include -#include - -#include - -// Kernel -#include -#include -#include - -#include -#include -#include -#include - -#include - - - - -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; - -typedef Kernel::Point_3 Point; - -typedef CGAL::Advancing_front_surface_reconstruction_vertex_base_3 LVb; -typedef CGAL::Advancing_front_surface_reconstruction_cell_base_3 LCb; - -typedef CGAL::Triangulation_data_structure_3 Tds; -typedef CGAL::Delaunay_triangulation_3 Triangulation_3; - -typedef Triangulation_3::Vertex_handle Vertex_handle; - -struct Perimeter { - - double bound; - - Perimeter(double bound) - : bound(bound) - {} - - bool operator()(const Point& p, const Point& q, const Point& r) const - { - if(bound == 0){ - return false; - } - double d = sqrt(squared_distance(p,q)); - if(d>bound) return true; - d += sqrt(squared_distance(p,r)) ; - if(d>bound) return true; - d+= sqrt(squared_distance(q,r)); - return d>bound; - } -}; - -typedef CGAL::Advancing_front_surface_reconstruction Surface; -typedef CGAL::AFSR_options Options; - -//--------------------------------------------------------------------- - -struct Auto_count : public std::unary_function >{ - mutable int i; - Auto_count() : i(0){} - std::pair operator()(const Point& p) const { - return std::make_pair(p,i++); - } -}; - - -bool -file_input(const Options& opt, std::vector& points) -{ - const char* finput = opt.finname; - bool xyz = opt.xyz; - - std::ios::openmode mode = (opt.binary) ? std::ios::binary : std::ios::in; - std::ifstream is(finput, mode); - - if(opt.binary){ - CGAL::set_binary_mode(is); - } - if(is.fail()) - { - std::cerr << "+++unable to open file for input" << std::endl; - exit(0); - return false; - } - else - std::cerr << "Input from file : " << finput << std::endl; - - std::size_t n; - if(! xyz){ - is >> n; - std::cerr << " reading " << n << " points" << std::endl; - points.reserve(n); - CGAL::cpp11::copy_n(std::istream_iterator(is), n, std::back_inserter(points)); - } else { - // we do not know beforehand how many points we will read - std::istream_iterator it(is), eof; - char ignore[256]; - while(it!= eof){ - points.push_back(*it); - is.getline(ignore,256); // ignore what comes after 3 doubles in a line - it++; - } - n = points.size(); - } - - return true; -} - - - -void usage(char* program) -{ - std::cerr << std::endl << "NAME " << std::endl - << program << " - surface extension -" << std::endl << std::endl; - - std::cerr << std::endl << "OPTIONS" << std::endl - << " -xyz : input data in xyz format" << std::endl - << " -no_border -nb : " << std::endl - << " -in fname : reads points from file fname" << std::endl - << " -out fname : writes points to file fname" << std::endl - << " -out_format -of : choose file format for output (iv, wrl, off, medit," << std::endl - << " ply, stl, all, none)" << std::endl - << " -rgb r g b : color of the surface" << std::endl - << " -no_header : The Vrml header and footer are not written" << std::endl - << " -perimeter p : No faces larger than perimeter * average_perimeter" << std::endl - << " -abs_perimeter p : No faces with perimeter longer than abs_perimeter" << std::endl - << "\n Options for internal use" << std::endl - - << " -binary : binary I/O" << std::endl - << " -delta x : set the delta constant" << std::endl - << " -ki x y : set the K interval (default : [1.1 5])" << std::endl - << " -ks x : set the K step (default : .1)" << std::endl - << " -k x : set the K constant (only one pass)" << std::endl - << " -Delaunay : display the underlying Delaunay triangulation" << std::endl - << " -max_of_connected_components x : set the max of connected components" << std::endl - << " (default : non-active)" << std::endl - << " -post x : set a number for the post process" << std::endl - << " -contours : display contours" << std::endl; -} - - - -bool -parse(int argc, char* argv[], Options &opt) -{ - std::strcpy(opt.program, argv[0]); - --argc; - argv++; - if(argc == 0) - std::cerr << "nothing ???" << std::endl; - - while ((argc > 0) && (argv[0][0] == '-')){ - if ((!std::strcmp(argv[0], "-D")) || (!std::strcmp(argv[0], "-Delaunay"))) { - opt.Delaunay = true; - argv++; - argc--; - std::cerr << "-D "; - } - else if ((!std::strcmp(argv[0], "-c")) || (!std::strcmp(argv[0], "-contours"))) { - opt.contour = true; - argv++; - argc--; - std::cerr << "-c "; - } - else if ((!std::strcmp(argv[0], "-b")) || (!std::strcmp(argv[0], "-binary"))) { - opt.binary = true; - argv++; - argc--; - std::cerr << "-b "; - } - else if ((!std::strcmp(argv[0], "-x")) || (!std::strcmp(argv[0], "-xyz"))) { - opt.xyz = true; - argv++; - argc--; - std::cerr << "-x "; - } - else if ((!std::strcmp(argv[0], "-nb")) || (!std::strcmp(argv[0], "-no_border"))) { - opt.K = HUGE_VAL; - opt.K_init = opt.K; - argv++; - argc--; - std::cerr << "-nb "; - } - else if ((!std::strcmp(argv[0], "-nh")) || (!std::strcmp(argv[0], "-no_header"))) { - opt.no_header = true; - argv++; - argc--; - std::cerr << "-nh "; - } - else if ((!std::strcmp(argv[0], "-d")) || (!std::strcmp(argv[0], "-delta"))){ - if (sscanf(argv[1], "%lf", &opt.delta) != 1) { - std::cerr << "Argument for delta must be a number" - << std::endl; - } - argv += 2; - argc -= 2; - std::cerr << "-d " << opt.delta << " "; - } - else if ((!std::strcmp(argv[0], "-pe")) || (!std::strcmp(argv[0], "-perimeter"))){ - if (sscanf(argv[1], "%lf", &opt.perimeter) != 1) { - std::cerr << "Argument for perimeter must be a number" - << std::endl; - } - argv += 2; - argc -= 2; - std::cerr << "-perimeter " << opt.perimeter << " "; - } - else if ((!std::strcmp(argv[0], "-ki"))){ - if ((sscanf(argv[1], "%lf", &opt.K_init) != 1)|| - (sscanf(argv[2], "%lf", &opt.K) != 1)){ - std::cerr << "Argument for K must be a number" - << std::endl; - } - argv += 3; - argc -= 3; - std::cerr << "-ki " << opt.K_init << " " << opt.K << " "; - } - else if ((!std::strcmp(argv[0], "-rgb"))){ - if ((sscanf(argv[1], "%lf", &opt.red) != 1)|| - (sscanf(argv[2], "%lf", &opt.green) != 1) || - (sscanf(argv[3], "%lf", &opt.blue) != 1)){ - std::cerr << "Argument for rgb must be three numbers" - << std::endl; - } - argv += 4; - argc -= 4; - std::cerr << "-rgb " << opt.red << " " << opt.green << " " << opt.blue << " " ; - } - else if ((!std::strcmp(argv[0], "-ks"))){ - if (sscanf(argv[1], "%lf", &opt.K_step) != 1) { - std::cerr << "Argument for K must be a number" - << std::endl; - } - argv += 2; - argc -= 2; - std::cerr << "-ks " << opt.K_step << " "; - } - else if ((!std::strcmp(argv[0], "-k"))){ - if (sscanf(argv[1], "%lf", &opt.K) != 1) { - std::cerr << "Argument for K must be a number" - << std::endl; - } - opt.K_init = opt.K; - argv += 2; - argc -= 2; - std::cerr << "-k " << opt.K_init << " "; - } - else if ((!std::strcmp(argv[0], "-m")) || (!std::strcmp(argv[0], "-max_of_connected_components"))){ - if (sscanf(argv[1], "%d", &opt.max_connected_comp) != 1) { - std::cerr << "Argument for the number of connected components must be a number" - << std::endl; - } - /* - if(opt.max_connected_comp < 1) { - std::cerr << "Argument for the number of connected components must be a positive number" - << "It is set to 1" << std::endl; - opt.max_connected_comp = 1; - } - */ - argv += 2; - argc -= 2; - std::cerr << "-m " << opt.max_connected_comp << " "; - } - else if ((!std::strcmp(argv[0], "-p")) || (!std::strcmp(argv[0], "-post"))){ - if (sscanf(argv[1], "%d", &opt.NB_BORDER_MAX) != 1) { - std::cerr << "Argument for post process must be a number" - << std::endl; - } - argv += 2; - argc -= 2; - std::cerr << "-p " << opt.NB_BORDER_MAX << " "; - } - else if ((!std::strcmp(argv[0], "-i")) || (!std::strcmp(argv[0], "-in"))) { - std::strcpy(opt.finname, argv[1]); - opt.file_input = true; - argv += 2; - argc -= 2; - std::cerr << "-i " << opt.finname << " "; - } - else if ((!std::strcmp(argv[0], "-s")) || (!std::strcmp(argv[0], "-sect_in"))) { - std::strcpy(opt.finname, argv[1]); - opt.Section_file = true; - opt.file_input = true; - argv += 2; - argc -= 2; - std::cerr << "-s " << opt.finname << " "; - } - else if ((!std::strcmp(argv[0], "-o")) || (!std::strcmp(argv[0], "-out"))) { - std::strcpy(opt.foutname, argv[1]); - opt.file_output = true; - argv += 2; - argc -= 2; - std::cerr << "-o " << opt.foutname << " "; - } - else if ((!std::strcmp(argv[0], "-of")) || (!std::strcmp(argv[0], "-out_format"))) { - if (!std::strcmp(argv[1], "wrl")) - opt.out_format = 0; - else if (!std::strcmp(argv[1], "off")) - opt.out_format = 1; - else if (!std::strcmp(argv[1], "medit")) - opt.out_format = 2; - else if (!std::strcmp(argv[1], "ply")) - opt.out_format = 3; - else if(!std::strcmp(argv[1], "iv")) - opt.out_format = 4; - else if(!std::strcmp(argv[1], "stl")) - opt.out_format = 5; - else if (!std::strcmp(argv[1], "all")) - opt.out_format = -1; - else if (!std::strcmp(argv[1], "none")) - opt.out_format = -2; - else - std::cerr << "unrecognized file format." << std::endl; - opt.file_output = true; - std::cerr << "-of " << argv[1] << " "; - argv += 2; - argc -= 2; - } - else if ((!std::strcmp(argv[0], "-?")) || - (!std::strcmp(argv[0], "-h")) || - (!std::strcmp(argv[0], "-help"))) { - usage(opt.program); - return false; - } - else { - std::cerr << "unrecognized option " << argv[0] << std::endl; - usage(opt.program); - return false; - } - } - if(argc > 0){ - std::cerr << "unrecognized option " << argv[0] << std::endl; - usage(opt.program); - return false; - } - return true; -} - -template -void reconstruction_test(PointIterator point_begin, PointIterator - point_end, TripleOutputIterator out, bool filter_input_points=false, - double perimeter=0) -{ - Options opt; - opt.abs_perimeter = perimeter; - std::cerr << "Compute Delaunay Tetrahedrization " << std::endl; - CGAL::Timer t1; - t1.start(); - - Triangulation_3 dt( boost::make_transform_iterator(point_begin, Auto_count()), - boost::make_transform_iterator(point_end, Auto_count() ) ); - t1.stop(); - std::cerr << " Inserted " << dt.number_of_vertices() << " points, " - << dt.number_of_cells() << " cells computed in " - << t1.time() << " sec." << std::endl; - - t1.reset(); - t1.start(); - Surface S(dt, opt); - t1.stop(); - std::cerr << "Reconstruction takes " << t1.time() << " sec.\n"; - std::cerr << " " << S.number_of_outliers() << " outliers.\n"; - std::cerr << " Reconstructed surface: " << S.number_of_facets() << - " facets, " << S.number_of_vertices() << " vertices.\n"; - std::cerr << " " << S.number_of_border_edges() << - " border edges.\n"; - std::cerr << " number of connected components <= " - << (std::max)(1, S.number_of_connected_components()-1) - << std::endl; - write_triple_indices(out, S); -} - - -//___________________________________________ -int main(int argc, char* argv[]) -{ - CGAL::Timer timer, total; - total.start(); - timer.start(); - //parse command line - Options opt; - std::cerr << "Option line for this execution is :" << std::endl; - if (!parse(argc, argv, opt)) - exit(0); - std::cerr << std::endl << std::endl; - - std::vector points; - - file_input(opt, points); - -#if 0 - std::cerr << "Time for reading " << timer.time() << " sec." << std::endl; - std::vector > triples; - reconstruction_test(points.begin(), points.end(), std::back_inserter(triples)); - - - std::cout << triples.size() << std::endl; - for(int i = 0; i < triples.size(); ++i){ - std::cout << "3 " << get<0>(triples[i]) << " " << get<1>(triples[i]) << " " << get<2>(triples[i]) << " " << std::endl; - } - -#else - - std::cerr << "Compute Delaunay Tetrahedrization " << std::endl; - CGAL::Timer t1; - t1.start(); - - Triangulation_3 dt( boost::make_transform_iterator(points.begin(),Auto_count()), - boost::make_transform_iterator(points.end(), Auto_count() ) ); - t1.stop(); - std::cerr << " Inserted " << dt.number_of_vertices() << " points, " - << dt.number_of_cells() << " cells computed in " - << t1.time() << " sec." << std::endl; - - if (dt.dimension() < 3) { - std::cerr << "-- 2D sample of points ???" << std::endl; - exit(0); - } - - points.clear(); - - Perimeter filter(opt.perimeter); - Surface S(dt, opt, filter); - S.run(opt); - - std::cerr << "Total time: " << timer.time() << " sec." << std::endl; - // write_to_file_vrml2(opt.foutname, S, opt.contour, opt.red, opt.green, opt.blue, opt.no_header); - write_to_file(opt.foutname, S, opt.contour, opt.out_format, opt.red, opt.green, opt.blue, opt.no_header); - - std::cerr << " " << S.number_of_outliers() - << " outliers." << std::endl; - std::cerr << " Reconstructed surface: " << S.number_of_facets() << - " facets, " << S.number_of_vertices() << " vertices." << std::endl; - std::cerr << " " << S.number_of_border_edges() << - " border edges." << std::endl; - std::cerr << " number of connected components <= " - << (std::max)(1, S.number_of_connected_components()-1) - << std::endl << std::endl; - -#endif - total.stop(); - std::cerr << "Total = " << total.time() << " sec." << std::endl; - return 0; -} - - - - diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 4bf12fc04e7..5da7e772ff7 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -38,12 +38,12 @@ #include #include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include namespace CGAL { diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h similarity index 100% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR_options.h rename to Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h similarity index 100% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_face_base_2.h rename to Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h similarity index 100% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR/Surface_vertex_base_2.h rename to Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h similarity index 100% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_polyhedron.h rename to Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h similarity index 100% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR/construct_surface_2.h rename to Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h similarity index 100% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR/orient.h rename to Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h similarity index 100% rename from Advancing_front_surface_reconstruction/include/CGAL/AFSR/write_triple_indices.h rename to Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h From 2b5ad00c42313586d2032d29ae33c9ad8d8ec243 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 9 Jun 2015 12:51:17 +0200 Subject: [PATCH 081/114] Improve doc for nested type Triangulation_data_structure_2 --- .../CGAL/Advancing_front_surface_reconstruction.h | 9 +++++---- .../Advancing_front_surface_reconstruction/dependencies | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index 5faddbee2b7..bf1eb0c4302 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -28,12 +28,13 @@ public: /// @{ /*! - The type of the 2D triangulation data structure describing the reconstructed surface. - The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the + The type of the 2D triangulation data structure describing the reconstructed surface, being a model of `TriangulationDataStructure_2`. + - The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the method `vertex_3()` that returns a `#Vertex_handle` to the associated 3D vertex. - The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the + - The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the method `facet()` that returns the associated `#Facet`, and a method `bool is_on_surface()` - for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. + for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. + In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite vertex of the 3D triangulation. */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies index 160ff7cc8ce..95a6a4e08d4 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies @@ -4,6 +4,7 @@ STL_Extension Algebraic_foundations Circulator Stream_support +TDS_2 Triangulation_2 Triangulation_3 Number_types From e6420cae53f74352f35121be34ccaac78e9ffd0c Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 10 Jun 2015 12:28:22 +0200 Subject: [PATCH 082/114] No need for a geometric traits and EPEC --- .../Advancing_front_surface_reconstruction.h | 16 ++++--- .../boundaries.cpp | 2 +- .../reconstruction_class.cpp | 2 +- .../reconstruction_fct.cpp | 18 ++++++-- .../Advancing_front_surface_reconstruction.h | 46 ++++++++++++++----- ...ont_surface_reconstruction_vertex_base_3.h | 4 +- .../CGAL/internal/AFSR/construct_polyhedron.h | 2 +- .../CGAL/internal/AFSR/construct_surface_2.h | 6 +-- .../include/CGAL/internal/AFSR/orient.h | 4 +- .../CGAL/internal/AFSR/write_triple_indices.h | 8 ++-- 10 files changed, 71 insertions(+), 37 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index bf1eb0c4302..dc5418c920f 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -11,16 +11,16 @@ data structure that describes the surface. The vertices and facets of the 2D tr store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the 2D as well as 3D neighborhood of vertices and facets of the surface. -\tparam Gt must be a model of `Kernel`. \tparam Dt must be a `Delaunay_triangulation_3` with -`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type, and the geometric traits class must be the `Exact_predicates_inexact_constructions_kernel`. +`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type. +The default uses the `Exact_predicates_inexact_constructions_kernel` as geometric traits class. -\tparam Filter must be a functor with `bool operator()(Gt::Point_3,Gt::Point_3,Gt::Point_3)` that allows the user to filter candidate triangles, for example based on its size. - It defaults to a functor that always returns `false`. +\tparam Filter must be a functor with `bool operator()(Point,Point,Point)` that allows the user to filter candidate triangles, for example based on its size. + The type `Point` must be the point type of the geometric traits class of the triangulation. It defaults to a functor that always returns `false`. */ - template< typename Gt, typename Dt, typename Filter> + template< typename Dt, typename Filter> class Advancing_front_surface_reconstruction { public: @@ -199,7 +199,8 @@ has_on_surface(Triangulation_data_structure_2::Vertex_handle v2) const; For a sequence of points computes a sequence of index triples describing the faces of the reconstructed surface. -\tparam PointInputIterator must be an input iterator with 3D points from the `Exact_predicates_inexact_constructions_kernel` as value type. +\tparam PointInputIterator must be an input iterator with 3D points as value type. This point type must +be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. \tparam IndicesOutputIterator must be an output iterator to which `CGAL::cpp11::tuple` can be assigned. @@ -223,7 +224,8 @@ describing the faces of the reconstructed surface. For a sequence of points computes a sequence of index triples describing the faces of the reconstructed surface. -\tparam PointInputIterator must be an input iterator with 3D points from the `Exact_predicates_inexact_constructions_kernel` as value type. +\tparam PointInputIterator must be an input iterator with 3D points as value type. This point type must +be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. \tparam IndicesOutputIterator must be an output iterator to which `CGAL::cpp11::tuple` can be assigned. \tparam Filter must be a functor with `bool operator()(Gt::Point_3,Gt::Point_3,Gt::Point_3)`. diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp index 42ceaf8e63f..32c566095ae 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp @@ -5,7 +5,7 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; +typedef CGAL::Advancing_front_surface_reconstruction<> Reconstruction; typedef Reconstruction::Triangulation_3 Triangulation_3; typedef Reconstruction::Outlier_range Outlier_range; typedef Reconstruction::Boundary_range Boundary_range; diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp index 8ef730cedad..a0264552108 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp @@ -5,7 +5,7 @@ #include typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; +typedef CGAL::Advancing_front_surface_reconstruction<> Reconstruction; typedef Reconstruction::Triangulation_3 Triangulation_3; typedef Reconstruction::Triangulation_data_structure_2 TDS_2; typedef K::Point_3 Point_3; diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index 479a4633dec..1077854c780 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -1,12 +1,12 @@ #include #include #include -#include +#include #include #include -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::Point_3 Point_3; +typedef CGAL::Simple_cartesian K; +typedef K::Point_3 Point_3; typedef CGAL::cpp11::tuple Facet; @@ -27,8 +27,16 @@ struct Perimeter { : bound(bound) {} - bool operator()(const Point_3& p, const Point_3& q, const Point_3& r) const + // The point type that will be injected here will be + // CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 + template + bool operator()(const Point& p, const Point& q, const Point& r) const { + // bound == 0 is better than bound < infinity + // as it avoids the distance computations + if(bound == 0){ + return false; + } double d = sqrt(squared_distance(p,q)); if(d>bound) return true; d += sqrt(squared_distance(p,r)) ; @@ -48,7 +56,7 @@ int main(int argc, char* argv[]) std::istream_iterator(), std::back_inserter(points)); - Perimeter perimeter(0.5); + Perimeter perimeter(0); CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), std::back_inserter(facets), diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 5da7e772ff7..8df15dc5d76 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -166,14 +167,15 @@ public: }; - template , Advancing_front_surface_reconstruction_cell_base_3 > >, + template < + class Triangulation = Delaunay_triangulation_3, Advancing_front_surface_reconstruction_cell_base_3 > >, class Reject = Always_false> class Advancing_front_surface_reconstruction { public: typedef Triangulation Triangulation_3; - typedef Advancing_front_surface_reconstruction Extract; + typedef typename Triangulation_3::Geom_traits Kernel; + typedef Advancing_front_surface_reconstruction Extract; typedef typename Triangulation_3::Geom_traits Geom_traits; typedef typename Kernel::FT coord_type; @@ -2305,11 +2307,30 @@ namespace AFSR { template struct Auto_count : public std::unary_function >{ mutable int i; - Auto_count() : i(0){} + + Auto_count() + : i(0) + {} + std::pair operator()(const T& p) const { return std::make_pair(p,i++); } }; + + template +struct Auto_count_cc : public std::unary_function >{ + mutable int i; + CC cc; + + Auto_count_cc(CC cc) + : i(0), cc(cc) + {} + + template + std::pair operator()(const T2& p) const { + return std::make_pair(cc(p),i++); + } + }; } @@ -2328,7 +2349,7 @@ advancing_front_surface_reconstruction(PointIterator b, typedef Triangulation_data_structure_3 Tds; typedef Delaunay_triangulation_3 Triangulation_3; - typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Advancing_front_surface_reconstruction Reconstruction; typedef Kernel::Point_3 Point_3; Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), @@ -2360,11 +2381,14 @@ advancing_front_surface_reconstruction(PointIterator b, typedef Triangulation_data_structure_3 Tds; typedef Delaunay_triangulation_3 Triangulation_3; - typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef std::iterator_traits::value_type InputPoint; + typedef typename Kernel_traits::Kernel InputKernel; + typedef Cartesian_converter CC; typedef Kernel::Point_3 Point_3; - - Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), - boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + CC cc=CC(); + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), + boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); AFSR_options opt; opt.K = radius_ratio_bound; @@ -2391,7 +2415,7 @@ advancing_front_surface_reconstructionP(PointIterator b, typedef Triangulation_data_structure_3 Tds; typedef Delaunay_triangulation_3 Triangulation_3; - typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Advancing_front_surface_reconstruction Reconstruction; typedef typename Kernel::Point_3 Point_3; Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), @@ -2419,7 +2443,7 @@ advancing_front_surface_reconstructionP(PointIterator b, typedef Triangulation_data_structure_3 Tds; typedef Delaunay_triangulation_3 Triangulation_3; - typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Advancing_front_surface_reconstruction Reconstruction; typedef typename Kernel::Point_3 Point_3; Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index cf77c286548..04504b7fae0 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -31,7 +31,7 @@ namespace CGAL { - template class Advancing_front_surface_reconstruction; + template class Advancing_front_surface_reconstruction; template > class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase @@ -45,7 +45,7 @@ public: }; - template friend class Advancing_front_surface_reconstruction; + template friend class Advancing_front_surface_reconstruction; typedef VertexBase Base; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h index 4ee56548a60..dc5f3603b8d 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h @@ -25,7 +25,7 @@ namespace CGAL { - template + template class Advancing_front_polyhedron_reconstruction; namespace AFSR { diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h index 7147d11cb3b..a217aeb4fe0 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h @@ -22,15 +22,15 @@ namespace CGAL { - template + template class Advancing_front_surface_reconstruction; namespace AFSR { - template + template typename TDS::Vertex_handle -construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface) +construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface) { typedef typename TDS::Vertex_handle Vertex_handle; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h index f7ab995e178..ae68077bc47 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h @@ -23,9 +23,9 @@ namespace CGAL { namespace AFSR { - template + template typename TDS::Vertex_handle - orient(TDS& tds, const Advancing_front_surface_reconstruction& surface) + orient(TDS& tds, const Advancing_front_surface_reconstruction& surface) { typedef typename TDS::Vertex_handle Vertex_handle; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h index 9a1899ad9ad..d91059a30b8 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h @@ -24,16 +24,16 @@ namespace CGAL { -template +template class Advancing_front_surface_reconstruction; -template +template OutputIterator - write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S) + write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S) { - typedef Advancing_front_surface_reconstruction Surface; + typedef Advancing_front_surface_reconstruction Surface; typedef typename Surface::TDS_2 TDS_2; typedef typename TDS_2::Face_iterator Face_iterator; From f47aa05f7b204250e888baed58d0bb40c2ec0209 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 10 Jun 2015 12:39:01 +0200 Subject: [PATCH 083/114] Add classified --- .../CGAL/Advancing_front_surface_reconstruction.h | 2 +- .../PackageDescription.txt | 10 ++++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h index dc5418c920f..7ee063a22e0 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h @@ -228,7 +228,7 @@ describing the faces of the reconstructed surface. be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. \tparam IndicesOutputIterator must be an output iterator to which `CGAL::cpp11::tuple` can be assigned. -\tparam Filter must be a functor with `bool operator()(Gt::Point_3,Gt::Point_3,Gt::Point_3)`. +\tparam Filter must be a functor with `bool operator()(Point,Point,Point)` where Point is `Exact_predicates_inexact_constructions_kernel::Point_3`. \param b iterator on the first point of the sequence \param e past the end iterator of the point sequence diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt index 0742df993a9..5333ea7f71a 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -23,7 +23,17 @@ of topological singularities. } \cgalPkgDescriptionEnd +\cgalClassifedRefPages +## Classes ## + +- `CGAL::Advancing_front_surface_reconstruction` +- `CGAL::Advancing_front_surface_reconstruction_vertex_base_3` +- `CGAL::Advancing_front_surface_reconstruction_cell_base_3` + +## Functions ## + +- `CGAL::advancing_front_surface_reconstruction()` */ From 110ae0574cae20c2d1311c74e533f452e29cff74 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 10 Jun 2015 13:10:46 +0200 Subject: [PATCH 084/114] make it work for Polyhedron as output (not yet documented) --- .../reconstruction_polyhedron.cpp | 2 +- .../Advancing_front_surface_reconstruction.h | 20 +++++++++++-------- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp index 47ea0f09a60..4b6da452bf0 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp @@ -22,7 +22,7 @@ int main() std::istream_iterator(), std::back_inserter(points)); - CGAL::advancing_front_surface_reconstructionP(points.begin(), + CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), P); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 8df15dc5d76..7c69a06479e 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2400,11 +2400,11 @@ advancing_front_surface_reconstruction(PointIterator b, } - template + template class HDS, typename Alloc,typename Filter> void -advancing_front_surface_reconstructionP(PointIterator b, +advancing_front_surface_reconstruction(PointIterator b, PointIterator e, - Polyhedron_3& polyhedron, + Polyhedron_3& polyhedron, Filter filter, double radius_ratio_bound = 5, double beta = 0.52) @@ -2416,10 +2416,14 @@ advancing_front_surface_reconstructionP(PointIterator b, typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; + typedef std::iterator_traits::value_type InputPoint; + typedef typename Kernel_traits::Kernel InputKernel; + typedef Cartesian_converter CC; typedef typename Kernel::Point_3 Point_3; - Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), - boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + CC cc=CC(); + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), + boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); AFSR_options opt; opt.K = radius_ratio_bound; @@ -2429,11 +2433,11 @@ advancing_front_surface_reconstructionP(PointIterator b, AFSR::construct_polyhedron(polyhedron, R); } -template + template class HDS, typename Alloc> void -advancing_front_surface_reconstructionP(PointIterator b, +advancing_front_surface_reconstruction(PointIterator b, PointIterator e, - Polyhedron_3& polyhedron, + Polyhedron_3& polyhedron, double radius_ratio_bound = 5, double beta = 0.52) { From 15e33a861fb49791b09251c00c145a5dc62c4925 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 10 Jun 2015 18:26:41 +0200 Subject: [PATCH 085/114] Write into a wrapper of a Surface_mesh as ouput iterator --- .../CMakeLists.txt | 1 + .../reconstruction_surface_mesh.cpp | 70 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt index fb6a1a31263..0a77c091b09 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt @@ -25,6 +25,7 @@ if ( CGAL_FOUND ) create_single_source_cgal_program( "reconstruction_fct.cpp" ) create_single_source_cgal_program( "reconstruction_class.cpp" ) create_single_source_cgal_program( "reconstruction_polyhedron.cpp" ) + create_single_source_cgal_program( "reconstruction_surface_mesh.cpp" ) create_single_source_cgal_program( "boundaries.cpp" ) else() diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp new file mode 100644 index 00000000000..a6544c9dc1c --- /dev/null +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp @@ -0,0 +1,70 @@ +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::cpp11::tuple Facet; + +typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; +typedef Kernel::Point_3 Point_3; + +typedef CGAL::Surface_mesh Mesh; + +struct Construct{ + Mesh& mesh; + + template < typename PointIterator> + Construct(Mesh& mesh,PointIterator b, PointIterator e) + : mesh(mesh) + { + for(; b!=e; ++b){ + boost::graph_traits::vertex_descriptor v; + v = add_vertex(mesh); + mesh.point(v) = *b; + } + } + + Construct& operator=(const Facet f) + { + typedef boost::graph_traits::vertex_descriptor vertex_descriptor; + mesh.add_face(vertex_descriptor(get<0>(f)), + vertex_descriptor(get<1>(f)), + vertex_descriptor(get<2>(f))); + return *this; + } + + Construct& + operator*() { return *this; } + + Construct& + operator++() { return *this; } + + Construct + operator++(int) { return *this; } + +}; + +int main(int argc, char* argv[]) +{ + std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); + std::vector points; + std::vector facets; + Mesh m; + + std::copy(std::istream_iterator(in), + std::istream_iterator(), + std::back_inserter(points)); + + Construct construct(m,points.begin(),points.end()); + + CGAL::advancing_front_surface_reconstruction(points.begin(), + points.end(), + construct); + + std::cout << m << std::endl; + + return 0; +} From 426e31681b01269d1201189083ad54bed1a10f30 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 11 Jun 2015 15:57:59 +0200 Subject: [PATCH 086/114] switch from tuple to array to describe a face --- .../reconstruction_fct.cpp | 4 ++-- .../reconstruction_surface_mesh.cpp | 11 ++++++----- .../include/CGAL/internal/AFSR/write_triple_indices.h | 8 ++++---- .../Polyhedron_demo_advancing_front_plugin.cpp | 2 +- 4 files changed, 13 insertions(+), 12 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index 1077854c780..b00870487fa 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -8,13 +8,13 @@ typedef CGAL::Simple_cartesian K; typedef K::Point_3 Point_3; -typedef CGAL::cpp11::tuple Facet; +typedef CGAL::cpp11::array Facet; namespace std { std::ostream& operator<<(std::ostream& os, const Facet& f) { - os << "3 " << get<0>(f) << " " << get<1>(f) << " " << get<2>(f); + os << "3 " << f[0] << " " << f[1] << " " << f[2]; return os; } } diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp index a6544c9dc1c..d237556efd0 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp @@ -4,9 +4,9 @@ #include #include #include -#include +#include -typedef CGAL::cpp11::tuple Facet; +typedef CGAL::cpp11::array Facet; typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; typedef Kernel::Point_3 Point_3; @@ -30,9 +30,10 @@ struct Construct{ Construct& operator=(const Facet f) { typedef boost::graph_traits::vertex_descriptor vertex_descriptor; - mesh.add_face(vertex_descriptor(get<0>(f)), - vertex_descriptor(get<1>(f)), - vertex_descriptor(get<2>(f))); + typedef boost::graph_traits::vertices_size_type size_type; + mesh.add_face(vertex_descriptor(static_cast(f[0])), + vertex_descriptor(static_cast(f[1])), + vertex_descriptor(static_cast(f[2]))); return *this; } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h index d91059a30b8..c888b69ace2 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h @@ -20,7 +20,7 @@ #ifndef CGAL_AFSR_WRITE_TRIPLE_INDICES_H #define CGAL_AFSR_WRITE_TRIPLE_INDICES_H -#include +#include namespace CGAL { @@ -46,9 +46,9 @@ OutputIterator for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ if(fit->is_on_surface()){ - *out++ = CGAL::cpp11::tuple(fit->vertex(0)->vertex_3()->id(), - fit->vertex(1)->vertex_3()->id(), - fit->vertex(2)->vertex_3()->id()); + *out++ = CGAL::make_array(std::size_t(fit->vertex(0)->vertex_3()->id()), + std::size_t(fit->vertex(1)->vertex_3()->id()), + std::size_t(fit->vertex(2)->vertex_3()->id())); } } return out; diff --git a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp index 3db1bfb534d..5f6aa369511 100644 --- a/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp +++ b/Polyhedron/demo/Polyhedron/Polyhedron_demo_advancing_front_plugin.cpp @@ -111,7 +111,7 @@ void Polyhedron_demo_advancing_front_plugin::on_actionAdvancingFrontReconstructi Scene_polyhedron_item* new_item = new Scene_polyhedron_item(Polyhedron()); Polyhedron& P = * const_cast(new_item->polyhedron()); Perimeter filter(sm_perimeter); - CGAL::advancing_front_surface_reconstructionP((points)->begin(), points->end(), P, filter); + CGAL::advancing_front_surface_reconstruction((points)->begin(), points->end(), P, filter); new_item->setName(tr("%1 Advancing Front (%2 %3)") From 2f89160cb259cc1901ff84034b49b20b495e639b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 11 Jun 2015 16:09:43 +0200 Subject: [PATCH 087/114] add example that generates a Surface_mesh --- ...Advancing_front_surface_reconstruction.txt | 9 ++++- .../dependencies | 2 ++ .../examples.txt | 2 ++ .../CMakeLists.txt | 36 ------------------- .../reconstruction_polyhedron.cpp | 2 -- 5 files changed, 12 insertions(+), 39 deletions(-) delete mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 07bf8b8639d..cc1c8f99f59 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -189,7 +189,7 @@ the faces are connected with the facets of underlying 3D Delaunay triangulation. The third example shows how to get outliers and the boundaries of the surface. -\subsection AFSR_Example_function Example for Global Function +\subsection AFSR_Example_function Examples for Global Function The global function `advancing_front_surface_reconstruction()` takes an iterator range of points as input and writes for each face of the @@ -204,6 +204,13 @@ than a given bound. \cgalExample{Advancing_front_surface_reconstruction/reconstruction_fct.cpp} +While the first example just writes index triples, the second example +uses as output iterator a wrapper around a reference to a `Surface_mesh` +and calls the function `add_face()`. + +\cgalExample{Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp} + + \subsection AFSR_Example_class Example for the Reconstruction Class The class `Advancing_front_surface_reconstruction` provides diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies index 95a6a4e08d4..943f828d722 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/dependencies @@ -8,3 +8,5 @@ TDS_2 Triangulation_2 Triangulation_3 Number_types +Surface_mesh +Polyhedron diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt index 8e5c59fceeb..3b7deaab2b8 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt @@ -1,5 +1,7 @@ /*! \example Advancing_front_surface_reconstruction/reconstruction_fct.cpp \example Advancing_front_surface_reconstruction/reconstruction_class.cpp +\example Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp +\example Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp \example Advancing_front_surface_reconstruction/boundaries.cpp */ diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt deleted file mode 100644 index 0a77c091b09..00000000000 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/CMakeLists.txt +++ /dev/null @@ -1,36 +0,0 @@ -# Created by the script cgal_create_cmake_script -# This is the CMake script for compiling a CGAL application. - - -project( Advancing_front_surface_reconstruction_example ) - -CMAKE_MINIMUM_REQUIRED(VERSION 2.4.5) - -set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true) - -if ( COMMAND cmake_policy ) - cmake_policy( SET CMP0003 NEW ) -endif() - -find_package(CGAL QUIET COMPONENTS Core ) - -if ( CGAL_FOUND ) - - include( ${CGAL_USE_FILE} ) - - include( CGAL_CreateSingleSourceCGALProgram ) - - include_directories (BEFORE ../../include) - - create_single_source_cgal_program( "reconstruction_fct.cpp" ) - create_single_source_cgal_program( "reconstruction_class.cpp" ) - create_single_source_cgal_program( "reconstruction_polyhedron.cpp" ) - create_single_source_cgal_program( "reconstruction_surface_mesh.cpp" ) - create_single_source_cgal_program( "boundaries.cpp" ) - -else() - - message(STATUS "This program requires the CGAL library, and will not be compiled.") - -endif() - diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp index 4b6da452bf0..c3c531b4f31 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp @@ -1,5 +1,3 @@ - - #include #include #include From 875a2a746d30d18a82c9c4411baa1c1e6630cc0a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Sun, 14 Jun 2015 10:40:15 +0200 Subject: [PATCH 088/114] remove a file in examples; Add a typname --- .../fill.cpp | 138 ------------------ .../Advancing_front_surface_reconstruction.h | 4 +- 2 files changed, 2 insertions(+), 140 deletions(-) delete mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp deleted file mode 100644 index 91b210b2f82..00000000000 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/fill.cpp +++ /dev/null @@ -1,138 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - - -typedef double NT; - -struct K : public CGAL::Filtered_kernel > {}; -typedef K::Point_3 Point; -typedef K::Vector_3 Vector; -typedef K::Segment_3 Segment; -typedef K::Triangle_3 Triangle; - -NT -weight(const Point& p, const Point& q, const Point& r){ - NT area = std::sqrt(Triangle(p,q,r).squared_area()); - NT l1 = std::sqrt((p-q) * (p-q)); - NT l2 = std::sqrt((p-r) * (p-r)); - NT l3 = std::sqrt((q-r) * (q-r)); - if(l1>l2) std::swap(l1,l2); - if(l2>l3) std::swap(l2,l3); - if(l1>l2) std::swap(l1,l2); - if(l2>l3) std::swap(l2,l3); - - // Taken from Piecewise-Linear Interpolation between Polygonal Slices - // from Gill Barequet and Micha Sharir - return 0.85 * area + 0.05 * (l1 +l2 + l3) + 0.1 * l3/l1; -} - - -void -insert(std::set >& triangles, int i, int j, int k){ - std::cout << i << ", " << j << ", " << k << std::endl; - if(i>j) std::swap(i,j); - if(j>k) std::swap(j,k); - if(i>j) std::swap(i,j); - if(j>k) std::swap(j,k); - std::cout << i << ", " << j << ", " << k << std::endl; - triangles.insert(CGAL::make_triple(i,j,k)); -} - - -void -collect(int i, int k, int n, const std::vector& O, std::set >& triangles){ - - std::cout << "collect(" << i << ", " << k << ")" << std::endl; - if((i+2) == k){ - insert(triangles, i, i+1, k); - }else { - int o = O[i*n+k]; - - if(o != (i+1)){ - collect(i, o, n, O, triangles); - } - insert(triangles, i, o, k); - if(o != (k-1)){ - collect(o, k, n, O, triangles); - } - } -} - - - -int -main(){ - - int n; - std::cin >> n; - - std::vector points(n); - CGAL::copy_n(std::istream_iterator(std::cin), n, points.begin()); - - - std::set > triangles; - - std::vector W(n*n); - std::vector O(n*n); - - for(int i = 0; i <= n-2; i++){ - W[i*n + i + 1] = 0; - } - for(int i = 0; i <= n-3; i++){ - W[i*n + i + 2] = weight(points[i], points[i+1], points[i+3]); - } - - for(int j = 3; j <= n-1; j++){ - for(int i=0; i <= n - j - 1; i++){ - int k = i + j; - double lmin = -1; - int lmin_index; - for(int m = i+1; m < k; m++){ - double d = W[i*n + m] + W[m*n + k] + weight(points[i], points[m], points[k]); - if( (lmin == -1) || (d < lmin )){ - lmin = d; - lmin_index = m; - } - } - W[i*n + k] = lmin; - O[i*n + k] = lmin_index; - - } - } - - collect(0, n-1, n, O, triangles); - - std::cout << "Shape {\n" - "appearance Appearance {\n" - "material Material { diffuseColor .9 .5 .1}}\n" - "geometry\n" - "IndexedFaceSet {\n" - "coord DEF def_coords Coordinate {\n" - "point [ \n" ; - - for (int i = 0; i < n; i++){ - std::cout << points[i].x() << " " << points[i].y() << " " << points[i].z() << ",\n "; - } - std::cout << "]\n" - "}\n" - "solid FALSE\n" - "coordIndex [ \n"; - - for(std::set >::iterator it = triangles.begin(); - it != triangles.end(); - it++){ - std::cout << it->first << ", " << it->second << ", " << it->third << ", -1,\n "; - } - std::cout << "]\n" - "}# IndexedFaceSet\n" - "}# Shape\n"; - - return 1; -} - - diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 7c69a06479e..3b237fc7927 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2382,7 +2382,7 @@ advancing_front_surface_reconstruction(PointIterator b, typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; - typedef std::iterator_traits::value_type InputPoint; + typedef typename std::iterator_traits::value_type InputPoint; typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef Kernel::Point_3 Point_3; @@ -2416,7 +2416,7 @@ advancing_front_surface_reconstruction(PointIterator b, typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; - typedef std::iterator_traits::value_type InputPoint; + typedef typename std::iterator_traits::value_type InputPoint; typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef typename Kernel::Point_3 Point_3; From 218e1a37e359ef61ad838b1c4cdb74aa43f406b3 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 17 Jun 2015 11:07:46 +0200 Subject: [PATCH 089/114] bug fix in example --- .../reconstruction_class.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp index a0264552108..70c38d3ef50 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp @@ -34,9 +34,10 @@ int main(int argc, char* argv[]) Triangulation_3::Cell_handle ch = f.first; int ci = f.second; Point_3 points[3]; - for(int i = 0, j = 0; i < 4; i++, j++){ + for(int i = 0, j = 0; i < 4; i++){ if(ci != i){ points[j] = ch->vertex(i)->point(); + j++; } } std::cout << " facet normal " From 5549a9e3b5a79699423e71b7597c750cda3b3826 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 17 Jun 2015 11:14:20 +0200 Subject: [PATCH 090/114] remove example which uses an undocumented API --- .../examples.txt | 1 - .../reconstruction_polyhedron.cpp | 30 ------------------- 2 files changed, 31 deletions(-) delete mode 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt index 3b7deaab2b8..44a2d6782f4 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/examples.txt @@ -1,7 +1,6 @@ /*! \example Advancing_front_surface_reconstruction/reconstruction_fct.cpp \example Advancing_front_surface_reconstruction/reconstruction_class.cpp -\example Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp \example Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp \example Advancing_front_surface_reconstruction/boundaries.cpp */ diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp deleted file mode 100644 index c3c531b4f31..00000000000 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_polyhedron.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include -#include -#include - -typedef CGAL::Exact_predicates_inexact_constructions_kernel Kernel; -typedef Kernel::Point_3 Point_3; - -typedef CGAL::Polyhedron_3 Polyhedron; - - -int main() -{ - std::vector points; - Polyhedron P; - - std::copy(std::istream_iterator(std::cin), - std::istream_iterator(), - std::back_inserter(points)); - - CGAL::advancing_front_surface_reconstruction(points.begin(), - points.end(), - P); - - std::cout << P << std::endl; - - return 0; -} From b1b40be4acb4aa2367dacac79fe58c696b7551ab Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 18 Jun 2015 09:47:11 +0200 Subject: [PATCH 091/114] only declare a private function to avoid warning --- .../include/CGAL/Advancing_front_surface_reconstruction.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 3b237fc7927..96fbd8b3e95 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -58,8 +58,8 @@ namespace CGAL { template < class Surface> class Advancing_front_surface_reconstruction_boundary_iterator { private: - Advancing_front_surface_reconstruction_boundary_iterator(){} -public: + Advancing_front_surface_reconstruction_boundary_iterator(); + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; typedef Advancing_front_surface_reconstruction_boundary_iterator Self; typedef typename Surface::Vertex_handle Vertex_handle; @@ -70,7 +70,8 @@ public: Finite_vertices_iterator first_vertex; Vertex_handle pos; bool first, last; - + +public: Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_, int m) : S(S_), mark(m), first_vertex(S.triangulation_3().finite_vertices_begin()), pos(first_vertex) { From f80113c0c8b2c9feb6a39a36e4805776d63990dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Thu, 18 Jun 2015 09:56:36 +0200 Subject: [PATCH 092/114] improve doc --- ...Advancing_front_surface_reconstruction.txt | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index cc1c8f99f59..2a9475f56fa 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -30,10 +30,10 @@ In most surface based Delaunay algorithms the triangles are selected independently, that is in parallel \cgalCite{agj-lcsr-00}\cgalCite{ab-srvf-98}. This chapter presents a surface-based Delaunay surface -reconstruction algorithm by selecting the triangles sequentially, that -is by using previous selected triangles to select a new triangle for +reconstruction algorithm that sequentially selects the triangles, that +is it uses previously selected triangles to select a new triangle for advancing the front. At each advancing step the most plausible -triangle is selected, and the triangles are selected in a way that +triangle is selected, and such that the triangles selected generates an orientable manifold triangulated surface. Two other examples of this greedy approach are the ball pivoting @@ -53,16 +53,16 @@ We describe next the algorithm and provide examples. A detailed description of the algorithm and the underlying theory are provided in \cgalCite{cgal:csd-gdbsra-04}. - The first step of the algorithm is the construction of a 3D Delaunay -triangulation of the point set. The Delaunay triangle with the -smallest radius is the starting point for the greedy algorithm. The -radius of a triangle \f$ t \f$ is the radius of the smallest sphere +triangulation of the point set. +The radius of a triangle \f$ t \f$ is the radius of the smallest sphere passing through the vertices of \f$ t\f$ and enclosing no sample point. In other words, the radius \f$ r_t\f$ is the distance from any vertex of \f$ t\f$ to the Voronoi edge dual to \f$ t\f$. This triangle with three boundary edges is the initial triangulated surface, and its boundary is the advancing front. +The Delaunay triangle with the smallest radius is the starting point +for the greedy algorithm. The algorithm maintains a priority queue of candidate triangles, that is of valid triangles incident to the boundary edges of the current @@ -77,7 +77,7 @@ which are explained next. \subsection AFSR_Topology Topological Constraints -Any triangle \f$t\f$ considered as next potential candidate shares an +Any triangle \f$t\f$ considered as the next potential candidate shares an edge \f$e\f$ with the front of the current reconstruction. Let \f$b\f$ be the vertex of \f$t\f$ opposite to \f$e\f$. There are four configurations where \f$t\f$ is added to the surface. @@ -105,15 +105,15 @@ radius. While the radius is a good criterion in the case of 2D smooth curve reconstruction \cgalCite{b-cccda-94}, we need another criterion for 3D surface reconstruction, namely the dihedral angle between triangles on the surface, that is the angle between the normals of the -triangles. - +triangles. There are two bounds namely \f$ \alpha_\mathrm{sliver} \f$ +and \f$ \beta \f$. We denote by \f$ \beta_t\f$ the angle between the normal of a triangle \f$ t\f$ incident on a boundary edge \f$ e \f$ and the normal of the triangle on the surface incident to \f$ e \f$. The *candidate* triangle of an edge \f$ e \f$ is the triangle -with the smallest radius, that is valid for \f$ e \f$ +with the smallest radius that is valid for \f$ e \f$ and that has \f$ \beta_t < \alpha_\mathrm{sliver} \f$. There may be no such triangle. In the implementation of the algorithm \f$ \alpha_\mathrm{sliver} = 5\pi/6 \f$. From 6805d06420342a7737ed54a41e2bfaa58066ce46 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 18 Jun 2015 12:12:19 +0200 Subject: [PATCH 093/114] Split SLIVER_ANGULUS in COS_ALPHA_SLIVER and COS_BETA --- .../Advancing_front_surface_reconstruction.h | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 96fbd8b3e95..0f1109e4e87 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -249,7 +249,8 @@ private: Ordered_border_type _ordered_border; int _number_of_border; - const coord_type SLIVER_ANGULUS; // = sampling quality of the surface + const coord_type COS_ALPHA_SLIVER; + const coord_type COS_BETA; coord_type DELTA; // = sampling quality of the border coord_type K, min_K; const coord_type eps; @@ -561,7 +562,7 @@ public: Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options(), Reject reject = Reject()) - : T(T_), _number_of_border(1), SLIVER_ANGULUS(.86), DELTA(opt.delta), min_K(HUGE_VAL), + : T(T_), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), COS_BETA(0.86), DELTA(opt.delta), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), @@ -1235,10 +1236,9 @@ public: // on peut alors tester v1*v2 >= 0 norm = sqrt(norm1 * (v2*v2)); pscal = v1*v2; - //SLIVER_ANGULUS represente la qualite d'echantillonnage de la - //surface + // check if the triangle will produce a sliver on the surface bool sliver_facet = ((succ_start || (neigh == c_predone))&& - (pscal <= -SLIVER_ANGULUS*norm)); + (pscal <= COS_ALPHA_SLIVER*norm)); if (succ_start) succ_start = false; @@ -1248,14 +1248,20 @@ public: { PnP1 = p1-pn; // DELTA represente la qualite d'echantillonnage du bord + // We skip triangles having an internal angle along e + // whose cosinus is smaller than -DELTA + // that is the angle is larger than arcos(-DELTA) border_facet = !((P2P1*P2Pn >= -DELTA*sqrt(norm12*(P2Pn*P2Pn)))&& (P2P1*PnP1 >= -DELTA*sqrt(norm12*(PnP1*PnP1)))); - + /// \todo investigate why we simply do not skip this triangle + /// but continue looking for a better candidate + /// if (!border_facet){ min_facetA = facet_it; min_valueA = tmp; min_valueP = pscal/norm; + ///} } } } @@ -1284,7 +1290,7 @@ public: // alors -(1+1/min_valueA) app a [-inf, -1] // -min_valueP app a [-1, 1] - if (min_valueP > SLIVER_ANGULUS) + if (min_valueP > COS_BETA) value = -(coord_type(1) + coord_type(1)/min_valueA); else { @@ -1429,7 +1435,7 @@ public: v2 = cross_product(p1-p2,pn-p2); coord_type norm = sqrt((v1*v1)*(v2*v2)); - if (v1*v2 > SLIVER_ANGULUS*norm) + if (v1*v2 > COS_BETA*norm) return 1; // label bonne pliure sinon: if (ear_alpha <= K*smallest_radius_delaunay_sphere(neigh, n_ind)) From 723bb674cf026873a2c80e16f74c73cf8a7f01b0 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 18 Jun 2015 12:19:29 +0200 Subject: [PATCH 094/114] plug beta into the algorithm --- .../Advancing_front_surface_reconstruction.h | 16 +++++++++------- .../include/CGAL/internal/AFSR/AFSR_options.h | 1 + 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 0f1109e4e87..760e910ab42 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -562,7 +562,7 @@ public: Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options(), Reject reject = Reject()) - : T(T_), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), COS_BETA(0.86), DELTA(opt.delta), min_K(HUGE_VAL), + : T(T_), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), COS_BETA(opt.COS_BETA), DELTA(opt.delta), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), @@ -591,21 +591,23 @@ public: } } + /* ~Advancing_front_surface_reconstruction() { - /* + std::cerr << "postprocessing" << postprocess_timer.time() << std::endl; std::cerr << "extend " << extend_timer.time() << std::endl; std::cerr << "extend2 " << extend2_timer.time() << std::endl; std::cerr << "init " << postprocess_timer.time() << std::endl; std::cerr << "#outliers " << number_of_outliers() << std::endl; - */ } + */ void run(double radius_ratio_bound=5, double beta=0.52) { AFSR_options opt; opt.K = radius_ratio_bound; + opt.COS_BETA = acos(beta); // TODO: what to do with beta run(opt); @@ -2364,7 +2366,7 @@ advancing_front_surface_reconstruction(PointIterator b, AFSR_options opt; opt.K = radius_ratio_bound; - // TODO: What to do with beta??? + opt.COS_BETA = acos(beta); Reconstruction R(dt,opt); R.run(opt); write_triple_indices(out, R); @@ -2399,7 +2401,7 @@ advancing_front_surface_reconstruction(PointIterator b, AFSR_options opt; opt.K = radius_ratio_bound; - // TODO: What to do with beta??? + opt.COS_BETA = acos(beta); Reconstruction R(dt,opt, filter); R.run(opt); write_triple_indices(out, R); @@ -2434,7 +2436,7 @@ advancing_front_surface_reconstruction(PointIterator b, AFSR_options opt; opt.K = radius_ratio_bound; - // TODO: What to do with beta??? + opt.COS_BETA = acos(beta); Reconstruction R(dt, opt,filter); R.run(opt); AFSR::construct_polyhedron(polyhedron, R); @@ -2462,7 +2464,7 @@ advancing_front_surface_reconstruction(PointIterator b, AFSR_options opt; opt.K = radius_ratio_bound; - // TODO: What to do with beta??? + opt.COS_BETA = acos(beta); Reconstruction R(dt, opt); R.run(opt); AFSR::construct_polyhedron(polyhedron, R); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h index e7fb724d3f1..2415c077179 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h @@ -33,6 +33,7 @@ public: double K_init; double K_step; double K; + double COS_BETA; int out_format; int NB_BORDER_MAX; double red, green, blue; From 75c353406a19458aca582cbeacfbab68fcaa2485 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 18 Jun 2015 12:38:29 +0200 Subject: [PATCH 095/114] document delta --- ...Advancing_front_surface_reconstruction.txt | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index 2a9475f56fa..b34a665e69a 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -105,19 +105,24 @@ radius. While the radius is a good criterion in the case of 2D smooth curve reconstruction \cgalCite{b-cccda-94}, we need another criterion for 3D surface reconstruction, namely the dihedral angle between triangles on the surface, that is the angle between the normals of the -triangles. There are two bounds namely \f$ \alpha_\mathrm{sliver} \f$ -and \f$ \beta \f$. +triangles. There are three bounds namely \f$ \alpha_\mathrm{sliver} \f$, +\f$ \beta \f$, and \f$ \delta \f$. + +The *candidate* triangle of an edge \f$ e \f$ is the triangle +with the smallest radius: +- that is valid for \f$ e \f$, and +- that has \f$ \beta_t < \alpha_\mathrm{sliver} \f$, and +- that has its internal angles with \f$ e \f$ smaller than \f$ \delta \f$. + +There may be no such triangle. In the implementation +of the algorithm \f$ \alpha_\mathrm{sliver} \f$ and \f$ \delta\f$ are equal +to \f$ 5\pi/6 \f$. + We denote by \f$ \beta_t\f$ the angle between the normal of a triangle \f$ t\f$ incident on a boundary edge \f$ e \f$ and the normal of the triangle on the surface incident to \f$ e \f$. -The *candidate* triangle of an edge \f$ e \f$ is the triangle -with the smallest radius that is valid for \f$ e \f$ -and that has \f$ \beta_t < \alpha_\mathrm{sliver} \f$. -There may be no such triangle. In the implementation -of the algorithm \f$ \alpha_\mathrm{sliver} = 5\pi/6 \f$. - We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if \f$ \beta_t < \beta \f$, and \f$ -\beta_t \f$ else. The parameter \f$ From 23e4e784541fb3f3d729a8a76409d1cb106b88a9 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 18 Jun 2015 13:01:25 +0200 Subject: [PATCH 096/114] reindent --- .../Advancing_front_surface_reconstruction.h | 3502 ++++++++--------- ...front_surface_reconstruction_cell_base_3.h | 134 +- ...ont_surface_reconstruction_vertex_base_3.h | 220 +- .../CGAL/internal/AFSR/Surface_face_base_2.h | 124 +- .../internal/AFSR/Surface_vertex_base_2.h | 70 +- .../CGAL/internal/AFSR/construct_polyhedron.h | 90 +- .../CGAL/internal/AFSR/construct_surface_2.h | 218 +- .../include/CGAL/internal/AFSR/orient.h | 206 +- .../CGAL/internal/AFSR/write_triple_indices.h | 44 +- 9 files changed, 2299 insertions(+), 2309 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 760e910ab42..f46cc857ad1 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -48,114 +48,114 @@ namespace CGAL { -// This iterator allows to visit all contours. It has the particularity -// that it visits the entry point of the contour twice. This allows to -// detect that the traversal of the border is finished. One more increment -// brings us to the next vertex. + // This iterator allows to visit all contours. It has the particularity + // that it visits the entry point of the contour twice. This allows to + // detect that the traversal of the border is finished. One more increment + // brings us to the next vertex. -template < class Surface> -class Advancing_front_surface_reconstruction_boundary_iterator { -private: - Advancing_front_surface_reconstruction_boundary_iterator(); + template < class Surface> + class Advancing_front_surface_reconstruction_boundary_iterator { + private: + Advancing_front_surface_reconstruction_boundary_iterator(); - typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; - typedef Advancing_front_surface_reconstruction_boundary_iterator Self; - typedef typename Surface::Vertex_handle Vertex_handle; - typedef typename Surface::Vertex Vertex; + typedef typename Surface::Finite_vertices_iterator Finite_vertices_iterator; + typedef Advancing_front_surface_reconstruction_boundary_iterator Self; + typedef typename Surface::Vertex_handle Vertex_handle; + typedef typename Surface::Vertex Vertex; - const Surface& S; - int mark; - Finite_vertices_iterator first_vertex; - Vertex_handle pos; - bool first, last; + const Surface& S; + int mark; + Finite_vertices_iterator first_vertex; + Vertex_handle pos; + bool first, last; -public: - Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_, int m) - : S(S_), mark(m), first_vertex(S.triangulation_3().finite_vertices_begin()), pos(first_vertex) - { - if (pos->number_of_incident_border() <= 0){ - advance_to_next_boundary(); - } - first = true; - last = false; - } - - Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_) - : S(S_), pos(NULL) - {} - - Advancing_front_surface_reconstruction_boundary_iterator(const Self& s) - : S(s.S), mark(s.mark), first_vertex(s.first_vertex), pos(s.pos), first(s.first), last(s.last) - {} - - bool operator==(const Self &s) const - { - return pos == s.pos; - } - - bool operator!=(const Self &s) const - { - return pos != s.pos; - } - - - Self operator++() - { - if(pos == NULL) { - return *this; - } - if(first){ - advance_on_boundary(); - first = false; - } else if (last) { - advance_to_next_boundary(); + public: + Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_, int m) + : S(S_), mark(m), first_vertex(S.triangulation_3().finite_vertices_begin()), pos(first_vertex) + { + if (pos->number_of_incident_border() <= 0){ + advance_to_next_boundary(); + } first = true; last = false; - } else { - advance_on_boundary(); - if(&*pos == &*first_vertex){ - last = true; + } + + Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_) + : S(S_), pos(NULL) + {} + + Advancing_front_surface_reconstruction_boundary_iterator(const Self& s) + : S(s.S), mark(s.mark), first_vertex(s.first_vertex), pos(s.pos), first(s.first), last(s.last) + {} + + bool operator==(const Self &s) const + { + return pos == s.pos; + } + + bool operator!=(const Self &s) const + { + return pos != s.pos; + } + + + Self operator++() + { + if(pos == NULL) { + return *this; + } + if(first){ + advance_on_boundary(); + first = false; + } else if (last) { + advance_to_next_boundary(); + first = true; + last = false; + } else { + advance_on_boundary(); + if(&*pos == &*first_vertex){ + last = true; + } + } + return *this; + } + + Vertex_handle operator*() + { + return pos; + } + + void advance_on_boundary() + { + if(pos == NULL) { + return; + } + pos = pos->first_incident()->first; + pos->set_post_mark(mark); + } + + void advance_to_next_boundary() + { + if(pos == NULL) { + return; + } + do { + first_vertex++; + } while((first_vertex != S.triangulation_3().finite_vertices_end()) && + (! ((first_vertex->is_on_border()) + && ! first_vertex->is_post_marked(mark)))); + if(first_vertex != S.triangulation_3().finite_vertices_end()) { + pos = first_vertex; + pos->set_post_mark(mark); + assert(pos->is_on_border()); + + } else { + pos = NULL; } } - return *this; - } - - Vertex_handle operator*() - { - return pos; - } - - void advance_on_boundary() - { - if(pos == NULL) { - return; - } - pos = pos->first_incident()->first; - pos->set_post_mark(mark); - } - - void advance_to_next_boundary() - { - if(pos == NULL) { - return; - } - do { - first_vertex++; - } while((first_vertex != S.triangulation_3().finite_vertices_end()) && - (! ((first_vertex->is_on_border()) - && ! first_vertex->is_post_marked(mark)))); - if(first_vertex != S.triangulation_3().finite_vertices_end()) { - pos = first_vertex; - pos->set_post_mark(mark); - assert(pos->is_on_border()); - - } else { - pos = NULL; - } - } -}; + }; struct Always_false { @@ -169,111 +169,111 @@ public: template < - class Triangulation = Delaunay_triangulation_3, Advancing_front_surface_reconstruction_cell_base_3 > >, - class Reject = Always_false> -class Advancing_front_surface_reconstruction { + class Triangulation = Delaunay_triangulation_3, Advancing_front_surface_reconstruction_cell_base_3 > >, + class Reject = Always_false> + class Advancing_front_surface_reconstruction { -public: - typedef Triangulation Triangulation_3; - typedef typename Triangulation_3::Geom_traits Kernel; - typedef Advancing_front_surface_reconstruction Extract; - typedef typename Triangulation_3::Geom_traits Geom_traits; + public: + typedef Triangulation Triangulation_3; + typedef typename Triangulation_3::Geom_traits Kernel; + typedef Advancing_front_surface_reconstruction Extract; + typedef typename Triangulation_3::Geom_traits Geom_traits; - typedef typename Kernel::FT coord_type; + typedef typename Kernel::FT coord_type; - typedef typename Kernel::Point_3 Point; - typedef typename Kernel::Vector_3 Vector; - typedef typename Kernel::Segment_3 Segment; - typedef typename Kernel::Triangle_3 Triangle; - typedef typename Kernel::Sphere_3 Sphere; + typedef typename Kernel::Point_3 Point; + typedef typename Kernel::Vector_3 Vector; + typedef typename Kernel::Segment_3 Segment; + typedef typename Kernel::Triangle_3 Triangle; + typedef typename Kernel::Sphere_3 Sphere; - typedef typename Triangulation_3::Cell Cell; - typedef typename Triangulation_3::Vertex Vertex; - typedef typename Triangulation_3::Edge Edge; - typedef typename Triangulation_3::Facet Facet; - typedef typename Triangulation_3::Cell_handle Cell_handle; - typedef typename Triangulation_3::Vertex_handle Vertex_handle; + typedef typename Triangulation_3::Cell Cell; + typedef typename Triangulation_3::Vertex Vertex; + typedef typename Triangulation_3::Edge Edge; + typedef typename Triangulation_3::Facet Facet; + typedef typename Triangulation_3::Cell_handle Cell_handle; + typedef typename Triangulation_3::Vertex_handle Vertex_handle; - typedef typename Triangulation_3::Cell_circulator Cell_circulator; - typedef typename Triangulation_3::Facet_circulator Facet_circulator; + typedef typename Triangulation_3::Cell_circulator Cell_circulator; + typedef typename Triangulation_3::Facet_circulator Facet_circulator; - typedef typename Triangulation_3::Locate_type Locate_type; + typedef typename Triangulation_3::Locate_type Locate_type; - typedef typename Triangulation_3::Finite_cells_iterator Finite_cells_iterator; - typedef typename Triangulation_3::Finite_facets_iterator Finite_facets_iterator; - typedef typename Triangulation_3::Finite_vertices_iterator Finite_vertices_iterator; - typedef typename Triangulation_3::Finite_edges_iterator Finite_edges_iterator; + typedef typename Triangulation_3::Finite_cells_iterator Finite_cells_iterator; + typedef typename Triangulation_3::Finite_facets_iterator Finite_facets_iterator; + typedef typename Triangulation_3::Finite_vertices_iterator Finite_vertices_iterator; + typedef typename Triangulation_3::Finite_edges_iterator Finite_edges_iterator; - typedef typename Triangulation_3::All_cells_iterator All_cells_iterator; - typedef typename Triangulation_3::All_facets_iterator All_facets_iterator; - typedef typename Triangulation_3::All_vertices_iterator All_vertices_iterator; - typedef typename Triangulation_3::All_edges_iterator All_edges_iterator; + typedef typename Triangulation_3::All_cells_iterator All_cells_iterator; + typedef typename Triangulation_3::All_facets_iterator All_facets_iterator; + typedef typename Triangulation_3::All_vertices_iterator All_vertices_iterator; + typedef typename Triangulation_3::All_edges_iterator All_edges_iterator; - typedef typename Triangulation_3::Vertex::Edge_incident_facet Edge_incident_facet; - typedef typename Triangulation_3::Vertex::IO_edge_type IO_edge_type; - typedef typename Triangulation_3::Vertex::criteria criteria; - typedef typename Triangulation_3::Vertex::Radius_edge_type Radius_edge_type; - typedef typename Triangulation_3::Vertex::Border_elt Border_elt; - typedef typename Triangulation_3::Vertex::Next_border_elt Next_border_elt; - typedef typename Triangulation_3::Vertex::Intern_successors_type Intern_successors_type; - typedef typename Triangulation_3::Vertex::Radius_ptr_type Radius_ptr_type; + typedef typename Triangulation_3::Vertex::Edge_incident_facet Edge_incident_facet; + typedef typename Triangulation_3::Vertex::IO_edge_type IO_edge_type; + typedef typename Triangulation_3::Vertex::criteria criteria; + typedef typename Triangulation_3::Vertex::Radius_edge_type Radius_edge_type; + typedef typename Triangulation_3::Vertex::Border_elt Border_elt; + typedef typename Triangulation_3::Vertex::Next_border_elt Next_border_elt; + typedef typename Triangulation_3::Vertex::Intern_successors_type Intern_successors_type; + typedef typename Triangulation_3::Vertex::Radius_ptr_type Radius_ptr_type; - typedef typename Triangulation_3::Vertex::Incidence_request_iterator Incidence_request_iterator; - typedef typename Triangulation_3::Vertex::Incidence_request_elt Incidence_request_elt; + typedef typename Triangulation_3::Vertex::Incidence_request_iterator Incidence_request_iterator; + typedef typename Triangulation_3::Vertex::Incidence_request_elt Incidence_request_elt; - typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; - typedef CGAL::Triple< Vertex_handle, Vertex_handle, Vertex_handle > Facet_like; + typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; + typedef CGAL::Triple< Vertex_handle, Vertex_handle, Vertex_handle > Facet_like; - typedef std::set Ordered_border_type; + typedef std::set Ordered_border_type; - typedef typename Ordered_border_type::iterator Ordered_border_iterator; + typedef typename Ordered_border_type::iterator Ordered_border_iterator; - enum Validation_case {NOT_VALID, NOT_VALID_CONNECTING_CASE, FINAL_CASE, - EAR_CASE, EXTERIOR_CASE, CONNECTING_CASE}; + enum Validation_case {NOT_VALID, NOT_VALID_CONNECTING_CASE, FINAL_CASE, + EAR_CASE, EXTERIOR_CASE, CONNECTING_CASE}; - //===================================================================== - //===================================================================== + //===================================================================== + //===================================================================== typedef const std::list > Boundary_range; typedef const std::list Vertex_on_boundary_range; -private: + private: mutable std::list > m_boundaries; - Timer postprocess_timer, extend_timer, extend2_timer, init_timer; + Timer postprocess_timer, extend_timer, extend2_timer, init_timer; - Triangulation_3& T; + Triangulation_3& T; Ordered_border_type _ordered_border; - int _number_of_border; + int _number_of_border; - const coord_type COS_ALPHA_SLIVER; - const coord_type COS_BETA; - coord_type DELTA; // = sampling quality of the border - coord_type K, min_K; - const coord_type eps; - const coord_type inv_eps_2; // 1/(eps^2) - const coord_type eps_3; // test de ^3 donc points tel 1e-7 soit petit - const criteria STANDBY_CANDIDATE; - const criteria STANDBY_CANDIDATE_BIS; - const criteria NOT_VALID_CANDIDATE; + const coord_type COS_ALPHA_SLIVER; + const coord_type COS_BETA; + coord_type DELTA; // = sampling quality of the border + coord_type K, min_K; + const coord_type eps; + const coord_type inv_eps_2; // 1/(eps^2) + const coord_type eps_3; // test de ^3 donc points tel 1e-7 soit petit + const criteria STANDBY_CANDIDATE; + const criteria STANDBY_CANDIDATE_BIS; + const criteria NOT_VALID_CANDIDATE; - //--------------------------------------------------------------------- - //Pour une visu correcte - //pour retenir les facettes selectionnees - int _vh_number; - int _facet_number; + //--------------------------------------------------------------------- + //Pour une visu correcte + //pour retenir les facettes selectionnees + int _vh_number; + int _facet_number; - //--------------------------------------------------------------------- - //Pour le post traitement - mutable int _postprocessing_counter; - int _size_before_postprocessing; + //--------------------------------------------------------------------- + //Pour le post traitement + mutable int _postprocessing_counter; + int _size_before_postprocessing; - std::list m_outliers; + std::list m_outliers; - int _number_of_connected_components; + int _number_of_connected_components; Vertex_handle added_vertex; bool deal_with_2d; @@ -286,23 +286,23 @@ private: std::list ist_pool; - Intern_successors_type* new_border() - { - nbe_pool.push_back(Next_border_elt()); + Intern_successors_type* new_border() + { + nbe_pool.push_back(Next_border_elt()); - Next_border_elt* p1 = & nbe_pool.back(); - nbe_pool.push_back(Next_border_elt()); - Next_border_elt* p2 = & nbe_pool.back(); + Next_border_elt* p1 = & nbe_pool.back(); + nbe_pool.push_back(Next_border_elt()); + Next_border_elt* p2 = & nbe_pool.back(); - Intern_successors_type ist(p1,p2); - ist_pool.push_back(ist); + Intern_successors_type ist(p1,p2); + ist_pool.push_back(ist); - Intern_successors_type* ret = &ist_pool.back(); + Intern_successors_type* ret = &ist_pool.back(); - ret->first->first = NULL; - ret->second->first = NULL; - return ret; - } + ret->first->first = NULL; + ret->second->first = NULL; + return ret; + } inline bool is_on_border(Vertex_handle vh, const int& i) const @@ -367,10 +367,10 @@ private: return r1; } - //------------------------------------------------------------------- - // pour gerer certaines aretes interieures: a savoir celle encore connectee au - // bord (en fait seule, les aretes interieures reliant 2 bords nous - // interressent...) + //------------------------------------------------------------------- + // pour gerer certaines aretes interieures: a savoir celle encore connectee au + // bord (en fait seule, les aretes interieures reliant 2 bords nous + // interressent...) inline void set_interior_edge(Vertex_handle w, Vertex_handle v) { @@ -417,7 +417,7 @@ private: } - //------------------------------------------------------------------- + //------------------------------------------------------------------- inline void set_incidence_request(Vertex_handle w, const Incidence_request_elt& ir) { @@ -432,7 +432,7 @@ private: } } - inline bool is_incidence_requested(Vertex_handle w) const + inline bool is_incidence_requested(Vertex_handle w) const { if(w->m_ir_last == sentinel ){ assert(w->m_ir_first == sentinel ); @@ -440,12 +440,12 @@ private: return (w->m_ir_last != sentinel ); } - inline Incidence_request_iterator incidence_request_begin(Vertex_handle w) + inline Incidence_request_iterator incidence_request_begin(Vertex_handle w) { return w->m_ir_first; } - inline Incidence_request_iterator incidence_request_end(Vertex_handle w) + inline Incidence_request_iterator incidence_request_end(Vertex_handle w) { if(w->m_ir_last != sentinel ){ assert(w->m_ir_first != sentinel ); @@ -456,7 +456,7 @@ private: return w->m_ir_last; } - inline void erase_incidence_request(Vertex_handle w) + inline void erase_incidence_request(Vertex_handle w) { if(w->m_ir_last != sentinel ){ assert(w->m_ir_first != sentinel ); @@ -491,7 +491,7 @@ private: - inline void dec_mark(Vertex_handle w) + inline void dec_mark(Vertex_handle w) { w->m_mark--; if(w->m_mark == 0) @@ -524,9 +524,9 @@ private: } } - //-------------------- DESTRUCTOR ----------------------------------- + //-------------------- DESTRUCTOR ----------------------------------- - void clear_vertex(Vertex_handle w) + void clear_vertex(Vertex_handle w) { if (w->m_incident_border != NULL) { @@ -558,15 +558,15 @@ private: } -public: + public: Advancing_front_surface_reconstruction(Triangulation_3& T_, const AFSR_options& opt = AFSR_options(), Reject reject = Reject()) : T(T_), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), COS_BETA(opt.COS_BETA), DELTA(opt.delta), min_K(HUGE_VAL), - eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), - STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), - NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), - _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), + eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), + STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), + NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), + _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), deal_with_2d(false), reject(reject) @@ -591,17 +591,17 @@ public: } } - /* - ~Advancing_front_surface_reconstruction() - { + /* + ~Advancing_front_surface_reconstruction() + { std::cerr << "postprocessing" << postprocess_timer.time() << std::endl; std::cerr << "extend " << extend_timer.time() << std::endl; std::cerr << "extend2 " << extend2_timer.time() << std::endl; std::cerr << "init " << postprocess_timer.time() << std::endl; std::cerr << "#outliers " << number_of_outliers() << std::endl; - } - */ + } + */ void run(double radius_ratio_bound=5, double beta=0.52) { @@ -620,1056 +620,1048 @@ public: return; } initialize_vertices_and_cells(); - bool re_init = false; - do - { - _number_of_connected_components++; + bool re_init = false; + do + { + _number_of_connected_components++; - if ( (re_init = init(re_init)) ) - { - //std::cerr << "Growing connected component " << _number_of_connected_components << std::endl; - extend_timer.start(); - extend(opt.K_init, opt.K_step, opt.K); - extend_timer.stop(); + if ( (re_init = init(re_init)) ) + { + //std::cerr << "Growing connected component " << _number_of_connected_components << std::endl; + extend_timer.start(); + extend(opt.K_init, opt.K_step, opt.K); + extend_timer.stop(); - if ((number_of_facets() > static_cast(T.number_of_vertices()))&& - (opt.NB_BORDER_MAX > 0)) - // en principe 2*nb_sommets = nb_facettes: y a encore de la marge!!! - { - while(postprocessing(opt.NB_BORDER_MAX)){ - extend2_timer.start(); - extend(opt.K_init, opt.K_step, opt.K); + if ((number_of_facets() > static_cast(T.number_of_vertices()))&& + (opt.NB_BORDER_MAX > 0)) + // en principe 2*nb_sommets = nb_facettes: y a encore de la marge!!! + { + while(postprocessing(opt.NB_BORDER_MAX)){ + extend2_timer.start(); + extend(opt.K_init, opt.K_step, opt.K); - extend2_timer.stop(); - } - } - } - }while(re_init && - ((_number_of_connected_components < opt.max_connected_comp)|| - (opt.max_connected_comp < 0))); + extend2_timer.stop(); + } + } + } + }while(re_init && + ((_number_of_connected_components < opt.max_connected_comp)|| + (opt.max_connected_comp < 0))); - _tds_2_inf = AFSR::construct_surface(_tds_2, *this); + _tds_2_inf = AFSR::construct_surface(_tds_2, *this); - boundaries(); - clear_vertices(); - } + boundaries(); + clear_vertices(); + } - typedef CGAL::Triangulation_data_structure_2, - AFSR::Surface_face_base_2 > TDS_2; + typedef CGAL::Triangulation_data_structure_2, + AFSR::Surface_face_base_2 > TDS_2; - typedef TDS_2 Triangulation_data_structure_2; + typedef TDS_2 Triangulation_data_structure_2; - mutable TDS_2 _tds_2; + mutable TDS_2 _tds_2; - mutable typename TDS_2::Vertex_handle _tds_2_inf; + mutable typename TDS_2::Vertex_handle _tds_2_inf; - const TDS_2& triangulation_data_structure_2() const - { - return _tds_2; - } + const TDS_2& triangulation_data_structure_2() const + { + return _tds_2; + } - bool - has_boundaries() const - { - return _tds_2_inf != typename TDS_2::Vertex_handle(); - } + bool + has_boundaries() const + { + return _tds_2_inf != typename TDS_2::Vertex_handle(); + } - bool has_on_surface(typename TDS_2::Vertex_handle vh) const - { - return vh != _tds_2_inf; - } + bool has_on_surface(typename TDS_2::Vertex_handle vh) const + { + return vh != _tds_2_inf; + } - bool has_on_surface(typename TDS_2::Face_handle fh) const - { - return fh->is_on_surface(); - } + bool has_on_surface(typename TDS_2::Face_handle fh) const + { + return fh->is_on_surface(); + } - bool has_on_surface(Facet fh) const - { - return fh.first->has_facet_on_surface(fh.second); - } - - - - int number_of_connected_components() const - { - return _number_of_connected_components; - } - - - Triangulation_3& - triangulation_3() const - { - return T; - } - - int number_of_facets() const - { - return _facet_number; - } - - int number_of_vertices() const - { - return _vh_number; - } - - int number_of_outliers() const - { - return static_cast(m_outliers.size()); - } - - typedef std::list Outlier_range; - - typedef typename std::list::const_iterator Outlier_iterator; - - const Outlier_range& outliers() const - { - return m_outliers; - } - - - Outlier_iterator outliers_begin() const - { - return m_outliers.begin(); - } - - Outlier_iterator m_outliers_end() const - { - return m_outliers.end(); - } - - typedef Advancing_front_surface_reconstruction_boundary_iterator Boundary_iterator; - - Boundary_iterator boundaries_begin() const - { - return Boundary_iterator(*this, next_mark()); - } - - Boundary_iterator boundaries_end() const - { - return Boundary_iterator(*this); - } - - const Boundary_range& boundaries() const - { - if(has_boundaries() && m_boundaries.empty()){ - Boundary_iterator b = boundaries_begin(); - Boundary_iterator e = boundaries_end(); - for(; b!= e; ++b){ - Vertex_handle v = *b; - std::list border; - m_boundaries.push_back(border); - do { - m_boundaries.back().push_back(*b); - ++b; - }while(*b != v); - } + bool has_on_surface(Facet fh) const + { + return fh.first->has_facet_on_surface(fh.second); } + + + + int number_of_connected_components() const + { + return _number_of_connected_components; + } + + + Triangulation_3& + triangulation_3() const + { + return T; + } + + + int number_of_facets() const + { + return _facet_number; + } + + + int number_of_vertices() const + { + return _vh_number; + } + + + int number_of_outliers() const + { + return static_cast(m_outliers.size()); + } + + + typedef std::list Outlier_range; + + typedef typename std::list::const_iterator Outlier_iterator; + + const Outlier_range& outliers() const + { + return m_outliers; + } + + + Outlier_iterator outliers_begin() const + { + return m_outliers.begin(); + } + + + Outlier_iterator m_outliers_end() const + { + return m_outliers.end(); + } + + + typedef Advancing_front_surface_reconstruction_boundary_iterator Boundary_iterator; + + Boundary_iterator boundaries_begin() const + { + return Boundary_iterator(*this, next_mark()); + } + + + Boundary_iterator boundaries_end() const + { + return Boundary_iterator(*this); + } + + + const Boundary_range& boundaries() const + { + if(has_boundaries() && m_boundaries.empty()){ + Boundary_iterator b = boundaries_begin(); + Boundary_iterator e = boundaries_end(); + for(; b!= e; ++b){ + Vertex_handle v = *b; + std::list border; + m_boundaries.push_back(border); + do { + m_boundaries.back().push_back(*b); + ++b; + }while(*b != v); + } + } - return m_boundaries; - } + return m_boundaries; + } - int next_mark() const - { - _postprocessing_counter++; - return _postprocessing_counter; - } + int next_mark() const + { + _postprocessing_counter++; + return _postprocessing_counter; + } - - Next_border_elt* border_elt(const Vertex_handle& v1, const Vertex_handle& v2) const - { - return v1->border_elt(v2); - } - - //public - - IO_edge_type* border_IO_elt(const Vertex_handle& v1, const Vertex_handle& v2) - { - return &border_elt(v1,v2)->second.first.second; - } - - IO_edge_type* set_border_elt(const Vertex_handle& v1, const Vertex_handle& v2, - const Border_elt& e) - { - v1->set_next_border_elt(Next_border_elt (v2, e)); - return border_IO_elt(v1, v2); - } + Next_border_elt* border_elt(const Vertex_handle& v1, const Vertex_handle& v2) const + { + return v1->border_elt(v2); + } - IO_edge_type* set_again_border_elt(const Vertex_handle& v1, const Vertex_handle& v2, - const Border_elt& e) - { - border_elt(v1,v2)->second = e; - return border_IO_elt(v1, v2); - } + //public - //--------------------------------------------------------------------- + IO_edge_type* border_IO_elt(const Vertex_handle& v1, const Vertex_handle& v2) + { + return &border_elt(v1,v2)->second.first.second; + } - bool is_border_elt(Edge_like& key, Border_elt& result) const - { - Next_border_elt* it12 = border_elt(key.first, key.second); - if (it12 != NULL) - { - result = it12->second; - return true; - } - Next_border_elt* it21 = border_elt(key.second, key.first); - if (it21 != NULL) - { - result = it21->second; - std::swap(key.first, key.second); - return true; - } - return false; - } + IO_edge_type* set_border_elt(const Vertex_handle& v1, const Vertex_handle& v2, + const Border_elt& e) + { + v1->set_next_border_elt(Next_border_elt (v2, e)); + return border_IO_elt(v1, v2); + } - //--------------------------------------------------------------------- - bool is_border_elt(Edge_like& key) const { - Next_border_elt* it12 = border_elt(key.first, key.second); - if (it12 != NULL) - { - return true; - } - Next_border_elt* it21 = border_elt(key.second, key.first); - if (it21 != NULL) - { - std::swap(key.first, key.second); - return true; - } - return false; - } - //--------------------------------------------------------------------- + IO_edge_type* set_again_border_elt(const Vertex_handle& v1, const Vertex_handle& v2, + const Border_elt& e) + { + border_elt(v1,v2)->second = e; + return border_IO_elt(v1, v2); + } - bool is_ordered_border_elt(const Edge_like& key, Border_elt& result) const - { - Next_border_elt* it12 = border_elt(key.first, key.second); - if (it12 != NULL) - { - result = it12->second; - return true; - } - return false; - } + //--------------------------------------------------------------------- + bool is_border_elt(Edge_like& key, Border_elt& result) const + { + Next_border_elt* it12 = border_elt(key.first, key.second); + if (it12 != NULL) + { + result = it12->second; + return true; + } - //--------------------------------------------------------------------- + Next_border_elt* it21 = border_elt(key.second, key.first); + if (it21 != NULL) + { + result = it21->second; + std::swap(key.first, key.second); + return true; + } + return false; + } - void - remove_border_elt(const Edge_like& ordered_key) - { - remove_border_edge(ordered_key.first, ordered_key.second); - } + //--------------------------------------------------------------------- + bool is_border_elt(Edge_like& key) const { + Next_border_elt* it12 = border_elt(key.first, key.second); + if (it12 != NULL) + { + return true; + } - //--------------------------------------------------------------------- + Next_border_elt* it21 = border_elt(key.second, key.first); + if (it21 != NULL) + { + std::swap(key.first, key.second); + return true; + } + return false; + } - bool is_ordered_border_elt(const Edge_like& e, - IO_edge_type* &ptr) const - { - Vertex_handle v1 = e.first; + //--------------------------------------------------------------------- + bool is_ordered_border_elt(const Edge_like& key, Border_elt& result) const + { + Next_border_elt* it12 = border_elt(key.first, key.second); + if (it12 != NULL) + { + result = it12->second; + return true; + } + return false; + } - Next_border_elt* it12 = border_elt(v1, e.second); - if (it12 != NULL) - { - ptr = &it12->second.first.second; - return true; - } - return false; - } + //--------------------------------------------------------------------- + void + remove_border_elt(const Edge_like& ordered_key) + { + remove_border_edge(ordered_key.first, ordered_key.second); + } - //--------------------------------------------------------------------- - void set_incidence_request(const Vertex_handle& v, - const criteria& value, - const Edge_like& e) - { - Incidence_request_elt incident_elt(value, e); - set_incidence_request(v, incident_elt); - } + //--------------------------------------------------------------------- + bool is_ordered_border_elt(const Edge_like& e, + IO_edge_type* &ptr) const + { + Vertex_handle v1 = e.first; - //--------------------------------------------------------------------- + Next_border_elt* it12 = border_elt(v1, e.second); + if (it12 != NULL) + { + ptr = &it12->second.first.second; + return true; + } + return false; + } - bool is_interior_edge(const Edge_like& key) const + //--------------------------------------------------------------------- + void set_incidence_request(const Vertex_handle& v, + const criteria& value, + const Edge_like& e) + { + Incidence_request_elt incident_elt(value, e); + set_incidence_request(v, incident_elt); + } + + //--------------------------------------------------------------------- + bool is_interior_edge(const Edge_like& key) const // pour gerer certaines aretes interieures: a savoir celle encore connectee au // bord (en fait seule, les aretes interieures reliant 2 bords nous // interressent...) - { - return (is_interior_edge(key.first, key.second)|| - is_interior_edge(key.second, key.first)); - } - - //--------------------------------------------------------------------- + { + return (is_interior_edge(key.first, key.second)|| + is_interior_edge(key.second, key.first)); + } + //--------------------------------------------------------------------- #ifdef AFSR_LAZY - coord_type lazy_squared_radius(const Cell_handle& c) - { - if (c->lazy_squared_radius() != NULL) + coord_type lazy_squared_radius(const Cell_handle& c) + { + if (c->lazy_squared_radius() != NULL) + return *(c->lazy_squared_radius()); + + c->set_lazy_squared_radius + (squared_radius(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point())); return *(c->lazy_squared_radius()); + } - c->set_lazy_squared_radius - (squared_radius(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point())); - return *(c->lazy_squared_radius()); - } + Point lazy_circumcenter(const Cell_handle& c) + { + if (c->lazy_circumcenter() != NULL) + return *(c->lazy_circumcenter()); - Point lazy_circumcenter(const Cell_handle& c) - { - if (c->lazy_circumcenter() != NULL) + c->set_lazy_circumcenter + (circumcenter(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point())); return *(c->lazy_circumcenter()); - - c->set_lazy_circumcenter - (circumcenter(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point())); - return *(c->lazy_circumcenter()); - } + } #endif //NOLAZY - //--------------------------------------------------------------------- - - Edge_incident_facet next(const Edge_incident_facet& e) const - { - Cell_handle c = e.first.first; - int i = e.second; - int i1 = e.first.second, i2 = e.first.third; - int i3 = (6 - e.second - i1 - i2); + //--------------------------------------------------------------------- + Edge_incident_facet next(const Edge_incident_facet& e) const + { + Cell_handle c = e.first.first; + int i = e.second; + int i1 = e.first.second, i2 = e.first.third; + int i3 = (6 - e.second - i1 - i2); - Cell_handle n = c->neighbor(i); - int j1 = n->index(c->vertex(i1)), j2 = n->index(c->vertex(i2)); - int j = n->index(c->vertex(i3)); - return Edge_incident_facet(Edge(n, j1, j2), j); - } - - //--------------------------------------------------------------------- - - Edge_incident_facet previous(const Edge_incident_facet& e) const - { - Cell_handle c = e.first.first; - int i = e.second; - int i1 = e.first.second, i2 = e.first.third; - int i3 = (6 - e.second - i1 - i2); - - Cell_handle n = c->neighbor(i3); - int j1 = n->index(c->vertex(i1)), j2 = n->index(c->vertex(i2)); - int j = n->index(c->vertex(i)); - return Edge_incident_facet(Edge(n, j1, j2), j); - } - - //--------------------------------------------------------------------- - - bool - my_coplanar(const Point& p, const Point& q, - const Point& r, const Point& s) const - { - coord_type qpx = q.x()-p.x(); - coord_type qpy = q.y()-p.y(); - coord_type qpz = q.z()-p.z(); - coord_type rpx = r.x()-p.x(); - coord_type rpy = r.y()-p.y(); - coord_type rpz = r.z()-p.z(); - coord_type spx = s.x()-p.x(); - coord_type spy = s.y()-p.y(); - coord_type spz = s.z()-p.z(); - - coord_type den = CGAL::determinant(qpx,qpy,qpz, - rpx,rpy,rpz, - spx,spy,spz); - return (CGAL_NTS abs(den) < eps_3); - } - - //--------------------------------------------------------------------- - - - bool - my_collinear(const Point& p, const Point& q, const Point& s) const - { - coord_type psx = p.x()-s.x(); - coord_type psy = p.y()-s.y(); - coord_type psz = p.z()-s.z(); - coord_type qsx = q.x()-s.x(); - coord_type qsy = q.y()-s.y(); - coord_type qsz = q.z()-s.z(); - coord_type rsx = psy*qsz-psz*qsy; - coord_type rsy = psz*qsx-psx*qsz; - coord_type rsz = psx*qsy-psy*qsx; - - coord_type den = CGAL::determinant(psx,psy,psz, - qsx,qsy,qsz, - rsx,rsy,rsz); - - return (CGAL_NTS abs(den) < eps_3); - } - - //--------------------------------------------------------------------- - - void - select_facet(const Cell_handle& c, const int& i) - { - c->select_facet(i); - _facet_number++; - c->set_facet_number(i, _facet_number); - } - - - void - unselect_facet(const Cell_handle& c, const int& i) - { - c->unselect_facet(i); - } - - int number_of_border_edges() - { - int _border_count(0); - for(Finite_edges_iterator e_it=T.finite_edges_begin(); - e_it!=T.finite_edges_end(); - e_it++) - { - Cell_handle c = (*e_it).first; - int i1 = (*e_it).second, i2 = (*e_it).third; - Edge_like key(c->vertex(i1), c->vertex(i2)); - - if (is_border_elt(key)) - _border_count++; - } - return _border_count; - } - - - - - //===================================================================== - - coord_type smallest_radius_delaunay_sphere(const Cell_handle& c, - const int& index) const - { - int i1, i2, i3; - - if(deal_with_2d && ( (c->vertex((index+1) & 3) == added_vertex) - || (c->vertex((index+2) & 3) == added_vertex) - || (c->vertex((index+3) & 3) == added_vertex) )) - { - return HUGE_VAL; - } - Cell_handle n = c->neighbor(index); - // lazy evaluation ... - coord_type value = c->smallest_radius(index); - if ((value >= 0)&&(n->smallest_radius(n->index(c)) == value)) - return value; - - const Point& cp0 = c->vertex(index)->point(); - const Point& cp1 = c->vertex((index+1) & 3)->point(); - const Point& cp2 = c->vertex((index+2) & 3)->point(); - const Point& cp3 = c->vertex((index+3) & 3)->point(); - - const Point& np0 = n->vertex(0)->point(); - const Point& np1 = n->vertex(1)->point(); - const Point& np2 = n->vertex(2)->point(); - const Point& np3 = n->vertex(3)->point(); - - bool c_is_plane(my_coplanar(cp0, cp1, cp2, cp3)); - bool n_is_plane(my_coplanar(np0, np1, np2, np3)); - - bool c_is_infinite(T.is_infinite(c)); - bool n_is_infinite(T.is_infinite(n)); - if ((c_is_plane && n_is_plane)|| - (c_is_plane && n_is_infinite)|| - (n_is_plane && c_is_infinite)|| - my_collinear(cp1, cp2, cp3)) - value = HUGE_VAL; - else - { - if (c_is_infinite||n_is_infinite||c_is_plane||n_is_plane) - { - int ind; - Cell_handle cc; - if(c_is_infinite||c_is_plane) - { - cc = n; - ind = n->index(c); - } - else - { - cc = c; - ind = index; - } - i1 = (ind+1) & 3; - i2 = (ind+2) & 3; - i3 = (ind+3) & 3; - - const Point& pp0 = cc->vertex(ind)->point(); - const Point& pp1 = cc->vertex(i1)->point(); - const Point& pp2 = cc->vertex(i2)->point(); - const Point& pp3 = cc->vertex(i3)->point(); - - Sphere facet_sphere(pp1, pp2, pp3); - if (squared_distance(facet_sphere.center(), pp0) < - facet_sphere.squared_radius()) - { -#ifdef AFSR_LAZY - value = lazy_squared_radius(cc); -#else - value = squared_radius(pp0, pp1, pp2, pp3); -#endif - } - else - value = facet_sphere.squared_radius(); - } - else - { - Point cc, cn; -#ifdef AFSR_LAZY - cc = lazy_circumcenter(c); - cn = lazy_circumcenter(n); -#else - cc = circumcenter(cp0, cp1, cp2, cp3); - cn = circumcenter(np0, np1, np2, np3); -#endif - // computation of the distance of cp1 to the dual segment cc, cn... - Vector V(cc - cn), Vc(cc - cp1), Vn(cp1 - cn); - coord_type ac(V * Vc), an(V * Vn), norm_V(V * V); - if ((ac > 0) && (an > 0)) - { - value = (Vc*Vc) - ac*ac/norm_V; - if ((value < 0)||(norm_V > inv_eps_2)) - value = squared_radius(cp1, cp2, cp3); - } - else - { - if (ac <= 0) - value = squared_distance(cc, cp1); - else // (an <= 0) - value = squared_distance(cn, cp1); - } - } - } - // cache computed values - c->set_smallest_radius(index, value); - n->set_smallest_radius(n->index(c), value); - - return value; - } - - - //--------------------------------------------------------------------- - // For a border edge e we determine the incident facet which has the highest - // chance to be a natural extension of the surface - - Radius_edge_type compute_value(const Edge_incident_facet& e) - { - Cell_handle c = e.first.first; - int i = e.second; - int i1 = e.first.second, i2 = e.first.third; - int i3 = 6 - e.second - i1 - i2; - - Edge_incident_facet e_it = e, predone = previous(e); - Cell_handle c_predone = predone.first.first; - - coord_type min_valueP = NOT_VALID_CANDIDATE, min_valueA = HUGE_VAL; - Facet min_facet, min_facetA; - bool border_facet(false); - - coord_type pscal; - const Point& p1 = c->vertex(i1)->point(); - const Point& p2 = c->vertex(i2)->point(); - const Point& pc = c->vertex(i3)->point(); - - Vector P2P1 = p1-p2, P2Pn, PnP1; - - Vector v2, v1 = cross_product(pc-p2, P2P1); - - coord_type norm, norm1 = v1*v1; - coord_type norm12 = P2P1*P2P1; - - e_it = next(e_it); - bool succ_start(true); - - do - { - Cell_handle neigh = e_it.first.first; - Facet facet_it(neigh, e_it.second); - - if (!T.is_infinite(facet_it)) - { - int n_ind = facet_it.second; - int n_i1 = e_it.first.second; - int n_i2 = e_it.first.third; - int n_i3 = 6 - n_ind - n_i1 - n_i2; - - coord_type tmp=0; - - // If the triangle has a high perimeter, - // we do not want to consider it as a good candidate. - - if(reject(facet_it.first->vertex(n_i1)->point(), - facet_it.first->vertex(n_i2)->point(), - facet_it.first->vertex(n_i3)->point())){ - tmp = HUGE_VAL; - } - - - if(tmp != HUGE_VAL){ - tmp = smallest_radius_delaunay_sphere(neigh, n_ind); - } - - Edge_like el1(neigh->vertex(n_i1),neigh->vertex(n_i3)), - el2(neigh->vertex(n_i2),neigh->vertex(n_i3)); - - if ((tmp != HUGE_VAL)&& - neigh->vertex(n_i3)->not_interior()&& - (!is_interior_edge(el1))&&(!is_interior_edge(el2))) - { - const Point& pn = neigh->vertex(n_i3)->point(); - - P2Pn = pn-p2; - v2 = cross_product(P2P1,P2Pn); - - //pas necessaire de normer pour un bon echantillon: - // on peut alors tester v1*v2 >= 0 - norm = sqrt(norm1 * (v2*v2)); - pscal = v1*v2; - // check if the triangle will produce a sliver on the surface - bool sliver_facet = ((succ_start || (neigh == c_predone))&& - (pscal <= COS_ALPHA_SLIVER*norm)); - - if (succ_start) succ_start = false; - - if (!sliver_facet) - { - if (tmp < min_valueA) - { - PnP1 = p1-pn; - // DELTA represente la qualite d'echantillonnage du bord - // We skip triangles having an internal angle along e - // whose cosinus is smaller than -DELTA - // that is the angle is larger than arcos(-DELTA) - border_facet = !((P2P1*P2Pn >= - -DELTA*sqrt(norm12*(P2Pn*P2Pn)))&& - (P2P1*PnP1 >= - -DELTA*sqrt(norm12*(PnP1*PnP1)))); - /// \todo investigate why we simply do not skip this triangle - /// but continue looking for a better candidate - /// if (!border_facet){ - min_facetA = facet_it; - min_valueA = tmp; - min_valueP = pscal/norm; - ///} - } - } - } - } - e_it = next(e_it); - } - while(e_it.first.first != c); - - criteria value; - - if ((min_valueA == HUGE_VAL) || border_facet) // bad facets case - { - min_facet = Facet(c, i); // !!! sans aucune signification.... - value = NOT_VALID_CANDIDATE; // Attention a ne pas inserer dans PQ - } - else - { - min_facet = min_facetA; - - //si on considere seulement la pliure value appartient a [0, 2] - //value = coord_type(1) - min_valueP; - - // si la pliure est bonne on note suivant le alpha sinon on prend en compte la - // pliure seule... pour discriminer entre les bons slivers... - // si on veut discriminer les facettes de bonnes pliures plus finement - // alors -(1+1/min_valueA) app a [-inf, -1] - // -min_valueP app a [-1, 1] - - if (min_valueP > COS_BETA) - value = -(coord_type(1) + coord_type(1)/min_valueA); - else - { - //on refuse une trop grande non-uniformite - coord_type tmp = smallest_radius_delaunay_sphere(c, i); - if (min_valueA <= K * tmp) - value = - min_valueP; - else - { - value = STANDBY_CANDIDATE; // tres mauvais candidat mauvaise pliure - // + grand alpha... a traiter plus tard.... - min_K = - (std::min)(min_K, - min_valueA/tmp); - } - } - } - - Cell_handle n = min_facet.first; - int ni1 = n->index(c->vertex(i1)), ni2 = n->index(c->vertex(i2)); - - return - Radius_edge_type(value, IO_edge_type(e, Edge_incident_facet - (Edge(n, ni1, ni2), - min_facet.second))); - } - - //===================================================================== - //===================================================================== - - // The parameter re_init is false the first time only - // Returns true, iff it found a face where the next surface can grow - bool - init(const bool& re_init) - { - init_timer.start(); - Facet min_facet; - coord_type min_value = HUGE_VAL; - int i1, i2, i3; - - if (!re_init){ - Finite_facets_iterator end = T.finite_facets_end(); - for(Finite_facets_iterator facet_it = T.finite_facets_begin(); - facet_it != end; - ++facet_it) - { - coord_type value = smallest_radius_delaunay_sphere((*facet_it).first, - (*facet_it).second); - if (value < min_value) - { - min_facet = *facet_it; - min_value = value; - } - } - }else{ //if (re_init) - Finite_facets_iterator end = T.finite_facets_end(); - for(Finite_facets_iterator facet_it = T.finite_facets_begin(); - facet_it != end; - ++facet_it) - { - Cell_handle c = (*facet_it).first; - int index = (*facet_it).second; - if (c->vertex((index+1) & 3)->is_exterior()) - if (c->vertex((index+2) & 3)->is_exterior()) - if (c->vertex((index+3) & 3)->is_exterior()) - { - coord_type value = smallest_radius_delaunay_sphere(c, index); - - // we might not want the triangle, for example because it is too large - if(reject(c->vertex((index+1)&3)->point(), - c->vertex((index+2)&3)->point(), - c->vertex((index+3)&3)->point())){ - value = min_value; - } - - if (value < min_value) - { - min_facet = *facet_it; - min_value = value; - } - } - } + Cell_handle n = c->neighbor(i); + int j1 = n->index(c->vertex(i1)), j2 = n->index(c->vertex(i2)); + int j = n->index(c->vertex(i3)); + return Edge_incident_facet(Edge(n, j1, j2), j); } - if (min_value != HUGE_VAL) - { - Cell_handle c_min = min_facet.first; + //--------------------------------------------------------------------- + Edge_incident_facet previous(const Edge_incident_facet& e) const + { + Cell_handle c = e.first.first; + int i = e.second; + int i1 = e.first.second, i2 = e.first.third; + int i3 = (6 - e.second - i1 - i2); + + Cell_handle n = c->neighbor(i3); + int j1 = n->index(c->vertex(i1)), j2 = n->index(c->vertex(i2)); + int j = n->index(c->vertex(i)); + return Edge_incident_facet(Edge(n, j1, j2), j); + } + + //--------------------------------------------------------------------- + bool + my_coplanar(const Point& p, const Point& q, + const Point& r, const Point& s) const + { + coord_type qpx = q.x()-p.x(); + coord_type qpy = q.y()-p.y(); + coord_type qpz = q.z()-p.z(); + coord_type rpx = r.x()-p.x(); + coord_type rpy = r.y()-p.y(); + coord_type rpz = r.z()-p.z(); + coord_type spx = s.x()-p.x(); + coord_type spy = s.y()-p.y(); + coord_type spz = s.z()-p.z(); + + coord_type den = CGAL::determinant(qpx,qpy,qpz, + rpx,rpy,rpz, + spx,spy,spz); + return (CGAL_NTS abs(den) < eps_3); + } + + //--------------------------------------------------------------------- + bool + my_collinear(const Point& p, const Point& q, const Point& s) const + { + coord_type psx = p.x()-s.x(); + coord_type psy = p.y()-s.y(); + coord_type psz = p.z()-s.z(); + coord_type qsx = q.x()-s.x(); + coord_type qsy = q.y()-s.y(); + coord_type qsz = q.z()-s.z(); + coord_type rsx = psy*qsz-psz*qsy; + coord_type rsy = psz*qsx-psx*qsz; + coord_type rsz = psx*qsy-psy*qsx; + + coord_type den = CGAL::determinant(psx,psy,psz, + qsx,qsy,qsz, + rsx,rsy,rsz); + + return (CGAL_NTS abs(den) < eps_3); + } + + //--------------------------------------------------------------------- + void + select_facet(const Cell_handle& c, const int& i) + { + c->select_facet(i); + _facet_number++; + c->set_facet_number(i, _facet_number); + } + + + void + unselect_facet(const Cell_handle& c, const int& i) + { + c->unselect_facet(i); + } + + + int + number_of_border_edges() + { + int _border_count(0); + for(Finite_edges_iterator e_it=T.finite_edges_begin(); + e_it!=T.finite_edges_end(); + e_it++) + { + Cell_handle c = (*e_it).first; + int i1 = (*e_it).second, i2 = (*e_it).third; + Edge_like key(c->vertex(i1), c->vertex(i2)); + + if (is_border_elt(key)) + _border_count++; + } + return _border_count; + } + + + //===================================================================== + coord_type + smallest_radius_delaunay_sphere(const Cell_handle& c, + const int& index) const + { + int i1, i2, i3; + + if(deal_with_2d && ( (c->vertex((index+1) & 3) == added_vertex) + || (c->vertex((index+2) & 3) == added_vertex) + || (c->vertex((index+3) & 3) == added_vertex) )) + { + return HUGE_VAL; + } + Cell_handle n = c->neighbor(index); + // lazy evaluation ... + coord_type value = c->smallest_radius(index); + if ((value >= 0)&&(n->smallest_radius(n->index(c)) == value)) + return value; + + const Point& cp0 = c->vertex(index)->point(); + const Point& cp1 = c->vertex((index+1) & 3)->point(); + const Point& cp2 = c->vertex((index+2) & 3)->point(); + const Point& cp3 = c->vertex((index+3) & 3)->point(); + + const Point& np0 = n->vertex(0)->point(); + const Point& np1 = n->vertex(1)->point(); + const Point& np2 = n->vertex(2)->point(); + const Point& np3 = n->vertex(3)->point(); + + bool c_is_plane(my_coplanar(cp0, cp1, cp2, cp3)); + bool n_is_plane(my_coplanar(np0, np1, np2, np3)); + + bool c_is_infinite(T.is_infinite(c)); + bool n_is_infinite(T.is_infinite(n)); + if ((c_is_plane && n_is_plane)|| + (c_is_plane && n_is_infinite)|| + (n_is_plane && c_is_infinite)|| + my_collinear(cp1, cp2, cp3)) + value = HUGE_VAL; + else + { + if (c_is_infinite||n_is_infinite||c_is_plane||n_is_plane) + { + int ind; + Cell_handle cc; + if(c_is_infinite||c_is_plane) + { + cc = n; + ind = n->index(c); + } + else + { + cc = c; + ind = index; + } + i1 = (ind+1) & 3; + i2 = (ind+2) & 3; + i3 = (ind+3) & 3; - int ind = min_facet.second; - i1 = (ind+1) & 3; - i2 = (ind+2) & 3; - i3 = (ind+3) & 3; + const Point& pp0 = cc->vertex(ind)->point(); + const Point& pp1 = cc->vertex(i1)->point(); + const Point& pp2 = cc->vertex(i2)->point(); + const Point& pp3 = cc->vertex(i3)->point(); - Radius_edge_type e12, e23, e31; + Sphere facet_sphere(pp1, pp2, pp3); + if (squared_distance(facet_sphere.center(), pp0) < + facet_sphere.squared_radius()) + { +#ifdef AFSR_LAZY + value = lazy_squared_radius(cc); +#else + value = squared_radius(pp0, pp1, pp2, pp3); +#endif + } + else + value = facet_sphere.squared_radius(); + } + else + { + Point cc, cn; +#ifdef AFSR_LAZY + cc = lazy_circumcenter(c); + cn = lazy_circumcenter(n); +#else + cc = circumcenter(cp0, cp1, cp2, cp3); + cn = circumcenter(np0, np1, np2, np3); +#endif + // computation of the distance of cp1 to the dual segment cc, cn... + Vector V(cc - cn), Vc(cc - cp1), Vn(cp1 - cn); + coord_type ac(V * Vc), an(V * Vn), norm_V(V * V); + if ((ac > 0) && (an > 0)) + { + value = (Vc*Vc) - ac*ac/norm_V; + if ((value < 0)||(norm_V > inv_eps_2)) + value = squared_radius(cp1, cp2, cp3); + } + else + { + if (ac <= 0) + value = squared_distance(cc, cp1); + else // (an <= 0) + value = squared_distance(cn, cp1); + } + } + } + // cache computed values + c->set_smallest_radius(index, value); + n->set_smallest_radius(n->index(c), value); - e12 = compute_value(Edge_incident_facet(Edge(c_min, i1, i2), ind)); - e23 = compute_value(Edge_incident_facet(Edge(c_min, i2, i3), ind)); - e31 = compute_value(Edge_incident_facet(Edge(c_min, i3, i1), ind)); + return value; + } - IO_edge_type* p12 = set_border_elt(c_min->vertex(i1), c_min->vertex(i2), - Border_elt(e12, _number_of_border)); - IO_edge_type* p23 = set_border_elt(c_min->vertex(i2), c_min->vertex(i3), - Border_elt(e23, _number_of_border)); - IO_edge_type* p31 = set_border_elt(c_min->vertex(i3), c_min->vertex(i1), - Border_elt(e31, _number_of_border)); + + //--------------------------------------------------------------------- + // For a border edge e we determine the incident facet which has the highest + // chance to be a natural extension of the surface + + Radius_edge_type + compute_value(const Edge_incident_facet& e) + { + Cell_handle c = e.first.first; + int i = e.second; + int i1 = e.first.second, i2 = e.first.third; + int i3 = 6 - e.second - i1 - i2; + + Edge_incident_facet e_it = e, predone = previous(e); + Cell_handle c_predone = predone.first.first; + + coord_type min_valueP = NOT_VALID_CANDIDATE, min_valueA = HUGE_VAL; + Facet min_facet, min_facetA; + bool border_facet(false); + + coord_type pscal; + const Point& p1 = c->vertex(i1)->point(); + const Point& p2 = c->vertex(i2)->point(); + const Point& pc = c->vertex(i3)->point(); - c_min->vertex(i1)->inc_mark(); - c_min->vertex(i2)->inc_mark(); - c_min->vertex(i3)->inc_mark(); - _ordered_border.insert(Radius_ptr_type (e12.first, p12)); - _ordered_border.insert(Radius_ptr_type (e23.first, p23)); - _ordered_border.insert(Radius_ptr_type (e31.first, p31)); + Vector P2P1 = p1-p2, P2Pn, PnP1; - select_facet(c_min, ind); - init_timer.stop(); - return true; - } - init_timer.stop(); - return false; - } + Vector v2, v1 = cross_product(pc-p2, P2P1); - //--------------------------------------------------------------------- - // test de reciprocite avant de recoller une oreille anti-singularite - int - test_merge(const Edge_like& ordered_key, const Border_elt& result, - const Vertex_handle& v, const coord_type& ear_alpha) - { - Edge_incident_facet Ifacet = result.first.second.first; + coord_type norm, norm1 = v1*v1; + coord_type norm12 = P2P1*P2P1; + + e_it = next(e_it); + bool succ_start(true); - const Point& p1 = (ordered_key.first)->point(); - const Point& p2 = (ordered_key.second)->point(); - const Point& pc = v->point(); + do + { + Cell_handle neigh = e_it.first.first; + Facet facet_it(neigh, e_it.second); - Cell_handle neigh = Ifacet.first.first; - int n_ind = Ifacet.second; - int n_i1 = Ifacet.first.second; - int n_i2 = Ifacet.first.third; - int n_i3 = (6 - n_ind - n_i1 - n_i2); + if (!T.is_infinite(facet_it)) + { + int n_ind = facet_it.second; + int n_i1 = e_it.first.second; + int n_i2 = e_it.first.third; + int n_i3 = 6 - n_ind - n_i1 - n_i2; - const Point& pn = neigh->vertex(n_i3)->point(); - Vector v1 = cross_product(pc-p2,p1-p2), - v2 = cross_product(p1-p2,pn-p2); - coord_type norm = sqrt((v1*v1)*(v2*v2)); - - if (v1*v2 > COS_BETA*norm) - return 1; // label bonne pliure sinon: - - if (ear_alpha <= K*smallest_radius_delaunay_sphere(neigh, n_ind)) - return 2; // label alpha coherent... - - return 0; //sinon oreille a rejeter... - } - - - //--------------------------------------------------------------------- - - void - ordered_map_erase(const criteria& value, const IO_edge_type* pkey) - { - _ordered_border.erase(Radius_ptr_type(value,(IO_edge_type*)pkey)); - } - - //--------------------------------------------------------------------- - - void - force_merge(const Edge_like& ordered_key, const Border_elt& result) - { - criteria value = result.first.first; - IO_edge_type* pkey = border_IO_elt(ordered_key.first, ordered_key.second); - - ordered_map_erase(value, pkey); - - remove_border_elt(ordered_key); - } - - //--------------------------------------------------------------------- - - void dequeue_incidence_request(const Vertex_handle& v) - { - if (is_incidence_requested(v)) - { - for(Incidence_request_iterator v_it = incidence_request_begin(v); - v_it != incidence_request_end(v); - v_it++) - { - IO_edge_type* ptr; - - if (is_ordered_border_elt(v_it->second, ptr)) - _ordered_border.insert(Radius_ptr_type(v_it->first, ptr)); - } - erase_incidence_request(v); - } - } - - - //--------------------------------------------------------------------- - - void - merge_ear(const Edge_like& ordered_el1, const Border_elt& result1, - const Edge_like& ordered_key, - const Vertex_handle& v1, const Vertex_handle& v2, - const Edge_incident_facet& edge_Ifacet_2) - { - remove_border_elt(ordered_key); - force_merge(ordered_el1, result1); - Radius_edge_type e2 = compute_value(edge_Ifacet_2); - IO_edge_type* p2; - if (ordered_el1.first == v1) - p2 = set_border_elt(v2, ordered_el1.second, - Border_elt(e2,result1.second)); - else - p2 = set_border_elt(ordered_el1.first, v2, - Border_elt(e2,result1.second)); - dec_mark(v1); - - _ordered_border.insert(Radius_ptr_type(e2.first, p2)); - - //depiler les eventuelles requettes de connections avortees... zones etoilees, - //en effet le bord a change donc on peut peut etre maintenant. - dequeue_incidence_request(v2); - if (ordered_el1.first == v1) - dequeue_incidence_request(ordered_el1.second); - else - dequeue_incidence_request(ordered_el1.first); - } - - //--------------------------------------------------------------------- - - void - border_extend(const Edge_like& ordered_key, const Border_elt& result12, - const Vertex_handle& v1, const Vertex_handle& v2, - const Vertex_handle& v3, - const Radius_edge_type& e1, const Radius_edge_type& e2, - IO_edge_type* &p1, IO_edge_type* &p2) - { - remove_border_elt(ordered_key); - - //depiler v3 avant de le mettre a jour... pour reperer s'il est sur un bord - if (v3->is_on_border()) - dequeue_incidence_request(v3); - - if (ordered_key.first == v1) - { - p1 = set_border_elt(v1, v3, Border_elt(e1,result12.second)); - p2 = set_border_elt(v3, v2, Border_elt(e2,result12.second)); - } - else - { - p2 = set_border_elt(v2, v3, Border_elt(e2,result12.second)); - p1 = set_border_elt(v3, v1, Border_elt(e1,result12.second)); - } - - v3->inc_mark(); - - //depiler les eventuelles requettes de connections avortees... zones etoilees, - //en effet le bord a change donc on peut peut etre maintenant. - dequeue_incidence_request(v1); - dequeue_incidence_request(v2); - } - - //===================================================================== - - Validation_case - validate(const Edge_incident_facet& edge_Efacet, - const criteria& value) - { - int i = (6 - edge_Efacet.second - - edge_Efacet.first.second - - edge_Efacet.first.third); - Cell_handle c = edge_Efacet.first.first; - - Vertex_handle v1 = c->vertex(edge_Efacet.first.second), - v2 = c->vertex(edge_Efacet.first.third); - - Edge_like ordered_el1(c->vertex(i), v1); - Edge_like ordered_el2(c->vertex(i), v2); - Border_elt result1, result2, result12; - - Edge_like ordered_key(v1,v2); - - if (!is_border_elt(ordered_key, result12)) - std::cerr << "+++probleme coherence bord " << std::endl; - - bool is_border_el1 = is_border_elt(ordered_el1, result1), - is_border_el2 = is_border_elt(ordered_el2, result2); - - Radius_edge_type e1, e2; - if (c->vertex(i)->not_interior()) - { - if ((!is_interior_edge(ordered_el1))&& - (!is_interior_edge(ordered_el2))) - { - //toujours utile meme avec l'essai de try_to_close_border avant - //validate pour la resolution de singularite par oreille qui elle - //doit etre dans Delaunay. - if (is_border_el1&&is_border_el2) - { - remove_border_elt(ordered_key); - force_merge(ordered_el1, result1); - force_merge(ordered_el2, result2); - - dec_mark(v1); - dec_mark(v2); - dec_mark(c->vertex(i)); - - select_facet(c, edge_Efacet.second); - - return FINAL_CASE; - } - //--------------------------------------------------------------------- - //on peut alors marquer v1 et on pourrait essayer de merger - //sans faire de calcul inutile??? - if (is_border_el1) - { - Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), - edge_Efacet.second); - merge_ear(ordered_el1, result1, - ordered_key, v1, v2, edge_Ifacet_2); - - select_facet(c, edge_Efacet.second); - - return EAR_CASE; - } - //--------------------------------------------------------------------- - //idem pour v2 - if (is_border_el2) - { - Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), - edge_Efacet.second); - merge_ear(ordered_el2, result2, - ordered_key, v2, v1, edge_Ifacet_1); - select_facet(c, edge_Efacet.second); - - return EAR_CASE; - } + coord_type tmp=0; - //--------------------------------------------------------------------- - if ((!is_border_el1)&&(!is_border_el2)) - { - // si on veut s'interdir de spliter un bord (pelure d'orange....) - // seulement c->vertex(i)->is_exterior() - // pour s'autoriser des split de bord surface a bord->sphere ou Moebius... - // alors || is_on_same_border: - // if (c->vertex(i)->is_exterior() || is_on_same_border) - // pour passer au tore (changementde type de topologie) - // recoller deux bord different... - // if (c->vertex(i)->not_interior() deja teste en haut + // If the triangle has a high perimeter, + // we do not want to consider it as a good candidate. + + if(reject(facet_it.first->vertex(n_i1)->point(), + facet_it.first->vertex(n_i2)->point(), + facet_it.first->vertex(n_i3)->point())){ + tmp = HUGE_VAL; + } + + + if(tmp != HUGE_VAL){ + tmp = smallest_radius_delaunay_sphere(neigh, n_ind); + } + + Edge_like el1(neigh->vertex(n_i1),neigh->vertex(n_i3)), + el2(neigh->vertex(n_i2),neigh->vertex(n_i3)); + + if ((tmp != HUGE_VAL)&& + neigh->vertex(n_i3)->not_interior()&& + (!is_interior_edge(el1))&&(!is_interior_edge(el2))) + { + const Point& pn = neigh->vertex(n_i3)->point(); + + P2Pn = pn-p2; + v2 = cross_product(P2P1,P2Pn); + + //pas necessaire de normer pour un bon echantillon: + // on peut alors tester v1*v2 >= 0 + norm = sqrt(norm1 * (v2*v2)); + pscal = v1*v2; + // check if the triangle will produce a sliver on the surface + bool sliver_facet = ((succ_start || (neigh == c_predone))&& + (pscal <= COS_ALPHA_SLIVER*norm)); - if(c->vertex(i)->is_exterior()) - { - Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), - edge_Efacet.second); - - Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), - edge_Efacet.second); - e1 = compute_value(edge_Ifacet_1); - e2 = compute_value(edge_Ifacet_2); - - IO_edge_type* p1; - IO_edge_type* p2; + if (succ_start) succ_start = false; - border_extend(ordered_key, result12, - v1, v2, c->vertex(i), - e1, e2, p1, p2); + if (!sliver_facet) + { + if (tmp < min_valueA) + { + PnP1 = p1-pn; + // DELTA represente la qualite d'echantillonnage du bord + // We skip triangles having an internal angle along e + // whose cosinus is smaller than -DELTA + // that is the angle is larger than arcos(-DELTA) + border_facet = !((P2P1*P2Pn >= + -DELTA*sqrt(norm12*(P2Pn*P2Pn)))&& + (P2P1*PnP1 >= + -DELTA*sqrt(norm12*(PnP1*PnP1)))); + /// \todo investigate why we simply do not skip this triangle + /// but continue looking for a better candidate + /// if (!border_facet){ + min_facetA = facet_it; + min_valueA = tmp; + min_valueP = pscal/norm; + ///} + } + } + } + } + e_it = next(e_it); + } + while(e_it.first.first != c); + + criteria value; + + if ((min_valueA == HUGE_VAL) || border_facet) // bad facets case + { + min_facet = Facet(c, i); // !!! sans aucune signification.... + value = NOT_VALID_CANDIDATE; // Attention a ne pas inserer dans PQ + } + else + { + min_facet = min_facetA; + + //si on considere seulement la pliure value appartient a [0, 2] + //value = coord_type(1) - min_valueP; + + // si la pliure est bonne on note suivant le alpha sinon on prend en compte la + // pliure seule... pour discriminer entre les bons slivers... + // si on veut discriminer les facettes de bonnes pliures plus finement + // alors -(1+1/min_valueA) app a [-inf, -1] + // -min_valueP app a [-1, 1] + + if (min_valueP > COS_BETA) + value = -(coord_type(1) + coord_type(1)/min_valueA); + else + { + //on refuse une trop grande non-uniformite + coord_type tmp = smallest_radius_delaunay_sphere(c, i); + if (min_valueA <= K * tmp) + value = - min_valueP; + else + { + value = STANDBY_CANDIDATE; // tres mauvais candidat mauvaise pliure + // + grand alpha... a traiter plus tard.... + min_K = + (std::min)(min_K, + min_valueA/tmp); + } + } + } + + Cell_handle n = min_facet.first; + int ni1 = n->index(c->vertex(i1)), ni2 = n->index(c->vertex(i2)); + + return + Radius_edge_type(value, IO_edge_type(e, Edge_incident_facet + (Edge(n, ni1, ni2), + min_facet.second))); + } + + //===================================================================== + // The parameter re_init is false the first time only + // Returns true, iff it found a face where the next surface can grow + bool + init(const bool& re_init) + { + init_timer.start(); + Facet min_facet; + coord_type min_value = HUGE_VAL; + int i1, i2, i3; + + if (!re_init){ + Finite_facets_iterator end = T.finite_facets_end(); + for(Finite_facets_iterator facet_it = T.finite_facets_begin(); + facet_it != end; + ++facet_it) + { + coord_type value = smallest_radius_delaunay_sphere((*facet_it).first, + (*facet_it).second); + if (value < min_value) + { + min_facet = *facet_it; + min_value = value; + } + } + }else{ //if (re_init) + Finite_facets_iterator end = T.finite_facets_end(); + for(Finite_facets_iterator facet_it = T.finite_facets_begin(); + facet_it != end; + ++facet_it) + { + Cell_handle c = (*facet_it).first; + int index = (*facet_it).second; + if (c->vertex((index+1) & 3)->is_exterior()) + if (c->vertex((index+2) & 3)->is_exterior()) + if (c->vertex((index+3) & 3)->is_exterior()) + { + coord_type value = smallest_radius_delaunay_sphere(c, index); + + // we might not want the triangle, for example because it is too large + if(reject(c->vertex((index+1)&3)->point(), + c->vertex((index+2)&3)->point(), + c->vertex((index+3)&3)->point())){ + value = min_value; + } + + if (value < min_value) + { + min_facet = *facet_it; + min_value = value; + } + } + } + } + + if (min_value != HUGE_VAL) + { + Cell_handle c_min = min_facet.first; + + int ind = min_facet.second; + i1 = (ind+1) & 3; + i2 = (ind+2) & 3; + i3 = (ind+3) & 3; + + Radius_edge_type e12, e23, e31; + + e12 = compute_value(Edge_incident_facet(Edge(c_min, i1, i2), ind)); + e23 = compute_value(Edge_incident_facet(Edge(c_min, i2, i3), ind)); + e31 = compute_value(Edge_incident_facet(Edge(c_min, i3, i1), ind)); + + IO_edge_type* p12 = set_border_elt(c_min->vertex(i1), c_min->vertex(i2), + Border_elt(e12, _number_of_border)); + IO_edge_type* p23 = set_border_elt(c_min->vertex(i2), c_min->vertex(i3), + Border_elt(e23, _number_of_border)); + IO_edge_type* p31 = set_border_elt(c_min->vertex(i3), c_min->vertex(i1), + Border_elt(e31, _number_of_border)); + + c_min->vertex(i1)->inc_mark(); + c_min->vertex(i2)->inc_mark(); + c_min->vertex(i3)->inc_mark(); + _ordered_border.insert(Radius_ptr_type (e12.first, p12)); + _ordered_border.insert(Radius_ptr_type (e23.first, p23)); + _ordered_border.insert(Radius_ptr_type (e31.first, p31)); + + select_facet(c_min, ind); + init_timer.stop(); + return true; + } + init_timer.stop(); + return false; + } + + //--------------------------------------------------------------------- + // test de reciprocite avant de recoller une oreille anti-singularite + int + test_merge(const Edge_like& ordered_key, const Border_elt& result, + const Vertex_handle& v, const coord_type& ear_alpha) + { + Edge_incident_facet Ifacet = result.first.second.first; + + const Point& p1 = (ordered_key.first)->point(); + const Point& p2 = (ordered_key.second)->point(); + const Point& pc = v->point(); + + Cell_handle neigh = Ifacet.first.first; + int n_ind = Ifacet.second; + int n_i1 = Ifacet.first.second; + int n_i2 = Ifacet.first.third; + int n_i3 = (6 - n_ind - n_i1 - n_i2); + + const Point& pn = neigh->vertex(n_i3)->point(); + Vector v1 = cross_product(pc-p2,p1-p2), + v2 = cross_product(p1-p2,pn-p2); + coord_type norm = sqrt((v1*v1)*(v2*v2)); + + if (v1*v2 > COS_BETA*norm) + return 1; // label bonne pliure sinon: + + if (ear_alpha <= K*smallest_radius_delaunay_sphere(neigh, n_ind)) + return 2; // label alpha coherent... + + return 0; //sinon oreille a rejeter... + } + + + //--------------------------------------------------------------------- + void + ordered_map_erase(const criteria& value, const IO_edge_type* pkey) + { + _ordered_border.erase(Radius_ptr_type(value,(IO_edge_type*)pkey)); + } + + //--------------------------------------------------------------------- + void + force_merge(const Edge_like& ordered_key, const Border_elt& result) + { + criteria value = result.first.first; + IO_edge_type* pkey = border_IO_elt(ordered_key.first, ordered_key.second); + + ordered_map_erase(value, pkey); + + remove_border_elt(ordered_key); + } + + //--------------------------------------------------------------------- + void + dequeue_incidence_request(const Vertex_handle& v) + { + if (is_incidence_requested(v)) + { + for(Incidence_request_iterator v_it = incidence_request_begin(v); + v_it != incidence_request_end(v); + v_it++) + { + IO_edge_type* ptr; + + if (is_ordered_border_elt(v_it->second, ptr)) + _ordered_border.insert(Radius_ptr_type(v_it->first, ptr)); + } + erase_incidence_request(v); + } + } + + + //--------------------------------------------------------------------- + void + merge_ear(const Edge_like& ordered_el1, const Border_elt& result1, + const Edge_like& ordered_key, + const Vertex_handle& v1, const Vertex_handle& v2, + const Edge_incident_facet& edge_Ifacet_2) + { + remove_border_elt(ordered_key); + force_merge(ordered_el1, result1); + Radius_edge_type e2 = compute_value(edge_Ifacet_2); + IO_edge_type* p2; + if (ordered_el1.first == v1) + p2 = set_border_elt(v2, ordered_el1.second, + Border_elt(e2,result1.second)); + else + p2 = set_border_elt(ordered_el1.first, v2, + Border_elt(e2,result1.second)); + dec_mark(v1); + + _ordered_border.insert(Radius_ptr_type(e2.first, p2)); + + //depiler les eventuelles requettes de connections avortees... zones etoilees, + //en effet le bord a change donc on peut peut etre maintenant. + dequeue_incidence_request(v2); + if (ordered_el1.first == v1) + dequeue_incidence_request(ordered_el1.second); + else + dequeue_incidence_request(ordered_el1.first); + } + + //--------------------------------------------------------------------- + void + border_extend(const Edge_like& ordered_key, const Border_elt& result12, + const Vertex_handle& v1, const Vertex_handle& v2, + const Vertex_handle& v3, + const Radius_edge_type& e1, const Radius_edge_type& e2, + IO_edge_type* &p1, IO_edge_type* &p2) + { + remove_border_elt(ordered_key); + + //depiler v3 avant de le mettre a jour... pour reperer s'il est sur un bord + if (v3->is_on_border()) + dequeue_incidence_request(v3); + + if (ordered_key.first == v1) + { + p1 = set_border_elt(v1, v3, Border_elt(e1,result12.second)); + p2 = set_border_elt(v3, v2, Border_elt(e2,result12.second)); + } + else + { + p2 = set_border_elt(v2, v3, Border_elt(e2,result12.second)); + p1 = set_border_elt(v3, v1, Border_elt(e1,result12.second)); + } + + v3->inc_mark(); + + //depiler les eventuelles requettes de connections avortees... zones etoilees, + //en effet le bord a change donc on peut peut etre maintenant. + dequeue_incidence_request(v1); + dequeue_incidence_request(v2); + } + + //===================================================================== + Validation_case + validate(const Edge_incident_facet& edge_Efacet, + const criteria& value) + { + int i = (6 - edge_Efacet.second + - edge_Efacet.first.second + - edge_Efacet.first.third); + Cell_handle c = edge_Efacet.first.first; + + Vertex_handle v1 = c->vertex(edge_Efacet.first.second), + v2 = c->vertex(edge_Efacet.first.third); + + Edge_like ordered_el1(c->vertex(i), v1); + Edge_like ordered_el2(c->vertex(i), v2); + Border_elt result1, result2, result12; + + Edge_like ordered_key(v1,v2); + + if (!is_border_elt(ordered_key, result12)) + std::cerr << "+++probleme coherence bord " << std::endl; + + bool is_border_el1 = is_border_elt(ordered_el1, result1), + is_border_el2 = is_border_elt(ordered_el2, result2); + + Radius_edge_type e1, e2; + if (c->vertex(i)->not_interior()) + { + if ((!is_interior_edge(ordered_el1))&& + (!is_interior_edge(ordered_el2))) + { + //toujours utile meme avec l'essai de try_to_close_border avant + //validate pour la resolution de singularite par oreille qui elle + //doit etre dans Delaunay. + if (is_border_el1&&is_border_el2) + { + remove_border_elt(ordered_key); + force_merge(ordered_el1, result1); + force_merge(ordered_el2, result2); + + dec_mark(v1); + dec_mark(v2); + dec_mark(c->vertex(i)); + + select_facet(c, edge_Efacet.second); + + return FINAL_CASE; + } + //--------------------------------------------------------------------- + //on peut alors marquer v1 et on pourrait essayer de merger + //sans faire de calcul inutile??? + if (is_border_el1) + { + Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), + edge_Efacet.second); + merge_ear(ordered_el1, result1, + ordered_key, v1, v2, edge_Ifacet_2); + + select_facet(c, edge_Efacet.second); + + return EAR_CASE; + } + //--------------------------------------------------------------------- + //idem pour v2 + if (is_border_el2) + { + Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), + edge_Efacet.second); + merge_ear(ordered_el2, result2, + ordered_key, v2, v1, edge_Ifacet_1); + select_facet(c, edge_Efacet.second); + + return EAR_CASE; + } + + //--------------------------------------------------------------------- + if ((!is_border_el1)&&(!is_border_el2)) + { + // si on veut s'interdir de spliter un bord (pelure d'orange....) + // seulement c->vertex(i)->is_exterior() + // pour s'autoriser des split de bord surface a bord->sphere ou Moebius... + // alors || is_on_same_border: + // if (c->vertex(i)->is_exterior() || is_on_same_border) + // pour passer au tore (changementde type de topologie) + // recoller deux bord different... + // if (c->vertex(i)->not_interior() deja teste en haut + + if(c->vertex(i)->is_exterior()) + { + Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), + edge_Efacet.second); + + Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), + edge_Efacet.second); + e1 = compute_value(edge_Ifacet_1); + e2 = compute_value(edge_Ifacet_2); + + IO_edge_type* p1; + IO_edge_type* p2; + + border_extend(ordered_key, result12, + v1, v2, c->vertex(i), + e1, e2, p1, p2); - // if e1 contain HUGE_VAL there is no candidates to - // continue: compute_value is not valid... + // if e1 contain HUGE_VAL there is no candidates to + // continue: compute_value is not valid... - _ordered_border.insert(Radius_ptr_type(e1.first, p1)); + _ordered_border.insert(Radius_ptr_type(e1.first, p1)); - _ordered_border.insert(Radius_ptr_type(e2.first, p2)); + _ordered_border.insert(Radius_ptr_type(e2.first, p2)); - select_facet(c, edge_Efacet.second); + select_facet(c, edge_Efacet.second); - return EXTERIOR_CASE; - } - else // c->vertex(i) is a border point (and now there's only 1 + return EXTERIOR_CASE; + } + else // c->vertex(i) is a border point (and now there's only 1 // border incident to a point... _mark<1 even if th orientation // may be such as one vh has 2 successorson the same border... { @@ -1677,9 +1669,9 @@ public: // maintenant la compatibilite d'orientation des bords (pour // surface orientable...) ou si elle est brisee... Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), - edge_Efacet.second); + edge_Efacet.second); Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), - edge_Efacet.second); + edge_Efacet.second); e1 = compute_value(edge_Ifacet_1); e2 = compute_value(edge_Ifacet_2); @@ -1816,659 +1808,659 @@ public: select_facet(c, edge_Efacet.second); return CONNECTING_CASE; } - } - } - } - return NOT_VALID; - } + } + } + } + return NOT_VALID; + } - //===================================================================== - void re_compute_values() - { - if(!_ordered_border.empty()) - { - Ordered_border_type _ordered_border_tmp; - do - { - Ordered_border_iterator e_it = _ordered_border.begin(); - Edge_incident_facet mem_Ifacet = e_it->second->first; - Cell_handle c_tmp = mem_Ifacet.first.first; - _ordered_border.erase(e_it); - Vertex_handle v1 = c_tmp->vertex(mem_Ifacet.first.second); - Vertex_handle v2 = c_tmp->vertex(mem_Ifacet.first.third); + //===================================================================== + void + re_compute_values() + { + if(!_ordered_border.empty()) + { + Ordered_border_type _ordered_border_tmp; + do + { + Ordered_border_iterator e_it = _ordered_border.begin(); + Edge_incident_facet mem_Ifacet = e_it->second->first; + Cell_handle c_tmp = mem_Ifacet.first.first; + _ordered_border.erase(e_it); + Vertex_handle v1 = c_tmp->vertex(mem_Ifacet.first.second); + Vertex_handle v2 = c_tmp->vertex(mem_Ifacet.first.third); - Radius_edge_type new_candidate; - new_candidate = compute_value(mem_Ifacet); + Radius_edge_type new_candidate; + new_candidate = compute_value(mem_Ifacet); - if (new_candidate.first == STANDBY_CANDIDATE) - { - // a garder pour un K un peu plus grand... - new_candidate.first = STANDBY_CANDIDATE_BIS; - } + if (new_candidate.first == STANDBY_CANDIDATE) + { + // a garder pour un K un peu plus grand... + new_candidate.first = STANDBY_CANDIDATE_BIS; + } - Border_elt result; - Edge_like key_tmp(v1,v2); - is_border_elt(key_tmp, result); - IO_edge_type* pnew = - set_again_border_elt(key_tmp.first, key_tmp.second, - Border_elt (new_candidate, result.second)); - _ordered_border_tmp.insert(Radius_ptr_type(new_candidate.first, pnew)); - } - while(!_ordered_border.empty()); + Border_elt result; + Edge_like key_tmp(v1,v2); + is_border_elt(key_tmp, result); + IO_edge_type* pnew = + set_again_border_elt(key_tmp.first, key_tmp.second, + Border_elt (new_candidate, result.second)); + _ordered_border_tmp.insert(Radius_ptr_type(new_candidate.first, pnew)); + } + while(!_ordered_border.empty()); - _ordered_border.swap(_ordered_border_tmp); - } - } - - //--------------------------------------------------------------------- - - void - extend(const coord_type& K_init, const coord_type& K_step, const coord_type& K_max) - { - // initilisation de la variable globale K: qualite d'echantillonnage requise - K = K_init; // valeur d'initialisation de K pour commencer prudemment... - - Vertex_handle v1, v2; - if (_ordered_border.empty()){ - return; + _ordered_border.swap(_ordered_border_tmp); + } } - do - { - min_K = HUGE_VAL; // pour retenir le prochain K necessaire pour progresser... - do - { - Ordered_border_iterator e_it = _ordered_border.begin(); + //--------------------------------------------------------------------- + void + extend(const coord_type& K_init, const coord_type& K_step, const coord_type& K_max) + { + // initilisation de la variable globale K: qualite d'echantillonnage requise + K = K_init; // valeur d'initialisation de K pour commencer prudemment... - criteria value = e_it->first; - if (value >= STANDBY_CANDIDATE) - re_compute_values(); - else - { - Edge_incident_facet candidate = e_it->second->second; - Cell_handle c_ext = candidate.first.first; - int i1, i2 , i3; - i1 = candidate.first.second; - i2 = candidate.first.third; - i3 = (6 - i1- i2 - candidate.second); - - Edge_incident_facet mem_Ifacet = e_it->second->first; - Cell_handle c_tmp = mem_Ifacet.first.first; - - v1 = c_tmp->vertex(mem_Ifacet.first.second); - v2 = c_tmp->vertex(mem_Ifacet.first.third); - - Radius_edge_type mem_e_it(e_it->first, *e_it->second); - - _ordered_border.erase(e_it); - Validation_case validate_result = validate(candidate, value); - if ((validate_result == NOT_VALID)|| - (validate_result == NOT_VALID_CONNECTING_CASE)) - { - Radius_edge_type new_candidate; - Border_elt result; - Edge_like key_tmp(v1,v2); - is_border_elt(key_tmp, result); - - if (validate_result == NOT_VALID_CONNECTING_CASE) - set_incidence_request(c_ext->vertex(i3), value, key_tmp); - - if (validate_result == NOT_VALID) - { - new_candidate = compute_value(mem_Ifacet); - if ((new_candidate != mem_e_it)) - // &&(new_candidate.first < NOT_VALID_CANDIDATE)) - { - IO_edge_type* pnew = - set_again_border_elt(key_tmp.first, key_tmp.second, - Border_elt (new_candidate, result.second)); - _ordered_border.insert(Radius_ptr_type(new_candidate.first, - pnew)); - } - } - } - } - } - while((!_ordered_border.empty())&& - (_ordered_border.begin()->first < STANDBY_CANDIDATE_BIS)); - - K += (std::max)(K_step, min_K-K+eps); - // on augmente progressivement le K mais on a deja rempli sans - // faire des betises auparavant... + Vertex_handle v1, v2; + if (_ordered_border.empty()){ + return; } - while((!_ordered_border.empty())&&(K <= K_max)&&(min_K != HUGE_VAL)); + do + { + min_K = HUGE_VAL; // pour retenir le prochain K necessaire pour progresser... + do + { + + Ordered_border_iterator e_it = _ordered_border.begin(); + + criteria value = e_it->first; + if (value >= STANDBY_CANDIDATE) + re_compute_values(); + else + { + Edge_incident_facet candidate = e_it->second->second; + Cell_handle c_ext = candidate.first.first; + int i1, i2 , i3; + i1 = candidate.first.second; + i2 = candidate.first.third; + i3 = (6 - i1- i2 - candidate.second); + + Edge_incident_facet mem_Ifacet = e_it->second->first; + Cell_handle c_tmp = mem_Ifacet.first.first; + + v1 = c_tmp->vertex(mem_Ifacet.first.second); + v2 = c_tmp->vertex(mem_Ifacet.first.third); + + Radius_edge_type mem_e_it(e_it->first, *e_it->second); + + _ordered_border.erase(e_it); + Validation_case validate_result = validate(candidate, value); + if ((validate_result == NOT_VALID)|| + (validate_result == NOT_VALID_CONNECTING_CASE)) + { + Radius_edge_type new_candidate; + Border_elt result; + Edge_like key_tmp(v1,v2); + is_border_elt(key_tmp, result); + + if (validate_result == NOT_VALID_CONNECTING_CASE) + set_incidence_request(c_ext->vertex(i3), value, key_tmp); + + if (validate_result == NOT_VALID) + { + new_candidate = compute_value(mem_Ifacet); + if ((new_candidate != mem_e_it)) + // &&(new_candidate.first < NOT_VALID_CANDIDATE)) + { + IO_edge_type* pnew = + set_again_border_elt(key_tmp.first, key_tmp.second, + Border_elt (new_candidate, result.second)); + _ordered_border.insert(Radius_ptr_type(new_candidate.first, + pnew)); + } + } + } + } + } + while((!_ordered_border.empty())&& + (_ordered_border.begin()->first < STANDBY_CANDIDATE_BIS)); + + K += (std::max)(K_step, min_K-K+eps); + // on augmente progressivement le K mais on a deja rempli sans + // faire des betises auparavant... + } + while((!_ordered_border.empty())&&(K <= K_max)&&(min_K != HUGE_VAL)); #ifdef VERBOSE - if ((min_K < HUGE_VAL)&&(!_ordered_border.empty())) { - std::cout << " [ next K required = " << min_K << " ]" << std::endl; - } + if ((min_K < HUGE_VAL)&&(!_ordered_border.empty())) { + std::cout << " [ next K required = " << min_K << " ]" << std::endl; + } #endif // VERBOSE - } + } + //--------------------------------------------------------------------- + // En principe, si l'allocateur de cellules etait bien fait on aurait pas besoin + // de mettre a jour les valeurs rajoutees pour les cellules a la main... + void + re_init_for_free_cells_cache(const Vertex_handle& vh) + { + std::list ch_set; + T.incident_cells(vh, std::back_inserter(ch_set)); + for (typename std::list::iterator c_it = ch_set.begin(); + c_it != ch_set.end(); + c_it++) + (*c_it)->clear(); + } - //--------------------------------------------------------------------- - // En principe, si l'allocateur de cellules etait bien fait on aurait pas besoin - // de mettre a jour les valeurs rajoutees pour les cellules a la main... + //--------------------------------------------------------------------- + void + swap_selected_facets_on_conflict_boundary(const Vertex_handle& vh) + { + std::list ch_set; + T.incident_cells(vh, std::back_inserter(ch_set)); + for (typename std::list::iterator c_it = ch_set.begin(); + c_it != ch_set.end(); c_it++) + { + Cell_handle c = *c_it; + int index = c->index(vh); + Cell_handle neigh = c->neighbor(index); + int n_ind = neigh->index(c); + neigh->set_smallest_radius(n_ind, -1); // pour obliger le recalcul + // si c est selectionnee c'est qu'elle est aussi le mem_IFacet renvoye par + // compute_value... donc a swapper aussi + if (c->is_selected_facet(index)) + { + int fn = c->facet_number(index); + unselect_facet(c, index); + neigh->select_facet(n_ind); + neigh->set_facet_number(n_ind, fn); + int i1 = (n_ind+1) & 3; + int i2 = (n_ind+2) & 3; + int i3 = (n_ind+3) & 3; + Edge_like key(neigh->vertex(i1), neigh->vertex(i2)); - void re_init_for_free_cells_cache(const Vertex_handle& vh) - { - std::list ch_set; - T.incident_cells(vh, std::back_inserter(ch_set)); - for (typename std::list::iterator c_it = ch_set.begin(); - c_it != ch_set.end(); - c_it++) - (*c_it)->clear(); - } - - - //--------------------------------------------------------------------- - - void swap_selected_facets_on_conflict_boundary(const Vertex_handle& vh) - { - std::list ch_set; - T.incident_cells(vh, std::back_inserter(ch_set)); - for (typename std::list::iterator c_it = ch_set.begin(); - c_it != ch_set.end(); c_it++) - { - Cell_handle c = *c_it; - int index = c->index(vh); - Cell_handle neigh = c->neighbor(index); - int n_ind = neigh->index(c); - neigh->set_smallest_radius(n_ind, -1); // pour obliger le recalcul - // si c est selectionnee c'est qu'elle est aussi le mem_IFacet renvoye par - // compute_value... donc a swapper aussi - if (c->is_selected_facet(index)) - { - int fn = c->facet_number(index); - unselect_facet(c, index); - neigh->select_facet(n_ind); - neigh->set_facet_number(n_ind, fn); - int i1 = (n_ind+1) & 3; - int i2 = (n_ind+2) & 3; - int i3 = (n_ind+3) & 3; - Edge_like key(neigh->vertex(i1), neigh->vertex(i2)); - - if (is_border_elt(key)) - { - Edge_incident_facet ei_facet(Edge(neigh, i1, i2), - n_ind); - *border_IO_elt(key.first, key.second) = - IO_edge_type(ei_facet, ei_facet); - } - key = Edge_like(neigh->vertex(i1), neigh->vertex(i3)); - if (is_border_elt(key)) - { - Edge_incident_facet ei_facet(Edge(neigh, i1, i3), - n_ind); - *border_IO_elt(key.first, key.second) = - IO_edge_type(ei_facet, ei_facet); - } - key = Edge_like(neigh->vertex(i3), neigh->vertex(i2)); - if (is_border_elt(key)) - { - Edge_incident_facet ei_facet(Edge(neigh, i3, i2), - n_ind); - *border_IO_elt(key.first, key.second) = - IO_edge_type(ei_facet, ei_facet); - } - } - } - } - - //--------------------------------------------------------------------- - - Facet next_surface_facet(const Edge_incident_facet& start) - { - Edge_incident_facet circ = next(start); - Cell_handle c = start.first.first; - do - { - Cell_handle ch = circ.first.first; - int ind = circ.second; - Cell_handle neigh = ch->neighbor(ind); - int n_ind = neigh->index(ch); - if (ch->is_selected_facet(ind)){ - return Facet(ch, ind); + if (is_border_elt(key)) + { + Edge_incident_facet ei_facet(Edge(neigh, i1, i2), + n_ind); + *border_IO_elt(key.first, key.second) = + IO_edge_type(ei_facet, ei_facet); + } + key = Edge_like(neigh->vertex(i1), neigh->vertex(i3)); + if (is_border_elt(key)) + { + Edge_incident_facet ei_facet(Edge(neigh, i1, i3), + n_ind); + *border_IO_elt(key.first, key.second) = + IO_edge_type(ei_facet, ei_facet); + } + key = Edge_like(neigh->vertex(i3), neigh->vertex(i2)); + if (is_border_elt(key)) + { + Edge_incident_facet ei_facet(Edge(neigh, i3, i2), + n_ind); + *border_IO_elt(key.first, key.second) = + IO_edge_type(ei_facet, ei_facet); + } + } } - if (neigh->is_selected_facet(n_ind)){ - return Facet(neigh, n_ind); + } + + //--------------------------------------------------------------------- + Facet + next_surface_facet(const Edge_incident_facet& start) + { + Edge_incident_facet circ = next(start); + Cell_handle c = start.first.first; + do + { + Cell_handle ch = circ.first.first; + int ind = circ.second; + Cell_handle neigh = ch->neighbor(ind); + int n_ind = neigh->index(ch); + if (ch->is_selected_facet(ind)){ + return Facet(ch, ind); + } + if (neigh->is_selected_facet(n_ind)){ + return Facet(neigh, n_ind); + } + circ = next(circ); } - circ = next(circ); - } - while(circ.first.first != c); - // si on passe par la, alors y a eu un probleme.... - std::cerr << "+++probleme dans la MAJ avant remove..." << std::endl; - return Facet(c, start.second); - } + while(circ.first.first != c); + // si on passe par la, alors y a eu un probleme.... + std::cerr << "+++probleme dans la MAJ avant remove..." << std::endl; + return Facet(c, start.second); + } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void + retract_border_for_incident_facets(const Vertex_handle& vh) + { + Next_border_elt border_elt = *(vh->first_incident()); + int border_index = border_elt.second.second; + Vertex_handle vh_succ = border_elt.first; + IO_edge_type io_edge = border_elt.second.first.second; + Edge_incident_facet i_facet = io_edge.first; + Cell_handle c = i_facet.first.first; + int i1 = c->index(vh); + int i2 = c->index(vh_succ); + int index = i_facet.second; + int i3 = 6 - index - i1 - i2; + Vertex_handle vh_int = c->vertex(i3); + ordered_map_erase(border_elt.second.first.first, + border_IO_elt(vh, vh_succ)); + remove_border_edge(vh, vh_succ); + // 1- a virer au cas ou car vh va etre detruit + remove_interior_edge(vh_succ, vh); + bool while_cond(true); + do + { + _facet_number--; - void retract_border_for_incident_facets(const Vertex_handle& vh) - { - Next_border_elt border_elt = *(vh->first_incident()); - int border_index = border_elt.second.second; - Vertex_handle vh_succ = border_elt.first; - IO_edge_type io_edge = border_elt.second.first.second; - Edge_incident_facet i_facet = io_edge.first; - Cell_handle c = i_facet.first.first; - int i1 = c->index(vh); - int i2 = c->index(vh_succ); - int index = i_facet.second; - int i3 = 6 - index - i1 - i2; - Vertex_handle vh_int = c->vertex(i3); - ordered_map_erase(border_elt.second.first.first, - border_IO_elt(vh, vh_succ)); - remove_border_edge(vh, vh_succ); - // 1- a virer au cas ou car vh va etre detruit - remove_interior_edge(vh_succ, vh); - bool while_cond(true); - do - { - _facet_number--; - - assert(c->is_selected_facet(index)); - unselect_facet(c, index); + assert(c->is_selected_facet(index)); + unselect_facet(c, index); - Facet f32 = - next_surface_facet(Edge_incident_facet(Edge(c, i3, i2), - index)); + Facet f32 = + next_surface_facet(Edge_incident_facet(Edge(c, i3, i2), + index)); - if (!vh_int->is_on_border()) - { - re_init(vh_int); - vh_int->inc_mark(); - } + if (!vh_int->is_on_border()) + { + re_init(vh_int); + vh_int->inc_mark(); + } - Edge_incident_facet e32(Edge(f32.first, - f32.first->index(vh_int), - f32.first->index(vh_succ)), f32.second); - Radius_edge_type rad_elt_32(STANDBY_CANDIDATE, IO_edge_type(e32, e32)); - Border_elt result; - if (is_ordered_border_elt(Edge_like(vh_int, vh), result)) - { - ordered_map_erase(result.first.first, border_IO_elt(vh_int, vh)); - remove_border_edge(vh_int, vh); - // 1- a virer au cas ou car vh va etre detruit - remove_interior_edge(vh_int, vh); - while_cond = false; - } - // a titre preventif... on essaye de s'assurer de marquer les aretes - // interieures au sens large... + Edge_incident_facet e32(Edge(f32.first, + f32.first->index(vh_int), + f32.first->index(vh_succ)), f32.second); + Radius_edge_type rad_elt_32(STANDBY_CANDIDATE, IO_edge_type(e32, e32)); + Border_elt result; + if (is_ordered_border_elt(Edge_like(vh_int, vh), result)) + { + ordered_map_erase(result.first.first, border_IO_elt(vh_int, vh)); + remove_border_edge(vh_int, vh); + // 1- a virer au cas ou car vh va etre detruit + remove_interior_edge(vh_int, vh); + while_cond = false; + } + // a titre preventif... on essaye de s'assurer de marquer les aretes + // interieures au sens large... - // 2- a virer a tout pris pour que maintenir le sens de interior edge - remove_interior_edge(vh_int, vh_succ); - remove_interior_edge(vh_succ, vh_int); + // 2- a virer a tout pris pour que maintenir le sens de interior edge + remove_interior_edge(vh_int, vh_succ); + remove_interior_edge(vh_succ, vh_int); - IO_edge_type* p32 = set_border_elt(vh_int, vh_succ, - Border_elt(rad_elt_32, border_index)); - _ordered_border.insert(Radius_ptr_type (STANDBY_CANDIDATE, p32)); + IO_edge_type* p32 = set_border_elt(vh_int, vh_succ, + Border_elt(rad_elt_32, border_index)); + _ordered_border.insert(Radius_ptr_type (STANDBY_CANDIDATE, p32)); - // incrementation... - if (while_cond) - { - Facet f31 = - next_surface_facet(Edge_incident_facet(Edge(c, i3, i1), - index)); + // incrementation... + if (while_cond) + { + Facet f31 = + next_surface_facet(Edge_incident_facet(Edge(c, i3, i1), + index)); - c = f31.first; - index = f31.second; - i1 = c->index(vh); - vh_succ = vh_int; - i2 = c->index(vh_int); - i3 = 6 - index - i1 - i2; - vh_int = c->vertex(i3); - } - } - while(while_cond); - } + c = f31.first; + index = f31.second; + i1 = c->index(vh); + vh_succ = vh_int; + i2 = c->index(vh_int); + i3 = 6 - index - i1 - i2; + vh_int = c->vertex(i3); + } + } + while(while_cond); + } - //--------------------------------------------------------------------- - - bool create_singularity(const Vertex_handle& vh) - { - // Pour reperer le cas de triangle isole - if (vh->is_on_border()) - { - // vh sommet 0 - Next_border_elt border_elt = *(vh->first_incident()); - Vertex_handle vh_1 = border_elt.first;// sommet 1 - border_elt = *(vh_1->first_incident()); - Vertex_handle vh_2 = border_elt.first;// sommet 2 - border_elt = *(vh_2->first_incident()); - Vertex_handle vh_3 = border_elt.first;// sommet 0 ??? - Cell_handle c; - int i, j, k; - if ((vh_3 == vh)&&(T.is_facet(vh, vh_1, vh_2, c, i ,j ,k))) - { - int l = 6-i-j-k; - Cell_handle neigh = c->neighbor(l); + //--------------------------------------------------------------------- + bool + create_singularity(const Vertex_handle& vh) + { + // Pour reperer le cas de triangle isole + if (vh->is_on_border()) + { + // vh sommet 0 + Next_border_elt border_elt = *(vh->first_incident()); + Vertex_handle vh_1 = border_elt.first;// sommet 1 + border_elt = *(vh_1->first_incident()); + Vertex_handle vh_2 = border_elt.first;// sommet 2 + border_elt = *(vh_2->first_incident()); + Vertex_handle vh_3 = border_elt.first;// sommet 0 ??? + Cell_handle c; + int i, j, k; + if ((vh_3 == vh)&&(T.is_facet(vh, vh_1, vh_2, c, i ,j ,k))) + { + int l = 6-i-j-k; + Cell_handle neigh = c->neighbor(l); - if - (c->is_selected_facet(l)||neigh->is_selected_facet(neigh->index(c))) - return true; - } - } + if + (c->is_selected_facet(l)||neigh->is_selected_facet(neigh->index(c))) + return true; + } + } - // Reperer le cas d'aretes interieures... - std::list vh_list; - T.incident_vertices(vh, std::back_inserter(vh_list)); + // Reperer le cas d'aretes interieures... + std::list vh_list; + T.incident_vertices(vh, std::back_inserter(vh_list)); - for (typename std::list::iterator v_it = vh_list.begin(); - v_it != vh_list.end(); v_it++) - if ((*v_it)->is_on_border() && is_interior_edge(Edge_like(vh, *v_it))) - return true; - return false; - } + for (typename std::list::iterator v_it = vh_list.begin(); + v_it != vh_list.end(); v_it++) + if ((*v_it)->is_on_border() && is_interior_edge(Edge_like(vh, *v_it))) + return true; + return false; + } - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + void + store_outlier(const Point& p){ + m_outliers.push_back(p); + } - void - store_outlier(const Point& p){ - m_outliers.push_back(p); - } - void dec_vh_number() - { - _vh_number--; - } + void dec_vh_number() + { + _vh_number--; + } - struct Remove : public std::unary_function - { - Extract& E; - Triangulation_3& T; + struct Remove : public std::unary_function + { - Remove(Extract& E_, Triangulation_3& T_) : E(E_), T(T_) {} + Extract& E; + Triangulation_3& T; - bool operator()(Vertex_handle vh) { - if (vh->is_exterior()) - { - E.swap_selected_facets_on_conflict_boundary(vh); - E.re_init_for_free_cells_cache(vh); - Point p = vh->point(); - T.remove(vh); - E.dec_vh_number(); - E.store_outlier(p); + Remove(Extract& E_, Triangulation_3& T_) : E(E_), T(T_) {} + + bool operator()(Vertex_handle vh) { + if (vh->is_exterior()) + { + E.swap_selected_facets_on_conflict_boundary(vh); + E.re_init_for_free_cells_cache(vh); + Point p = vh->point(); + T.remove(vh); + E.dec_vh_number(); + E.store_outlier(p); - return true; - } - else if (vh->is_on_border()&&(!E.create_singularity(vh))) - { - E.swap_selected_facets_on_conflict_boundary(vh); - E.retract_border_for_incident_facets(vh); - E.re_init_for_free_cells_cache(vh); - Point p = vh->point(); - T.remove(vh); - E.dec_vh_number(); - E.store_outlier(p); + return true; + } + else if (vh->is_on_border()&&(!E.create_singularity(vh))) + { + E.swap_selected_facets_on_conflict_boundary(vh); + E.retract_border_for_incident_facets(vh); + E.re_init_for_free_cells_cache(vh); + Point p = vh->point(); + T.remove(vh); + E.dec_vh_number(); + E.store_outlier(p); - return true; - } - else - { } - return false; - } - }; + return true; + } + else + { } + return false; + } + }; - //--------------------------------------------------------------------- + //--------------------------------------------------------------------- + bool + postprocessing(int NB_BORDER_MAX) + { + postprocess_timer.start(); - bool postprocessing(int NB_BORDER_MAX) - { - postprocess_timer.start(); + _postprocessing_counter++; - _postprocessing_counter++; + std::list L_v; - std::list L_v; - - // Pour controler les sommets choisis sur le bord... + // Pour controler les sommets choisis sur le bord... - // nombre d'aretes a partir duquel on considere que c'est irrecuperable NB_BORDER_MAX + // nombre d'aretes a partir duquel on considere que c'est irrecuperable NB_BORDER_MAX - int vh_on_border_inserted(0); - for(Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++) - { - erase_incidence_request(v_it); - if ((v_it->is_on_border())&& - (!v_it->is_post_marked(_postprocessing_counter))) - { - std::list L_v_tmp; - Vertex_handle vprev_it(v_it), done(vprev_it), vh_it; - // Vertex_handle vsucc_it; - int v_count(0); - // collect all vertices on the border - do - { - vh_it = vprev_it->first_incident()->first; - L_v_tmp.push_back(vh_it); - vh_it->set_post_mark(_postprocessing_counter); - vprev_it = vh_it; - v_count++; - } - while((vprev_it != done)&&(v_count < NB_BORDER_MAX)); - // we stopped either because we did a complete tour, or because - // the border was so long that we consider it as too big to close - // e.g., if it is a terrain with only one real border at the exterior - if (v_count < NB_BORDER_MAX) - { - L_v.insert(L_v.begin(), L_v_tmp.begin(), L_v_tmp.end()); - vh_on_border_inserted += v_count; - } + int vh_on_border_inserted(0); + for(Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++) + { + erase_incidence_request(v_it); + if ((v_it->is_on_border())&& + (!v_it->is_post_marked(_postprocessing_counter))) + { + std::list L_v_tmp; + Vertex_handle vprev_it(v_it), done(vprev_it), vh_it; + // Vertex_handle vsucc_it; + int v_count(0); + // collect all vertices on the border + do + { + vh_it = vprev_it->first_incident()->first; + L_v_tmp.push_back(vh_it); + vh_it->set_post_mark(_postprocessing_counter); + vprev_it = vh_it; + v_count++; + } + while((vprev_it != done)&&(v_count < NB_BORDER_MAX)); + // we stopped either because we did a complete tour, or because + // the border was so long that we consider it as too big to close + // e.g., if it is a terrain with only one real border at the exterior + if (v_count < NB_BORDER_MAX) + { + L_v.insert(L_v.begin(), L_v_tmp.begin(), L_v_tmp.end()); + vh_on_border_inserted += v_count; + } - } - if (v_it->is_exterior()) - L_v.push_back(v_it); - } + } + if (v_it->is_exterior()) + L_v.push_back(v_it); + } - std::size_t itmp, L_v_size_mem; - L_v_size_mem = L_v.size(); - if ((vh_on_border_inserted != 0)&& // pour ne post-traiter que les bords - (L_v.size() < .1 * _size_before_postprocessing)) - { - { - do - { - itmp = L_v.size(); - typename std::list::iterator new_end = - std::remove_if(L_v.begin(), L_v.end(), Remove(*this,T)); - L_v.erase(new_end, L_v.end()); - } - while (!L_v.empty() && (L_v.size() < itmp)); - } + std::size_t itmp, L_v_size_mem; + L_v_size_mem = L_v.size(); + if ((vh_on_border_inserted != 0)&& // pour ne post-traiter que les bords + (L_v.size() < .1 * _size_before_postprocessing)) + { + { + do + { + itmp = L_v.size(); + typename std::list::iterator new_end = + std::remove_if(L_v.begin(), L_v.end(), Remove(*this,T)); + L_v.erase(new_end, L_v.end()); + } + while (!L_v.empty() && (L_v.size() < itmp)); + } #ifdef VERBOSE - if(L_v.size() > 0){ - std::cout << " " << L_v.size() << " non regular points." << std::endl; - } + if(L_v.size() > 0){ + std::cout << " " << L_v.size() << " non regular points." << std::endl; + } #endif // VERBOSE - re_compute_values(); + re_compute_values(); + } + else{ + postprocess_timer.stop(); + return false; } - else{ + // we stop if we removed more than 10% of points or after 20 rounds + if ((L_v_size_mem == L_v.size())|| + ((_size_before_postprocessing - T.number_of_vertices()) > + .1 * _size_before_postprocessing)|| + (_postprocessing_counter > 20)){ + postprocess_timer.stop(); + return false; + } + + min_K = HUGE_VAL; + // fin-- + // if (_postprocessing_counter < 5) + // return true; postprocess_timer.stop(); - return false; - } - // we stop if we removed more than 10% of points or after 20 rounds - if ((L_v_size_mem == L_v.size())|| - ((_size_before_postprocessing - T.number_of_vertices()) > - .1 * _size_before_postprocessing)|| - (_postprocessing_counter > 20)){ - postprocess_timer.stop(); - return false; + return true; } - min_K = HUGE_VAL; - // fin-- - // if (_postprocessing_counter < 5) - // return true; - postprocess_timer.stop(); - return true; + }; // class Advancing_front_surface_reconstruction + + namespace AFSR { + + template + struct Auto_count : public std::unary_function >{ + mutable int i; + + Auto_count() + : i(0) + {} + + std::pair operator()(const T& p) const { + return std::make_pair(p,i++); + } + }; + + template + struct Auto_count_cc : public std::unary_function >{ + mutable int i; + CC cc; + + Auto_count_cc(CC cc) + : i(0), cc(cc) + {} + + template + std::pair operator()(const T2& p) const { + return std::make_pair(cc(p),i++); + } + }; } -}; // class Advancing_front_surface_reconstruction -namespace AFSR { + template + IndexTripleIterator + advancing_front_surface_reconstruction(PointIterator b, + PointIterator e, + IndexTripleIterator out, + double radius_ratio_bound = 5, + double beta = 0.52 ) + { + typedef Exact_predicates_inexact_constructions_kernel Kernel; + typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; + typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; + + typedef Triangulation_data_structure_3 Tds; + typedef Delaunay_triangulation_3 Triangulation_3; + + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef Kernel::Point_3 Point_3; - template -struct Auto_count : public std::unary_function >{ - mutable int i; + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), + boost::make_transform_iterator(e, AFSR::Auto_count() ) ); - Auto_count() - : i(0) - {} - - std::pair operator()(const T& p) const { - return std::make_pair(p,i++); - } - }; - - template -struct Auto_count_cc : public std::unary_function >{ - mutable int i; - CC cc; - - Auto_count_cc(CC cc) - : i(0), cc(cc) - {} - - template - std::pair operator()(const T2& p) const { - return std::make_pair(cc(p),i++); - } - }; -} - - -template -IndexTripleIterator -advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, - IndexTripleIterator out, - double radius_ratio_bound = 5, - double beta = 0.52 ) -{ - typedef Exact_predicates_inexact_constructions_kernel Kernel; - typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; - typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; - - typedef Triangulation_data_structure_3 Tds; - typedef Delaunay_triangulation_3 Triangulation_3; - - typedef Advancing_front_surface_reconstruction Reconstruction; - typedef Kernel::Point_3 Point_3; - - Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), - boost::make_transform_iterator(e, AFSR::Auto_count() ) ); - - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - Reconstruction R(dt,opt); - R.run(opt); - write_triple_indices(out, R); - return out; -} + AFSR_options opt; + opt.K = radius_ratio_bound; + opt.COS_BETA = acos(beta); + Reconstruction R(dt,opt); + R.run(opt); + write_triple_indices(out, R); + return out; + } template -IndexTripleIterator -advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, - IndexTripleIterator out, - Filter filter, - double radius_ratio_bound = 5, - double beta = 0.52 ) -{ - typedef Exact_predicates_inexact_constructions_kernel Kernel; - typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; - typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; + IndexTripleIterator + advancing_front_surface_reconstruction(PointIterator b, + PointIterator e, + IndexTripleIterator out, + Filter filter, + double radius_ratio_bound = 5, + double beta = 0.52 ) + { + typedef Exact_predicates_inexact_constructions_kernel Kernel; + typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; + typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; - typedef Triangulation_data_structure_3 Tds; - typedef Delaunay_triangulation_3 Triangulation_3; + typedef Triangulation_data_structure_3 Tds; + typedef Delaunay_triangulation_3 Triangulation_3; - typedef Advancing_front_surface_reconstruction Reconstruction; - typedef typename std::iterator_traits::value_type InputPoint; - typedef typename Kernel_traits::Kernel InputKernel; - typedef Cartesian_converter CC; - typedef Kernel::Point_3 Point_3; - CC cc=CC(); - Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), - boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef typename std::iterator_traits::value_type InputPoint; + typedef typename Kernel_traits::Kernel InputKernel; + typedef Cartesian_converter CC; + typedef Kernel::Point_3 Point_3; + CC cc=CC(); + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), + boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - Reconstruction R(dt,opt, filter); - R.run(opt); - write_triple_indices(out, R); - return out; -} + AFSR_options opt; + opt.K = radius_ratio_bound; + opt.COS_BETA = acos(beta); + Reconstruction R(dt,opt, filter); + R.run(opt); + write_triple_indices(out, R); + return out; + } template class HDS, typename Alloc,typename Filter> -void -advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, - Polyhedron_3& polyhedron, - Filter filter, - double radius_ratio_bound = 5, - double beta = 0.52) -{ - typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; - typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; + void + advancing_front_surface_reconstruction(PointIterator b, + PointIterator e, + Polyhedron_3& polyhedron, + Filter filter, + double radius_ratio_bound = 5, + double beta = 0.52) + { + typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; + typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; - typedef Triangulation_data_structure_3 Tds; - typedef Delaunay_triangulation_3 Triangulation_3; + typedef Triangulation_data_structure_3 Tds; + typedef Delaunay_triangulation_3 Triangulation_3; - typedef Advancing_front_surface_reconstruction Reconstruction; - typedef typename std::iterator_traits::value_type InputPoint; - typedef typename Kernel_traits::Kernel InputKernel; - typedef Cartesian_converter CC; - typedef typename Kernel::Point_3 Point_3; + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef typename std::iterator_traits::value_type InputPoint; + typedef typename Kernel_traits::Kernel InputKernel; + typedef Cartesian_converter CC; + typedef typename Kernel::Point_3 Point_3; - CC cc=CC(); - Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), - boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); + CC cc=CC(); + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), + boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - Reconstruction R(dt, opt,filter); - R.run(opt); - AFSR::construct_polyhedron(polyhedron, R); -} + AFSR_options opt; + opt.K = radius_ratio_bound; + opt.COS_BETA = acos(beta); + Reconstruction R(dt, opt,filter); + R.run(opt); + AFSR::construct_polyhedron(polyhedron, R); + } + template class HDS, typename Alloc> -void -advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, - Polyhedron_3& polyhedron, - double radius_ratio_bound = 5, - double beta = 0.52) -{ - typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; - typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; + void + advancing_front_surface_reconstruction(PointIterator b, + PointIterator e, + Polyhedron_3& polyhedron, + double radius_ratio_bound = 5, + double beta = 0.52) + { + typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; + typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; - typedef Triangulation_data_structure_3 Tds; - typedef Delaunay_triangulation_3 Triangulation_3; + typedef Triangulation_data_structure_3 Tds; + typedef Delaunay_triangulation_3 Triangulation_3; - typedef Advancing_front_surface_reconstruction Reconstruction; - typedef typename Kernel::Point_3 Point_3; + typedef Advancing_front_surface_reconstruction Reconstruction; + typedef typename Kernel::Point_3 Point_3; - Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), - boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), + boost::make_transform_iterator(e, AFSR::Auto_count() ) ); - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - Reconstruction R(dt, opt); - R.run(opt); - AFSR::construct_polyhedron(polyhedron, R); -} + AFSR_options opt; + opt.K = radius_ratio_bound; + opt.COS_BETA = acos(beta); + Reconstruction R(dt, opt); + R.run(opt); + AFSR::construct_polyhedron(polyhedron, R); + } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h index 8fb77be47c8..9e662fa3caa 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h @@ -25,44 +25,44 @@ namespace CGAL { template < class Kernel, class CellBase = Triangulation_cell_base_3 > -class Advancing_front_surface_reconstruction_cell_base_3 : public CellBase -{ + class Advancing_front_surface_reconstruction_cell_base_3 : public CellBase + { -public: - template < typename TDS2 > - struct Rebind_TDS { - typedef typename CellBase::template Rebind_TDS::Other Cb2; - typedef Advancing_front_surface_reconstruction_cell_base_3 Other; - }; + public: + template < typename TDS2 > + struct Rebind_TDS { + typedef typename CellBase::template Rebind_TDS::Other Cb2; + typedef Advancing_front_surface_reconstruction_cell_base_3 Other; + }; - typedef typename CellBase::Vertex_handle Vertex_handle; - typedef typename CellBase::Cell_handle Cell_handle; + typedef typename CellBase::Vertex_handle Vertex_handle; + typedef typename CellBase::Cell_handle Cell_handle; -private: + private: #ifdef AFSR_FACET_NUMBER - int _facet_number[4]; + int _facet_number[4]; #endif - typedef double coord_type; + typedef double coord_type; #ifdef AFSR_LAZY - typedef typename CGAL::Simple_cartesian::Point_3 D_Point; + typedef typename CGAL::Simple_cartesian::Point_3 D_Point; #endif - //-------------------- DATA MEMBERS --------------------------------- + //-------------------- DATA MEMBERS --------------------------------- - coord_type* _smallest_radius_facet_tab; - unsigned char selected_facet; + coord_type* _smallest_radius_facet_tab; + unsigned char selected_facet; #ifdef AFSR_LAZY - D_Point* _circumcenter; - coord_type* _squared_radius; + D_Point* _circumcenter; + coord_type* _squared_radius; #endif - //-------------------- CONSTRUCTORS ---------------------------------- + //-------------------- CONSTRUCTORS ---------------------------------- -public: + public: - Advancing_front_surface_reconstruction_cell_base_3() - : CellBase(), - _smallest_radius_facet_tab(NULL), selected_facet(0) + Advancing_front_surface_reconstruction_cell_base_3() + : CellBase(), + _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY , _circumcenter(NULL), _squared_radius(NULL) #endif @@ -74,9 +74,9 @@ public: #endif } - Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) - : CellBase( v0, v1, v2, v3), - _smallest_radius_facet_tab(NULL), selected_facet(0) + Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) + : CellBase( v0, v1, v2, v3), + _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY , _circumcenter(NULL), _squared_radius(NULL) #endif @@ -88,11 +88,11 @@ public: #endif } - Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, - Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) - : CellBase(v0, v1, v2, v3, - n0, n1, n2, n3), - _smallest_radius_facet_tab(NULL), selected_facet(0) + Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, + Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) + : CellBase(v0, v1, v2, v3, + n0, n1, n2, n3), + _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY , _circumcenter(NULL), _squared_radius(NULL) #endif @@ -104,12 +104,12 @@ public: #endif } - //-------------------- DESTRUCTOR ----------------------------------- + //-------------------- DESTRUCTOR ----------------------------------- - inline ~Advancing_front_surface_reconstruction_cell_base_3() + inline ~Advancing_front_surface_reconstruction_cell_base_3() { if (_smallest_radius_facet_tab != NULL) - delete[] _smallest_radius_facet_tab; + delete[] _smallest_radius_facet_tab; #ifdef AFSR_LAZY if (_circumcenter != NULL) delete _circumcenter; @@ -118,11 +118,10 @@ public: #endif } - //-------------------- MEMBER FUNCTIONS ---------------------------- - -public: + //-------------------- MEMBER FUNCTIONS ---------------------------- + public: - inline void clear() + inline void clear() { if (_smallest_radius_facet_tab != NULL) delete[] _smallest_radius_facet_tab; @@ -138,16 +137,15 @@ public: #endif } - //------------------------------------------------------------------- - - inline coord_type smallest_radius(const int& i) + //------------------------------------------------------------------- + inline coord_type smallest_radius(const int& i) { if (_smallest_radius_facet_tab == NULL) return -1; return _smallest_radius_facet_tab[i]; } - inline void set_smallest_radius(const int& i, const coord_type& c) + inline void set_smallest_radius(const int& i, const coord_type& c) { if (_smallest_radius_facet_tab == NULL) { @@ -158,8 +156,8 @@ public: _smallest_radius_facet_tab[i] = c; } - // pour un controle de l'allocation memoire... utile??? - inline bool alloc_smallest_radius_tab(coord_type* ptr) + // pour un controle de l'allocation memoire... utile??? + inline bool alloc_smallest_radius_tab(coord_type* ptr) { if (_smallest_radius_facet_tab==NULL) { @@ -170,75 +168,75 @@ public: } - //------------------------------------------------------------------- + //------------------------------------------------------------------- #ifdef FACET_NUMBER - void set_facet_number(int i, int n){} - { - _facet_number[i] = n; - } + void set_facet_number(int i, int n){} + { + _facet_number[i] = n; + } - int facet_number(int i) - { - return _facet_number[i]; - } + int facet_number(int i) + { + return _facet_number[i]; + } #else - void set_facet_number(int, int){} - int facet_number(int){return 0;} + void set_facet_number(int, int){} + int facet_number(int){return 0;} #endif - //------------------------------------------------------------------- + //------------------------------------------------------------------- - inline void select_facet(const int& i) + inline void select_facet(const int& i) { selected_facet |= (1 << i); } - inline void unselect_facet(const int& i) + inline void unselect_facet(const int& i) { selected_facet &= (15 - (1 << i)); } - inline bool is_selected_facet(const int& i) + inline bool is_selected_facet(const int& i) { return (selected_facet & (1 << i)) != 0; } - inline bool has_facet_on_surface(const int& i) + inline bool has_facet_on_surface(const int& i) { return (selected_facet & (1 << i)) != 0; } #ifdef AFSR_LAZY - //------------------------------------------------------------------- + //------------------------------------------------------------------- - inline D_Point* lazy_circumcenter() + inline D_Point* lazy_circumcenter() { return _circumcenter; } - inline void set_lazy_circumcenter(const D_Point& p) + inline void set_lazy_circumcenter(const D_Point& p) { _circumcenter = new D_Point(p); } - //------------------------------------------------------------------- + //------------------------------------------------------------------- - inline coord_type* lazy_squared_radius() + inline coord_type* lazy_squared_radius() { return _squared_radius; } - inline void set_lazy_squared_radius(const coord_type& sr) + inline void set_lazy_squared_radius(const coord_type& sr) { _squared_radius = new coord_type(sr); } #endif //AFSR_LAZY -}; + }; } // namespace CGAL diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index 04504b7fae0..0cd528afc83 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -33,138 +33,138 @@ namespace CGAL { template class Advancing_front_surface_reconstruction; -template > -class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase -{ -public: + template > + class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase + { + public: - template < typename TDS2 > - struct Rebind_TDS { - typedef typename VertexBase::template Rebind_TDS::Other Vb2; - typedef Advancing_front_surface_reconstruction_vertex_base_3 Other; - }; + template < typename TDS2 > + struct Rebind_TDS { + typedef typename VertexBase::template Rebind_TDS::Other Vb2; + typedef Advancing_front_surface_reconstruction_vertex_base_3 Other; + }; - template friend class Advancing_front_surface_reconstruction; + template friend class Advancing_front_surface_reconstruction; - typedef VertexBase Base; - typedef typename Base::Vertex_handle Vertex_handle; - typedef typename Base::Cell_handle Cell_handle; - typedef typename VertexBase::Point Point; - typedef double coord_type; + typedef VertexBase Base; + typedef typename Base::Vertex_handle Vertex_handle; + typedef typename Base::Cell_handle Cell_handle; + typedef typename VertexBase::Point Point; + typedef double coord_type; - typedef Triple< Cell_handle, int, int > Edge; - typedef std::pair< Edge, int > Edge_incident_facet; - typedef std::pair< Edge_incident_facet, Edge_incident_facet > IO_edge_type; + typedef Triple< Cell_handle, int, int > Edge; + typedef std::pair< Edge, int > Edge_incident_facet; + typedef std::pair< Edge_incident_facet, Edge_incident_facet > IO_edge_type; - typedef coord_type criteria; + typedef coord_type criteria; - typedef std::pair< criteria, IO_edge_type > Radius_edge_type; - typedef std::pair< Radius_edge_type, int > Border_elt; - typedef std::pair< Vertex_handle, Border_elt > Next_border_elt; + typedef std::pair< criteria, IO_edge_type > Radius_edge_type; + typedef std::pair< Radius_edge_type, int > Border_elt; + typedef std::pair< Vertex_handle, Border_elt > Next_border_elt; - //par convention je remplis d'abord first et si necessaire second... - typedef std::pair< Next_border_elt*, Next_border_elt*> Intern_successors_type; + //par convention je remplis d'abord first et si necessaire second... + typedef std::pair< Next_border_elt*, Next_border_elt*> Intern_successors_type; -public: + public: - typedef std::pair< criteria, IO_edge_type* > Radius_ptr_type; - typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; - typedef std::pair< criteria, Edge_like > Incidence_request_elt; - typedef std::list< Incidence_request_elt > Incidence_request_type; - typedef typename Incidence_request_type::iterator Incidence_request_iterator; + typedef std::pair< criteria, IO_edge_type* > Radius_ptr_type; + typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; + typedef std::pair< criteria, Edge_like > Incidence_request_elt; + typedef std::list< Incidence_request_elt > Incidence_request_type; + typedef typename Incidence_request_type::iterator Incidence_request_iterator; - //-------------------- DATA MEMBERS --------------------------------- + //-------------------- DATA MEMBERS --------------------------------- - typedef int Info; // so that we are a model of TriangulationVertexBaseWithInfo_3 + typedef int Info; // so that we are a model of TriangulationVertexBaseWithInfo_3 -private: - int m_id; - int m_mark; - int m_post_mark; - Intern_successors_type* m_incident_border; + private: + int m_id; + int m_mark; + int m_post_mark; + Intern_successors_type* m_incident_border; - // Instead of having a set per vertex, there is a global list - // in the surface reconstruction class - // and two iterators per vertex in this list - // Note that m_ie_last is not past the end - // m_ie_first == m_ie_last == interior_edge.end() iff the set is empty - typename std::list::iterator m_ie_first, m_ie_last; + // Instead of having a set per vertex, there is a global list + // in the surface reconstruction class + // and two iterators per vertex in this list + // Note that m_ie_last is not past the end + // m_ie_first == m_ie_last == interior_edge.end() iff the set is empty + typename std::list::iterator m_ie_first, m_ie_last; - // We do the same for the incidence requests - typename std::list< Incidence_request_elt >::iterator m_ir_first, m_ir_last; + // We do the same for the incidence requests + typename std::list< Incidence_request_elt >::iterator m_ir_first, m_ir_last; - //-------------------- CONSTRUCTORS --------------------------------- + //-------------------- CONSTRUCTORS --------------------------------- -public: + public: - Advancing_front_surface_reconstruction_vertex_base_3() - : VertexBase(), m_mark(-1), - m_post_mark(-1) + Advancing_front_surface_reconstruction_vertex_base_3() + : VertexBase(), m_mark(-1), + m_post_mark(-1) {} - Advancing_front_surface_reconstruction_vertex_base_3(const Point & p) - : VertexBase(p), m_mark(-1), - m_post_mark(-1) - {} + Advancing_front_surface_reconstruction_vertex_base_3(const Point & p) + : VertexBase(p), m_mark(-1), + m_post_mark(-1) + {} - Advancing_front_surface_reconstruction_vertex_base_3(const Point & p, Cell_handle f) - : VertexBase(p, f), m_mark(-1), - m_post_mark(-1) + Advancing_front_surface_reconstruction_vertex_base_3(const Point & p, Cell_handle f) + : VertexBase(p, f), m_mark(-1), + m_post_mark(-1) {} - Advancing_front_surface_reconstruction_vertex_base_3(Cell_handle f) - : VertexBase(f), m_mark(-1), - m_post_mark(-1) + Advancing_front_surface_reconstruction_vertex_base_3(Cell_handle f) + : VertexBase(f), m_mark(-1), + m_post_mark(-1) {} - Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other) - : VertexBase(), m_mark(-1), - m_post_mark(-1) - {} + Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other) + : VertexBase(), m_mark(-1), + m_post_mark(-1) + {} - //-------------------- MEMBER FUNCTIONS ----------------------------- + //-------------------- MEMBER FUNCTIONS ----------------------------- -public: + public: - int& id() - { - return m_id; - } + int& id() + { + return m_id; + } - const int& id() const - { - return m_id; - } + const int& id() const + { + return m_id; + } - int& info() - { - return m_id; - } + int& info() + { + return m_id; + } - const int& info() const - { - return m_id; - } + const int& info() const + { + return m_id; + } - //------------------------------------------------------------------- -private: + //------------------------------------------------------------------- + private: - void delete_border() - { - m_incident_border = NULL; - } + void delete_border() + { + m_incident_border = NULL; + } - inline Next_border_elt* next_on_border(const int& i) const + inline Next_border_elt* next_on_border(const int& i) const { if (m_incident_border == NULL) return NULL; //vh is interior if (m_incident_border->first->first != NULL) @@ -179,14 +179,14 @@ private: - inline bool is_border_edge(Vertex_handle v) const + inline bool is_border_edge(Vertex_handle v) const { if (m_incident_border == NULL) return false; return ((m_incident_border->first->first == v)|| (m_incident_border->second->first == v)); } - inline Next_border_elt* border_elt(Vertex_handle v) const + inline Next_border_elt* border_elt(Vertex_handle v) const { if (m_incident_border == NULL) return NULL; if (m_incident_border->first->first == v) return m_incident_border->first; @@ -194,21 +194,21 @@ private: return NULL; } -public: - inline Next_border_elt* first_incident() const + public: + inline Next_border_elt* first_incident() const { if (m_incident_border == NULL) return NULL; return m_incident_border->first; } -private: - inline Next_border_elt* second_incident() const + private: + inline Next_border_elt* second_incident() const { if (m_incident_border == NULL) return NULL; return m_incident_border->second; } - inline void set_next_border_elt(const Next_border_elt& elt) + inline void set_next_border_elt(const Next_border_elt& elt) { if (m_incident_border->first->first == NULL) *m_incident_border->first = elt; @@ -222,34 +222,34 @@ private: - //------------------------------------------------------------------- + //------------------------------------------------------------------- -public: + public: - inline bool is_on_border() const + inline bool is_on_border() const { return (m_mark > 0); } - inline bool not_interior() const + inline bool not_interior() const { return (m_mark != 0); } - inline int number_of_incident_border() const + inline int number_of_incident_border() const { return m_mark; } - inline bool is_exterior() const + inline bool is_exterior() const { return (m_mark < 0); } - //------------------------------------------------------------------- -private: + //------------------------------------------------------------------- + private: - inline void inc_mark() + inline void inc_mark() { if (m_mark==-1) m_mark=1; @@ -257,18 +257,18 @@ private: m_mark++; } - //------------------------------------------------------------------- -public: - inline void set_post_mark(const int& i) + //------------------------------------------------------------------- + public: + inline void set_post_mark(const int& i) { m_post_mark = i; } - inline bool is_post_marked(const int& i) + inline bool is_post_marked(const int& i) { return (m_post_mark == i); } -}; + }; } // namespace CGAL diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h index c52a1ce5d86..e39eada6e8e 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h @@ -24,84 +24,84 @@ // When it gets reoriented by the TDS, it also changes the facet namespace CGAL { -namespace AFSR { + namespace AFSR { -template < typename GT, - typename F3, - typename Fb = CGAL::Triangulation_ds_face_base_2<> > -class Surface_face_base_2 - : public Fb -{ - typedef typename Fb::Triangulation_data_structure Tds; + template < typename GT, + typename F3, + typename Fb = CGAL::Triangulation_ds_face_base_2<> > + class Surface_face_base_2 + : public Fb + { + typedef typename Fb::Triangulation_data_structure Tds; -public: - typedef typename Tds::Face_handle Face_handle; - typedef typename Tds::Vertex_handle Vertex_handle; + public: + typedef typename Tds::Face_handle Face_handle; + typedef typename Tds::Vertex_handle Vertex_handle; - template < typename TDS2 > - struct Rebind_TDS { - typedef typename Fb::template Rebind_TDS::Other Fb2; - typedef Surface_face_base_2 Other; - }; + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Fb::template Rebind_TDS::Other Fb2; + typedef Surface_face_base_2 Other; + }; -private: - F3 _facet; - bool _is_on_surface; + private: + F3 _facet; + bool _is_on_surface; -public: - Surface_face_base_2() - : Fb(), _is_on_surface(true) - {} + public: + Surface_face_base_2() + : Fb(), _is_on_surface(true) + {} - Surface_face_base_2(Vertex_handle v0, - Vertex_handle v1, - Vertex_handle v2) - : Fb(v0, v1, v2), _is_on_surface(true) - {} + Surface_face_base_2(Vertex_handle v0, + Vertex_handle v1, + Vertex_handle v2) + : Fb(v0, v1, v2), _is_on_surface(true) + {} - Surface_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), _is_on_surface(true) - {} + Surface_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), _is_on_surface(true) + {} - void set_facet(const F3& facet) - { - _facet = facet; - } + void set_facet(const F3& facet) + { + _facet = facet; + } - const F3& facet() const - { - return _facet; - } + const F3& facet() const + { + return _facet; + } - void set_is_on_surface(bool is_on_surface) - { - _is_on_surface = is_on_surface; - } + void set_is_on_surface(bool is_on_surface) + { + _is_on_surface = is_on_surface; + } - bool is_on_surface() const - { - return _is_on_surface; - } + bool is_on_surface() const + { + return _is_on_surface; + } - void reorient() - { - Fb::reorient(); - if( is_on_surface()){ - _facet = std::make_pair(_facet.first->neighbor(_facet.second), - _facet.first->neighbor(_facet.second)->index(_facet.first)); - } - } + void reorient() + { + Fb::reorient(); + if( is_on_surface()){ + _facet = std::make_pair(_facet.first->neighbor(_facet.second), + _facet.first->neighbor(_facet.second)->index(_facet.first)); + } + } -}; + }; -} // namespace AFSR + } // namespace AFSR } // namespace CGAL #endif // CGAL_AFSR_SURFACE_FACE_BASE_2_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h index 6c15ca2185b..9e231e44519 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h @@ -24,55 +24,55 @@ #include namespace CGAL { -namespace AFSR { + namespace AFSR { -template < typename GT, - typename V3, - typename Vb = CGAL::Triangulation_ds_vertex_base_2<> > -class Surface_vertex_base_2 - : public Vb + template < typename GT, + typename V3, + typename Vb = CGAL::Triangulation_ds_vertex_base_2<> > + class Surface_vertex_base_2 + : public Vb -{ - typedef typename Vb::Triangulation_data_structure Tds; -public: - typedef GT Geom_traits; - typedef typename GT::Point_3 Point; - typedef Tds Triangulation_data_structure; - typedef typename Tds::Face_handle Face_handle; - typedef typename Tds::Vertex_handle Vertex_handle; + { + typedef typename Vb::Triangulation_data_structure Tds; + public: + typedef GT Geom_traits; + typedef typename GT::Point_3 Point; + typedef Tds Triangulation_data_structure; + typedef typename Tds::Face_handle Face_handle; + typedef typename Tds::Vertex_handle Vertex_handle; - template < typename TDS2 > - struct Rebind_TDS { - typedef typename Vb::template Rebind_TDS::Other Vb2; - typedef Surface_vertex_base_2 Other; - }; + template < typename TDS2 > + struct Rebind_TDS { + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef Surface_vertex_base_2 Other; + }; -private: - V3 _vertex; -public: - Surface_vertex_base_2() : Vb() {} - Surface_vertex_base_2(Face_handle f) : Vb(f) {} + private: + V3 _vertex; + public: + Surface_vertex_base_2() : Vb() {} + Surface_vertex_base_2(Face_handle f) : Vb(f) {} - void set_vertex(const V3& v) - { - _vertex = v; - } + void set_vertex(const V3& v) + { + _vertex = v; + } - V3 vertex_3() const - { - return _vertex; - } + V3 vertex_3() const + { + return _vertex; + } - const Point& point() const { return _vertex->point(); } + const Point& point() const { return _vertex->point(); } -}; + }; -} // namespace AFSR + } // namespace AFSR } // namespace CGAL #endif //CGAL::AFSR_SURFACE_VERTEX_BASE_2_H diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h index dc5f3603b8d..2cc32c38149 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h @@ -26,65 +26,65 @@ namespace CGAL { template -class Advancing_front_polyhedron_reconstruction; + class Advancing_front_polyhedron_reconstruction; -namespace AFSR { + namespace AFSR { - template -class Construct_polyhedron: public CGAL::Modifier_base { + template + class Construct_polyhedron: public CGAL::Modifier_base { - const Surface& s; + const Surface& s; -public: - Construct_polyhedron(Surface& s) - : s(s) - {} + public: + Construct_polyhedron(Surface& s) + : s(s) + {} - void operator()( HDS& hds) - { - CGAL::Polyhedron_incremental_builder_3 B( hds, true); - B.begin_surface( s.number_of_vertices(), s.number_of_facets(), 6* s.number_of_facets()); + void operator()( HDS& hds) + { + CGAL::Polyhedron_incremental_builder_3 B( hds, true); + B.begin_surface( s.number_of_vertices(), s.number_of_facets(), 6* s.number_of_facets()); - typedef typename Surface::TDS_2 TDS_2; - typedef typename TDS_2::Face_iterator Face_iterator; - typedef typename TDS_2::Vertex_iterator Vertex_iterator; + typedef typename Surface::TDS_2 TDS_2; + typedef typename TDS_2::Face_iterator Face_iterator; + typedef typename TDS_2::Vertex_iterator Vertex_iterator; - const TDS_2& tds = s.triangulation_data_structure_2(); + const TDS_2& tds = s.triangulation_data_structure_2(); - int index = 0; - Vertex_iterator end = tds.vertices_end(); + int index = 0; + Vertex_iterator end = tds.vertices_end(); - for(Vertex_iterator vit = tds.vertices_begin(); vit != end; ++vit){ - if(vit->vertex_3() != s.triangulation_3().infinite_vertex()){ - B.add_vertex(vit->point()); - vit->vertex_3()->id() = index++; - } - } - - for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ - - if(fit->is_on_surface()){ - B.begin_facet(); - for(int i=0; i < 3; i++){ - B.add_vertex_to_facet(fit->vertex(i)->vertex_3()->id()); + for(Vertex_iterator vit = tds.vertices_begin(); vit != end; ++vit){ + if(vit->vertex_3() != s.triangulation_3().infinite_vertex()){ + B.add_vertex(vit->point()); + vit->vertex_3()->id() = index++; } - B.end_facet(); } + + for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ + + if(fit->is_on_surface()){ + B.begin_facet(); + for(int i=0; i < 3; i++){ + B.add_vertex_to_facet(fit->vertex(i)->vertex_3()->id()); + } + B.end_facet(); + } + } + B.end_surface(); } - B.end_surface(); - } -}; + }; -template -void -construct_polyhedron(Polyhedron& P, Surface& surface) -{ - typedef typename Polyhedron::HalfedgeDS HalfedgeDS; - Construct_polyhedron builder(surface); - P.delegate(builder); -} + template + void + construct_polyhedron(Polyhedron& P, Surface& surface) + { + typedef typename Polyhedron::HalfedgeDS HalfedgeDS; + Construct_polyhedron builder(surface); + P.delegate(builder); + } -} // namespace AFSR + } // namespace AFSR } // namespace CGAL #endif // CGAL_AFSR_CONSTRUCT_POLYHEDRON_2 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h index a217aeb4fe0..54ba7943b87 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h @@ -23,125 +23,125 @@ namespace CGAL { template -class Advancing_front_surface_reconstruction; + class Advancing_front_surface_reconstruction; -namespace AFSR { + namespace AFSR { - template -typename TDS::Vertex_handle -construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface) -{ - - typedef typename TDS::Vertex_handle Vertex_handle; - typedef std::pair Vh_pair; - typedef typename TDS::Face_handle Face_handle; - typedef typename TDS::Edge Edge; - - - Triangulation& T = surface.triangulation_3(); - // create an infinite-vertex and infinite faces with the - // boundary edges if any. - // return the infinite vertex if created - Vertex_handle vinf; - - std::vector vvh; - if(tds.number_of_vertices() != 0){ - tds.clear(); - } - int dim = 2; - tds.set_dimension(dim); - - CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); - - int i=0; - for (typename Triangulation::Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++){ - typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; - if ((!v_it->is_exterior()) && d == -1){ - d = i; - Vertex_handle vh = tds.create_vertex(); - vvh.push_back(vh); - vh->set_vertex(typename Triangulation::Vertex_handle(v_it)); - i++; - } - } - std::map edge_map; - - for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); - f_it++) + template + typename TDS::Vertex_handle + construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface) { - typename Triangulation::Cell_handle n, c = (*f_it).first; - int ni, ci = (*f_it).second; - n = c->neighbor(ci); - ni = n->index(c); - int i1, i2 ,i3; - if (c->is_selected_facet(ci)) - { - i1 = (ci+1) & 3; - i2 = (ci+2) & 3; - i3 = (ci+3) & 3; + typedef typename TDS::Vertex_handle Vertex_handle; + typedef std::pair Vh_pair; + typedef typename TDS::Face_handle Face_handle; + typedef typename TDS::Edge Edge; + + + Triangulation& T = surface.triangulation_3(); + // create an infinite-vertex and infinite faces with the + // boundary edges if any. + // return the infinite vertex if created + Vertex_handle vinf; + + std::vector vvh; + if(tds.number_of_vertices() != 0){ + tds.clear(); + } + int dim = 2; + tds.set_dimension(dim); + + CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); + + int i=0; + for (typename Triangulation::Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++){ + typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; + if ((!v_it->is_exterior()) && d == -1){ + d = i; + Vertex_handle vh = tds.create_vertex(); + vvh.push_back(vh); + vh->set_vertex(typename Triangulation::Vertex_handle(v_it)); + i++; + } + } + std::map edge_map; + + for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + typename Triangulation::Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; - Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]], - vvh[vertex_index_map[c->vertex(i2)]], - vvh[vertex_index_map[c->vertex(i3)]]); - fh->set_facet(*f_it); - vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh); - vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh); - vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh); - for (int ih = 0; ih < 3; ++ih) { - tds.set_adjacency(fh, ih, edge_map); - } - } + Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]], + vvh[vertex_index_map[c->vertex(i2)]], + vvh[vertex_index_map[c->vertex(i3)]]); + fh->set_facet(*f_it); + vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh); + vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh); + vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh); + for (int ih = 0; ih < 3; ++ih) { + tds.set_adjacency(fh, ih, edge_map); + } + } - if (n->is_selected_facet(ni)) - { - i1 = (ni+1) & 3; - i2 = (ni+2) & 3; - i3 = (ni+3) & 3; - Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]], - vvh[vertex_index_map[n->vertex(i2)]], - vvh[vertex_index_map[n->vertex(i3)]]); - fh->set_facet(std::make_pair(n, ni)); - vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh); - vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh); - vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh); - for (int ih = 0; ih < 3; ++ih) { - tds.set_adjacency(fh, ih, edge_map); - } - } + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]], + vvh[vertex_index_map[n->vertex(i2)]], + vvh[vertex_index_map[n->vertex(i3)]]); + fh->set_facet(std::make_pair(n, ni)); + vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh); + vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh); + vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh); + for (int ih = 0; ih < 3; ++ih) { + tds.set_adjacency(fh, ih, edge_map); + } + } + } + + if ( !edge_map.empty()) { + vinf = tds.create_vertex(); + vinf->set_vertex(T.infinite_vertex()); + std::map inf_edge_map; + while (!edge_map.empty()) { + Face_handle fh = edge_map.begin()->second.first; + int ih = edge_map.begin()->second.second; + Face_handle fn = tds.create_face( vinf, + fh->vertex(TDS::cw(ih)), + fh->vertex(TDS::ccw(ih))); + fn->set_facet(std::make_pair( typename Triangulation::Cell_handle(),0)); + fn->set_is_on_surface(false); + vinf->set_face(fn); + tds.set_adjacency(fn, 0, fh, ih); + tds.set_adjacency(fn, 1, inf_edge_map); + tds.set_adjacency(fn, 2, inf_edge_map); + edge_map.erase(edge_map.begin()); + } + CGAL_triangulation_assertion(inf_edge_map.empty()); + } + tds.reorient_faces(); + return vinf; + } - if ( !edge_map.empty()) { - vinf = tds.create_vertex(); - vinf->set_vertex(T.infinite_vertex()); - std::map inf_edge_map; - while (!edge_map.empty()) { - Face_handle fh = edge_map.begin()->second.first; - int ih = edge_map.begin()->second.second; - Face_handle fn = tds.create_face( vinf, - fh->vertex(TDS::cw(ih)), - fh->vertex(TDS::ccw(ih))); - fn->set_facet(std::make_pair( typename Triangulation::Cell_handle(),0)); - fn->set_is_on_surface(false); - vinf->set_face(fn); - tds.set_adjacency(fn, 0, fh, ih); - tds.set_adjacency(fn, 1, inf_edge_map); - tds.set_adjacency(fn, 2, inf_edge_map); - edge_map.erase(edge_map.begin()); - } - CGAL_triangulation_assertion(inf_edge_map.empty()); - } - tds.reorient_faces(); - return vinf; -} - - -} // namespace AFSR + } // namespace AFSR } // namespace CGAL #endif // CGAL_AFSR_CONSTRUCT_SURFACE_2 diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h index ae68077bc47..5240009520e 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h @@ -20,120 +20,120 @@ #ifndef CGAL_AFSR_ORIENT namespace CGAL { -namespace AFSR { + namespace AFSR { - template -typename TDS::Vertex_handle - orient(TDS& tds, const Advancing_front_surface_reconstruction& surface) -{ - - typedef typename TDS::Vertex_handle Vertex_handle; - typedef std::pair Vh_pair; - typedef typename TDS::Face_handle Face_handle; - typedef typename TDS::Edge Edge; - - Triangulation& T = surface.triangulation_3(); - // create an infinite-vertex and infinite faces with the - // boundary edges if any. - // return the infinite vertex if created - Vertex_handle vinf; - - std::vector vvh; - if(tds.number_of_vertices() != 0) tds.clear(); - int dim = 2; - tds.set_dimension(dim); - - CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); - - int i=0; - for (typename Triangulation::Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); - v_it++){ - typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; - if ((!v_it->is_exterior()) && d == -1){ - d = i; - Vertex_handle vh = tds.create_vertex(); - vvh.push_back(vh); - vh->set_point(v_it->point()); - i++; - } - } - std::map edge_map; - - - for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); - f_it++) + template + typename TDS::Vertex_handle + orient(TDS& tds, const Advancing_front_surface_reconstruction& surface) { - typename Triangulation::Cell_handle n, c = (*f_it).first; - int ni, ci = (*f_it).second; - n = c->neighbor(ci); - ni = n->index(c); - int i1, i2 ,i3; - if (c->is_selected_facet(ci)) - { - i1 = (ci+1) & 3; - i2 = (ci+2) & 3; - i3 = (ci+3) & 3; + typedef typename TDS::Vertex_handle Vertex_handle; + typedef std::pair Vh_pair; + typedef typename TDS::Face_handle Face_handle; + typedef typename TDS::Edge Edge; + + Triangulation& T = surface.triangulation_3(); + // create an infinite-vertex and infinite faces with the + // boundary edges if any. + // return the infinite vertex if created + Vertex_handle vinf; + + std::vector vvh; + if(tds.number_of_vertices() != 0) tds.clear(); + int dim = 2; + tds.set_dimension(dim); + + CGAL::Unique_hash_map vertex_index_map(-1, T.number_of_vertices()); + + int i=0; + for (typename Triangulation::Finite_vertices_iterator v_it = T.finite_vertices_begin(); + v_it != T.finite_vertices_end(); + v_it++){ + typename CGAL::Unique_hash_map::Data& d = vertex_index_map[v_it]; + if ((!v_it->is_exterior()) && d == -1){ + d = i; + Vertex_handle vh = tds.create_vertex(); + vvh.push_back(vh); + vh->set_point(v_it->point()); + i++; + } + } + std::map edge_map; + + + for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); + f_it++) + { + typename Triangulation::Cell_handle n, c = (*f_it).first; + int ni, ci = (*f_it).second; + n = c->neighbor(ci); + ni = n->index(c); + int i1, i2 ,i3; + + if (c->is_selected_facet(ci)) + { + i1 = (ci+1) & 3; + i2 = (ci+2) & 3; + i3 = (ci+3) & 3; - Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]], - vvh[vertex_index_map[c->vertex(i2)]], - vvh[vertex_index_map[c->vertex(i3)]]); - vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh); - vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh); - vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh); - for (int ih = 0; ih < 3; ++ih) { - tds.set_adjacency(fh, ih, edge_map); - } - } + Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]], + vvh[vertex_index_map[c->vertex(i2)]], + vvh[vertex_index_map[c->vertex(i3)]]); + vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh); + vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh); + vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh); + for (int ih = 0; ih < 3; ++ih) { + tds.set_adjacency(fh, ih, edge_map); + } + } - if (n->is_selected_facet(ni)) - { - i1 = (ni+1) & 3; - i2 = (ni+2) & 3; - i3 = (ni+3) & 3; - Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]], - vvh[vertex_index_map[n->vertex(i2)]], - vvh[vertex_index_map[n->vertex(i3)]]); - vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh); - vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh); - vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh); - for (int ih = 0; ih < 3; ++ih) { - tds.set_adjacency(fh, ih, edge_map); - } - } + if (n->is_selected_facet(ni)) + { + i1 = (ni+1) & 3; + i2 = (ni+2) & 3; + i3 = (ni+3) & 3; + Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]], + vvh[vertex_index_map[n->vertex(i2)]], + vvh[vertex_index_map[n->vertex(i3)]]); + vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh); + vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh); + vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh); + for (int ih = 0; ih < 3; ++ih) { + tds.set_adjacency(fh, ih, edge_map); + } + } + } + + if ( !edge_map.empty()) { + vinf = tds.create_vertex(); + std::map inf_edge_map; + while (!edge_map.empty()) { + Face_handle fh = edge_map.begin()->second.first; + int ih = edge_map.begin()->second.second; + Face_handle fn = tds.create_face( vinf, + fh->vertex(TDS::cw(ih)), + fh->vertex(TDS::ccw(ih))); + vinf->set_face(fn); + tds.set_adjacency(fn, 0, fh, ih); + tds.set_adjacency(fn, 1, inf_edge_map); + tds.set_adjacency(fn, 2, inf_edge_map); + edge_map.erase(edge_map.begin()); + } + CGAL_triangulation_assertion(inf_edge_map.empty()); + } + + + tds.reorient_faces(); + return vinf; + } - - if ( !edge_map.empty()) { - vinf = tds.create_vertex(); - std::map inf_edge_map; - while (!edge_map.empty()) { - Face_handle fh = edge_map.begin()->second.first; - int ih = edge_map.begin()->second.second; - Face_handle fn = tds.create_face( vinf, - fh->vertex(TDS::cw(ih)), - fh->vertex(TDS::ccw(ih))); - vinf->set_face(fn); - tds.set_adjacency(fn, 0, fh, ih); - tds.set_adjacency(fn, 1, inf_edge_map); - tds.set_adjacency(fn, 2, inf_edge_map); - edge_map.erase(edge_map.begin()); - } - CGAL_triangulation_assertion(inf_edge_map.empty()); - } - - - tds.reorient_faces(); - return vinf; - -} -} // namespace AFSR + } // namespace AFSR } // namespace CGAL #endif //CGAL_AFSR_ORIENT diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h index c888b69ace2..e9f5fc3b183 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h @@ -24,35 +24,35 @@ namespace CGAL { -template -class Advancing_front_surface_reconstruction; + template + class Advancing_front_surface_reconstruction; -template -OutputIterator + template + OutputIterator write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S) -{ - typedef Advancing_front_surface_reconstruction Surface; - typedef typename Surface::TDS_2 TDS_2; - typedef typename TDS_2::Face_iterator Face_iterator; + { + typedef Advancing_front_surface_reconstruction Surface; + typedef typename Surface::TDS_2 TDS_2; + typedef typename TDS_2::Face_iterator Face_iterator; - if(S.triangulation_3().dimension() < 3){ - std::cerr << "not 3D\n"; - return out; - } - const TDS_2& tds = S.triangulation_data_structure_2(); - - for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ - - if(fit->is_on_surface()){ - *out++ = CGAL::make_array(std::size_t(fit->vertex(0)->vertex_3()->id()), - std::size_t(fit->vertex(1)->vertex_3()->id()), - std::size_t(fit->vertex(2)->vertex_3()->id())); + if(S.triangulation_3().dimension() < 3){ + std::cerr << "not 3D\n"; + return out; + } + const TDS_2& tds = S.triangulation_data_structure_2(); + + for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ + + if(fit->is_on_surface()){ + *out++ = CGAL::make_array(std::size_t(fit->vertex(0)->vertex_3()->id()), + std::size_t(fit->vertex(1)->vertex_3()->id()), + std::size_t(fit->vertex(2)->vertex_3()->id())); + } } - } return out; -} + } } From c7ca25a7c0b11a4a4299c629dd2a25787895081b Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 18 Jun 2015 19:03:04 +0200 Subject: [PATCH 097/114] Add Default; get rid of Options --- .../boundaries.cpp | 34 +++++++- .../Advancing_front_surface_reconstruction.h | 85 +++++++------------ ...ont_surface_reconstruction_vertex_base_3.h | 2 +- .../CGAL/internal/AFSR/construct_surface_2.h | 6 +- 4 files changed, 69 insertions(+), 58 deletions(-) diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp index 32c566095ae..98d3d24fd44 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp @@ -4,8 +4,36 @@ #include #include +struct Perimeter { + + double bound; + + Perimeter(double bound) + : bound(bound) + {} + + // The point type that will be injected here will be + // CGAL::Exact_predicates_inexact_constructions_kernel::Point_3 + template + bool operator()(const Point& p, const Point& q, const Point& r) const + { + // bound == 0 is better than bound < infinity + // as it avoids the distance computations + if(bound == 0){ + return false; + } + double d = sqrt(squared_distance(p,q)); + if(d>bound) return true; + d += sqrt(squared_distance(p,r)) ; + if(d>bound) return true; + d+= sqrt(squared_distance(q,r)); + return d>bound; + } +}; + + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; -typedef CGAL::Advancing_front_surface_reconstruction<> Reconstruction; +typedef CGAL::Advancing_front_surface_reconstruction Reconstruction; typedef Reconstruction::Triangulation_3 Triangulation_3; typedef Reconstruction::Outlier_range Outlier_range; typedef Reconstruction::Boundary_range Boundary_range; @@ -13,14 +41,16 @@ typedef Reconstruction::Vertex_on_boundary_range Vertex_on_boundary_range; typedef Reconstruction::Vertex_handle Vertex_handle; typedef K::Point_3 Point_3; + int main(int argc, char* argv[]) { std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); std::istream_iterator begin(in); std::istream_iterator end; + Perimeter perimeter(0.5); Triangulation_3 dt(begin, end); - Reconstruction reconstruction(dt); + Reconstruction reconstruction(dt, perimeter); reconstruction.run(); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index f46cc857ad1..0813252b80a 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -43,7 +43,6 @@ #include #include #include -#include #include namespace CGAL { @@ -169,14 +168,16 @@ namespace CGAL { template < - class Triangulation = Delaunay_triangulation_3, Advancing_front_surface_reconstruction_cell_base_3 > >, + class Triangulation_ = Default, class Reject = Always_false> class Advancing_front_surface_reconstruction { + typedef typename Default::Get, Advancing_front_surface_reconstruction_cell_base_3 > > >::type Triangulation; + public: typedef Triangulation Triangulation_3; typedef typename Triangulation_3::Geom_traits Kernel; - typedef Advancing_front_surface_reconstruction Extract; + typedef Advancing_front_surface_reconstruction Extract; typedef typename Triangulation_3::Geom_traits Geom_traits; typedef typename Kernel::FT coord_type; @@ -250,7 +251,8 @@ namespace CGAL { int _number_of_border; const coord_type COS_ALPHA_SLIVER; - const coord_type COS_BETA; + coord_type COS_BETA; + const int NB_BORDER_MAX; coord_type DELTA; // = sampling quality of the border coord_type K, min_K; const coord_type eps; @@ -278,6 +280,8 @@ namespace CGAL { Vertex_handle added_vertex; bool deal_with_2d; Reject reject; + int max_connected_component; + double K_init, K_step; std::list interior_edges; std::list< Incidence_request_elt > incidence_requests; typename std::list< Incidence_request_elt >::iterator sentinel; @@ -560,15 +564,15 @@ namespace CGAL { public: Advancing_front_surface_reconstruction(Triangulation_3& T_, - const AFSR_options& opt = AFSR_options(), Reject reject = Reject()) - : T(T_), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), COS_BETA(opt.COS_BETA), DELTA(opt.delta), min_K(HUGE_VAL), + : T(T_), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), + NB_BORDER_MAX(15), DELTA(.86), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), - deal_with_2d(false), reject(reject) + deal_with_2d(false), reject(reject), max_connected_component(-1), K_init(1.1), K_step(.1) { if(T.dimension() == 2){ @@ -604,17 +608,6 @@ namespace CGAL { */ void run(double radius_ratio_bound=5, double beta=0.52) - { - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - // TODO: what to do with beta - - run(opt); - } - - - void run(const AFSR_options opt) { if(T.dimension() < 3){ return; @@ -629,24 +622,24 @@ namespace CGAL { { //std::cerr << "Growing connected component " << _number_of_connected_components << std::endl; extend_timer.start(); - extend(opt.K_init, opt.K_step, opt.K); + extend(); extend_timer.stop(); if ((number_of_facets() > static_cast(T.number_of_vertices()))&& - (opt.NB_BORDER_MAX > 0)) + (NB_BORDER_MAX > 0)) // en principe 2*nb_sommets = nb_facettes: y a encore de la marge!!! { - while(postprocessing(opt.NB_BORDER_MAX)){ + while(postprocessing()){ extend2_timer.start(); - extend(opt.K_init, opt.K_step, opt.K); + extend(); extend2_timer.stop(); } } } }while(re_init && - ((_number_of_connected_components < opt.max_connected_comp)|| - (opt.max_connected_comp < 0))); + ((_number_of_connected_components < max_connected_component)|| + (max_connected_component < 0))); _tds_2_inf = AFSR::construct_surface(_tds_2, *this); @@ -1855,7 +1848,7 @@ namespace CGAL { //--------------------------------------------------------------------- void - extend(const coord_type& K_init, const coord_type& K_step, const coord_type& K_max) + extend() { // initilisation de la variable globale K: qualite d'echantillonnage requise K = K_init; // valeur d'initialisation de K pour commencer prudemment... @@ -1924,11 +1917,11 @@ namespace CGAL { while((!_ordered_border.empty())&& (_ordered_border.begin()->first < STANDBY_CANDIDATE_BIS)); - K += (std::max)(K_step, min_K-K+eps); + K += (std::max)(K_step, min_K - K + eps); // on augmente progressivement le K mais on a deja rempli sans // faire des betises auparavant... } - while((!_ordered_border.empty())&&(K <= K_max)&&(min_K != HUGE_VAL)); + while((!_ordered_border.empty())&&(K <= K)&&(min_K != HUGE_VAL)); #ifdef VERBOSE if ((min_K < HUGE_VAL)&&(!_ordered_border.empty())) { @@ -2208,7 +2201,7 @@ namespace CGAL { //--------------------------------------------------------------------- bool - postprocessing(int NB_BORDER_MAX) + postprocessing() { postprocess_timer.start(); @@ -2340,7 +2333,7 @@ namespace CGAL { PointIterator e, IndexTripleIterator out, double radius_ratio_bound = 5, - double beta = 0.52 ) + double beta = 0.52 ) { typedef Exact_predicates_inexact_constructions_kernel Kernel; typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; @@ -2355,11 +2348,8 @@ namespace CGAL { Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), boost::make_transform_iterator(e, AFSR::Auto_count() ) ); - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - Reconstruction R(dt,opt); - R.run(opt); + Reconstruction R(dt); + R.run(radius_ratio_bound, acos(beta)); write_triple_indices(out, R); return out; } @@ -2372,7 +2362,7 @@ namespace CGAL { IndexTripleIterator out, Filter filter, double radius_ratio_bound = 5, - double beta = 0.52 ) + double beta = 0.52 ) { typedef Exact_predicates_inexact_constructions_kernel Kernel; typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; @@ -2390,11 +2380,8 @@ namespace CGAL { Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - Reconstruction R(dt,opt, filter); - R.run(opt); + Reconstruction R(dt, filter); + R.run(radius_ratio_bound, acos(beta)); write_triple_indices(out, R); return out; } @@ -2407,7 +2394,7 @@ namespace CGAL { Polyhedron_3& polyhedron, Filter filter, double radius_ratio_bound = 5, - double beta = 0.52) + double beta = 0.52) { typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; @@ -2425,11 +2412,8 @@ namespace CGAL { Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - Reconstruction R(dt, opt,filter); - R.run(opt); + Reconstruction R(dt, filter); + R.run(radius_ratio_bound, acos(beta)); AFSR::construct_polyhedron(polyhedron, R); } @@ -2440,7 +2424,7 @@ namespace CGAL { PointIterator e, Polyhedron_3& polyhedron, double radius_ratio_bound = 5, - double beta = 0.52) + double beta = 0.52) { typedef Advancing_front_surface_reconstruction_vertex_base_3 LVb; typedef Advancing_front_surface_reconstruction_cell_base_3 LCb; @@ -2454,11 +2438,8 @@ namespace CGAL { Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), boost::make_transform_iterator(e, AFSR::Auto_count() ) ); - AFSR_options opt; - opt.K = radius_ratio_bound; - opt.COS_BETA = acos(beta); - Reconstruction R(dt, opt); - R.run(opt); + Reconstruction R(dt); + R.run(radius_ratio_bound, acos(beta)); AFSR::construct_polyhedron(polyhedron, R); } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index 0cd528afc83..06d8f6c0771 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -126,7 +126,7 @@ namespace CGAL { {} Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other) - : VertexBase(), m_mark(-1), + : VertexBase(other), m_mark(-1), m_post_mark(-1) {} diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h index 54ba7943b87..8fc8af2a308 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h @@ -28,16 +28,16 @@ namespace CGAL { namespace AFSR { - template + template typename TDS::Vertex_handle - construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction& surface) + construct_surface(TDS& tds, const Advancing_front_surface_reconstruction& surface) { typedef typename TDS::Vertex_handle Vertex_handle; typedef std::pair Vh_pair; typedef typename TDS::Face_handle Face_handle; typedef typename TDS::Edge Edge; - + typedef typename Advancing_front_surface_reconstruction::Triangulation_3 Triangulation; Triangulation& T = surface.triangulation_3(); // create an infinite-vertex and infinite faces with the From c2ad8db566822c0c45c7464ac294ed0e335316c6 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 18 Jun 2015 19:04:24 +0200 Subject: [PATCH 098/114] remove the options file --- .../include/CGAL/internal/AFSR/AFSR_options.h | 46 ------------------- 1 file changed, 46 deletions(-) delete mode 100644 Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h deleted file mode 100644 index 2415c077179..00000000000 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/AFSR_options.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef CGAL_AFSR_OPTIONS_H -#define CGAL_AFSR_OPTIONS_H - - -namespace CGAL { - -class AFSR_options { -public: - AFSR_options() - : file_input(true), file_output(false), - Delaunay(false), contour(false), binary(false), xyz(false), - Section_file(false), max_connected_comp(-1), - delta(.86), K_init(1.1), K_step(.1), K(5), out_format(0), - NB_BORDER_MAX(15), red(0), green(0), blue(0), no_header(false) - { - std::strcpy(finname,"finput"); - std::strcpy(foutname,"foutput"); - } - - char program[100]; - char finname[100]; - char foutname[100]; - bool file_input; - bool file_output; - bool Delaunay; - bool contour; - bool binary; - bool xyz; - double perimeter; - bool Section_file; - int max_connected_comp; - double delta; - double K_init; - double K_step; - double K; - double COS_BETA; - int out_format; - int NB_BORDER_MAX; - double red, green, blue; - bool no_header; -}; - - -} // namespace CGAL - -#endif // CGAL_AFSR_OPTIONS_H From b40729ed8a2b8eaae537dbda89a447212904e488 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 18 Jun 2015 19:19:46 +0200 Subject: [PATCH 099/114] fix calls of acos --- .../CGAL/Advancing_front_surface_reconstruction.h | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 0813252b80a..8d67c2300b7 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -607,8 +607,10 @@ namespace CGAL { } */ - void run(double radius_ratio_bound=5, double beta=0.52) + void run(double radius_ratio_bound=5, double beta= 0.52) { + K = radius_ratio_bound; + COS_BETA = acos(beta); if(T.dimension() < 3){ return; } @@ -2349,7 +2351,7 @@ namespace CGAL { boost::make_transform_iterator(e, AFSR::Auto_count() ) ); Reconstruction R(dt); - R.run(radius_ratio_bound, acos(beta)); + R.run(radius_ratio_bound, beta); write_triple_indices(out, R); return out; } @@ -2381,7 +2383,7 @@ namespace CGAL { boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); Reconstruction R(dt, filter); - R.run(radius_ratio_bound, acos(beta)); + R.run(radius_ratio_bound, beta); write_triple_indices(out, R); return out; } @@ -2413,7 +2415,7 @@ namespace CGAL { boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); Reconstruction R(dt, filter); - R.run(radius_ratio_bound, acos(beta)); + R.run(radius_ratio_bound, beta); AFSR::construct_polyhedron(polyhedron, R); } @@ -2439,7 +2441,7 @@ namespace CGAL { boost::make_transform_iterator(e, AFSR::Auto_count() ) ); Reconstruction R(dt); - R.run(radius_ratio_bound, acos(beta)); + R.run(radius_ratio_bound, beta); AFSR::construct_polyhedron(polyhedron, R); } From 6194bd5f66dbabd4c9b9474c6ee21acfa2d5e29c Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Fri, 19 Jun 2015 10:13:18 +0200 Subject: [PATCH 100/114] qualify a function call with CGAL:: to avoid clang error --- .../CGAL/Advancing_front_surface_reconstruction.h | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 8d67c2300b7..8c3ccf4e2e7 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -913,10 +913,10 @@ namespace CGAL { return *(c->lazy_squared_radius()); c->set_lazy_squared_radius - (squared_radius(c->vertex(0)->point(), - c->vertex(1)->point(), - c->vertex(2)->point(), - c->vertex(3)->point())); + (CGAL::squared_radius(c->vertex(0)->point(), + c->vertex(1)->point(), + c->vertex(2)->point(), + c->vertex(3)->point())); return *(c->lazy_squared_radius()); } @@ -1112,6 +1112,7 @@ namespace CGAL { #ifdef AFSR_LAZY value = lazy_squared_radius(cc); #else + // qualified with CGAL, to avoid a compilation error with clang value = squared_radius(pp0, pp1, pp2, pp3); #endif } @@ -1134,8 +1135,10 @@ namespace CGAL { if ((ac > 0) && (an > 0)) { value = (Vc*Vc) - ac*ac/norm_V; - if ((value < 0)||(norm_V > inv_eps_2)) - value = squared_radius(cp1, cp2, cp3); + if ((value < 0)||(norm_V > inv_eps_2)){ + // qualified with CGAL, to avoid a compilation error with clang + value = CGAL::squared_radius(cp1, cp2, cp3); + } } else { From 6de70537e73ab41a63fff413b46078b2f3c53562 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Sun, 21 Jun 2015 12:21:01 +0200 Subject: [PATCH 101/114] CGAL::squared_radius --- .../include/CGAL/Advancing_front_surface_reconstruction.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 8c3ccf4e2e7..004837650ea 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -1113,7 +1113,7 @@ namespace CGAL { value = lazy_squared_radius(cc); #else // qualified with CGAL, to avoid a compilation error with clang - value = squared_radius(pp0, pp1, pp2, pp3); + value = CGAL::squared_radius(pp0, pp1, pp2, pp3); #endif } else From 3757ca30c6a60e7367b13370e09657692c6e4550 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Tue, 23 Jun 2015 10:35:50 +0200 Subject: [PATCH 102/114] Add tests for low dimensional data sets and for different kernels --- .../Advancing_front_surface_reconstruction.h | 18 +++-- .../kernels.cpp | 69 +++++++++++++++++++ .../lowdim.cpp | 53 ++++++++++++++ .../scale_space.cpp | 5 +- 4 files changed, 138 insertions(+), 7 deletions(-) create mode 100644 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp create mode 100644 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/lowdim.cpp diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 004837650ea..aa915969a0c 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2348,10 +2348,14 @@ namespace CGAL { typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; + typedef typename std::iterator_traits::value_type InputPoint; + typedef typename Kernel_traits::Kernel InputKernel; + typedef Cartesian_converter CC; typedef Kernel::Point_3 Point_3; - - Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), - boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + + CC cc=CC(); + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), + boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); Reconstruction R(dt); R.run(radius_ratio_bound, beta); @@ -2381,6 +2385,7 @@ namespace CGAL { typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef Kernel::Point_3 Point_3; + CC cc=CC(); Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); @@ -2438,10 +2443,13 @@ namespace CGAL { typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; + typedef typename std::iterator_traits::value_type InputPoint; + typedef typename Kernel_traits::Kernel InputKernel; + typedef Cartesian_converter CC; typedef typename Kernel::Point_3 Point_3; - Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count()), - boost::make_transform_iterator(e, AFSR::Auto_count() ) ); + Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), + boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); Reconstruction R(dt); R.run(radius_ratio_bound, beta); diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp new file mode 100644 index 00000000000..7f8eb68e0fa --- /dev/null +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp @@ -0,0 +1,69 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian K; + + +typedef CGAL::cpp11::array Facet; + +namespace std { +std::ostream& +operator<<(std::ostream& os, const Facet& f) +{ + os << "3 " << f[0] << " " << f[1] << " " << f[2]; + return os; +} + +} + +template +void fct(const char* fname) +{ + typedef K::Point_3 Point_3; + std::ifstream in(fname); + std::vector points; + std::vector facets; + + std::copy(std::istream_iterator(in), + std::istream_iterator(), + std::back_inserter(points)); + + CGAL::advancing_front_surface_reconstruction(points.begin(), + points.end(), + std::back_inserter(facets)); + + std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n"; + std::copy(points.begin(), + points.end(), + std::ostream_iterator(std::cout, "\n")); + std::copy(facets.begin(), + facets.end(), + std::ostream_iterator(std::cout, "\n")); +} + +int main() +{ + { + typedef CGAL::Simple_cartesian K; + fct("data/planar.xyz"); + } + { + typedef CGAL::Simple_cartesian K; + fct("data/planar.xyz"); + } + { + typedef CGAL::Exact_predicates_inexact_constructions_kernel K; + fct("data/planar.xyz"); + } + { + typedef CGAL::Exact_predicates_exact_constructions_kernel K; + fct("data/planar.xyz"); + } + return 0; +} diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/lowdim.cpp b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/lowdim.cpp new file mode 100644 index 00000000000..92c78c64940 --- /dev/null +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/lowdim.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian K; +typedef K::Point_3 Point_3; + +typedef CGAL::cpp11::array Facet; + +namespace std { +std::ostream& +operator<<(std::ostream& os, const Facet& f) +{ + os << "3 " << f[0] << " " << f[1] << " " << f[2]; + return os; +} + +} + +void fct(const char* fname) +{ + std::ifstream in(fname); + std::vector points; + std::vector facets; + + std::copy(std::istream_iterator(in), + std::istream_iterator(), + std::back_inserter(points)); + + CGAL::advancing_front_surface_reconstruction(points.begin(), + points.end(), + std::back_inserter(facets)); + + std::cout << "OFF\n" << points.size() << " " << facets.size() << " 0\n"; + std::copy(points.begin(), + points.end(), + std::ostream_iterator(std::cout, "\n")); + std::copy(facets.begin(), + facets.end(), + std::ostream_iterator(std::cout, "\n")); +} + +int main() +{ + fct("data/point.xyz"); + fct("data/segment.xyz"); + fct("data/triangle.xyz"); + fct("data/planar.xyz"); + return 0; +} diff --git a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp index 7bf1187d2ae..382e8f38ab5 100644 --- a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp +++ b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp @@ -36,12 +36,13 @@ int main(int argc, char* argv[]) { reconstruct.reconstruct_surface( points.begin(), points.end(), 4 ); std::cerr << "Reconstruction done:" << std::endl; + std::ofstream out ("out.off"); // Write the reconstruction. std::cerr << "Neighborhood radius^2 = " << reconstruct.neighborhood_squared_radius() << std::endl; for( std::size_t shell = 0; shell < reconstruct.number_of_shells(); ++shell ) { - std::cerr << "Shell " << shell << std::endl; + //std::cerr << "Shell " << shell << std::endl; for( Triple_iterator it = reconstruct.shell_begin( shell ); it != reconstruct.shell_end( shell ); ++it ) - std::cout << "3 "<< *it << std::endl; // We write a '3' in front so that it can be assembled into an OFF file + out << "3 "<< *it << std::endl; // We write a '3' in front so that it can be assembled into an OFF file } std::cerr << "Done." << std::endl; From 740479e8f08e1c2a02319ac977abd5157e3b3aff Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Wed, 24 Jun 2015 09:34:17 +0200 Subject: [PATCH 103/114] Add a test; make it ork on non-VC++ platforms --- .../Advancing_front_surface_reconstruction.h | 2 +- .../kernels.cpp | 3 +- .../polyhedron.cpp | 47 +++++++++++++++++++ 3 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index aa915969a0c..4ee14b7fa22 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -2447,7 +2447,7 @@ namespace CGAL { typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef typename Kernel::Point_3 Point_3; - + CC cc=CC(); Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp index 7f8eb68e0fa..b34155c2961 100644 --- a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp @@ -5,7 +5,6 @@ #include #include #include -#include typedef CGAL::Simple_cartesian K; @@ -25,7 +24,7 @@ operator<<(std::ostream& os, const Facet& f) template void fct(const char* fname) { - typedef K::Point_3 Point_3; + typedef typename K::Point_3 Point_3; std::ifstream in(fname); std::vector points; std::vector facets; diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp new file mode 100644 index 00000000000..4de9c841cb5 --- /dev/null +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +typedef CGAL::Simple_cartesian K; +typedef K::Point_3 Point_3; + +typedef CGAL::Polyhedron_3 Polyhedron; + +typedef CGAL::cpp11::array Facet; + +namespace std { +std::ostream& +operator<<(std::ostream& os, const Facet& f) +{ + os << "3 " << f[0] << " " << f[1] << " " << f[2]; + return os; +} + +} + + +int main() +{ + Polyhedron polyhedron; + std::ifstream in("data.planar.xyz"); + std::vector points; + std::vector facets; + + std::copy(std::istream_iterator(in), + std::istream_iterator(), + std::back_inserter(points)); + + CGAL::advancing_front_surface_reconstruction(points.begin(), + points.end(), + polyhedron); + + std::cout << polyhedron << std::endl; + + return 0; +} From c7240808498c9ca6b58e66ee958ab4fcbaae99ea Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 25 Jun 2015 09:30:17 +0200 Subject: [PATCH 104/114] fix typo in path to test data --- .../test/Advancing_front_surface_reconstruction/polyhedron.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp index 4de9c841cb5..858054ef013 100644 --- a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp @@ -29,7 +29,7 @@ operator<<(std::ostream& os, const Facet& f) int main() { Polyhedron polyhedron; - std::ifstream in("data.planar.xyz"); + std::ifstream in("data/planar.xyz"); std::vector points; std::vector facets; From 60333f3e81f099415f3cadf1364687b7be6cf288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 29 Jun 2015 10:43:42 +0200 Subject: [PATCH 105/114] remove exe flags --- .../fig/afsr-detail.png | Bin .../fig/wedges.png | Bin .../data/half.xyz | 0 .../data/planar.xyz | 0 .../data/point.xyz | 0 .../data/segment.xyz | 0 .../data/triangle.xyz | 0 7 files changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png mode change 100755 => 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/wedges.png mode change 100755 => 100644 Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/half.xyz mode change 100755 => 100644 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/planar.xyz mode change 100755 => 100644 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/point.xyz mode change 100755 => 100644 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/segment.xyz mode change 100755 => 100644 Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/afsr-detail.png old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/wedges.png b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig/wedges.png old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/half.xyz b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/data/half.xyz old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/planar.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/planar.xyz old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/point.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/point.xyz old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/segment.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/segment.xyz old mode 100755 new mode 100644 diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/data/triangle.xyz old mode 100755 new mode 100644 From 85fa6cf343d1109858579c96a7ec545c7d857c95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 29 Jun 2015 12:18:26 +0200 Subject: [PATCH 106/114] move the doc inside the code and update the code accordingly --- .../Advancing_front_surface_reconstruction.h | 249 ---------- ...front_surface_reconstruction_cell_base_3.h | 22 - ...ont_surface_reconstruction_vertex_base_3.h | 23 - .../Doxyfile.in | 11 +- .../Advancing_front_surface_reconstruction.h | 448 ++++++++++++------ ...front_surface_reconstruction_cell_base_3.h | 30 +- ...ont_surface_reconstruction_vertex_base_3.h | 32 +- 7 files changed, 357 insertions(+), 458 deletions(-) delete mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h delete mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h delete mode 100644 Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h deleted file mode 100644 index 7ee063a22e0..00000000000 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction.h +++ /dev/null @@ -1,249 +0,0 @@ - -namespace CGAL { - -/*! -\ingroup PkgAdvancingFrontSurfaceReconstruction - -The class `Advancing_front_surface_reconstruction` enables advanced users to provide the unstructured -point cloud in a 3D Delaunay triangulation. The reconstruction algorithm then marks vertices and faces -in the triangulation as being on the 2D surface embedded in 3D space, and constructs a 2D triangulation -data structure that describes the surface. The vertices and facets of the 2D triangulation data structure -store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the -2D as well as 3D neighborhood of vertices and facets of the surface. - -\tparam Dt must be a `Delaunay_triangulation_3` with -`Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type. -The default uses the `Exact_predicates_inexact_constructions_kernel` as geometric traits class. - -\tparam Filter must be a functor with `bool operator()(Point,Point,Point)` that allows the user to filter candidate triangles, for example based on its size. - The type `Point` must be the point type of the geometric traits class of the triangulation. It defaults to a functor that always returns `false`. - -*/ - - template< typename Dt, typename Filter> -class Advancing_front_surface_reconstruction { -public: - -/// \name Types -/// @{ - -/*! - The type of the 2D triangulation data structure describing the reconstructed surface, being a model of `TriangulationDataStructure_2`. - - The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the - method `vertex_3()` that returns a `#Vertex_handle` to the associated 3D vertex. - - The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the - method `facet()` that returns the associated `#Facet`, and a method `bool is_on_surface()` - for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. - - In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite - vertex of the 3D triangulation. -*/ - typedef unspecified_type Triangulation_data_structure_2; - - -/*! -The type of the 3D triangulation. - -*/ - typedef Dt Triangulation_3; - -/*! -The point type. - -*/ - typedef typename Triangulation_3::Point Point; -/*! -The vertex handle type of the 3D triangulation. - -*/ - typedef typename Triangulation_3::Vertex_handle Vertex_handle; - -/*! -The cell handle type of the 3D triangulation. - -*/ - typedef typename Triangulation_3::Cell_handle Cell_handle; - -/*! -The facet type of the 3D triangulation. - -*/ - typedef typename Triangulation_3::Facet Facet; - - -/*! - A bidirectional iterator range which enables to enumerate all points that were removed - from the 3D Delaunay triangulation during the surface reconstruction. The value type - of the iterator is `#Point`. -*/ -typedef unspecified_type Outlier_range; - -#if 0 -/*! - A forward iterator which enables to visit all boundaries. It - visits the entry point of each boundary twice. This allows to - detect that the traversal of a boundary is finished. One more increment - brings us to the vertex on the next boundary. - The value type of the iterator is `#Vertex_handle`. -*/ - -#endif - /*! - A bidirectional iterator range which enables to visit all boundaries. - The value type of the iterator is `Vertex_on_boundary_range`. - */ -typedef unspecified_type Boundary_range; - - /*! - A bidirectional iterator range which enables to visit all vertices on a boundary. - The value type of the iterator is `#Vertex_handle` - */ -typedef unspecified_type Vertex_on_boundary_range; - - -/// @} - -/// \name Creation -/// @{ - -/*! -Constructor for the unstructured point cloud given as 3D Delaunay triangulation. -*/ -Advancing_front_surface_reconstruction(Dt& dt); - - -/// @} - -/// \name Operations -/// @{ - -/*! -runs the surface reconstruction function. - -\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge - are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. - Described in Section \ref AFSR_Boundaries -\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. - Described in Section \ref AFSR_Selection - -*/ - void run(double radius_ratio_bound =5 , double beta = 0.52); - -/*! -returns the reconstructed surface. -*/ -const Triangulation_data_structure_2& -triangulation_data_structure_2() const; - -/*! -returns the underlying 3D Delaunay triangulation. -*/ -const Triangulation_3& -triangulation_3(); - - - - -/*! -returns an iterator range over the outliers. -*/ -Outlier_range outliers(); - - -/*! -returns an iterator range over the boundaries. -*/ -Boundary_range boundaries(); - - -/// @} - -/// \name Predicates -/// @{ - -/*! -returns `true` if the reconstructed surface has boundaries. -*/ -bool -has_boundaries() const; - - -/*! -returns `true` if the facet is on the surface. -*/ -bool -has_on_surface(Facet f) const; - -/*! -returns `true` if the facet `f2` is on the surface. -*/ -bool -has_on_surface(Triangulation_data_structure_2::Face_handle f2) const; - -/*! -returns `true` if the vertex `v2` is on the surface. -*/ -bool -has_on_surface(Triangulation_data_structure_2::Vertex_handle v2) const; -/// @} - - - - -}; /* end Advancing_front_surface_reconstruction */ - - -/*! -\ingroup PkgAdvancingFrontSurfaceReconstruction - -For a sequence of points computes a sequence of index triples -describing the faces of the reconstructed surface. - -\tparam PointInputIterator must be an input iterator with 3D points as value type. This point type must -be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. -\tparam IndicesOutputIterator must be an output iterator to which -`CGAL::cpp11::tuple` can be assigned. - -\param b iterator on the first point of the sequence -\param e past the end iterator of the point sequence -\param out output iterator -\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge - are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. - Described in Section \ref AFSR_Boundaries -\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. - Described in Section \ref AFSR_Selection - -*/ - template - IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, double radius_ratio_bound = 5, double beta= 0.52 ); - - -/*! -\ingroup PkgAdvancingFrontSurfaceReconstruction - -For a sequence of points computes a sequence of index triples -describing the faces of the reconstructed surface. - -\tparam PointInputIterator must be an input iterator with 3D points as value type. This point type must -be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. -\tparam IndicesOutputIterator must be an output iterator to which -`CGAL::cpp11::tuple` can be assigned. -\tparam Filter must be a functor with `bool operator()(Point,Point,Point)` where Point is `Exact_predicates_inexact_constructions_kernel::Point_3`. - -\param b iterator on the first point of the sequence -\param e past the end iterator of the point sequence -\param out output iterator -\param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge - are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. - Described in Section \ref AFSR_Boundaries -\param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. - Described in Section \ref AFSR_Selection -\param filter allows the user to filter candidate triangles, for example based on their size. - -*/ - template - IndicesOutputIterator advancing_front_surface_reconstruction(PointInputIterator b, PointInputIterator e, IndicesOutputIterator out, Filter filter, double radius_ratio_bound = 5, double beta= 0.52 ); - - - -} /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h deleted file mode 100644 index 3b902c4e79d..00000000000 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h +++ /dev/null @@ -1,22 +0,0 @@ - -namespace CGAL { - -/*! -\ingroup PkgAdvancingFrontSurfaceReconstruction - -The class `Advancing_front_surface_reconstruction_cell_base_3` is the default -cell type for the class `Advancing_front_surface_reconstruction`. - -\tparam Traits has to be a model of `DelaunayTriangulationTraits_3`. - -\tparam Cb has to be a model of `TriangulationCellBase_3`. - -*/ -template< typename Traits, typename Cb = Triangulation_cell_base_3 > -class Advancing_front_surface_reconstruction_cell_base_3 : public Cb { -public: - -/// @} - -}; /* end Advancing_front_surface_reconstruction_cell_base_3 */ -} /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h deleted file mode 100644 index 49414059b97..00000000000 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ /dev/null @@ -1,23 +0,0 @@ - -namespace CGAL { - -/*! -\ingroup PkgAdvancingFrontSurfaceReconstruction - -The class `Advancing_front_surface_reconstruction_vertex_base_3` is the default -vertex type for the class `Advancing_front_surface_reconstruction`. - -\tparam Traits has to be a model of `DelaunayTriangulationTraits_3`. - -\tparam Vb has to be a model of `TriangulationVertexBase_3`. - - -*/ - template< typename Traits, typename Vb = Triangulation_vertex_base_3 > -class Advancing_front_surface_reconstruction_vertex_base_3 : public Vb { -public: - -/// @} - -}; /* end Advancing_front_surface_reconstruction_vertex_base_3 */ -} /* end namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in index b440784ea24..cb6bc2d0850 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Doxyfile.in @@ -2,9 +2,10 @@ PROJECT_NAME = "CGAL ${CGAL_CREATED_VERSION_NUM} - Advancing Front Surface Reconstruction" +INPUT = ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/ \ + ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/include -INPUT = ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/ - - - -MULTILINE_CPP_IS_BRIEF = YES \ No newline at end of file +EXTRACT_ALL = false +HIDE_UNDOC_MEMBERS = true +HIDE_UNDOC_CLASSES = true +MULTILINE_CPP_IS_BRIEF = YES diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index 4ee14b7fa22..e4484d35948 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -156,28 +156,118 @@ namespace CGAL { } }; - struct Always_false { + namespace AFSR{ + struct Always_false { - template - bool operator()(const T&, const T&, const T&) const - { - return false; - } - - }; + template + bool operator()(const T&, const T&, const T&) const + { + return false; + } + }; + } //end of namespa AFSR + /*! + \ingroup PkgAdvancingFrontSurfaceReconstruction + + The class `Advancing_front_surface_reconstruction` enables advanced users to provide the unstructured + point cloud in a 3D Delaunay triangulation. The reconstruction algorithm then marks vertices and faces + in the triangulation as being on the 2D surface embedded in 3D space, and constructs a 2D triangulation + data structure that describes the surface. The vertices and facets of the 2D triangulation data structure + store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the + 2D as well as 3D neighborhood of vertices and facets of the surface. + + \tparam Dt must be a `Delaunay_triangulation_3` with + `Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type. + The default uses the `Exact_predicates_inexact_constructions_kernel` as geometric traits class. + + \tparam F must be a functor with `bool operator()(Point,Point,Point)` returning `true` if a triangle should not appear in the output. + This functor enables the user to filter candidate triangles, for example based on its size. + The type `Point` must be the point type of the geometric traits class of the triangulation. + It defaults to a functor that always returns `false`. + + */ template < - class Triangulation_ = Default, - class Reject = Always_false> + class Dt = Default, + class F = Default> class Advancing_front_surface_reconstruction { - typedef typename Default::Get, Advancing_front_surface_reconstruction_cell_base_3 > > >::type Triangulation; - + typedef typename Default::Get, Advancing_front_surface_reconstruction_cell_base_3 > > >::type Triangulation; + typedef typename Default::Get::type Filter; public: + +#ifdef DOXYGEN_RUNNING + /// \name Types + /// @{ + + /*! + The type of the 2D triangulation data structure describing the reconstructed surface, being a model of `TriangulationDataStructure_2`. + - The type `Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally the + method `vertex_3()` that returns a `#Vertex_handle` to the associated 3D vertex. + - The type `Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the + method `facet()` that returns the associated `#Facet`, and a method `bool is_on_surface()` + for testing if a face is part of the reconstructed surface or a face incident to a boundary edge. + + In case the surface has boundaries, the 2D surface has one vertex which is associated to the infinite + vertex of the 3D triangulation. + */ + typedef unspecified_type Triangulation_data_structure_2; + + /*! + The type of the 3D triangulation. + */ + typedef unspecified_type Triangulation_3; + + /*! + The type of the triangle filter functor. + */ + typedef unspecified_type Filter; + + /*! + The point type. + */ + typedef typename Triangulation_3::Point Point; + + /*! + The vertex handle type of the 3D triangulation. + */ + typedef typename Triangulation_3::Vertex_handle Vertex_handle; + + /*! + The cell handle type of the 3D triangulation. + */ + typedef typename Triangulation_3::Cell_handle Cell_handle; + + /*! + The facet type of the 3D triangulation. + */ + typedef typename Triangulation_3::Facet Facet; + + /*! + A bidirectional iterator range which enables to enumerate all points that were removed + from the 3D Delaunay triangulation during the surface reconstruction. The value type + of the iterator is `#Point`. + */ + typedef unspecified_type Outlier_range; + + /*! + A bidirectional iterator range which enables to visit all boundaries. + The value type of the iterator is `Vertex_on_boundary_range`. + */ + typedef unspecified_type Boundary_range; + + /*! + A bidirectional iterator range which enables to visit all vertices on a boundary. + The value type of the iterator is `#Vertex_handle` + */ + typedef unspecified_type Vertex_on_boundary_range; + /// @} +#endif + typedef Triangulation Triangulation_3; typedef typename Triangulation_3::Geom_traits Kernel; - typedef Advancing_front_surface_reconstruction Extract; + typedef Advancing_front_surface_reconstruction Extract; typedef typename Triangulation_3::Geom_traits Geom_traits; typedef typename Kernel::FT coord_type; @@ -279,7 +369,7 @@ namespace CGAL { Vertex_handle added_vertex; bool deal_with_2d; - Reject reject; + Filter filter; int max_connected_component; double K_init, K_step; std::list interior_edges; @@ -563,16 +653,22 @@ namespace CGAL { public: - Advancing_front_surface_reconstruction(Triangulation_3& T_, - Reject reject = Reject()) - : T(T_), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), + /// \name Creation + /// @{ + + /*! + Constructor for the unstructured point cloud given as 3D Delaunay triangulation. + */ + Advancing_front_surface_reconstruction(Triangulation_3& dt, + Filter filter = Filter()) + : T(dt), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), NB_BORDER_MAX(15), DELTA(.86), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), - deal_with_2d(false), reject(reject), max_connected_component(-1), K_init(1.1), K_step(.1) + deal_with_2d(false), filter(filter), max_connected_component(-1), K_init(1.1), K_step(.1) { if(T.dimension() == 2){ @@ -595,6 +691,9 @@ namespace CGAL { } } + /// @} + + /* ~Advancing_front_surface_reconstruction() { @@ -607,6 +706,43 @@ namespace CGAL { } */ + typedef Advancing_front_surface_reconstruction_boundary_iterator Boundary_iterator; + + Boundary_iterator boundaries_begin() const + { + return Boundary_iterator(*this, next_mark()); + } + + + Boundary_iterator boundaries_end() const + { + return Boundary_iterator(*this); + } + + typedef std::list Outlier_range; + + typedef CGAL::Triangulation_data_structure_2, + AFSR::Surface_face_base_2 > TDS_2; + + typedef TDS_2 Triangulation_data_structure_2; + + mutable TDS_2 _tds_2; + + mutable typename TDS_2::Vertex_handle _tds_2_inf; + + /// \name Operations + /// @{ + + /*! + runs the surface reconstruction function. + + \param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge + are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. + Described in Section \ref AFSR_Boundaries + \param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. + Described in Section \ref AFSR_Selection + + */ void run(double radius_ratio_bound=5, double beta= 0.52) { K = radius_ratio_bound; @@ -649,115 +785,34 @@ namespace CGAL { clear_vertices(); } - - typedef CGAL::Triangulation_data_structure_2, - AFSR::Surface_face_base_2 > TDS_2; - - typedef TDS_2 Triangulation_data_structure_2; - - mutable TDS_2 _tds_2; - - mutable typename TDS_2::Vertex_handle _tds_2_inf; - - const TDS_2& triangulation_data_structure_2() const + /*! + returns the reconstructed surface. + */ + const Triangulation_data_structure_2& triangulation_data_structure_2() const { return _tds_2; } - - bool - has_boundaries() const - { - return _tds_2_inf != typename TDS_2::Vertex_handle(); - } - - - bool has_on_surface(typename TDS_2::Vertex_handle vh) const - { - return vh != _tds_2_inf; - } - - bool has_on_surface(typename TDS_2::Face_handle fh) const - { - return fh->is_on_surface(); - } - - - - bool has_on_surface(Facet fh) const - { - return fh.first->has_facet_on_surface(fh.second); - } - - - - int number_of_connected_components() const - { - return _number_of_connected_components; - } - - + /*! + returns the underlying 3D Delaunay triangulation. + */ Triangulation_3& triangulation_3() const { return T; } - - int number_of_facets() const - { - return _facet_number; - } - - - int number_of_vertices() const - { - return _vh_number; - } - - - int number_of_outliers() const - { - return static_cast(m_outliers.size()); - } - - - typedef std::list Outlier_range; - - typedef typename std::list::const_iterator Outlier_iterator; - + /*! + returns an iterator range over the outliers. + */ const Outlier_range& outliers() const { return m_outliers; } - - Outlier_iterator outliers_begin() const - { - return m_outliers.begin(); - } - - - Outlier_iterator m_outliers_end() const - { - return m_outliers.end(); - } - - - typedef Advancing_front_surface_reconstruction_boundary_iterator Boundary_iterator; - - Boundary_iterator boundaries_begin() const - { - return Boundary_iterator(*this, next_mark()); - } - - - Boundary_iterator boundaries_end() const - { - return Boundary_iterator(*this); - } - - + /*! + returns an iterator range over the boundaries. + */ const Boundary_range& boundaries() const { if(has_boundaries() && m_boundaries.empty()){ @@ -776,7 +831,83 @@ namespace CGAL { return m_boundaries; } + /// @} +/// \name Predicates +/// @{ + + /*! + returns `true` if the reconstructed surface has boundaries. + */ + bool + has_boundaries() const + { + return _tds_2_inf != typename TDS_2::Vertex_handle(); + } + + /*! + returns `true` if the facet is on the surface. + */ + bool + has_on_surface(Facet f) const + { + return f.first->has_facet_on_surface(f.second); + } + + /*! + returns `true` if the facet `f2` is on the surface. + */ + bool + has_on_surface(typename Triangulation_data_structure_2::Face_handle f2) const + { + return f2->is_on_surface(); + } + + /*! + returns `true` if the vertex `v2` is on the surface. + */ + bool + has_on_surface(typename Triangulation_data_structure_2::Vertex_handle v2) const + { + return v2 != _tds_2_inf; + } + /// @} + + int number_of_connected_components() const + { + return _number_of_connected_components; + } + + int number_of_facets() const + { + return _facet_number; + } + + + int number_of_vertices() const + { + return _vh_number; + } + + + int number_of_outliers() const + { + return static_cast(m_outliers.size()); + } + + typedef typename std::list::const_iterator Outlier_iterator; + + + Outlier_iterator outliers_begin() const + { + return m_outliers.begin(); + } + + + Outlier_iterator m_outliers_end() const + { + return m_outliers.end(); + } int next_mark() const { @@ -1208,7 +1339,7 @@ namespace CGAL { // If the triangle has a high perimeter, // we do not want to consider it as a good candidate. - if(reject(facet_it.first->vertex(n_i1)->point(), + if(filter(facet_it.first->vertex(n_i1)->point(), facet_it.first->vertex(n_i2)->point(), facet_it.first->vertex(n_i3)->point())){ tmp = HUGE_VAL; @@ -1254,13 +1385,12 @@ namespace CGAL { -DELTA*sqrt(norm12*(P2Pn*P2Pn)))&& (P2P1*PnP1 >= -DELTA*sqrt(norm12*(PnP1*PnP1)))); - /// \todo investigate why we simply do not skip this triangle - /// but continue looking for a better candidate - /// if (!border_facet){ + // \todo investigate why we simply do not skip this triangle + // but continue looking for a better candidate + // if (!border_facet){ min_facetA = facet_it; min_valueA = tmp; min_valueP = pscal/norm; - ///} } } } @@ -1357,7 +1487,7 @@ namespace CGAL { coord_type value = smallest_radius_delaunay_sphere(c, index); // we might not want the triangle, for example because it is too large - if(reject(c->vertex((index+1)&3)->point(), + if(filter(c->vertex((index+1)&3)->point(), c->vertex((index+2)&3)->point(), c->vertex((index+3)&3)->point())){ value = min_value; @@ -2331,12 +2461,32 @@ namespace CGAL { }; } + /*! + \ingroup PkgAdvancingFrontSurfaceReconstruction - template - IndexTripleIterator - advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, - IndexTripleIterator out, + For a sequence of points computes a sequence of index triples + describing the faces of the reconstructed surface. + + \tparam PointInputIterator must be an input iterator with 3D points as value type. This point type must + be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. + \tparam IndicesOutputIterator must be an output iterator to which + `CGAL::cpp11::tuple` can be assigned. + + \param b iterator on the first point of the sequence + \param e past the end iterator of the point sequence + \param out output iterator + \param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge + are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. + Described in Section \ref AFSR_Boundaries + \param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. + Described in Section \ref AFSR_Selection + + */ + template + IndicesOutputIterator + advancing_front_surface_reconstruction(PointInputIterator b, + PointInputIterator e, + IndicesOutputIterator out, double radius_ratio_bound = 5, double beta = 0.52 ) { @@ -2348,7 +2498,7 @@ namespace CGAL { typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; - typedef typename std::iterator_traits::value_type InputPoint; + typedef typename std::iterator_traits::value_type InputPoint; typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef Kernel::Point_3 Point_3; @@ -2363,12 +2513,34 @@ namespace CGAL { return out; } + /*! + \ingroup PkgAdvancingFrontSurfaceReconstruction - template - IndexTripleIterator - advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, - IndexTripleIterator out, + For a sequence of points computes a sequence of index triples + describing the faces of the reconstructed surface. + + \tparam PointInputIterator must be an input iterator with 3D points as value type. This point type must + be convertible to `Exact_predicates_inexact_constructions_kernel::Point_3` with the `Cartesian_converter`. + \tparam IndicesOutputIterator must be an output iterator to which + `CGAL::cpp11::tuple` can be assigned. + \tparam Filter must be a functor with `bool operator()(Point,Point,Point)` where Point is `Exact_predicates_inexact_constructions_kernel::Point_3`. + + \param b iterator on the first point of the sequence + \param e past the end iterator of the point sequence + \param out output iterator + \param radius_ratio_bound candidates incident to surface triangles which are not in the beta-wedge + are discarded, if the ratio of their radius and the radius of the surface triangle is larger than `radius_ratio_bound`. + Described in Section \ref AFSR_Boundaries + \param beta half the angle of the wedge in which only the radius of triangles counts for the plausibility of candidates. + Described in Section \ref AFSR_Selection + \param filter allows the user to filter candidate triangles, for example based on their size. + + */ + template + IndicesOutputIterator + advancing_front_surface_reconstruction(PointInputIterator b, + PointInputIterator e, + IndicesOutputIterator out, Filter filter, double radius_ratio_bound = 5, double beta = 0.52 ) @@ -2381,7 +2553,7 @@ namespace CGAL { typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; - typedef typename std::iterator_traits::value_type InputPoint; + typedef typename std::iterator_traits::value_type InputPoint; typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef Kernel::Point_3 Point_3; @@ -2397,10 +2569,10 @@ namespace CGAL { } - template class HDS, typename Alloc,typename Filter> + template class HDS, typename Alloc,typename Filter> void - advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, + advancing_front_surface_reconstruction(PointInputIterator b, + PointInputIterator e, Polyhedron_3& polyhedron, Filter filter, double radius_ratio_bound = 5, @@ -2413,7 +2585,7 @@ namespace CGAL { typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; - typedef typename std::iterator_traits::value_type InputPoint; + typedef typename std::iterator_traits::value_type InputPoint; typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef typename Kernel::Point_3 Point_3; @@ -2428,10 +2600,10 @@ namespace CGAL { } - template class HDS, typename Alloc> + template class HDS, typename Alloc> void - advancing_front_surface_reconstruction(PointIterator b, - PointIterator e, + advancing_front_surface_reconstruction(PointInputIterator b, + PointInputIterator e, Polyhedron_3& polyhedron, double radius_ratio_bound = 5, double beta = 0.52) @@ -2443,7 +2615,7 @@ namespace CGAL { typedef Delaunay_triangulation_3 Triangulation_3; typedef Advancing_front_surface_reconstruction Reconstruction; - typedef typename std::iterator_traits::value_type InputPoint; + typedef typename std::iterator_traits::value_type InputPoint; typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef typename Kernel::Point_3 Point_3; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h index 9e662fa3caa..26b7b4a82fb 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h @@ -24,19 +24,29 @@ namespace CGAL { - template < class Kernel, class CellBase = Triangulation_cell_base_3 > - class Advancing_front_surface_reconstruction_cell_base_3 : public CellBase + /*! + \ingroup PkgAdvancingFrontSurfaceReconstruction + + The class `Advancing_front_surface_reconstruction_cell_base_3` is the default + cell type for the class `Advancing_front_surface_reconstruction`. + + \tparam Traits has to be a model of `DelaunayTriangulationTraits_3`. + + \tparam Cb has to be a model of `TriangulationCellBase_3`. + */ + template < typename Traits, typename Cb = Triangulation_cell_base_3 > + class Advancing_front_surface_reconstruction_cell_base_3 : public Cb { public: template < typename TDS2 > struct Rebind_TDS { - typedef typename CellBase::template Rebind_TDS::Other Cb2; - typedef Advancing_front_surface_reconstruction_cell_base_3 Other; + typedef typename Cb::template Rebind_TDS::Other Cb2; + typedef Advancing_front_surface_reconstruction_cell_base_3 Other; }; - typedef typename CellBase::Vertex_handle Vertex_handle; - typedef typename CellBase::Cell_handle Cell_handle; + typedef typename Cb::Vertex_handle Vertex_handle; + typedef typename Cb::Cell_handle Cell_handle; private: @@ -61,7 +71,7 @@ namespace CGAL { public: Advancing_front_surface_reconstruction_cell_base_3() - : CellBase(), + : Cb(), _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY , _circumcenter(NULL), _squared_radius(NULL) @@ -75,7 +85,7 @@ namespace CGAL { } Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) - : CellBase( v0, v1, v2, v3), + : Cb( v0, v1, v2, v3), _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY , _circumcenter(NULL), _squared_radius(NULL) @@ -90,8 +100,8 @@ namespace CGAL { Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) - : CellBase(v0, v1, v2, v3, - n0, n1, n2, n3), + : Cb(v0, v1, v2, v3, + n0, n1, n2, n3), _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY , _circumcenter(NULL), _squared_radius(NULL) diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index 06d8f6c0771..9f6f2e77528 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -33,25 +33,35 @@ namespace CGAL { template class Advancing_front_surface_reconstruction; - template > - class Advancing_front_surface_reconstruction_vertex_base_3 : public VertexBase + /*! + \ingroup PkgAdvancingFrontSurfaceReconstruction + + The class `Advancing_front_surface_reconstruction_vertex_base_3` is the default + vertex type for the class `Advancing_front_surface_reconstruction`. + + \tparam Traits has to be a model of `DelaunayTriangulationTraits_3`. + + \tparam Vb has to be a model of `TriangulationVertexBase_3`. + */ + template > + class Advancing_front_surface_reconstruction_vertex_base_3 : public Vb { public: template < typename TDS2 > struct Rebind_TDS { - typedef typename VertexBase::template Rebind_TDS::Other Vb2; - typedef Advancing_front_surface_reconstruction_vertex_base_3 Other; + typedef typename Vb::template Rebind_TDS::Other Vb2; + typedef Advancing_front_surface_reconstruction_vertex_base_3 Other; }; template friend class Advancing_front_surface_reconstruction; - typedef VertexBase Base; + typedef Vb Base; typedef typename Base::Vertex_handle Vertex_handle; typedef typename Base::Cell_handle Cell_handle; - typedef typename VertexBase::Point Point; + typedef typename Vb::Point Point; typedef double coord_type; typedef Triple< Cell_handle, int, int > Edge; @@ -106,27 +116,27 @@ namespace CGAL { public: Advancing_front_surface_reconstruction_vertex_base_3() - : VertexBase(), m_mark(-1), + : Vb(), m_mark(-1), m_post_mark(-1) {} Advancing_front_surface_reconstruction_vertex_base_3(const Point & p) - : VertexBase(p), m_mark(-1), + : Vb(p), m_mark(-1), m_post_mark(-1) {} Advancing_front_surface_reconstruction_vertex_base_3(const Point & p, Cell_handle f) - : VertexBase(p, f), m_mark(-1), + : Vb(p, f), m_mark(-1), m_post_mark(-1) {} Advancing_front_surface_reconstruction_vertex_base_3(Cell_handle f) - : VertexBase(f), m_mark(-1), + : Vb(f), m_mark(-1), m_post_mark(-1) {} Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other) - : VertexBase(other), m_mark(-1), + : Vb(other), m_mark(-1), m_post_mark(-1) {} From d80d69b3505490634cbe28e0413de7bdb5509448 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Loriot?= Date: Mon, 29 Jun 2015 12:22:13 +0200 Subject: [PATCH 107/114] remove trailing whitespaces --- ...Advancing_front_surface_reconstruction.txt | 52 +-- .../PackageDescription.txt | 6 +- .../boundaries.cpp | 16 +- .../reconstruction_class.cpp | 8 +- .../reconstruction_fct.cpp | 18 +- .../reconstruction_surface_mesh.cpp | 18 +- .../Advancing_front_surface_reconstruction.h | 418 +++++++++--------- ...front_surface_reconstruction_cell_base_3.h | 48 +- ...ont_surface_reconstruction_vertex_base_3.h | 50 +-- .../CGAL/internal/AFSR/Surface_face_base_2.h | 22 +- .../internal/AFSR/Surface_vertex_base_2.h | 4 +- .../CGAL/internal/AFSR/construct_polyhedron.h | 8 +- .../CGAL/internal/AFSR/construct_surface_2.h | 18 +- .../include/CGAL/internal/AFSR/orient.h | 20 +- .../CGAL/internal/AFSR/write_triple_indices.h | 4 +- .../kernels.cpp | 16 +- .../lowdim.cpp | 14 +- .../polyhedron.cpp | 14 +- 18 files changed, 377 insertions(+), 377 deletions(-) diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt index b34a665e69a..7d4048bc210 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/Advancing_front_surface_reconstruction.txt @@ -2,7 +2,7 @@ namespace CGAL { /*! -\mainpage User Manual +\mainpage User Manual \anchor Chapter_Advancing_Front_Surface_Reconstruction \anchor I1ChapterAdvancingFrontSurfaceReconstruction \cgalAutoToc @@ -22,7 +22,7 @@ For Delaunay based algorithms the output surface is commonly generated as the union of some triangles selected in the 3D Delaunay triangulation of the input points. Such algorithms are either volume-based by generating as output the boundary of selected -tetrahedra \cgalCite{abe-cbscc-97}\cgalCite{ack-pcubm-01}, +tetrahedra \cgalCite{abe-cbscc-97}\cgalCite{ack-pcubm-01}, or surface-based by selecting a set of triangles. @@ -92,7 +92,7 @@ Valid candidates. \cgalFigureEnd While the first three operations never induce a non-manifold edge or vertex, -we only can perform gluing, if triangle \f$t\f$ has a *twin* facet, that is a +we only can perform gluing, if triangle \f$t\f$ has a *twin* facet, that is a triangle with an edge on the front and incident to \f$b\f$, and the third vertex on edge \f$e\f$. @@ -130,12 +130,12 @@ We define the *plausibility* grade \f$ p(t) \f$ as \f$ 1/r_t \f$, if Let's have a look at the figure below. \cgalFigureBegin{figAFSRplausible,wedges.png} -Plausibility. Triangle `t'` and incidident triangles sharing edge `e` seen from the side. +Plausibility. Triangle `t'` and incidident triangles sharing edge `e` seen from the side. \cgalFigureEnd \f$ \alpha_\mathrm{sliver}\f$ corresponds to the red wedge. The algorithm will never select triangle `t1` -even if it is the only candidate triangle. - +even if it is the only candidate triangle. + \f$\beta\f$ corresponds to the green wedge. If there is a candidate triangle in this zone, the one with the smallest radius is the most plausible. @@ -152,7 +152,7 @@ surface. In case of noisy data or outliers, the user must filter out small surface components. It is impossible to handle all kinds of boundaries and non uniform sampling -at the same time, as a void can either be an undersampled area of the surface, +at the same time, as a void can either be an undersampled area of the surface, or a hole. As we do not want the algorithm to rely on a uniformity condition on @@ -167,25 +167,25 @@ would be very different. These heuristic facts can be used for boundary detection. More specifically, we discard any candidate triangle \f$ t \f$, for an edge \f$ e \f$ -such that \f$ p(t) < 0\f$, and \f$ r_t > \mathrm{radius\_ratio\_bound} \times r_{t'}\f$ where \f$ t'\f$ is -the triangle on the surface incident on \f$ e \f$. The parameter \f$\mathrm{radius\_ratio\_bound}\f$ +such that \f$ p(t) < 0\f$, and \f$ r_t > \mathrm{radius\_ratio\_bound} \times r_{t'}\f$ where \f$ t'\f$ is +the triangle on the surface incident on \f$ e \f$. The parameter \f$\mathrm{radius\_ratio\_bound}\f$ is specified by the user and is set by default to 5. -For the example given in \cgalFigureRef{figAFSRplausible}, we said that if there +For the example given in \cgalFigureRef{figAFSRplausible}, we said that if there was no triangle `t3` in the green wedge, triangle `t4` would be chosen as it has -the smallest angle between its normal and the normal of triangle `t'`. +the smallest angle between its normal and the normal of triangle `t'`. However, in case its radius was \f$\mathrm{radius\_ratio\_bound}\f$ times larger than the radius of triangle `t'`, triangle `t2` would be chosen, assuming that its radius is not \f$\mathrm{radius\_ratio\_bound}\f$ times larger. -Note that this heuristic implies that +Note that this heuristic implies that where the sampling is too sparse with respect to curvature, it must be sufficiently uniform for our algorithm to work. \section AFSR_Examples Examples -The first of the following three examples presents a free function for doing surface +The first of the following three examples presents a free function for doing surface reconstruction. For a sequence of points the function produces a sequence of triplets of indices describing the triangles of the surface. The second example presents a class that enables to traverse the @@ -194,13 +194,13 @@ the faces are connected with the facets of underlying 3D Delaunay triangulation. The third example shows how to get outliers and the boundaries of the surface. -\subsection AFSR_Example_function Examples for Global Function +\subsection AFSR_Example_function Examples for Global Function -The global function `advancing_front_surface_reconstruction()` -takes an iterator range of points as input and writes for each face of the -reconstructed surface a triplet of point indices into an output iterator. +The global function `advancing_front_surface_reconstruction()` +takes an iterator range of points as input and writes for each face of the +reconstructed surface a triplet of point indices into an output iterator. The following example writes the output triangulated surface to `std::cout` -in accordance to the OFF format. +in accordance to the OFF format. The function has an overload with an additional argument that allows to filter triangles, for example to avoid the generation of triangles with a perimeter larger @@ -218,15 +218,15 @@ and calls the function `add_face()`. \subsection AFSR_Example_class Example for the Reconstruction Class -The class `Advancing_front_surface_reconstruction` provides +The class `Advancing_front_surface_reconstruction` provides access to a 2D triangulation data structure describing the output surface. The latter can be explored by hopping from a face to its neighboring faces, and by hopping from faces of the 2D triangulation data structure to corresponding facets of the underlying 3D Delaunay triangulation. The type of the 2D triangulation data structure describing the -reconstructed surface is the nested type -\link Advancing_front_surface_reconstruction::Triangulation_data_structure_2 `Advancing_front_surface_reconstruction::Triangulation_data_structure_2`\endlink. +reconstructed surface is the nested type +\link Advancing_front_surface_reconstruction::Triangulation_data_structure_2 `Advancing_front_surface_reconstruction::Triangulation_data_structure_2`\endlink. The type `Advancing_front_surface_reconstruction::Triangulation_data_structure_2::Vertex` is model of the concept `TriangulationDataStructure_2::Vertex` and has additionally @@ -235,9 +235,9 @@ associated 3D vertex. The type `Advancing_front_surface_reconstruction::Triangulation_data_structure_2::Face` is model of the concept `TriangulationDataStructure_2::Face` and has additionally the method -`facet()` that returns the associated `Advancing_front_surface_reconstruction::Facet`, +`facet()` that returns the associated `Advancing_front_surface_reconstruction::Facet`, and a method `is_on_surface()` for testing if a face is part of the reconstructed -surface. +surface. In case the surface has boundaries, the 2D surface has one vertex which is associated to @@ -260,13 +260,13 @@ a surface are outliers. The member function \link Advancing_front_surface_recons returns an iterator range of those points. Boundary edges can be traversed with the member function \link Advancing_front_surface_reconstruction::boundaries() `boundaries()`\endlink -It returns an iterator range type \link Advancing_front_surface_reconstruction::Boundary_range `Boundary_range`\endlink whose iterators have the value type -\link Advancing_front_surface_reconstruction::Vertex_on_boundary_range `Vertex_on_boundary_range`\endlink. This is again an iterator range whose iterators have the value type +It returns an iterator range type \link Advancing_front_surface_reconstruction::Boundary_range `Boundary_range`\endlink whose iterators have the value type +\link Advancing_front_surface_reconstruction::Vertex_on_boundary_range `Vertex_on_boundary_range`\endlink. This is again an iterator range whose iterators have the value type \link Advancing_front_surface_reconstruction::Vertex_handle `Vertex_handle`\endlink. \cgalExample{Advancing_front_surface_reconstruction/boundaries.cpp} -*/ +*/ } /* namespace CGAL */ diff --git a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt index 5333ea7f71a..8e104c34c35 100644 --- a/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt +++ b/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/PackageDescription.txt @@ -8,9 +8,9 @@ \cgalPkgSummaryBegin \cgalPkgAuthors{Tran Kai Frank Da, David Cohen-Steiner} \cgalPkgDesc{This package provides a greedy algorithm for surface reconstruction from an -unorganized point set. Starting from a seed facet, a piecewise linear -surface is grown by adding Delaunay triangles one by one. The most -plausible triangles are added first, in a way that avoids the appearance +unorganized point set. Starting from a seed facet, a piecewise linear +surface is grown by adding Delaunay triangles one by one. The most +plausible triangles are added first, in a way that avoids the appearance of topological singularities. } \cgalPkgManuals{Chapter_Advancing_Front_Surface_Reconstruction,PkgAdvancingFrontSurfaceReconstruction} \cgalPkgSummaryEnd diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp index 98d3d24fd44..db9082a959a 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/boundaries.cpp @@ -17,8 +17,8 @@ struct Perimeter { template bool operator()(const Point& p, const Point& q, const Point& r) const { - // bound == 0 is better than bound < infinity - // as it avoids the distance computations + // bound == 0 is better than bound < infinity + // as it avoids the distance computations if(bound == 0){ return false; } @@ -44,21 +44,21 @@ typedef K::Point_3 Point_3; int main(int argc, char* argv[]) { - std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); + std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); std::istream_iterator begin(in); std::istream_iterator end; Perimeter perimeter(0.5); - Triangulation_3 dt(begin, end); + Triangulation_3 dt(begin, end); Reconstruction reconstruction(dt, perimeter); reconstruction.run(); - + std::cout << reconstruction.number_of_outliers() << " outliers:\n" << std::endl; BOOST_FOREACH(const Point_3& p, reconstruction.outliers()){ std::cout << p << std::endl; } - + std::cout << "Boundaries:" << std::endl ; BOOST_FOREACH(const Vertex_on_boundary_range & vobr, reconstruction.boundaries()){ std::cout << "boundary\n"; @@ -66,7 +66,7 @@ int main(int argc, char* argv[]) BOOST_FOREACH(Vertex_handle v, vobr){ std::cout << v->point() << std::endl; } - } - + } + return 0; } diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp index 70c38d3ef50..dc85210d852 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_class.cpp @@ -18,11 +18,11 @@ int main(int argc, char* argv[]) std::istream_iterator end; Triangulation_3 dt(begin,end); - + Reconstruction reconstruction(dt); reconstruction.run(); - + const TDS_2& tds = reconstruction.triangulation_data_structure_2(); std::cout << "solid produced with CGAL::Advancing_front_surface_reconstruction\n"; @@ -40,7 +40,7 @@ int main(int argc, char* argv[]) j++; } } - std::cout << " facet normal " + std::cout << " facet normal " << CGAL::unit_normal(points[0],points[1], points[2]) << "\n" << " outer loop\n" << " vertex " << points[0] << "\n" @@ -51,6 +51,6 @@ int main(int argc, char* argv[]) } } std::cout << "endsolid" << std::endl; - + return 0; } diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp index b00870487fa..c612ee5c929 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_fct.cpp @@ -11,7 +11,7 @@ typedef K::Point_3 Point_3; typedef CGAL::cpp11::array Facet; namespace std { - std::ostream& + std::ostream& operator<<(std::ostream& os, const Facet& f) { os << "3 " << f[0] << " " << f[1] << " " << f[2]; @@ -32,8 +32,8 @@ struct Perimeter { template bool operator()(const Point& p, const Point& q, const Point& r) const { - // bound == 0 is better than bound < infinity - // as it avoids the distance computations + // bound == 0 is better than bound < infinity + // as it avoids the distance computations if(bound == 0){ return false; } @@ -48,14 +48,14 @@ struct Perimeter { int main(int argc, char* argv[]) { - std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); + std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); std::vector points; std::vector facets; - - std::copy(std::istream_iterator(in), - std::istream_iterator(), + + std::copy(std::istream_iterator(in), + std::istream_iterator(), std::back_inserter(points)); - + Perimeter perimeter(0); CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), @@ -69,6 +69,6 @@ int main(int argc, char* argv[]) std::copy(facets.begin(), facets.end(), std::ostream_iterator(std::cout, "\n")); - + return 0; } diff --git a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp index d237556efd0..225eef0b170 100644 --- a/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp +++ b/Advancing_front_surface_reconstruction/examples/Advancing_front_surface_reconstruction/reconstruction_surface_mesh.cpp @@ -15,7 +15,7 @@ typedef CGAL::Surface_mesh Mesh; struct Construct{ Mesh& mesh; - + template < typename PointIterator> Construct(Mesh& mesh,PointIterator b, PointIterator e) : mesh(mesh) @@ -25,13 +25,13 @@ struct Construct{ v = add_vertex(mesh); mesh.point(v) = *b; } - } - + } + Construct& operator=(const Facet f) { typedef boost::graph_traits::vertex_descriptor vertex_descriptor; typedef boost::graph_traits::vertices_size_type size_type; - mesh.add_face(vertex_descriptor(static_cast(f[0])), + mesh.add_face(vertex_descriptor(static_cast(f[0])), vertex_descriptor(static_cast(f[1])), vertex_descriptor(static_cast(f[2]))); return *this; @@ -45,20 +45,20 @@ struct Construct{ Construct operator++(int) { return *this; } - + }; int main(int argc, char* argv[]) { - std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); + std::ifstream in((argc>1)?argv[1]:"data/half.xyz"); std::vector points; std::vector facets; Mesh m; - std::copy(std::istream_iterator(in), - std::istream_iterator(), + std::copy(std::istream_iterator(in), + std::istream_iterator(), std::back_inserter(points)); - + Construct construct(m,points.begin(),points.end()); CGAL::advancing_front_surface_reconstruction(points.begin(), diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h index e4484d35948..4d1904c02e2 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction.h @@ -50,7 +50,7 @@ namespace CGAL { // This iterator allows to visit all contours. It has the particularity // that it visits the entry point of the contour twice. This allows to // detect that the traversal of the border is finished. One more increment - // brings us to the next vertex. + // brings us to the next vertex. @@ -70,7 +70,7 @@ namespace CGAL { Vertex_handle pos; bool first, last; - public: + public: Advancing_front_surface_reconstruction_boundary_iterator(const Surface& S_, int m) : S(S_), mark(m), first_vertex(S.triangulation_3().finite_vertices_begin()), pos(first_vertex) { @@ -142,19 +142,19 @@ namespace CGAL { } do { first_vertex++; - } while((first_vertex != S.triangulation_3().finite_vertices_end()) && - (! ((first_vertex->is_on_border()) + } while((first_vertex != S.triangulation_3().finite_vertices_end()) && + (! ((first_vertex->is_on_border()) && ! first_vertex->is_post_marked(mark)))); if(first_vertex != S.triangulation_3().finite_vertices_end()) { pos = first_vertex; pos->set_post_mark(mark); assert(pos->is_on_border()); - + } else { pos = NULL; } } - }; + }; namespace AFSR{ struct Always_false { @@ -171,12 +171,12 @@ namespace CGAL { /*! \ingroup PkgAdvancingFrontSurfaceReconstruction - The class `Advancing_front_surface_reconstruction` enables advanced users to provide the unstructured + The class `Advancing_front_surface_reconstruction` enables advanced users to provide the unstructured point cloud in a 3D Delaunay triangulation. The reconstruction algorithm then marks vertices and faces in the triangulation as being on the 2D surface embedded in 3D space, and constructs a 2D triangulation - data structure that describes the surface. The vertices and facets of the 2D triangulation data structure + data structure that describes the surface. The vertices and facets of the 2D triangulation data structure store handles to the vertices and faces of the 3D triangulation, which enables the user to explore the - 2D as well as 3D neighborhood of vertices and facets of the surface. + 2D as well as 3D neighborhood of vertices and facets of the surface. \tparam Dt must be a `Delaunay_triangulation_3` with `Advancing_front_surface_reconstruction_vertex_base_3` and `Advancing_front_surface_reconstruction_cell_base_3` blended into the vertex and cell type. @@ -222,7 +222,7 @@ namespace CGAL { /*! The type of the triangle filter functor. */ - typedef unspecified_type Filter; + typedef unspecified_type Filter; /*! The point type. @@ -287,7 +287,7 @@ namespace CGAL { typedef typename Triangulation_3::Cell_circulator Cell_circulator; typedef typename Triangulation_3::Facet_circulator Facet_circulator; - + typedef typename Triangulation_3::Locate_type Locate_type; typedef typename Triangulation_3::Finite_cells_iterator Finite_cells_iterator; @@ -299,19 +299,19 @@ namespace CGAL { typedef typename Triangulation_3::All_facets_iterator All_facets_iterator; typedef typename Triangulation_3::All_vertices_iterator All_vertices_iterator; typedef typename Triangulation_3::All_edges_iterator All_edges_iterator; - + typedef typename Triangulation_3::Vertex::Edge_incident_facet Edge_incident_facet; typedef typename Triangulation_3::Vertex::IO_edge_type IO_edge_type; typedef typename Triangulation_3::Vertex::criteria criteria; typedef typename Triangulation_3::Vertex::Radius_edge_type Radius_edge_type; typedef typename Triangulation_3::Vertex::Border_elt Border_elt; typedef typename Triangulation_3::Vertex::Next_border_elt Next_border_elt; - typedef typename Triangulation_3::Vertex::Intern_successors_type Intern_successors_type; + typedef typename Triangulation_3::Vertex::Intern_successors_type Intern_successors_type; typedef typename Triangulation_3::Vertex::Radius_ptr_type Radius_ptr_type; typedef typename Triangulation_3::Vertex::Incidence_request_iterator Incidence_request_iterator; typedef typename Triangulation_3::Vertex::Incidence_request_elt Incidence_request_elt; - + typedef std::pair< Vertex_handle, Vertex_handle > Edge_like; typedef CGAL::Triple< Vertex_handle, Vertex_handle, Vertex_handle > Facet_like; @@ -325,16 +325,16 @@ namespace CGAL { //===================================================================== //===================================================================== - + typedef const std::list > Boundary_range; typedef const std::list Vertex_on_boundary_range; - private: + private: + + mutable std::list > m_boundaries; - mutable std::list > m_boundaries; - Timer postprocess_timer, extend_timer, extend2_timer, init_timer; - + Triangulation_3& T; Ordered_border_type _ordered_border; @@ -378,22 +378,22 @@ namespace CGAL { typename std::list::iterator ie_sentinel; std::list nbe_pool; std::list ist_pool; - + Intern_successors_type* new_border() - { + { nbe_pool.push_back(Next_border_elt()); Next_border_elt* p1 = & nbe_pool.back(); nbe_pool.push_back(Next_border_elt()); Next_border_elt* p2 = & nbe_pool.back(); - + Intern_successors_type ist(p1,p2); ist_pool.push_back(ist); Intern_successors_type* ret = &ist_pool.back(); - ret->first->first = NULL; + ret->first->first = NULL; ret->second->first = NULL; return ret; } @@ -403,16 +403,16 @@ namespace CGAL { { if (vh->m_incident_border == NULL) return false; //vh is interior if (vh->m_incident_border->first->first != NULL) - { + { if (vh->m_incident_border->second->first != NULL) return ((vh->m_incident_border->first->second.second == i)|| (vh->m_incident_border->second->second.second == i)); return (vh->m_incident_border->first->second.second == i); } - return false; //vh is still exterior + return false; //vh is still exterior } - + void remove_border_edge(Vertex_handle w, Vertex_handle v) { if (w->m_incident_border != NULL) @@ -435,7 +435,7 @@ namespace CGAL { return; } else - { + { w->m_incident_border->first->first = NULL; set_interior_edge(w,v); return; @@ -462,7 +462,7 @@ namespace CGAL { } //------------------------------------------------------------------- - // pour gerer certaines aretes interieures: a savoir celle encore connectee au + // pour gerer certaines aretes interieures: a savoir celle encore connectee au // bord (en fait seule, les aretes interieures reliant 2 bords nous // interressent...) @@ -512,7 +512,7 @@ namespace CGAL { //------------------------------------------------------------------- - + inline void set_incidence_request(Vertex_handle w, const Incidence_request_elt& ir) { if(w->m_ir_last == sentinel ){ @@ -533,7 +533,7 @@ namespace CGAL { } return (w->m_ir_last != sentinel ); } - + inline Incidence_request_iterator incidence_request_begin(Vertex_handle w) { return w->m_ir_first; @@ -551,7 +551,7 @@ namespace CGAL { } inline void erase_incidence_request(Vertex_handle w) - { + { if(w->m_ir_last != sentinel ){ assert(w->m_ir_first != sentinel ); w->m_ir_last++; @@ -560,7 +560,7 @@ namespace CGAL { w->m_ir_last = sentinel ; } } - + void re_init(Vertex_handle w) { @@ -599,7 +599,7 @@ namespace CGAL { void initialize_vertices_and_cells() { - + Incidence_request_elt ire; incidence_requests.clear(); incidence_requests.push_back(ire); @@ -661,15 +661,15 @@ namespace CGAL { */ Advancing_front_surface_reconstruction(Triangulation_3& dt, Filter filter = Filter()) - : T(dt), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), - NB_BORDER_MAX(15), DELTA(.86), min_K(HUGE_VAL), + : T(dt), _number_of_border(1), COS_ALPHA_SLIVER(-0.86), + NB_BORDER_MAX(15), DELTA(.86), min_K(HUGE_VAL), eps(1e-7), inv_eps_2(coord_type(1)/(eps*eps)), eps_3(eps*eps*eps), - STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), + STANDBY_CANDIDATE(3), STANDBY_CANDIDATE_BIS(STANDBY_CANDIDATE+1), NOT_VALID_CANDIDATE(STANDBY_CANDIDATE+2), _vh_number(static_cast(T.number_of_vertices())), _facet_number(0), _postprocessing_counter(0), _size_before_postprocessing(0), _number_of_connected_components(0), deal_with_2d(false), filter(filter), max_connected_component(-1), K_init(1.1), K_step(.1) - + { if(T.dimension() == 2){ deal_with_2d = true; @@ -706,7 +706,7 @@ namespace CGAL { } */ - typedef Advancing_front_surface_reconstruction_boundary_iterator Boundary_iterator; + typedef Advancing_front_surface_reconstruction_boundary_iterator Boundary_iterator; Boundary_iterator boundaries_begin() const { @@ -752,7 +752,7 @@ namespace CGAL { } initialize_vertices_and_cells(); bool re_init = false; - do + do { _number_of_connected_components++; @@ -770,14 +770,14 @@ namespace CGAL { while(postprocessing()){ extend2_timer.start(); extend(); - + extend2_timer.stop(); } } - } + } }while(re_init && ((_number_of_connected_components < max_connected_component)|| - (max_connected_component < 0))); + (max_connected_component < 0))); _tds_2_inf = AFSR::construct_surface(_tds_2, *this); @@ -828,8 +828,8 @@ namespace CGAL { }while(*b != v); } } - - return m_boundaries; + + return m_boundaries; } /// @} @@ -842,7 +842,7 @@ namespace CGAL { bool has_boundaries() const { - return _tds_2_inf != typename TDS_2::Vertex_handle(); + return _tds_2_inf != typename TDS_2::Vertex_handle(); } /*! @@ -872,7 +872,7 @@ namespace CGAL { return v2 != _tds_2_inf; } /// @} - + int number_of_connected_components() const { return _number_of_connected_components; @@ -897,7 +897,7 @@ namespace CGAL { typedef typename std::list::const_iterator Outlier_iterator; - + Outlier_iterator outliers_begin() const { return m_outliers.begin(); @@ -950,14 +950,14 @@ namespace CGAL { { Next_border_elt* it12 = border_elt(key.first, key.second); if (it12 != NULL) - { + { result = it12->second; return true; } Next_border_elt* it21 = border_elt(key.second, key.first); if (it21 != NULL) - { + { result = it21->second; std::swap(key.first, key.second); return true; @@ -969,13 +969,13 @@ namespace CGAL { bool is_border_elt(Edge_like& key) const { Next_border_elt* it12 = border_elt(key.first, key.second); if (it12 != NULL) - { + { return true; } Next_border_elt* it21 = border_elt(key.second, key.first); if (it21 != NULL) - { + { std::swap(key.first, key.second); return true; } @@ -987,7 +987,7 @@ namespace CGAL { { Next_border_elt* it12 = border_elt(key.first, key.second); if (it12 != NULL) - { + { result = it12->second; return true; } @@ -1002,14 +1002,14 @@ namespace CGAL { } //--------------------------------------------------------------------- - bool is_ordered_border_elt(const Edge_like& e, + bool is_ordered_border_elt(const Edge_like& e, IO_edge_type* &ptr) const { Vertex_handle v1 = e.first; Next_border_elt* it12 = border_elt(v1, e.second); if (it12 != NULL) - { + { ptr = &it12->second.first.second; return true; } @@ -1027,7 +1027,7 @@ namespace CGAL { //--------------------------------------------------------------------- bool is_interior_edge(const Edge_like& key) const - // pour gerer certaines aretes interieures: a savoir celle encore connectee au + // pour gerer certaines aretes interieures: a savoir celle encore connectee au // bord (en fait seule, les aretes interieures reliant 2 bords nous // interressent...) { @@ -1073,11 +1073,11 @@ namespace CGAL { int i = e.second; int i1 = e.first.second, i2 = e.first.third; int i3 = (6 - e.second - i1 - i2); - + Cell_handle n = c->neighbor(i); int j1 = n->index(c->vertex(i1)), j2 = n->index(c->vertex(i2)); int j = n->index(c->vertex(i3)); - return Edge_incident_facet(Edge(n, j1, j2), j); + return Edge_incident_facet(Edge(n, j1, j2), j); } //--------------------------------------------------------------------- @@ -1087,16 +1087,16 @@ namespace CGAL { int i = e.second; int i1 = e.first.second, i2 = e.first.third; int i3 = (6 - e.second - i1 - i2); - + Cell_handle n = c->neighbor(i3); int j1 = n->index(c->vertex(i1)), j2 = n->index(c->vertex(i2)); int j = n->index(c->vertex(i)); - return Edge_incident_facet(Edge(n, j1, j2), j); + return Edge_incident_facet(Edge(n, j1, j2), j); } //--------------------------------------------------------------------- bool - my_coplanar(const Point& p, const Point& q, + my_coplanar(const Point& p, const Point& q, const Point& r, const Point& s) const { coord_type qpx = q.x()-p.x(); @@ -1171,16 +1171,16 @@ namespace CGAL { return _border_count; } - + //===================================================================== - coord_type + coord_type smallest_radius_delaunay_sphere(const Cell_handle& c, const int& index) const { int i1, i2, i3; - if(deal_with_2d && ( (c->vertex((index+1) & 3) == added_vertex) - || (c->vertex((index+2) & 3) == added_vertex) + if(deal_with_2d && ( (c->vertex((index+1) & 3) == added_vertex) + || (c->vertex((index+2) & 3) == added_vertex) || (c->vertex((index+3) & 3) == added_vertex) )) { return HUGE_VAL; @@ -1214,7 +1214,7 @@ namespace CGAL { else { if (c_is_infinite||n_is_infinite||c_is_plane||n_is_plane) - { + { int ind; Cell_handle cc; if(c_is_infinite||c_is_plane) @@ -1230,7 +1230,7 @@ namespace CGAL { i1 = (ind+1) & 3; i2 = (ind+2) & 3; i3 = (ind+3) & 3; - + const Point& pp0 = cc->vertex(ind)->point(); const Point& pp1 = cc->vertex(i1)->point(); const Point& pp2 = cc->vertex(i2)->point(); @@ -1289,7 +1289,7 @@ namespace CGAL { //--------------------------------------------------------------------- - // For a border edge e we determine the incident facet which has the highest + // For a border edge e we determine the incident facet which has the highest // chance to be a natural extension of the surface Radius_edge_type @@ -1311,7 +1311,7 @@ namespace CGAL { const Point& p1 = c->vertex(i1)->point(); const Point& p2 = c->vertex(i2)->point(); const Point& pc = c->vertex(i3)->point(); - + Vector P2P1 = p1-p2, P2Pn, PnP1; Vector v2, v1 = cross_product(pc-p2, P2P1); @@ -1321,7 +1321,7 @@ namespace CGAL { e_it = next(e_it); bool succ_start(true); - + do { Cell_handle neigh = e_it.first.first; @@ -1332,10 +1332,10 @@ namespace CGAL { int n_ind = facet_it.second; int n_i1 = e_it.first.second; int n_i2 = e_it.first.third; - int n_i3 = 6 - n_ind - n_i1 - n_i2; + int n_i3 = 6 - n_ind - n_i1 - n_i2; coord_type tmp=0; - + // If the triangle has a high perimeter, // we do not want to consider it as a good candidate. @@ -1344,32 +1344,32 @@ namespace CGAL { facet_it.first->vertex(n_i3)->point())){ tmp = HUGE_VAL; } - - + + if(tmp != HUGE_VAL){ tmp = smallest_radius_delaunay_sphere(neigh, n_ind); } - + Edge_like el1(neigh->vertex(n_i1),neigh->vertex(n_i3)), el2(neigh->vertex(n_i2),neigh->vertex(n_i3)); - + if ((tmp != HUGE_VAL)&& neigh->vertex(n_i3)->not_interior()&& (!is_interior_edge(el1))&&(!is_interior_edge(el2))) { const Point& pn = neigh->vertex(n_i3)->point(); - + P2Pn = pn-p2; v2 = cross_product(P2P1,P2Pn); - //pas necessaire de normer pour un bon echantillon: + //pas necessaire de normer pour un bon echantillon: // on peut alors tester v1*v2 >= 0 norm = sqrt(norm1 * (v2*v2)); pscal = v1*v2; // check if the triangle will produce a sliver on the surface - bool sliver_facet = ((succ_start || (neigh == c_predone))&& + bool sliver_facet = ((succ_start || (neigh == c_predone))&& (pscal <= COS_ALPHA_SLIVER*norm)); - + if (succ_start) succ_start = false; if (!sliver_facet) @@ -1381,14 +1381,14 @@ namespace CGAL { // We skip triangles having an internal angle along e // whose cosinus is smaller than -DELTA // that is the angle is larger than arcos(-DELTA) - border_facet = !((P2P1*P2Pn >= + border_facet = !((P2P1*P2Pn >= -DELTA*sqrt(norm12*(P2Pn*P2Pn)))&& - (P2P1*PnP1 >= + (P2P1*PnP1 >= -DELTA*sqrt(norm12*(PnP1*PnP1)))); // \todo investigate why we simply do not skip this triangle // but continue looking for a better candidate - // if (!border_facet){ - min_facetA = facet_it; + // if (!border_facet){ + min_facetA = facet_it; min_valueA = tmp; min_valueP = pscal/norm; } @@ -1402,18 +1402,18 @@ namespace CGAL { criteria value; if ((min_valueA == HUGE_VAL) || border_facet) // bad facets case - { + { min_facet = Facet(c, i); // !!! sans aucune signification.... value = NOT_VALID_CANDIDATE; // Attention a ne pas inserer dans PQ } else { - min_facet = min_facetA; + min_facet = min_facetA; //si on considere seulement la pliure value appartient a [0, 2] //value = coord_type(1) - min_valueP; - - // si la pliure est bonne on note suivant le alpha sinon on prend en compte la + + // si la pliure est bonne on note suivant le alpha sinon on prend en compte la // pliure seule... pour discriminer entre les bons slivers... // si on veut discriminer les facettes de bonnes pliures plus finement // alors -(1+1/min_valueA) app a [-inf, -1] @@ -1431,17 +1431,17 @@ namespace CGAL { { value = STANDBY_CANDIDATE; // tres mauvais candidat mauvaise pliure // + grand alpha... a traiter plus tard.... - min_K = + min_K = (std::min)(min_K, min_valueA/tmp); } } } - + Cell_handle n = min_facet.first; int ni1 = n->index(c->vertex(i1)), ni2 = n->index(c->vertex(i2)); - return + return Radius_edge_type(value, IO_edge_type(e, Edge_incident_facet (Edge(n, ni1, ni2), min_facet.second))); @@ -1460,8 +1460,8 @@ namespace CGAL { if (!re_init){ Finite_facets_iterator end = T.finite_facets_end(); - for(Finite_facets_iterator facet_it = T.finite_facets_begin(); - facet_it != end; + for(Finite_facets_iterator facet_it = T.finite_facets_begin(); + facet_it != end; ++facet_it) { coord_type value = smallest_radius_delaunay_sphere((*facet_it).first, @@ -1474,12 +1474,12 @@ namespace CGAL { } }else{ //if (re_init) Finite_facets_iterator end = T.finite_facets_end(); - for(Finite_facets_iterator facet_it = T.finite_facets_begin(); - facet_it != end; + for(Finite_facets_iterator facet_it = T.finite_facets_begin(); + facet_it != end; ++facet_it) { Cell_handle c = (*facet_it).first; - int index = (*facet_it).second; + int index = (*facet_it).second; if (c->vertex((index+1) & 3)->is_exterior()) if (c->vertex((index+2) & 3)->is_exterior()) if (c->vertex((index+3) & 3)->is_exterior()) @@ -1505,7 +1505,7 @@ namespace CGAL { if (min_value != HUGE_VAL) { Cell_handle c_min = min_facet.first; - + int ind = min_facet.second; i1 = (ind+1) & 3; i2 = (ind+2) & 3; @@ -1523,7 +1523,7 @@ namespace CGAL { Border_elt(e23, _number_of_border)); IO_edge_type* p31 = set_border_elt(c_min->vertex(i3), c_min->vertex(i1), Border_elt(e31, _number_of_border)); - + c_min->vertex(i1)->inc_mark(); c_min->vertex(i2)->inc_mark(); c_min->vertex(i3)->inc_mark(); @@ -1542,11 +1542,11 @@ namespace CGAL { //--------------------------------------------------------------------- // test de reciprocite avant de recoller une oreille anti-singularite int - test_merge(const Edge_like& ordered_key, const Border_elt& result, + test_merge(const Edge_like& ordered_key, const Border_elt& result, const Vertex_handle& v, const coord_type& ear_alpha) { Edge_incident_facet Ifacet = result.first.second.first; - + const Point& p1 = (ordered_key.first)->point(); const Point& p2 = (ordered_key.second)->point(); const Point& pc = v->point(); @@ -1562,12 +1562,12 @@ namespace CGAL { v2 = cross_product(p1-p2,pn-p2); coord_type norm = sqrt((v1*v1)*(v2*v2)); - if (v1*v2 > COS_BETA*norm) + if (v1*v2 > COS_BETA*norm) return 1; // label bonne pliure sinon: if (ear_alpha <= K*smallest_radius_delaunay_sphere(neigh, n_ind)) return 2; // label alpha coherent... - + return 0; //sinon oreille a rejeter... } @@ -1602,7 +1602,7 @@ namespace CGAL { v_it++) { IO_edge_type* ptr; - + if (is_ordered_border_elt(v_it->second, ptr)) _ordered_border.insert(Radius_ptr_type(v_it->first, ptr)); } @@ -1613,11 +1613,11 @@ namespace CGAL { //--------------------------------------------------------------------- void - merge_ear(const Edge_like& ordered_el1, const Border_elt& result1, + merge_ear(const Edge_like& ordered_el1, const Border_elt& result1, const Edge_like& ordered_key, const Vertex_handle& v1, const Vertex_handle& v2, const Edge_incident_facet& edge_Ifacet_2) - { + { remove_border_elt(ordered_key); force_merge(ordered_el1, result1); Radius_edge_type e2 = compute_value(edge_Ifacet_2); @@ -1632,7 +1632,7 @@ namespace CGAL { _ordered_border.insert(Radius_ptr_type(e2.first, p2)); - //depiler les eventuelles requettes de connections avortees... zones etoilees, + //depiler les eventuelles requettes de connections avortees... zones etoilees, //en effet le bord a change donc on peut peut etre maintenant. dequeue_incidence_request(v2); if (ordered_el1.first == v1) @@ -1643,7 +1643,7 @@ namespace CGAL { //--------------------------------------------------------------------- void - border_extend(const Edge_like& ordered_key, const Border_elt& result12, + border_extend(const Edge_like& ordered_key, const Border_elt& result12, const Vertex_handle& v1, const Vertex_handle& v2, const Vertex_handle& v3, const Radius_edge_type& e1, const Radius_edge_type& e2, @@ -1666,9 +1666,9 @@ namespace CGAL { p1 = set_border_elt(v3, v1, Border_elt(e1,result12.second)); } - v3->inc_mark(); + v3->inc_mark(); - //depiler les eventuelles requettes de connections avortees... zones etoilees, + //depiler les eventuelles requettes de connections avortees... zones etoilees, //en effet le bord a change donc on peut peut etre maintenant. dequeue_incidence_request(v1); dequeue_incidence_request(v2); @@ -1676,17 +1676,17 @@ namespace CGAL { //===================================================================== Validation_case - validate(const Edge_incident_facet& edge_Efacet, + validate(const Edge_incident_facet& edge_Efacet, const criteria& value) { - int i = (6 - edge_Efacet.second + int i = (6 - edge_Efacet.second - edge_Efacet.first.second - edge_Efacet.first.third); Cell_handle c = edge_Efacet.first.first; Vertex_handle v1 = c->vertex(edge_Efacet.first.second), v2 = c->vertex(edge_Efacet.first.third); - + Edge_like ordered_el1(c->vertex(i), v1); Edge_like ordered_el2(c->vertex(i), v2); Border_elt result1, result2, result12; @@ -1704,13 +1704,13 @@ namespace CGAL { { if ((!is_interior_edge(ordered_el1))&& (!is_interior_edge(ordered_el2))) - { + { //toujours utile meme avec l'essai de try_to_close_border avant //validate pour la resolution de singularite par oreille qui elle //doit etre dans Delaunay. if (is_border_el1&&is_border_el2) - { - remove_border_elt(ordered_key); + { + remove_border_elt(ordered_key); force_merge(ordered_el1, result1); force_merge(ordered_el2, result2); @@ -1718,18 +1718,18 @@ namespace CGAL { dec_mark(v2); dec_mark(c->vertex(i)); - select_facet(c, edge_Efacet.second); + select_facet(c, edge_Efacet.second); return FINAL_CASE; } - //--------------------------------------------------------------------- - //on peut alors marquer v1 et on pourrait essayer de merger + //--------------------------------------------------------------------- + //on peut alors marquer v1 et on pourrait essayer de merger //sans faire de calcul inutile??? if (is_border_el1) { - Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), + Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), edge_Efacet.second); - merge_ear(ordered_el1, result1, + merge_ear(ordered_el1, result1, ordered_key, v1, v2, edge_Ifacet_2); select_facet(c, edge_Efacet.second); @@ -1740,44 +1740,44 @@ namespace CGAL { //idem pour v2 if (is_border_el2) { - Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), + Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), edge_Efacet.second); - merge_ear(ordered_el2, result2, + merge_ear(ordered_el2, result2, ordered_key, v2, v1, edge_Ifacet_1); select_facet(c, edge_Efacet.second); return EAR_CASE; } - + //--------------------------------------------------------------------- if ((!is_border_el1)&&(!is_border_el2)) - { - // si on veut s'interdir de spliter un bord (pelure d'orange....) + { + // si on veut s'interdir de spliter un bord (pelure d'orange....) // seulement c->vertex(i)->is_exterior() // pour s'autoriser des split de bord surface a bord->sphere ou Moebius... // alors || is_on_same_border: - // if (c->vertex(i)->is_exterior() || is_on_same_border) + // if (c->vertex(i)->is_exterior() || is_on_same_border) // pour passer au tore (changementde type de topologie) // recoller deux bord different... - // if (c->vertex(i)->not_interior() deja teste en haut - + // if (c->vertex(i)->not_interior() deja teste en haut + if(c->vertex(i)->is_exterior()) - { - Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), + { + Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), edge_Efacet.second); - - Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), + + Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), edge_Efacet.second); e1 = compute_value(edge_Ifacet_1); e2 = compute_value(edge_Ifacet_2); - - IO_edge_type* p1; - IO_edge_type* p2; - border_extend(ordered_key, result12, + IO_edge_type* p1; + IO_edge_type* p2; + + border_extend(ordered_key, result12, v1, v2, c->vertex(i), e1, e2, p1, p2); - + // if e1 contain HUGE_VAL there is no candidates to // continue: compute_value is not valid... @@ -1792,19 +1792,19 @@ namespace CGAL { else // c->vertex(i) is a border point (and now there's only 1 // border incident to a point... _mark<1 even if th orientation // may be such as one vh has 2 successorson the same border... - { + { // a ce niveau on peut tester si le recollement se fait en // maintenant la compatibilite d'orientation des bords (pour // surface orientable...) ou si elle est brisee... - Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), + Edge_incident_facet edge_Ifacet_1(Edge(c, i, edge_Efacet.first.second), edge_Efacet.second); - Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), + Edge_incident_facet edge_Ifacet_2(Edge(c, i, edge_Efacet.first.third), edge_Efacet.second); e1 = compute_value(edge_Ifacet_1); e2 = compute_value(edge_Ifacet_2); - if ((e1.first >= STANDBY_CANDIDATE)&&(e2.first >= STANDBY_CANDIDATE)) + if ((e1.first >= STANDBY_CANDIDATE)&&(e2.first >= STANDBY_CANDIDATE)) return NOT_VALID_CONNECTING_CASE; // vu compute value: les candidats oreilles fournis sont sans @@ -1812,13 +1812,13 @@ namespace CGAL { Edge_incident_facet ear1 = e1.second.second; Edge_incident_facet ear2 = e2.second.second; - int ear1_i = (6 - ear1.second + int ear1_i = (6 - ear1.second - ear1.first.second - ear1.first.third); Cell_handle ear1_c = ear1.first.first; Border_elt result_ear1; - int ear2_i = (6 - ear2.second + int ear2_i = (6 - ear2.second - ear2.first.second - ear2.first.third); Cell_handle ear2_c = ear2.first.first; @@ -1832,14 +1832,14 @@ namespace CGAL { ear1_e = Edge_like(c->vertex(i), ear1_c ->vertex(ear1_i)); ear2_e = Edge_like(ear2_c ->vertex(ear2_i), c->vertex(i)); } - else + else { ear1_e = Edge_like(ear1_c ->vertex(ear1_i), c->vertex(i)); ear2_e = Edge_like(c->vertex(i), ear2_c ->vertex(ear2_i)); } - + //maintient la surface orientable - bool is_border_ear1 = is_ordered_border_elt(ear1_e, result_ear1); + bool is_border_ear1 = is_ordered_border_elt(ear1_e, result_ear1); bool is_border_ear2 = is_ordered_border_elt(ear2_e, result_ear2); bool ear1_valid(false), ear2_valid(false); if (is_border_ear1&&(e1.first < STANDBY_CANDIDATE)&& @@ -1847,7 +1847,7 @@ namespace CGAL { (result12.second==result_ear1.second)) { ear1_valid = test_merge(ear1_e, result_ear1, v1, - smallest_radius_delaunay_sphere(ear1_c, + smallest_radius_delaunay_sphere(ear1_c, ear1.second)) != 0; } if (is_border_ear2&&(e2.first < STANDBY_CANDIDATE)&& @@ -1855,26 +1855,26 @@ namespace CGAL { (result12.second==result_ear2.second)) { ear2_valid = test_merge(ear2_e, result_ear2, v2, - smallest_radius_delaunay_sphere(ear2_c, + smallest_radius_delaunay_sphere(ear2_c, ear2.second)) != 0; - } - if ((!ear1_valid)&&(!ear2_valid)) + } + if ((!ear1_valid)&&(!ear2_valid)) return NOT_VALID_CONNECTING_CASE; - IO_edge_type* p1; - IO_edge_type* p2; + IO_edge_type* p1; + IO_edge_type* p2; - border_extend(ordered_key, result12, + border_extend(ordered_key, result12, v1, v2, c->vertex(i), e1, e2, p1, p2); if (ear1_valid&&ear2_valid&&(ear1_e==ear2_e)) { if (e1.first < e2.first) - { + { Validation_case res = validate(ear1, e1.first); if (!((res == EAR_CASE)||(res == FINAL_CASE))) - std::cerr << "+++probleme de recollement : cas " + std::cerr << "+++probleme de recollement : cas " << res << std::endl; e2 = compute_value(edge_Ifacet_2); @@ -1891,14 +1891,14 @@ namespace CGAL { { Validation_case res = validate(ear2, e2.first); if (!((res == EAR_CASE)||(res == FINAL_CASE))) - std::cerr << "+++probleme de recollement : cas " + std::cerr << "+++probleme de recollement : cas " << res << std::endl; e1 = compute_value(edge_Ifacet_1); - if (ordered_key.first == v1) + if (ordered_key.first == v1) p1 = set_again_border_elt(v1, c->vertex(i), Border_elt(e1, result1.second)); - else + else p1 = set_again_border_elt(c->vertex(i), v1, Border_elt(e1, result1.second)); @@ -1912,14 +1912,14 @@ namespace CGAL { { Validation_case res = validate(ear1, e1.first); if (!((res == EAR_CASE)||(res == FINAL_CASE))) - std::cerr << "+++probleme de recollement : cas " + std::cerr << "+++probleme de recollement : cas " << res << std::endl; } if (ear2_valid) { Validation_case res = validate(ear2, e2.first); if (!((res == EAR_CASE)||(res == FINAL_CASE))) - std::cerr << "+++probleme de recollement : cas " + std::cerr << "+++probleme de recollement : cas " << res << std::endl; } // on met a jour la PQ s'il y a lieu... mais surtout pas @@ -1928,7 +1928,7 @@ namespace CGAL { { _ordered_border.insert(Radius_ptr_type(e1.first, p1)); } - if (!ear2_valid) + if (!ear2_valid) { _ordered_border.insert(Radius_ptr_type(e2.first, p2)); } @@ -1937,7 +1937,7 @@ namespace CGAL { return CONNECTING_CASE; } } - } + } } return NOT_VALID; } @@ -1949,7 +1949,7 @@ namespace CGAL { if(!_ordered_border.empty()) { Ordered_border_type _ordered_border_tmp; - do + do { Ordered_border_iterator e_it = _ordered_border.begin(); Edge_incident_facet mem_Ifacet = e_it->second->first; @@ -1966,12 +1966,12 @@ namespace CGAL { // a garder pour un K un peu plus grand... new_candidate.first = STANDBY_CANDIDATE_BIS; } - + Border_elt result; Edge_like key_tmp(v1,v2); is_border_elt(key_tmp, result); - IO_edge_type* pnew = - set_again_border_elt(key_tmp.first, key_tmp.second, + IO_edge_type* pnew = + set_again_border_elt(key_tmp.first, key_tmp.second, Border_elt (new_candidate, result.second)); _ordered_border_tmp.insert(Radius_ptr_type(new_candidate.first, pnew)); } @@ -1982,7 +1982,7 @@ namespace CGAL { } //--------------------------------------------------------------------- - void + void extend() { // initilisation de la variable globale K: qualite d'echantillonnage requise @@ -1996,7 +1996,7 @@ namespace CGAL { { min_K = HUGE_VAL; // pour retenir le prochain K necessaire pour progresser... do - { + { Ordered_border_iterator e_it = _ordered_border.begin(); @@ -2024,7 +2024,7 @@ namespace CGAL { Validation_case validate_result = validate(candidate, value); if ((validate_result == NOT_VALID)|| (validate_result == NOT_VALID_CONNECTING_CASE)) - { + { Radius_edge_type new_candidate; Border_elt result; Edge_like key_tmp(v1,v2); @@ -2034,13 +2034,13 @@ namespace CGAL { set_incidence_request(c_ext->vertex(i3), value, key_tmp); if (validate_result == NOT_VALID) - { + { new_candidate = compute_value(mem_Ifacet); if ((new_candidate != mem_e_it)) // &&(new_candidate.first < NOT_VALID_CANDIDATE)) { - IO_edge_type* pnew = - set_again_border_elt(key_tmp.first, key_tmp.second, + IO_edge_type* pnew = + set_again_border_elt(key_tmp.first, key_tmp.second, Border_elt (new_candidate, result.second)); _ordered_border.insert(Radius_ptr_type(new_candidate.first, pnew)); @@ -2052,7 +2052,7 @@ namespace CGAL { while((!_ordered_border.empty())&& (_ordered_border.begin()->first < STANDBY_CANDIDATE_BIS)); - K += (std::max)(K_step, min_K - K + eps); + K += (std::max)(K_step, min_K - K + eps); // on augmente progressivement le K mais on a deja rempli sans // faire des betises auparavant... } @@ -2067,7 +2067,7 @@ namespace CGAL { //--------------------------------------------------------------------- - // En principe, si l'allocateur de cellules etait bien fait on aurait pas besoin + // En principe, si l'allocateur de cellules etait bien fait on aurait pas besoin // de mettre a jour les valeurs rajoutees pour les cellules a la main... void @@ -2076,13 +2076,13 @@ namespace CGAL { std::list ch_set; T.incident_cells(vh, std::back_inserter(ch_set)); for (typename std::list::iterator c_it = ch_set.begin(); - c_it != ch_set.end(); + c_it != ch_set.end(); c_it++) (*c_it)->clear(); } //--------------------------------------------------------------------- - void + void swap_selected_facets_on_conflict_boundary(const Vertex_handle& vh) { std::list ch_set; @@ -2095,7 +2095,7 @@ namespace CGAL { Cell_handle neigh = c->neighbor(index); int n_ind = neigh->index(c); neigh->set_smallest_radius(n_ind, -1); // pour obliger le recalcul - // si c est selectionnee c'est qu'elle est aussi le mem_IFacet renvoye par + // si c est selectionnee c'est qu'elle est aussi le mem_IFacet renvoye par // compute_value... donc a swapper aussi if (c->is_selected_facet(index)) { @@ -2110,7 +2110,7 @@ namespace CGAL { if (is_border_elt(key)) { - Edge_incident_facet ei_facet(Edge(neigh, i1, i2), + Edge_incident_facet ei_facet(Edge(neigh, i1, i2), n_ind); *border_IO_elt(key.first, key.second) = IO_edge_type(ei_facet, ei_facet); @@ -2118,7 +2118,7 @@ namespace CGAL { key = Edge_like(neigh->vertex(i1), neigh->vertex(i3)); if (is_border_elt(key)) { - Edge_incident_facet ei_facet(Edge(neigh, i1, i3), + Edge_incident_facet ei_facet(Edge(neigh, i1, i3), n_ind); *border_IO_elt(key.first, key.second) = IO_edge_type(ei_facet, ei_facet); @@ -2126,7 +2126,7 @@ namespace CGAL { key = Edge_like(neigh->vertex(i3), neigh->vertex(i2)); if (is_border_elt(key)) { - Edge_incident_facet ei_facet(Edge(neigh, i3, i2), + Edge_incident_facet ei_facet(Edge(neigh, i3, i2), n_ind); *border_IO_elt(key.first, key.second) = IO_edge_type(ei_facet, ei_facet); @@ -2136,7 +2136,7 @@ namespace CGAL { } //--------------------------------------------------------------------- - Facet + Facet next_surface_facet(const Edge_incident_facet& start) { Edge_incident_facet circ = next(start); @@ -2176,7 +2176,7 @@ namespace CGAL { int index = i_facet.second; int i3 = 6 - index - i1 - i2; Vertex_handle vh_int = c->vertex(i3); - ordered_map_erase(border_elt.second.first.first, + ordered_map_erase(border_elt.second.first.first, border_IO_elt(vh, vh_succ)); remove_border_edge(vh, vh_succ); // 1- a virer au cas ou car vh va etre detruit @@ -2188,21 +2188,21 @@ namespace CGAL { assert(c->is_selected_facet(index)); unselect_facet(c, index); - - Facet f32 = - next_surface_facet(Edge_incident_facet(Edge(c, i3, i2), + + Facet f32 = + next_surface_facet(Edge_incident_facet(Edge(c, i3, i2), index)); if (!vh_int->is_on_border()) { - re_init(vh_int); + re_init(vh_int); vh_int->inc_mark(); } - Edge_incident_facet e32(Edge(f32.first, + Edge_incident_facet e32(Edge(f32.first, f32.first->index(vh_int), f32.first->index(vh_succ)), f32.second); - Radius_edge_type rad_elt_32(STANDBY_CANDIDATE, IO_edge_type(e32, e32)); + Radius_edge_type rad_elt_32(STANDBY_CANDIDATE, IO_edge_type(e32, e32)); Border_elt result; if (is_ordered_border_elt(Edge_like(vh_int, vh), result)) { @@ -2218,16 +2218,16 @@ namespace CGAL { // 2- a virer a tout pris pour que maintenir le sens de interior edge remove_interior_edge(vh_int, vh_succ); remove_interior_edge(vh_succ, vh_int); - - IO_edge_type* p32 = set_border_elt(vh_int, vh_succ, + + IO_edge_type* p32 = set_border_elt(vh_int, vh_succ, Border_elt(rad_elt_32, border_index)); _ordered_border.insert(Radius_ptr_type (STANDBY_CANDIDATE, p32)); // incrementation... if (while_cond) { - Facet f31 = - next_surface_facet(Edge_incident_facet(Edge(c, i3, i1), + Facet f31 = + next_surface_facet(Edge_incident_facet(Edge(c, i3, i1), index)); c = f31.first; @@ -2236,7 +2236,7 @@ namespace CGAL { vh_succ = vh_int; i2 = c->index(vh_int); i3 = 6 - index - i1 - i2; - vh_int = c->vertex(i3); + vh_int = c->vertex(i3); } } while(while_cond); @@ -2246,7 +2246,7 @@ namespace CGAL { bool create_singularity(const Vertex_handle& vh) { - // Pour reperer le cas de triangle isole + // Pour reperer le cas de triangle isole if (vh->is_on_border()) { // vh sommet 0 @@ -2262,13 +2262,13 @@ namespace CGAL { { int l = 6-i-j-k; Cell_handle neigh = c->neighbor(l); - + if (c->is_selected_facet(l)||neigh->is_selected_facet(neigh->index(c))) return true; } } - + // Reperer le cas d'aretes interieures... std::list vh_list; @@ -2293,7 +2293,7 @@ namespace CGAL { { _vh_number--; } - + struct Remove : public std::unary_function { @@ -2305,18 +2305,18 @@ namespace CGAL { bool operator()(Vertex_handle vh) { if (vh->is_exterior()) - { + { E.swap_selected_facets_on_conflict_boundary(vh); E.re_init_for_free_cells_cache(vh); Point p = vh->point(); T.remove(vh); E.dec_vh_number(); E.store_outlier(p); - + return true; } else if (vh->is_on_border()&&(!E.create_singularity(vh))) - { + { E.swap_selected_facets_on_conflict_boundary(vh); E.retract_border_for_incident_facets(vh); E.re_init_for_free_cells_cache(vh); @@ -2324,7 +2324,7 @@ namespace CGAL { T.remove(vh); E.dec_vh_number(); E.store_outlier(p); - + return true; } else @@ -2345,12 +2345,12 @@ namespace CGAL { std::list L_v; // Pour controler les sommets choisis sur le bord... - + // nombre d'aretes a partir duquel on considere que c'est irrecuperable NB_BORDER_MAX int vh_on_border_inserted(0); for(Finite_vertices_iterator v_it = T.finite_vertices_begin(); - v_it != T.finite_vertices_end(); + v_it != T.finite_vertices_end(); v_it++) { erase_incidence_request(v_it); @@ -2363,7 +2363,7 @@ namespace CGAL { int v_count(0); // collect all vertices on the border do - { + { vh_it = vprev_it->first_incident()->first; L_v_tmp.push_back(vh_it); vh_it->set_post_mark(_postprocessing_counter); @@ -2380,7 +2380,7 @@ namespace CGAL { vh_on_border_inserted += v_count; } - } + } if (v_it->is_exterior()) L_v.push_back(v_it); } @@ -2431,7 +2431,7 @@ namespace CGAL { }; // class Advancing_front_surface_reconstruction namespace AFSR { - + template struct Auto_count : public std::unary_function >{ mutable int i; @@ -2503,7 +2503,7 @@ namespace CGAL { typedef Cartesian_converter CC; typedef Kernel::Point_3 Point_3; - CC cc=CC(); + CC cc=CC(); Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); @@ -2589,11 +2589,11 @@ namespace CGAL { typedef typename Kernel_traits::Kernel InputKernel; typedef Cartesian_converter CC; typedef typename Kernel::Point_3 Point_3; - + CC cc=CC(); Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); - + Reconstruction R(dt, filter); R.run(radius_ratio_bound, beta); AFSR::construct_polyhedron(polyhedron, R); @@ -2622,7 +2622,7 @@ namespace CGAL { CC cc=CC(); Triangulation_3 dt( boost::make_transform_iterator(b, AFSR::Auto_count_cc(cc)), boost::make_transform_iterator(e, AFSR::Auto_count_cc(cc) ) ); - + Reconstruction R(dt); R.run(radius_ratio_bound, beta); AFSR::construct_polyhedron(polyhedron, R); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h index 26b7b4a82fb..06f71e93fad 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_cell_base_3.h @@ -27,12 +27,12 @@ namespace CGAL { /*! \ingroup PkgAdvancingFrontSurfaceReconstruction - The class `Advancing_front_surface_reconstruction_cell_base_3` is the default + The class `Advancing_front_surface_reconstruction_cell_base_3` is the default cell type for the class `Advancing_front_surface_reconstruction`. - \tparam Traits has to be a model of `DelaunayTriangulationTraits_3`. + \tparam Traits has to be a model of `DelaunayTriangulationTraits_3`. - \tparam Cb has to be a model of `TriangulationCellBase_3`. + \tparam Cb has to be a model of `TriangulationCellBase_3`. */ template < typename Traits, typename Cb = Triangulation_cell_base_3 > class Advancing_front_surface_reconstruction_cell_base_3 : public Cb @@ -49,14 +49,14 @@ namespace CGAL { typedef typename Cb::Cell_handle Cell_handle; private: - + #ifdef AFSR_FACET_NUMBER int _facet_number[4]; #endif - typedef double coord_type; -#ifdef AFSR_LAZY + typedef double coord_type; +#ifdef AFSR_LAZY typedef typename CGAL::Simple_cartesian::Point_3 D_Point; -#endif +#endif //-------------------- DATA MEMBERS --------------------------------- coord_type* _smallest_radius_facet_tab; @@ -64,13 +64,13 @@ namespace CGAL { #ifdef AFSR_LAZY D_Point* _circumcenter; coord_type* _squared_radius; -#endif +#endif //-------------------- CONSTRUCTORS ---------------------------------- public: - - Advancing_front_surface_reconstruction_cell_base_3() + + Advancing_front_surface_reconstruction_cell_base_3() : Cb(), _smallest_radius_facet_tab(NULL), selected_facet(0) #ifdef AFSR_LAZY @@ -83,7 +83,7 @@ namespace CGAL { } #endif } - + Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3) : Cb( v0, v1, v2, v3), _smallest_radius_facet_tab(NULL), selected_facet(0) @@ -97,7 +97,7 @@ namespace CGAL { } #endif } - + Advancing_front_surface_reconstruction_cell_base_3(Vertex_handle v0, Vertex_handle v1, Vertex_handle v2, Vertex_handle v3, Cell_handle n0, Cell_handle n1, Cell_handle n2, Cell_handle n3) : Cb(v0, v1, v2, v3, @@ -130,7 +130,7 @@ namespace CGAL { //-------------------- MEMBER FUNCTIONS ---------------------------- public: - + inline void clear() { if (_smallest_radius_facet_tab != NULL) @@ -149,12 +149,12 @@ namespace CGAL { //------------------------------------------------------------------- inline coord_type smallest_radius(const int& i) - { + { if (_smallest_radius_facet_tab == NULL) return -1; return _smallest_radius_facet_tab[i]; } - + inline void set_smallest_radius(const int& i, const coord_type& c) { if (_smallest_radius_facet_tab == NULL) @@ -177,7 +177,7 @@ namespace CGAL { return false; } - + //------------------------------------------------------------------- #ifdef FACET_NUMBER @@ -197,14 +197,14 @@ namespace CGAL { //------------------------------------------------------------------- - + inline void select_facet(const int& i) { selected_facet |= (1 << i); } - + inline void unselect_facet(const int& i) - { + { selected_facet &= (15 - (1 << i)); } @@ -217,9 +217,9 @@ namespace CGAL { { return (selected_facet & (1 << i)) != 0; } - + #ifdef AFSR_LAZY - + //------------------------------------------------------------------- inline D_Point* lazy_circumcenter() @@ -231,16 +231,16 @@ namespace CGAL { { _circumcenter = new D_Point(p); } - + //------------------------------------------------------------------- inline coord_type* lazy_squared_radius() - { + { return _squared_radius; } inline void set_lazy_squared_radius(const coord_type& sr) - { + { _squared_radius = new coord_type(sr); } diff --git a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h index 9f6f2e77528..6df0cdc28c2 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/Advancing_front_surface_reconstruction_vertex_base_3.h @@ -63,7 +63,7 @@ namespace CGAL { typedef typename Base::Cell_handle Cell_handle; typedef typename Vb::Point Point; typedef double coord_type; - + typedef Triple< Cell_handle, int, int > Edge; typedef std::pair< Edge, int > Edge_incident_facet; typedef std::pair< Edge_incident_facet, Edge_incident_facet > IO_edge_type; @@ -87,8 +87,8 @@ namespace CGAL { typedef std::pair< criteria, Edge_like > Incidence_request_elt; typedef std::list< Incidence_request_elt > Incidence_request_type; typedef typename Incidence_request_type::iterator Incidence_request_iterator; - - + + //-------------------- DATA MEMBERS --------------------------------- typedef int Info; // so that we are a model of TriangulationVertexBaseWithInfo_3 @@ -110,34 +110,34 @@ namespace CGAL { // We do the same for the incidence requests typename std::list< Incidence_request_elt >::iterator m_ir_first, m_ir_last; - + //-------------------- CONSTRUCTORS --------------------------------- public: Advancing_front_surface_reconstruction_vertex_base_3() - : Vb(), m_mark(-1), + : Vb(), m_mark(-1), m_post_mark(-1) {} - + Advancing_front_surface_reconstruction_vertex_base_3(const Point & p) - : Vb(p), m_mark(-1), - m_post_mark(-1) + : Vb(p), m_mark(-1), + m_post_mark(-1) {} - + Advancing_front_surface_reconstruction_vertex_base_3(const Point & p, Cell_handle f) - : Vb(p, f), m_mark(-1), - m_post_mark(-1) + : Vb(p, f), m_mark(-1), + m_post_mark(-1) {} Advancing_front_surface_reconstruction_vertex_base_3(Cell_handle f) - : Vb(f), m_mark(-1), - m_post_mark(-1) + : Vb(f), m_mark(-1), + m_post_mark(-1) {} Advancing_front_surface_reconstruction_vertex_base_3(const Advancing_front_surface_reconstruction_vertex_base_3& other) - : Vb(other), m_mark(-1), - m_post_mark(-1) + : Vb(other), m_mark(-1), + m_post_mark(-1) {} //-------------------- MEMBER FUNCTIONS ----------------------------- @@ -163,19 +163,19 @@ namespace CGAL { { return m_id; } - + //------------------------------------------------------------------- private: void delete_border() { - m_incident_border = NULL; + m_incident_border = NULL; } inline Next_border_elt* next_on_border(const int& i) const - { + { if (m_incident_border == NULL) return NULL; //vh is interior if (m_incident_border->first->first != NULL) if (m_incident_border->first->second.second == i) @@ -187,10 +187,10 @@ namespace CGAL { } - + inline bool is_border_edge(Vertex_handle v) const - { + { if (m_incident_border == NULL) return false; return ((m_incident_border->first->first == v)|| (m_incident_border->second->first == v)); @@ -201,7 +201,7 @@ namespace CGAL { if (m_incident_border == NULL) return NULL; if (m_incident_border->first->first == v) return m_incident_border->first; if (m_incident_border->second->first == v) return m_incident_border->second; - return NULL; + return NULL; } public: @@ -230,8 +230,8 @@ namespace CGAL { } } - - + + //------------------------------------------------------------------- public: @@ -255,7 +255,7 @@ namespace CGAL { { return (m_mark < 0); } - + //------------------------------------------------------------------- private: @@ -273,7 +273,7 @@ namespace CGAL { { m_post_mark = i; } - + inline bool is_post_marked(const int& i) { return (m_post_mark == i); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h index e39eada6e8e..2a578ab4ae6 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_face_base_2.h @@ -33,7 +33,7 @@ namespace CGAL { : public Fb { typedef typename Fb::Triangulation_data_structure Tds; - + public: typedef typename Tds::Face_handle Face_handle; typedef typename Tds::Vertex_handle Vertex_handle; @@ -53,17 +53,17 @@ namespace CGAL { : Fb(), _is_on_surface(true) {} - Surface_face_base_2(Vertex_handle v0, - Vertex_handle v1, + Surface_face_base_2(Vertex_handle v0, + Vertex_handle v1, Vertex_handle v2) : Fb(v0, v1, v2), _is_on_surface(true) {} - Surface_face_base_2(Vertex_handle v0, - Vertex_handle v1, + Surface_face_base_2(Vertex_handle v0, + Vertex_handle v1, Vertex_handle v2, - Face_handle n0, - Face_handle n1, + Face_handle n0, + Face_handle n1, Face_handle n2) : Fb(v0, v1, v2, n0, n1, n2), _is_on_surface(true) {} @@ -71,8 +71,8 @@ namespace CGAL { void set_facet(const F3& facet) { _facet = facet; - } - + } + const F3& facet() const { return _facet; @@ -82,7 +82,7 @@ namespace CGAL { { _is_on_surface = is_on_surface; } - + bool is_on_surface() const { return _is_on_surface; @@ -91,7 +91,7 @@ namespace CGAL { void reorient() { - Fb::reorient(); + Fb::reorient(); if( is_on_surface()){ _facet = std::make_pair(_facet.first->neighbor(_facet.second), _facet.first->neighbor(_facet.second)->index(_facet.first)); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h index 9e231e44519..e5872a7935e 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/Surface_vertex_base_2.h @@ -51,13 +51,13 @@ namespace CGAL { V3 _vertex; public: Surface_vertex_base_2() : Vb() {} - Surface_vertex_base_2(Face_handle f) : Vb(f) {} + Surface_vertex_base_2(Face_handle f) : Vb(f) {} void set_vertex(const V3& v) { _vertex = v; } - + V3 vertex_3() const { return _vertex; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h index 2cc32c38149..4cd4e4b5b16 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_polyhedron.h @@ -44,7 +44,7 @@ namespace CGAL { { CGAL::Polyhedron_incremental_builder_3 B( hds, true); B.begin_surface( s.number_of_vertices(), s.number_of_facets(), 6* s.number_of_facets()); - + typedef typename Surface::TDS_2 TDS_2; typedef typename TDS_2::Face_iterator Face_iterator; typedef typename TDS_2::Vertex_iterator Vertex_iterator; @@ -60,9 +60,9 @@ namespace CGAL { vit->vertex_3()->id() = index++; } } - + for(Face_iterator fit = tds.faces_begin(); fit != tds.faces_end(); ++fit){ - + if(fit->is_on_surface()){ B.begin_facet(); for(int i=0; i < 3; i++){ @@ -73,7 +73,7 @@ namespace CGAL { } B.end_surface(); } - + }; template diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h index 8fc8af2a308..47d9f179d25 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/construct_surface_2.h @@ -69,8 +69,8 @@ namespace CGAL { } std::map edge_map; - for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); + for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); f_it++) { typename Triangulation::Cell_handle n, c = (*f_it).first; @@ -84,11 +84,11 @@ namespace CGAL { i1 = (ci+1) & 3; i2 = (ci+2) & 3; i3 = (ci+3) & 3; - + Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]], vvh[vertex_index_map[c->vertex(i2)]], vvh[vertex_index_map[c->vertex(i3)]]); - fh->set_facet(*f_it); + fh->set_facet(*f_it); vvh[vertex_index_map[c->vertex(i1)]]->set_face(fh); vvh[vertex_index_map[c->vertex(i2)]]->set_face(fh); vvh[vertex_index_map[c->vertex(i3)]]->set_face(fh); @@ -104,8 +104,8 @@ namespace CGAL { i3 = (ni+3) & 3; Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]], vvh[vertex_index_map[n->vertex(i2)]], - vvh[vertex_index_map[n->vertex(i3)]]); - fh->set_facet(std::make_pair(n, ni)); + vvh[vertex_index_map[n->vertex(i3)]]); + fh->set_facet(std::make_pair(n, ni)); vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh); vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh); vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh); @@ -113,7 +113,7 @@ namespace CGAL { tds.set_adjacency(fh, ih, edge_map); } } - + } if ( !edge_map.empty()) { @@ -123,8 +123,8 @@ namespace CGAL { while (!edge_map.empty()) { Face_handle fh = edge_map.begin()->second.first; int ih = edge_map.begin()->second.second; - Face_handle fn = tds.create_face( vinf, - fh->vertex(TDS::cw(ih)), + Face_handle fn = tds.create_face( vinf, + fh->vertex(TDS::cw(ih)), fh->vertex(TDS::ccw(ih))); fn->set_facet(std::make_pair( typename Triangulation::Cell_handle(),0)); fn->set_is_on_surface(false); diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h index 5240009520e..f38b0ad9d58 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/orient.h @@ -62,8 +62,8 @@ namespace CGAL { std::map edge_map; - for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); - f_it != T.finite_facets_end(); + for(typename Triangulation::Finite_facets_iterator f_it = T.finite_facets_begin(); + f_it != T.finite_facets_end(); f_it++) { typename Triangulation::Cell_handle n, c = (*f_it).first; @@ -77,7 +77,7 @@ namespace CGAL { i1 = (ci+1) & 3; i2 = (ci+2) & 3; i3 = (ci+3) & 3; - + Face_handle fh = tds.create_face(vvh[vertex_index_map[c->vertex(i1)]], vvh[vertex_index_map[c->vertex(i2)]], vvh[vertex_index_map[c->vertex(i3)]]); @@ -96,7 +96,7 @@ namespace CGAL { i3 = (ni+3) & 3; Face_handle fh = tds.create_face(vvh[vertex_index_map[n->vertex(i1)]], vvh[vertex_index_map[n->vertex(i2)]], - vvh[vertex_index_map[n->vertex(i3)]]); + vvh[vertex_index_map[n->vertex(i3)]]); vvh[vertex_index_map[n->vertex(i1)]]->set_face(fh); vvh[vertex_index_map[n->vertex(i2)]]->set_face(fh); vvh[vertex_index_map[n->vertex(i3)]]->set_face(fh); @@ -104,17 +104,17 @@ namespace CGAL { tds.set_adjacency(fh, ih, edge_map); } } - + } - + if ( !edge_map.empty()) { vinf = tds.create_vertex(); std::map inf_edge_map; while (!edge_map.empty()) { Face_handle fh = edge_map.begin()->second.first; int ih = edge_map.begin()->second.second; - Face_handle fn = tds.create_face( vinf, - fh->vertex(TDS::cw(ih)), + Face_handle fn = tds.create_face( vinf, + fh->vertex(TDS::cw(ih)), fh->vertex(TDS::ccw(ih))); vinf->set_face(fn); tds.set_adjacency(fn, 0, fh, ih); @@ -124,8 +124,8 @@ namespace CGAL { } CGAL_triangulation_assertion(inf_edge_map.empty()); } - - + + tds.reorient_faces(); return vinf; diff --git a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h index e9f5fc3b183..373252ab94d 100644 --- a/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h +++ b/Advancing_front_surface_reconstruction/include/CGAL/internal/AFSR/write_triple_indices.h @@ -32,7 +32,7 @@ namespace CGAL { template OutputIterator write_triple_indices(OutputIterator out, const Advancing_front_surface_reconstruction& S) - { + { typedef Advancing_front_surface_reconstruction Surface; typedef typename Surface::TDS_2 TDS_2; typedef typename TDS_2::Face_iterator Face_iterator; @@ -54,7 +54,7 @@ namespace CGAL { return out; } -} +} #endif diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp index b34155c2961..68ae25a20e0 100644 --- a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/kernels.cpp @@ -12,7 +12,7 @@ typedef CGAL::Simple_cartesian K; typedef CGAL::cpp11::array Facet; namespace std { -std::ostream& +std::ostream& operator<<(std::ostream& os, const Facet& f) { os << "3 " << f[0] << " " << f[1] << " " << f[2]; @@ -25,14 +25,14 @@ template void fct(const char* fname) { typedef typename K::Point_3 Point_3; - std::ifstream in(fname); + std::ifstream in(fname); std::vector points; std::vector facets; - - std::copy(std::istream_iterator(in), - std::istream_iterator(), + + std::copy(std::istream_iterator(in), + std::istream_iterator(), std::back_inserter(points)); - + CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), std::back_inserter(facets)); @@ -46,7 +46,7 @@ void fct(const char* fname) std::ostream_iterator(std::cout, "\n")); } -int main() +int main() { { typedef CGAL::Simple_cartesian K; @@ -55,7 +55,7 @@ int main() { typedef CGAL::Simple_cartesian K; fct("data/planar.xyz"); - } + } { typedef CGAL::Exact_predicates_inexact_constructions_kernel K; fct("data/planar.xyz"); diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/lowdim.cpp b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/lowdim.cpp index 92c78c64940..5bd09771f38 100644 --- a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/lowdim.cpp +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/lowdim.cpp @@ -11,7 +11,7 @@ typedef K::Point_3 Point_3; typedef CGAL::cpp11::array Facet; namespace std { -std::ostream& +std::ostream& operator<<(std::ostream& os, const Facet& f) { os << "3 " << f[0] << " " << f[1] << " " << f[2]; @@ -22,14 +22,14 @@ operator<<(std::ostream& os, const Facet& f) void fct(const char* fname) { - std::ifstream in(fname); + std::ifstream in(fname); std::vector points; std::vector facets; - - std::copy(std::istream_iterator(in), - std::istream_iterator(), + + std::copy(std::istream_iterator(in), + std::istream_iterator(), std::back_inserter(points)); - + CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), std::back_inserter(facets)); @@ -43,7 +43,7 @@ void fct(const char* fname) std::ostream_iterator(std::cout, "\n")); } -int main() +int main() { fct("data/point.xyz"); fct("data/segment.xyz"); diff --git a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp index 858054ef013..ed7e532c21f 100644 --- a/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp +++ b/Advancing_front_surface_reconstruction/test/Advancing_front_surface_reconstruction/polyhedron.cpp @@ -16,7 +16,7 @@ typedef CGAL::Polyhedron_3 Polyhedron; typedef CGAL::cpp11::array Facet; namespace std { -std::ostream& +std::ostream& operator<<(std::ostream& os, const Facet& f) { os << "3 " << f[0] << " " << f[1] << " " << f[2]; @@ -26,17 +26,17 @@ operator<<(std::ostream& os, const Facet& f) } -int main() +int main() { Polyhedron polyhedron; - std::ifstream in("data/planar.xyz"); + std::ifstream in("data/planar.xyz"); std::vector points; std::vector facets; - - std::copy(std::istream_iterator(in), - std::istream_iterator(), + + std::copy(std::istream_iterator(in), + std::istream_iterator(), std::back_inserter(points)); - + CGAL::advancing_front_surface_reconstruction(points.begin(), points.end(), polyhedron); From 6b4acda55904b8b0e6468ba476bfe8b76f3a2f81 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 29 Jun 2015 10:48:28 +0200 Subject: [PATCH 108/114] Add Advancing Front Reconstruction to changes.html --- Installation/changes.html | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Installation/changes.html b/Installation/changes.html index 61644f991bc..f85d884c3f1 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -130,6 +130,18 @@ and src/ directories). components of the mesh. + +

Advancing Front Surface Reconstruction

+
    +
  • + This package provides a greedy algorithm for surface reconstruction from an + unorganized point set. Starting from a seed facet, a piecewise linear + surface is grown by adding Delaunay triangles one by one. The most + plausible triangles are added first, in a way that avoids the appearance + of topological singularities. +
  • +

    Approximation of Ridges and Umbilics on Triangulated Surface Meshes

      From e0361f0c04d2c3096d5f44326c1b2eceb0951d75 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Mon, 29 Jun 2015 10:56:29 +0200 Subject: [PATCH 109/114] undo changes in Scale Space package --- .../examples/Scale_space_reconstruction_3/scale_space.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp index 382e8f38ab5..7bf1187d2ae 100644 --- a/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp +++ b/Scale_space_reconstruction_3/examples/Scale_space_reconstruction_3/scale_space.cpp @@ -36,13 +36,12 @@ int main(int argc, char* argv[]) { reconstruct.reconstruct_surface( points.begin(), points.end(), 4 ); std::cerr << "Reconstruction done:" << std::endl; - std::ofstream out ("out.off"); // Write the reconstruction. std::cerr << "Neighborhood radius^2 = " << reconstruct.neighborhood_squared_radius() << std::endl; for( std::size_t shell = 0; shell < reconstruct.number_of_shells(); ++shell ) { - //std::cerr << "Shell " << shell << std::endl; + std::cerr << "Shell " << shell << std::endl; for( Triple_iterator it = reconstruct.shell_begin( shell ); it != reconstruct.shell_end( shell ); ++it ) - out << "3 "<< *it << std::endl; // We write a '3' in front so that it can be assembled into an OFF file + std::cout << "3 "<< *it << std::endl; // We write a '3' in front so that it can be assembled into an OFF file } std::cerr << "Done." << std::endl; From e076bc179c15c26e8b3f0ad555add5aa1d47edbd Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 2 Jul 2015 12:48:34 +0200 Subject: [PATCH 110/114] move lines to facilitate merge --- Documentation/doc/Documentation/Doxyfile.in | 2 +- Documentation/doc/Documentation/dependencies | 2 +- Documentation/doc/Documentation/packages.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Documentation/doc/Documentation/Doxyfile.in b/Documentation/doc/Documentation/Doxyfile.in index fd9bdee420d..98b7f0bc585 100644 --- a/Documentation/doc/Documentation/Doxyfile.in +++ b/Documentation/doc/Documentation/Doxyfile.in @@ -33,6 +33,7 @@ ALIASES += "cgalReleaseNumber=${CGAL_CREATED_VERSION_NUM}" # all image paths, maybe auto-generate this? IMAGE_PATH = ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/fig \ + ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig \ ${CMAKE_SOURCE_DIR}/Algebraic_foundations/doc/Algebraic_foundations/fig \ ${CMAKE_SOURCE_DIR}/AABB_tree/doc/AABB_tree/fig \ ${CMAKE_SOURCE_DIR}/Polygon/doc/Polygon/fig \ @@ -120,5 +121,4 @@ IMAGE_PATH = ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/fig \ ${CMAKE_SOURCE_DIR}/Surface_modeling/doc/Surface_modeling/fig \ ${CMAKE_SOURCE_DIR}/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/fig \ ${CMAKE_SOURCE_DIR}/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/fig \ - ${CMAKE_SOURCE_DIR}/Advancing_front_surface_reconstruction/doc/Advancing_front_surface_reconstruction/fig \ diff --git a/Documentation/doc/Documentation/dependencies b/Documentation/doc/Documentation/dependencies index f945d5610d4..2454eb9c8e4 100644 --- a/Documentation/doc/Documentation/dependencies +++ b/Documentation/doc/Documentation/dependencies @@ -1,4 +1,5 @@ Algebraic_foundations +Advancing_front_surface_reconstruction AABB_tree Polygon Number_types @@ -86,6 +87,5 @@ Surface_modeling Barycentric_coordinates_2 Surface_mesh Surface_mesh_shortest_path -Advancing_front_surface_reconstruction diff --git a/Documentation/doc/Documentation/packages.txt b/Documentation/doc/Documentation/packages.txt index 1d9bfd1bd2b..2eb32d43071 100644 --- a/Documentation/doc/Documentation/packages.txt +++ b/Documentation/doc/Documentation/packages.txt @@ -93,9 +93,9 @@ h1 { \package_listing{Surface_mesher} \package_listing{Surface_reconstruction_points_3} \package_listing{Scale_space_reconstruction_3} +\package_listing{Advancing_front_surface_reconstruction} \package_listing{Skin_surface_3} \package_listing{Mesh_3} -\package_listing{Advancing_front_surface_reconstruction} \section PartGeometryProcessing Geometry Processing From a900133057609bebc44700b585b19c060fe4668a Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 2 Jul 2015 12:52:54 +0200 Subject: [PATCH 111/114] move package in changes.html to avoid merge conflict --- Installation/changes.html | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/Installation/changes.html b/Installation/changes.html index f85d884c3f1..aefa3c20294 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -118,6 +118,17 @@ and src/ directories). +

      Advancing Front Surface Reconstruction (new package)

      +
        +
      • + This package provides a greedy algorithm for surface reconstruction from an + unorganized point set. Starting from a seed facet, a piecewise linear + surface is grown by adding Delaunay triangles one by one. The most + plausible triangles are added first, in a way that avoids the appearance + of topological singularities. +
      • +
      +

      Triangulated Surface Mesh Shortest Paths (new package)

      • @@ -131,16 +142,6 @@ and src/ directories).
      -

      Advancing Front Surface Reconstruction

      -
        -
      • - This package provides a greedy algorithm for surface reconstruction from an - unorganized point set. Starting from a seed facet, a piecewise linear - surface is grown by adding Delaunay triangles one by one. The most - plausible triangles are added first, in a way that avoids the appearance - of topological singularities. -
      • Approximation of Ridges and Umbilics on Triangulated Surface Meshes

        From c97f1e6d264766ea094dce97240f5a3af6db635d Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 2 Jul 2015 12:55:46 +0200 Subject: [PATCH 112/114] remove 2 empty lines --- Installation/changes.html | 2 -- 1 file changed, 2 deletions(-) diff --git a/Installation/changes.html b/Installation/changes.html index aefa3c20294..5f60d3ddf55 100644 --- a/Installation/changes.html +++ b/Installation/changes.html @@ -141,8 +141,6 @@ and src/ directories). components of the mesh.
      - -

      Approximation of Ridges and Umbilics on Triangulated Surface Meshes

        From b4595e8802fa27a947a8336cc4e61f6f6fca07c5 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 2 Jul 2015 12:57:17 +0200 Subject: [PATCH 113/114] remove empty line --- Documentation/doc/Documentation/Doxyfile.in | 1 - 1 file changed, 1 deletion(-) diff --git a/Documentation/doc/Documentation/Doxyfile.in b/Documentation/doc/Documentation/Doxyfile.in index 98b7f0bc585..e07c40a0b1d 100644 --- a/Documentation/doc/Documentation/Doxyfile.in +++ b/Documentation/doc/Documentation/Doxyfile.in @@ -121,4 +121,3 @@ IMAGE_PATH = ${CMAKE_SOURCE_DIR}/Documentation/doc/Documentation/fig \ ${CMAKE_SOURCE_DIR}/Surface_modeling/doc/Surface_modeling/fig \ ${CMAKE_SOURCE_DIR}/Barycentric_coordinates_2/doc/Barycentric_coordinates_2/fig \ ${CMAKE_SOURCE_DIR}/Surface_mesh_shortest_path/doc/Surface_mesh_shortest_path/fig \ - From 46a24d03354469ef7759fe9e78a07f411db18bb3 Mon Sep 17 00:00:00 2001 From: Andreas Fabri Date: Thu, 2 Jul 2015 13:11:11 +0200 Subject: [PATCH 114/114] take code as in the Qt5 branch --- .../Scene_points_with_normal_item.cpp | 57 +++++++++---------- .../Polyhedron/Scene_polygon_soup_item.cpp | 5 +- 2 files changed, 30 insertions(+), 32 deletions(-) diff --git a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp index 91d80d21f3b..f6db00db0e2 100644 --- a/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp @@ -290,43 +290,42 @@ void Scene_points_with_normal_item::computes_local_spacing(int k) QMenu* Scene_points_with_normal_item::contextMenu() { - const char* prop_name = "Menu modified by Scene_points_with_normal_item."; + const char* prop_name = "Menu modified by Scene_points_with_normal_item."; - QMenu* menu = Scene_item::contextMenu(); + QMenu* menu = Scene_item::contextMenu(); - // Use dynamic properties: - // http://doc.trolltech.com/lastest/qobject.html#property - bool menuChanged = menu->property(prop_name).toBool(); + // Use dynamic properties: + // http://doc.trolltech.com/lastest/qobject.html#property + bool menuChanged = menu->property(prop_name).toBool(); - if(!menuChanged) { - actionDeleteSelection = menu->addAction(tr("Delete Selection")); - actionDeleteSelection->setObjectName("actionDeleteSelection"); - connect(actionDeleteSelection, SIGNAL(triggered()),this, SLOT(deleteSelection())); + if(!menuChanged) { + actionDeleteSelection = menu->addAction(tr("Delete Selection")); + actionDeleteSelection->setObjectName("actionDeleteSelection"); + connect(actionDeleteSelection, SIGNAL(triggered()),this, SLOT(deleteSelection())); - actionResetSelection = menu->addAction(tr("Reset Selection")); - actionResetSelection->setObjectName("actionResetSelection"); - connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection())); + actionResetSelection = menu->addAction(tr("Reset Selection")); + actionResetSelection->setObjectName("actionResetSelection"); + connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection())); - actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points")); - actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints"); - connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates())); + actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points")); + actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints"); + connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates())); + menu->setProperty(prop_name, true); + } - menu->setProperty(prop_name, true); - } + if (isSelectionEmpty()) + { + actionDeleteSelection->setDisabled(true); + actionResetSelection->setDisabled(true); + } + else + { + actionDeleteSelection->setDisabled(false); + actionResetSelection->setDisabled(false); + } - if (isSelectionEmpty()) - { - actionDeleteSelection->setDisabled(true); - actionResetSelection->setDisabled(true); - } - else - { - actionDeleteSelection->setDisabled(false); - actionResetSelection->setDisabled(false); - } - - return menu; + return menu; } void Scene_points_with_normal_item::setRenderingMode(RenderingMode m) diff --git a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp index fffbd8a1b48..f51a90f1885 100644 --- a/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp +++ b/Polyhedron/demo/Polyhedron/Scene_polygon_soup_item.cpp @@ -329,9 +329,8 @@ Scene_polygon_soup_item::new_vertex(const double& x, const double& y, const double& z) { - if(!soup) - soup = new Polygon_soup; - soup->points.push_back(Point_3(x, y, z)); + + soup->points.push_back(Point_3(x, y, z)); } void