mirror of https://github.com/CGAL/cgal
Merge branch 'old' into Advancing_front_surface_reconstruction-afabri
Apply "My branch is really old.." from the FAQ Conflicts: Installation/changes.html Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.cpp Polyhedron/demo/Polyhedron/Scene_points_with_normal_item.h Polyhedron/demo/Polyhedron/include/CGAL/gl_render.h
This commit is contained in:
commit
6802db2f6b
|
|
@ -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 */
|
||||||
|
|
||||||
|
|
@ -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 */
|
||||||
|
|
@ -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<Traits> >
|
||||||
|
class Advancing_front_surface_reconstruction_cell_base_3 : public Cb {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
}; /* end Advancing_front_surface_reconstruction_cell_base_3 */
|
||||||
|
} /* end namespace CGAL */
|
||||||
|
|
@ -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<Traits> >
|
||||||
|
class Advancing_front_surface_reconstruction_vertex_base_3 : public Vb {
|
||||||
|
public:
|
||||||
|
|
||||||
|
/// @}
|
||||||
|
|
||||||
|
}; /* end Advancing_front_surface_reconstruction_vertex_base_3 */
|
||||||
|
} /* end namespace CGAL */
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
/*!
|
||||||
|
\example Advancing_front_surface_reconstruction/reconstruction_fct.cpp
|
||||||
|
\example Advancing_front_surface_reconstruction/reconstruction_class.cpp
|
||||||
|
*/
|
||||||
|
|
@ -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}
|
||||||
|
}
|
||||||
|
|
@ -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.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
\begin{ccRefClass}{AFSR_cell_base_3<Kernel, CellBase >}
|
||||||
|
|
||||||
|
\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}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -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}
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
\begin{ccRefClass}{AFSR_vertex_base_3<Kernel,VertexBase>}
|
||||||
|
|
||||||
|
\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}
|
||||||
|
|
@ -0,0 +1,31 @@
|
||||||
|
\begin{ccRefClass}{AFSR_vertex_base_with_id_3<Kernel, VertexBase >}
|
||||||
|
|
||||||
|
\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}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
\begin{ccRefClass}{Advancing_front_surface_reconstruction<Kernel,Delaunay_3>}
|
||||||
|
|
||||||
|
\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<Cell_handle, int,int> 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,int> 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}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
\begin{ccRefClass}{AFSR::Surface_face_base_2<Kernel, Facet, Fb_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}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
\begin{ccRefClass}{AFSR::Surface_vertex_base_2<Kernel, Vh_3, Vb_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}
|
||||||
|
|
@ -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}
|
||||||
|
|
@ -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}
|
||||||
|
|
@ -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 <class Surface>
|
||||||
|
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}
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
@ -0,0 +1,468 @@
|
||||||
|
#define NOLAZY
|
||||||
|
#define BLIND
|
||||||
|
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
|
|
||||||
|
// Kernel
|
||||||
|
#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
|
||||||
|
#include <CGAL/Triangulation_data_structure_3.h>
|
||||||
|
#include <CGAL/Delaunay_triangulation_3.h>
|
||||||
|
|
||||||
|
#include <CGAL/AFSR_vertex_base_with_id_3.h>
|
||||||
|
#include <CGAL/Triangulation_cell_base_3.h>
|
||||||
|
#include <CGAL/AFSR_cell_base_3.h>
|
||||||
|
#include <CGAL/Advancing_front_surface_reconstruction.h>
|
||||||
|
#include <CGAL/AFSR_options.h>
|
||||||
|
#include <CGAL/IO/Advancing_front_surface_reconstruction.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
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<Kernel> LVb;
|
||||||
|
|
||||||
|
typedef CGAL::Triangulation_cell_base_3<Kernel> Cb;
|
||||||
|
typedef CGAL::AFSR_cell_base_3<Cb> LCb;
|
||||||
|
|
||||||
|
typedef CGAL::Triangulation_data_structure_3<LVb,LCb> Tds;
|
||||||
|
typedef CGAL::Delaunay_triangulation_3<Kernel,Tds> Triangulation_3;
|
||||||
|
|
||||||
|
typedef Triangulation_3::Vertex_handle Vertex_handle;
|
||||||
|
|
||||||
|
typedef CGAL::Advancing_front_surface_reconstruction<Kernel,Triangulation_3> Surface;
|
||||||
|
typedef CGAL::AFSR_options Options;
|
||||||
|
|
||||||
|
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
|
||||||
|
struct Auto_count : public std::unary_function<const Point&,std::pair<Point,int> >{
|
||||||
|
mutable int i;
|
||||||
|
Auto_count() : i(0){}
|
||||||
|
std::pair<Point,int> operator()(const Point& p) const {
|
||||||
|
return std::make_pair(p,i++);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
file_input(const Options& opt, std::vector<Point>& 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<Point>(is), n, std::back_inserter(points));
|
||||||
|
} else {
|
||||||
|
// we do not know beforehand how many points we will read
|
||||||
|
std::istream_iterator<Point> 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
|
||||||
|
<< " -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
|
||||||
|
|
||||||
|
<< " -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::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], "-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"
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
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)){
|
||||||
|
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 <class PointIterator, class TripleOutputIterator>
|
||||||
|
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<Point> points;
|
||||||
|
|
||||||
|
file_input(opt, points);
|
||||||
|
|
||||||
|
#if 1
|
||||||
|
std::cerr << "Time for reading " << timer.time() << " sec." << std::endl;
|
||||||
|
std::vector<CGAL::Triple<std::size_t,std::size_t,std::size_t> > 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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();
|
||||||
|
|
||||||
|
|
||||||
|
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::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,138 @@
|
||||||
|
#include <CGAL/basic.h>
|
||||||
|
#include <CGAL/Simple_cartesian.h>
|
||||||
|
#include <CGAL/Filtered_kernel.h>
|
||||||
|
#include <CGAL/algorithm.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
|
||||||
|
typedef double NT;
|
||||||
|
|
||||||
|
struct K : public CGAL::Filtered_kernel<CGAL::Simple_cartesian<NT> > {};
|
||||||
|
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<CGAL::Triple<int,int,int> >& 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<NT>& O, std::set<CGAL::Triple<int,int,int> >& 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<Point> points(n);
|
||||||
|
CGAL::copy_n(std::istream_iterator<Point>(std::cin), n, points.begin());
|
||||||
|
|
||||||
|
|
||||||
|
std::set<CGAL::Triple<int,int,int> > triangles;
|
||||||
|
|
||||||
|
std::vector<NT> W(n*n);
|
||||||
|
std::vector<NT> 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<CGAL::Triple<int,int,int> >::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -0,0 +1,88 @@
|
||||||
|
#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<TDS2>::Other Fb2;
|
||||||
|
typedef Surface_face_base_2<GT, F3, Fb2> 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
|
||||||
|
|
@ -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 <CGAL/basic.h>
|
||||||
|
#include <CGAL/Triangulation_ds_vertex_base_2.h>
|
||||||
|
|
||||||
|
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<TDS2>::Other Vb2;
|
||||||
|
typedef Surface_vertex_base_2<GT,V3, Vb2> 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
|
||||||
|
|
@ -0,0 +1,127 @@
|
||||||
|
#ifndef CGAL_AFSR_CONSTRUCT_SURFACE_2
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <class Kernel, class Triangulation>
|
||||||
|
class Advancing_front_surface_reconstruction;
|
||||||
|
|
||||||
|
namespace AFSR {
|
||||||
|
|
||||||
|
|
||||||
|
template <class Kernel, class Triangulation, class TDS>
|
||||||
|
typename TDS::Vertex_handle
|
||||||
|
construct_surface(TDS& tds, const CGAL::Advancing_front_surface_reconstruction<Kernel,Triangulation>& surface)
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef typename TDS::Vertex_handle Vertex_handle;
|
||||||
|
typedef std::pair<Vertex_handle,Vertex_handle> 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<Vertex_handle > vvh;
|
||||||
|
if(tds.number_of_vertices() != 0){
|
||||||
|
tds.clear();
|
||||||
|
}
|
||||||
|
int dim = 2;
|
||||||
|
tds.set_dimension(dim);
|
||||||
|
|
||||||
|
CGAL::Unique_hash_map<typename Triangulation::Vertex_handle, int> 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<typename Triangulation::Vertex_handle, int>::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<Vh_pair, Edge> 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();
|
||||||
|
vinf->set_vertex(T.infinite_vertex());
|
||||||
|
std::map<Vh_pair, Edge> 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 CGAL
|
||||||
|
#endif // CGAL_AFSR_CONSTRUCT_SURFACE_2
|
||||||
|
|
@ -0,0 +1,120 @@
|
||||||
|
#ifndef CGAL_AFSR_ORIENT
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
namespace AFSR {
|
||||||
|
|
||||||
|
|
||||||
|
template <class Kernel, class Triangulation, class TDS>
|
||||||
|
typename TDS::Vertex_handle
|
||||||
|
orient(TDS& tds, const Advancing_front_surface_reconstruction<Kernel,Triangulation>& surface)
|
||||||
|
{
|
||||||
|
|
||||||
|
typedef typename TDS::Vertex_handle Vertex_handle;
|
||||||
|
typedef std::pair<Vertex_handle,Vertex_handle> 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<Vertex_handle > vvh;
|
||||||
|
if(tds.number_of_vertices() != 0) tds.clear();
|
||||||
|
int dim = 2;
|
||||||
|
tds.set_dimension(dim);
|
||||||
|
|
||||||
|
CGAL::Unique_hash_map<typename Triangulation::Vertex_handle, int> 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<typename Triangulation::Vertex_handle, int>::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<Vh_pair, Edge> 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<Vh_pair, Edge> 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
|
||||||
|
|
@ -0,0 +1,224 @@
|
||||||
|
#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<TDS2>::Other Cb2;
|
||||||
|
typedef AFSR_cell_base_3<Cb2> 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<coord_type>::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifdef FACET_NUMBER
|
||||||
|
void set_facet_number(int i, int n){}
|
||||||
|
{
|
||||||
|
_facet_number[i] = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
int facet_number(int i)
|
||||||
|
{
|
||||||
|
return _facet_number[i];
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
void set_facet_number(int, int){}
|
||||||
|
int facet_number(int){return 0;}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------
|
||||||
|
|
||||||
|
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)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool has_facet_on_surface(const int& i)
|
||||||
|
{
|
||||||
|
return (selected_facet & (1 << i)) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#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
|
||||||
|
|
@ -0,0 +1,46 @@
|
||||||
|
#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), 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 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;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGAL_AFSR_OPTIONS_H
|
||||||
|
|
@ -0,0 +1,473 @@
|
||||||
|
#ifndef CGAL_AFSR_VERTEX_BASE_3_H
|
||||||
|
#define CGAL_AFSR_VERTEX_BASE_3_H
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <CGAL/Triangulation_vertex_base_3.h>
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <class K, class VertexBase = Triangulation_vertex_base_3<K> >
|
||||||
|
class AFSR_vertex_base_3 : public VertexBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
template < typename TDS2 >
|
||||||
|
struct Rebind_TDS {
|
||||||
|
typedef typename VertexBase::template Rebind_TDS<TDS2>::Other Vb2;
|
||||||
|
typedef AFSR_vertex_base_3<K,Vb2> 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<Vertex_handle> 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<Vertex_handle>::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<Vertex_handle>::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 <Vertex_base>" << 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<Vertex_handle>::iterator b(ie_first), e(ie_last);
|
||||||
|
e++;
|
||||||
|
typename std::list<Vertex_handle>::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<Vertex_handle>::iterator e(ie_last);
|
||||||
|
e++;
|
||||||
|
#ifdef DEBUG
|
||||||
|
typename std::list<Vertex_handle>::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<Vertex_handle>::iterator b(ie_first), e(ie_last);
|
||||||
|
e++;
|
||||||
|
typename std::list<Vertex_handle>::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<Incidence_request_elt>::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 <class K, class VertexBase>
|
||||||
|
std::list<typename AFSR_vertex_base_3<K,VertexBase>::Vertex_handle> AFSR_vertex_base_3<K,VertexBase>::interior_edges;
|
||||||
|
|
||||||
|
template <class K, class VertexBase>
|
||||||
|
std::list<typename AFSR_vertex_base_3<K,VertexBase>::Incidence_request_elt> AFSR_vertex_base_3<K,VertexBase>::incidence_requests;
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif //CGAL_AFSR_VERTEX_BASE_3_H
|
||||||
|
|
||||||
|
|
@ -0,0 +1,557 @@
|
||||||
|
#ifndef CGAL_AFSR_VERTEX_BASE_WITH_ID_3_H
|
||||||
|
#define CGAL_AFSR_VERTEX_BASE_WITH_ID_3_H
|
||||||
|
|
||||||
|
#include <CGAL/Triangulation_vertex_base_3.h>
|
||||||
|
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <boost/pool/object_pool.hpp>
|
||||||
|
|
||||||
|
|
||||||
|
namespace CGAL {
|
||||||
|
|
||||||
|
template <class K, class VertexBase = Triangulation_vertex_base_3<K> >
|
||||||
|
class AFSR_vertex_base_with_id_3 : public VertexBase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
template < typename TDS2 >
|
||||||
|
struct Rebind_TDS {
|
||||||
|
typedef typename VertexBase::template Rebind_TDS<TDS2>::Other Vb2;
|
||||||
|
typedef AFSR_vertex_base_with_id_3<K,Vb2> 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 ---------------------------------
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
// Instead of having a set per vertex, there is a global list.
|
||||||
|
static std::list<Vertex_handle> 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<Vertex_handle>::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<Next_border_elt> bbb;
|
||||||
|
static boost::object_pool<Next_border_elt> nbe_pool;
|
||||||
|
static boost::object_pool<Intern_successors_type> ist_pool;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------- CONSTRUCTORS ---------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
Intern_successors_type* new_border()
|
||||||
|
{
|
||||||
|
Intern_successors_type* ret;
|
||||||
|
/*
|
||||||
|
std::allocator<Next_border_elt> nbea;
|
||||||
|
std::allocator<Intern_successors_type> 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<Next_border_elt> nbea;
|
||||||
|
std::allocator<Intern_successors_type> 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<Vertex_handle>::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int& info()
|
||||||
|
{
|
||||||
|
return _id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int& info() 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 <Vertex_base>" << 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<Vertex_handle>::iterator b(ie_first), e(ie_last);
|
||||||
|
e++;
|
||||||
|
typename std::list<Vertex_handle>::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<Vertex_handle>::iterator e(ie_last);
|
||||||
|
e++;
|
||||||
|
#ifdef DEBUG
|
||||||
|
typename std::list<Vertex_handle>::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<Vertex_handle>::iterator b(ie_first), e(ie_last);
|
||||||
|
e++;
|
||||||
|
typename std::list<Vertex_handle>::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<Incidence_request_elt>::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 <class K, class VertexBase>
|
||||||
|
boost::object_pool<typename AFSR_vertex_base_with_id_3<K,VertexBase>::Next_border_elt> AFSR_vertex_base_with_id_3<K,VertexBase>::nbe_pool;
|
||||||
|
|
||||||
|
template <class K, class VertexBase>
|
||||||
|
boost::object_pool<typename AFSR_vertex_base_with_id_3<K,VertexBase>::Intern_successors_type> AFSR_vertex_base_with_id_3<K,VertexBase>::ist_pool;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
template <class K, class VertexBase>
|
||||||
|
std::list<typename AFSR_vertex_base_with_id_3<K,VertexBase>::Vertex_handle> AFSR_vertex_base_with_id_3<K,VertexBase>::interior_edges;
|
||||||
|
|
||||||
|
template <class K, class VertexBase>
|
||||||
|
std::list<typename AFSR_vertex_base_with_id_3<K,VertexBase>::Incidence_request_elt> AFSR_vertex_base_with_id_3<K,VertexBase>::incidence_requests;
|
||||||
|
|
||||||
|
} // namespace CGAL
|
||||||
|
|
||||||
|
#endif // CGALAFSR_VERTEX_BASE_3_H
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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<Vb,Fb>& tds,
|
||||||
|
std::ostream& os, double r, double g, double b,
|
||||||
|
typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle v, bool skip_infinite)
|
||||||
|
{
|
||||||
|
typedef typename Triangulation_data_structure_2<Vb,Fb>::Vertex_handle Vertex_handle;
|
||||||
|
typedef typename Triangulation_data_structure_2<Vb,Fb>::Vertex_iterator Vertex_iterator;
|
||||||
|
typedef typename Triangulation_data_structure_2<Vb,Fb>::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<Vertex_handle,int> 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
|
||||||
|
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -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 <CGAL/basic.h>
|
||||||
|
#include <CGAL/Triangulation_ds_vertex_base_2.h>
|
||||||
|
|
||||||
|
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<TDS2>::Other Vb2;
|
||||||
|
typedef Tvb_3_2<GT, Vb2> 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<GT, Vb> &v)
|
||||||
|
// non combinatorial information. Default = point
|
||||||
|
{
|
||||||
|
return is >> static_cast<Vb&>(v) >> v.point();
|
||||||
|
}
|
||||||
|
|
||||||
|
template < class GT, class Vb >
|
||||||
|
std::ostream&
|
||||||
|
operator<<(std::ostream &os, const Tvb_3_2<GT, Vb> &v)
|
||||||
|
// non combinatorial information. Default = point
|
||||||
|
{
|
||||||
|
return os << static_cast<const Vb&>(v) << v.point();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} //namespace CGAL
|
||||||
|
|
||||||
|
#endif //CGAL_TVB_3_2_H
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
INRIA Sophia-Antipolis (France)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Surface reconstruction using an advancing front method.
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
GPL (v3 or later)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
Andreas Fabri <Andreas.Fabri@geometryfactory.com>
|
||||||
|
|
@ -91,6 +91,7 @@ h1 {
|
||||||
\package_listing{Surface_reconstruction_points_3}
|
\package_listing{Surface_reconstruction_points_3}
|
||||||
\package_listing{Skin_surface_3}
|
\package_listing{Skin_surface_3}
|
||||||
\package_listing{Mesh_3}
|
\package_listing{Mesh_3}
|
||||||
|
\package_listing{Advancing_front_surface_reconstruction}
|
||||||
|
|
||||||
\section PartGeometryProcessing Geometry Processing
|
\section PartGeometryProcessing Geometry Processing
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ foreach(DEP_PKG AABB_tree STL_Extension GraphicsView Surface_mesher Filtered_ker
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
# Include this package's headers first
|
# 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 )
|
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)
|
polyhedron_demo_plugin(pca_plugin Polyhedron_demo_pca_plugin)
|
||||||
target_link_libraries(pca_plugin scene_polyhedron_item scene_basic_objects)
|
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)
|
if(EIGEN3_FOUND OR TAUCS_FOUND)
|
||||||
polyhedron_demo_plugin(parameterization_plugin Polyhedron_demo_parameterization_plugin)
|
polyhedron_demo_plugin(parameterization_plugin Polyhedron_demo_parameterization_plugin)
|
||||||
target_link_libraries(parameterization_plugin scene_polyhedron_item scene_textured_polyhedron_item )
|
target_link_libraries(parameterization_plugin scene_polyhedron_item scene_textured_polyhedron_item )
|
||||||
|
|
|
||||||
|
|
@ -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 <Scene_polygon_soup_item.h>
|
||||||
|
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QAction>
|
||||||
|
#include <QMainWindow>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QtPlugin>
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
|
#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_points_with_normal_item*>(scene->item(scene->mainSelectionIndex()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QList<QAction*> actions() const {
|
||||||
|
return QList<QAction*>() << 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_points_with_normal_item*>(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"
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<ui version="4.0">
|
||||||
|
<class>AdvancingFrontDialog</class>
|
||||||
|
<widget class="QDialog" name="AdvancingFrontDialog">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>376</width>
|
||||||
|
<height>170</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="windowTitle">
|
||||||
|
<string>Advancing front reconstruction</string>
|
||||||
|
</property>
|
||||||
|
<layout class="QGridLayout" name="gridLayout">
|
||||||
|
<item row="0" column="0">
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="text">
|
||||||
|
<string>Min triangle perimeter:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="0" column="1" colspan="2">
|
||||||
|
<widget class="QDoubleSpinBox" name="m_inputPerimeter">
|
||||||
|
<property name="suffix">
|
||||||
|
<string>* average spacing</string>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>30.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Max triangle area:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="1" colspan="2">
|
||||||
|
<widget class="QDoubleSpinBox" name="m_inputArea">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> * average spacing^2</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>20.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="2">
|
||||||
|
<widget class="QDialogButtonBox" name="buttonBox">
|
||||||
|
<property name="standardButtons">
|
||||||
|
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</widget>
|
||||||
|
<resources/>
|
||||||
|
<connections>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>accepted()</signal>
|
||||||
|
<receiver>AdvancingFrontDialog</receiver>
|
||||||
|
<slot>accept()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>177</x>
|
||||||
|
<y>123</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>53</x>
|
||||||
|
<y>125</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
<connection>
|
||||||
|
<sender>buttonBox</sender>
|
||||||
|
<signal>rejected()</signal>
|
||||||
|
<receiver>AdvancingFrontDialog</receiver>
|
||||||
|
<slot>reject()</slot>
|
||||||
|
<hints>
|
||||||
|
<hint type="sourcelabel">
|
||||||
|
<x>257</x>
|
||||||
|
<y>119</y>
|
||||||
|
</hint>
|
||||||
|
<hint type="destinationlabel">
|
||||||
|
<x>257</x>
|
||||||
|
<y>143</y>
|
||||||
|
</hint>
|
||||||
|
</hints>
|
||||||
|
</connection>
|
||||||
|
</connections>
|
||||||
|
</ui>
|
||||||
|
|
@ -275,11 +275,14 @@ QMenu* Scene_points_with_normal_item::contextMenu()
|
||||||
actionResetSelection = menu->addAction(tr("Reset Selection"));
|
actionResetSelection = menu->addAction(tr("Reset Selection"));
|
||||||
actionResetSelection->setObjectName("actionResetSelection");
|
actionResetSelection->setObjectName("actionResetSelection");
|
||||||
connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection()));
|
connect(actionResetSelection, SIGNAL(triggered()),this, SLOT(resetSelection()));
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points"));
|
actionSelectDuplicatedPoints = menu->addAction(tr("Select duplicated points"));
|
||||||
actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints");
|
actionSelectDuplicatedPoints->setObjectName("actionSelectDuplicatedPoints");
|
||||||
connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates()));
|
connect(actionSelectDuplicatedPoints, SIGNAL(triggered()),this, SLOT(selectDuplicates()));
|
||||||
|
|
||||||
|
=======
|
||||||
|
>>>>>>> old
|
||||||
menu->setProperty(prop_name, true);
|
menu->setProperty(prop_name, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -404,17 +404,19 @@ Scene_polygon_soup_item::bbox() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Scene_polygon_soup_item::new_vertex(const double& x,
|
Scene_polygon_soup_item::new_vertex(double x,
|
||||||
const double& y,
|
double y,
|
||||||
const double& z)
|
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
|
void
|
||||||
Scene_polygon_soup_item::new_triangle(const std::size_t i,
|
Scene_polygon_soup_item::new_triangle(std::size_t i,
|
||||||
const std::size_t j,
|
std::size_t j,
|
||||||
const std::size_t k)
|
std::size_t k)
|
||||||
{
|
{
|
||||||
Polygon_soup::Polygon_3 new_polygon(3);
|
Polygon_soup::Polygon_3 new_polygon(3);
|
||||||
new_polygon[0] = i;
|
new_polygon[0] = i;
|
||||||
|
|
|
||||||
|
|
@ -34,10 +34,10 @@ public:
|
||||||
bool isFinite() const { return true; }
|
bool isFinite() const { return true; }
|
||||||
bool isEmpty() const;
|
bool isEmpty() const;
|
||||||
Bbox bbox() const;
|
Bbox bbox() const;
|
||||||
|
|
||||||
void new_vertex(const double&, const double&, const double&);
|
void new_vertex(double, double, double);
|
||||||
void new_triangle(const std::size_t, const std::size_t, const std::size_t);
|
void new_triangle(std::size_t, std::size_t, std::size_t);
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void shuffle_orientations();
|
void shuffle_orientations();
|
||||||
bool orient();
|
bool orient();
|
||||||
|
|
|
||||||
|
|
@ -301,7 +301,9 @@ public:
|
||||||
Face_handle f1,
|
Face_handle f1,
|
||||||
Face_handle f2,
|
Face_handle f2,
|
||||||
Face_handle f3);
|
Face_handle f3);
|
||||||
|
|
||||||
void set_adjacency(Face_handle f0, int i0, Face_handle f1, int i1) const;
|
void set_adjacency(Face_handle f0, int i0, Face_handle f1, int i1) const;
|
||||||
|
|
||||||
void delete_face(Face_handle);
|
void delete_face(Face_handle);
|
||||||
void delete_vertex(Vertex_handle);
|
void delete_vertex(Vertex_handle);
|
||||||
|
|
||||||
|
|
@ -342,10 +344,12 @@ public:
|
||||||
// HELPING
|
// HELPING
|
||||||
private:
|
private:
|
||||||
typedef std::pair<Vertex_handle,Vertex_handle> Vh_pair;
|
typedef std::pair<Vertex_handle,Vertex_handle> Vh_pair;
|
||||||
|
public:
|
||||||
void set_adjacency(Face_handle fh,
|
void set_adjacency(Face_handle fh,
|
||||||
int ih,
|
int ih,
|
||||||
std::map< Vh_pair, Edge>& edge_map);
|
std::map< Vh_pair, Edge>& edge_map);
|
||||||
void reorient_faces();
|
void reorient_faces();
|
||||||
|
private:
|
||||||
bool dim_down_precondition(Face_handle f, int i);
|
bool dim_down_precondition(Face_handle f, int i);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -2224,24 +2228,24 @@ reorient_faces()
|
||||||
std::set<Face_handle> oriented_set;
|
std::set<Face_handle> oriented_set;
|
||||||
std::stack<Face_handle> st;
|
std::stack<Face_handle> st;
|
||||||
Face_iterator fit = faces_begin();
|
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<int>(oriented_set.size()) != nf) {
|
while (0 != nf) {
|
||||||
while ( oriented_set.find(fit) != oriented_set.end()){
|
while ( !oriented_set.insert(fit).second ){
|
||||||
++fit; // find a germ for non oriented components
|
++fit; // find a germ for non oriented components
|
||||||
}
|
}
|
||||||
// orient component
|
// orient component
|
||||||
oriented_set.insert(fit);
|
--nf;
|
||||||
st.push(fit);
|
st.push(fit);
|
||||||
while ( ! st.empty()) {
|
while ( ! st.empty()) {
|
||||||
Face_handle fh = st.top();
|
Face_handle fh = st.top();
|
||||||
st.pop();
|
st.pop();
|
||||||
for(int ih = 0 ; ih < 3 ; ++ih){
|
for(int ih = 0 ; ih < 3 ; ++ih){
|
||||||
Face_handle fn = fh->neighbor(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);
|
int in = fn->index(fh);
|
||||||
if (fn->vertex(cw(in)) != fh->vertex(ccw(ih))) fn->reorient();
|
if (fn->vertex(cw(in)) != fh->vertex(ccw(ih))) fn->reorient();
|
||||||
oriented_set.insert(fn);
|
--nf;
|
||||||
st.push(fn);
|
st.push(fn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue