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:
Andreas Fabri 2013-11-28 14:58:29 +01:00
commit 6802db2f6b
45 changed files with 6372 additions and 17 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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.
*/

View File

@ -0,0 +1,4 @@
/*!
\example Advancing_front_surface_reconstruction/reconstruction_fct.cpp
\example Advancing_front_surface_reconstruction/reconstruction_class.cpp
*/

View File

@ -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}
}

View File

@ -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.

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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}

View File

@ -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()

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -0,0 +1 @@
INRIA Sophia-Antipolis (France)

View File

@ -0,0 +1 @@
Surface reconstruction using an advancing front method.

View File

@ -0,0 +1 @@
Andreas Fabri <Andreas.Fabri@geometryfactory.com>

View File

@ -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

View File

@ -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 )

View File

@ -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"

View File

@ -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>

View File

@ -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);
} }

View File

@ -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;

View File

@ -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();

View File

@ -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);
} }
} }