LCC: Add an incremental builder (#7210)

## Summary of Changes

The code exists already and only the documentation is missing. It is
pretty close to the incremental builder of `Polyhedron_3`.

## Release Management

* Affected package(s): Linear_cell_complex
* Feature/Small Feature (if any):
[link](https://cgal.geometryfactory.com/CGAL/Members/wiki/Features/Small_Features/Linear_cell_complex_incremental_builder_3),
pre-approved by @gdamiand the 2th Feb 2023.
* Link to compiled documentation [Reference
Manual](https://cgal.github.io/7210/v0/Linear_cell_complex/classCGAL_1_1Linear__cell__complex__incremental__builder__3.html)
and subsection for an
[example](https://cgal.github.io/7210/v0/Linear_cell_complex/index.html#Linear_cell_complexIncrementalBuilderExample).
* License and copyright ownership: cnrs
This commit is contained in:
Laurent Rineau 2023-02-16 11:16:20 +01:00 committed by GitHub
commit 73bda7c846
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 205 additions and 16 deletions

View File

@ -14,6 +14,9 @@ Release date: June 2023
- Added a version that uses indices instead of handles as dart and attribute descriptors. As the indices are integers convertible from and to `std::size_t`, they can be used as index into vectors which store properties. To use the index version, `Use_index` must be defined and be equal to `CGAL::Tag_true` in the item class.
### [Linear Cell Complex](https://doc.cgal.org/5.6/Manual/packages.html#PkgLinearCellComplex)
- Added the class `Linear_cell_complex_incremental_builder_3`.
### [Polygon Mesh Processing](https://doc.cgal.org/5.6/Manual/packages.html#PkgPolygonMeshProcessing)
- **Breaking change**: Deprecated the overloads of functions `CGAL::Polygon_mesh_processing::triangulate_hole()`,

View File

@ -0,0 +1,99 @@
namespace CGAL {
/*!
\ingroup PkgLinearCellComplexClasses
The auxiliary class `Linear_cell_complex_incremental_builder_3` supports the incremental
construction of linear cell complexes.
\tparam LCC must be a model of the concept `LinearCellComplex`
*/
template < class LCC >
class Linear_cell_complex_incremental_builder_3
{
public:
typedef LCC_ LCC;
typedef typename LCC::Dart_descriptor DH;
typedef typename LCC::Vertex_attribute_descriptor VAH;
typedef typename LCC::Point Point_3;
typedef typename LCC::size_type size_type;
/// \name Creation
/// @{
/*!
* Constructor
*/
Linear_cell_complex_incremental_builder_3(LCC & alcc);
/// @}
/*!
\name Surface Creation
To build a linear cell complex, the following regular expression gives
the correct and allowed order and nesting of method calls from this
section:
\code
begin_surface ( add_vertex | ( begin_facet add_vertex_to_facet end_facet ) ) end_surface
\endcode
When an edge is added in a facet, if the same edge exists in another facet of the same surface, then the two facets are glued along this edge.
When a facet is added, if the same facet exists in another surface, the two surfaces are glued along this facet.
*/
/// @{
/*!
* starts a new surface.
*/
void begin_surface();
/*!
* adds a new vertex for `p` and returns its handle.
*/
VAH add_vertex(const Point_3& p);
/*!
* starts a new facet.
*/
void begin_facet();
/*!
* adds vertex `i` at the end of the current facet.
*/
void add_vertex_to_facet(size_type i);
/*!
* ends the construction of the facet and returns the first dart of this facet.
*/
DH end_facet();
/*!
* ends the construction of the surface and returns one dart of the created surface.
*/
DH end_surface();
/// @}
/// \name Additional Operations
/// @{
/*!
* is a synonym for `begin_facet()`, a call to `add_vertex_to_facet()` for each
* value in the range `[first,beyond)`, and a call to `end_facet()`.
*/
DH add_facet(std::initializer_list<size_type> l);
/// @}
};
} // namespace CGAL

View File

@ -141,6 +141,14 @@ Some examples of use of these operations are given in Section \ref ssec5dexample
If \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(false)`\endlink is called, all the future insertion or removal operations will not update non void attributes. These attributes will be updated latter by the call to \link GenericMap::set_automatic_attributes_management `set_automatic_attributes_management(true)`\endlink. This can be useful to speed up an algorithm which uses several successive insertion and removal operations. See example \ref ssecAttributesManagement "Automatic attributes management".
\cgalAdvancedEnd
\subsection Linear_cell_complexIncrementalBuilder Incremental Builder
A utility class `Linear_cell_complex_incremental_builder_3` helps in creating 2D and 3D linear cell complexes
from a list of points followed by a list of facets that are represented as indices into the point list.
Note that, compared to `Polyhedron_incremental_builder_3` it has only absolute indexing and no rollback
mechanism.
\section Linear_cell_complexExamples Examples
\subsection Linear_cell_complexA3DLinearCellComplex A 3D Linear Cell Complex
@ -264,10 +272,16 @@ Linking with the cmake target `CGAL::CGAL_Basic_viewer` will link with `CGAL_Qt5
Result of the run of the draw_linear_cell_complex program. A window shows two 3D cubes and allows to navigate through the 3D scene.
\cgalFigureEnd
\subsection Linear_cell_complexIncrementalBuilderExample Incremental Builder
The following example shows the incremental builder.
\cgalExample{Linear_cell_complex/linear_cell_complex_3_incremental_builder.cpp}
\section Linear_cell_complexDesign Design and Implementation History
This package was developed by Guillaume Damiand, with the help of Andreas Fabri, S&eacute;bastien Loriot and Laurent Rineau. Monique Teillaud and Bernd G&auml;rtner contributed to the manual.
*/
} /* namespace CGAL */

View File

@ -62,7 +62,7 @@
- `CGAL::Linear_cell_complex_traits<d,K>`
- `CGAL::Cell_attribute_with_point<LCC,Info_,Tag,OnMerge,OnSplit>`
- `CGAL::Cell_attribute_with_point_and_id<LCC,Info_,Tag,OnMerge,OnSplit>`
- `CGAL::Linear_cell_complex<d,d2,LCCTraits,Items,Alloc>`
- `CGAL::Linear_cell_complex_incremental_builder_3<LCC>`
\cgalCRPSection{Global Functions}
\cgalCRPSubsection{Constructions for Linear Cell Complex}
@ -78,4 +78,3 @@
- \link PkgDrawLinearCellComplex CGAL::draw<LCC>() \endlink
*/

View File

@ -3,5 +3,6 @@
\example Linear_cell_complex/linear_cell_complex_3.cpp
\example Linear_cell_complex/linear_cell_complex_4.cpp
\example Linear_cell_complex/linear_cell_complex_3_attributes_management.cpp
\example Linear_cell_complex/linear_cell_complex_3_incremental_builder.cpp
\example Linear_cell_complex/draw_linear_cell_complex.cpp
*/

View File

@ -21,6 +21,7 @@ create_single_source_cgal_program("linear_cell_complex_3_operations.cpp")
create_single_source_cgal_program(
"linear_cell_complex_3_with_colored_vertices.cpp")
create_single_source_cgal_program("linear_cell_complex_3_with_mypoint.cpp")
create_single_source_cgal_program("linear_cell_complex_3_incremental_builder.cpp")
create_single_source_cgal_program("linear_cell_complex_4.cpp")
create_single_source_cgal_program("plane_graph_to_lcc_2.cpp")
create_single_source_cgal_program("voronoi_2.cpp")
@ -29,4 +30,5 @@ create_single_source_cgal_program("voronoi_3.cpp")
create_single_source_cgal_program("draw_linear_cell_complex.cpp")
if(CGAL_Qt5_FOUND)
target_link_libraries(draw_linear_cell_complex PUBLIC CGAL::CGAL_Basic_viewer)
target_link_libraries(linear_cell_complex_3_incremental_builder PUBLIC CGAL::CGAL_Basic_viewer)
endif()

View File

@ -0,0 +1,71 @@
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/Linear_cell_complex_incremental_builder_3.h>
#include <CGAL/draw_linear_cell_complex.h>
typedef CGAL::Linear_cell_complex_for_combinatorial_map<3, 3> LCC_3;
using Point=LCC_3::Point;
int main()
{
LCC_3 lcc;
CGAL::Linear_cell_complex_incremental_builder_3<LCC_3> ib(lcc);
ib.add_vertex(Point(0,0,0)); // vertex 0
ib.add_vertex(Point(1,0,0)); // vertex 1
ib.add_vertex(Point(1,1,0)); // vertex 2
ib.add_vertex(Point(0,1,0)); // vertex 3
ib.add_vertex(Point(0,1,1)); // vertex 4
ib.add_vertex(Point(0,0,1)); // vertex 5
ib.add_vertex(Point(1,0,1)); // vertex 6
ib.add_vertex(Point(1,1,1)); // vertex 7
// Create a cube
ib.begin_surface();
ib.add_facet({0,1,2,3}); // Create a new facet version 1: given all of its indices
ib.add_facet({1,0,5,6});
ib.add_facet({2,1,6,7});
ib.add_facet({3,2,7,4});
ib.add_facet({5,4,7,6});
ib.begin_facet(); // Create a new facet version 2: begin facet
ib.add_vertex_to_facet(0); // add sucessively its indices
ib.add_vertex_to_facet(3);
ib.add_vertex_to_facet(4);
ib.add_vertex_to_facet(5);
ib.end_facet();
ib.end_surface();
ib.add_vertex(Point(-1, 0.5, 0.5)); // vertex 8
// Create a pyramid, sharing one of its facets with a facet of the cube
ib.begin_surface();
ib.add_facet({3,0,5,4});
ib.add_facet({0,3,8});
ib.add_facet({3,4,8});
ib.add_facet({4,5,8});
ib.add_facet({5,0,8});
ib.end_surface();
LCC_3::One_dart_per_cell_range<3,3> cells = lcc.one_dart_per_cell<3>();
for (auto c = cells.begin(); c != cells.end(); ++c) {
std::cout << "a cell"<< std::endl;
LCC_3::One_dart_per_incident_cell_range<2,3> faces = lcc.one_dart_per_incident_cell<2,3>(c);
for (auto f = faces.begin(); f != faces.end(); ++f) {
std::cout << " a face"<< std::endl;
LCC_3::One_dart_per_incident_cell_range<0,2> vertices = lcc.one_dart_per_incident_cell<0,2>(f);
for(auto v = vertices.begin(); v!= vertices.end(); ++v){
std::cout << " " << lcc.point(v) << std::endl;
}
}
}
// Draw the lcc and display its characteristics
lcc.display_characteristics(std::cout)<<std::endl;
CGAL::draw(lcc);
return EXIT_SUCCESS;
}

View File

@ -13,7 +13,7 @@
#define CGAL_LINEAR_CELL_COMPLEX_CONSTRUCTORS_H 1
#include <CGAL/IO/OFF.h>
#include <CGAL/Linear_cell_complex_incremental_builder.h>
#include <CGAL/Linear_cell_complex_incremental_builder_3.h>
#include <CGAL/Unique_hash_map.h>
#include <CGAL/assertions.h>

View File

@ -9,8 +9,8 @@
//
// Author(s) : Guillaume Damiand <guillaume.damiand@liris.cnrs.fr>
//
#ifndef CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_H
#define CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_H 1
#ifndef CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_3_H
#define CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_3_H 1
#include <vector>
#include <cstddef>
@ -127,7 +127,7 @@ struct Find_opposite_2_with_control<LCC, CGAL::Combinatorial_map_tag>
{
if (!lcc.template is_free<2>(res))
{ // Here a dart vah1->vah2 already exists, and it was already 2-sewn.
std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."<<std::endl;
std::cerr<<"ERROR in Linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."<<std::endl;
return lcc.null_descriptor;
}
}
@ -135,7 +135,7 @@ struct Find_opposite_2_with_control<LCC, CGAL::Combinatorial_map_tag>
vertex_to_dart_map_in_surface,
vah2, vah1)!=lcc.null_descriptor)
{ // Here a dart vah1->vah2 already exists (but it was not already 2-sewn).
std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."<<std::endl;
std::cerr<<"ERROR in Linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."<<std::endl;
return lcc.null_descriptor;
}
@ -159,7 +159,7 @@ struct Find_opposite_2_with_control<LCC, CGAL::Generalized_map_tag>
{
if (!lcc.template is_free<2>(res))
{ // Here a dart vah1->vah2 already exists, and it was already 2-sewn.
std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."<<std::endl;
std::cerr<<"ERROR in Linear_cell_complex_incremental_builder_3: try to use a same oriented edge twice."<<std::endl;
return lcc.null_descriptor;
}
}
@ -209,7 +209,7 @@ struct Add_edge_in_associative_array<LCC, CGAL::Generalized_map_tag>
};
///////////////////////////////////////////////////////////////////////////////
template<class LCC_, unsigned int dim=LCC_::dimension>
struct Sew3_for_LCC_incremental_builder
struct Sew3_for_LCC_incremental_builder_3
{
static void run(LCC_& lcc,
typename LCC_::Dart_descriptor dh1, typename LCC_::Dart_descriptor dh2)
@ -218,8 +218,8 @@ struct Sew3_for_LCC_incremental_builder
{
if(!lcc.template is_free<3>(dh1))
{
std::cerr<<"ERROR in My_linear_cell_complex_incremental_builder_3: "
<<"it exists more than 2 faces with same indices."<<std::endl;
std::cerr<<"ERROR in Linear_cell_complex_incremental_builder_3: "
<<"it exist more than 2 faces with same indices."<<std::endl;
}
else
{ lcc.template sew<3>(lcc.other_orientation(dh1), dh2); }
@ -227,7 +227,7 @@ struct Sew3_for_LCC_incremental_builder
}
};
template<class LCC_>
struct Sew3_for_LCC_incremental_builder<LCC_, 2>
struct Sew3_for_LCC_incremental_builder_3<LCC_, 2>
{
static void run(LCC_&, typename LCC_::Dart_descriptor, typename LCC_::Dart_descriptor)
{}
@ -319,7 +319,7 @@ public:
if(LCC::dimension>2)
{
opposite=opposite_face();
Sew3_for_LCC_incremental_builder<LCC>::run(lcc, opposite, min_dart);
Sew3_for_LCC_incremental_builder_3<LCC>::run(lcc, opposite, min_dart);
add_face_in_array();
}
return first_dart;
@ -404,5 +404,5 @@ private:
} //namespace CGAL
#endif // CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_H //
#endif // CGAL_LINEAR_CELL_COMPLEX_INCREMENTAL_BUILDER_3_H //
// EOF //

View File

@ -1,6 +1,6 @@
#include <CGAL/Linear_cell_complex_for_combinatorial_map.h>
#include <CGAL/Linear_cell_complex_for_generalized_map.h>
#include <CGAL/Linear_cell_complex_incremental_builder.h>
#include <CGAL/Linear_cell_complex_incremental_builder_3.h>
#include <CGAL/Combinatorial_map_save_load.h>
#include "Linear_cell_complex_3_test.h"