mirror of https://github.com/CGAL/cgal
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:
commit
73bda7c846
|
|
@ -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()`,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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ébastien Loriot and Laurent Rineau. Monique Teillaud and Bernd Gärtner contributed to the manual.
|
||||
|
||||
*/
|
||||
} /* namespace CGAL */
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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 //
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Reference in New Issue