From f41b5b60f7aecf5a83ac3ed88ccbbfd61eae4529 Mon Sep 17 00:00:00 2001 From: Guillaume Damiand Date: Wed, 3 Sep 2025 12:46:19 +0200 Subject: [PATCH] Add prisms and pyramids creation --- .../include/CGAL/Combinatorial_map.h | 176 ++++++++++++++++++ .../include/CGAL/Linear_cell_complex_base.h | 141 +++++++++++++- 2 files changed, 310 insertions(+), 7 deletions(-) diff --git a/Combinatorial_map/include/CGAL/Combinatorial_map.h b/Combinatorial_map/include/CGAL/Combinatorial_map.h index 59f88e34970..336b317f566 100644 --- a/Combinatorial_map/include/CGAL/Combinatorial_map.h +++ b/Combinatorial_map/include/CGAL/Combinatorial_map.h @@ -4019,6 +4019,182 @@ namespace CGAL { return make_combinatorial_hexahedron(d1, d2, d3, d4, d5, d6); } + /** Test if a volume is a combinatorial prism. + * @param adart an intial dart + * @return true iff the volume containing adart is a combinatorial prism. + */ + bool is_volume_combinatorial_prism(Dart_const_descriptor d1) const + { + Dart_const_descriptor d2=beta(d1, 2); + Dart_const_descriptor d3=beta(d1, 1, 2); + Dart_const_descriptor d4=beta(d1, 0, 2); + Dart_const_descriptor d5=beta(d2, 1, 1, 2); + + if ( d1==null_dart_descriptor || d2==null_dart_descriptor || + d3==null_dart_descriptor || d4==null_dart_descriptor || + d5==null_dart_descriptor ) { return false; } + + if (!is_face_combinatorial_polygon(d1, 3) || + !is_face_combinatorial_polygon(d2, 4) || + !is_face_combinatorial_polygon(d3, 4) || + !is_face_combinatorial_polygon(d4, 4) || + !is_face_combinatorial_polygon(d5, 3)) { return false; } + + // TODO do better with marks. + if (belong_to_same_cell<2,1>(d1, d2) || + belong_to_same_cell<2,1>(d1, d3) || + belong_to_same_cell<2,1>(d1, d4) || + belong_to_same_cell<2,1>(d1, d5) || + belong_to_same_cell<2,1>(d2, d3) || + belong_to_same_cell<2,1>(d2, d4) || + belong_to_same_cell<2,1>(d2, d5) || + belong_to_same_cell<2,1>(d3, d4) || + belong_to_same_cell<2,1>(d3, d5) || + belong_to_same_cell<2,1>(d4, d5)) + { return false; } + + if (beta(d2,0,2) !=beta(d3,1) || + beta(d2,1,2) !=beta(d4,0) || + beta(d3,0,2) !=beta(d4,1) || + beta(d3,1,1,2)!=beta(d5,0) || + beta(d4,1,1,2)!=beta(d5,1)) { return false; } + + return true; + } + + /** Create a combinatorial prism from 2 triangles and 3 squares. + * @param d1 a dart onto a first triangle. + * @param d2 a dart onto a first square. + * @param d3 a dart onto a second square. + * @param d4 a dart onto a thirth square. + * @param d5 a dart onto a second triangle. + * @return a new dart. + */ + Dart_descriptor make_combinatorial_prism(Dart_descriptor d1, + Dart_descriptor d2, + Dart_descriptor d3, + Dart_descriptor d4, + Dart_descriptor d5) + { + // 2-link for first triangle + basic_link_beta_for_involution(d1, d2, 2); + basic_link_beta_for_involution(beta(d1, 1), d3, 2); + basic_link_beta_for_involution(beta(d1, 0), d4, 2); + + // 2-link for quandrangles between them + basic_link_beta_for_involution(beta(d2, 0), beta(d3, 1), 2); + basic_link_beta_for_involution(beta(d2, 1), beta(d4, 0), 2); + basic_link_beta_for_involution(beta(d3, 0), beta(d4, 1), 2); + + // 2-link for second triangle + basic_link_beta_for_involution(beta(d2, 1, 1), d5, 2); + basic_link_beta_for_involution(beta(d3, 1, 1), beta(d5, 0), 2); + basic_link_beta_for_involution(beta(d4, 1, 1), beta(d5, 1), 2); + + return d1; + } + + /** Create a new combinatorial prism. + * @return a new dart. + */ + Dart_descriptor make_combinatorial_prism() + { + Dart_descriptor d1 = make_combinatorial_polygon(3); + Dart_descriptor d2 = make_combinatorial_polygon(4); + Dart_descriptor d3 = make_combinatorial_polygon(4); + Dart_descriptor d4 = make_combinatorial_polygon(4); + Dart_descriptor d5 = make_combinatorial_polygon(3); + + return make_combinatorial_prism( d1, d2, d3, d4, d5); + } + + /** Test if a volume is a combinatorial pyramid. + * @param adart an intial dart + * @return true iff the volume containing adart is a combinatorial pyramid. + */ + bool is_volume_combinatorial_pyramid(Dart_const_descriptor d1) const + { + Dart_const_descriptor d2=beta(d1, 2); + Dart_const_descriptor d3=beta(d1, 0, 2); + Dart_const_descriptor d4=beta(d1, 1, 1, 2); + Dart_const_descriptor d5=beta(d1, 1, 2); + + if (d1==null_dart_descriptor || d2==null_dart_descriptor || + d3==null_dart_descriptor || d4==null_dart_descriptor || + d5==null_dart_descriptor) { return false; } + + if (!is_face_combinatorial_polygon(d1, 4) || + !is_face_combinatorial_polygon(d2, 3) || + !is_face_combinatorial_polygon(d3, 3) || + !is_face_combinatorial_polygon(d4, 3) || + !is_face_combinatorial_polygon(d5, 3)) { return false; } + + // TODO do better with marks. + if (belong_to_same_cell<2,1>(d1, d2) || + belong_to_same_cell<2,1>(d1, d3) || + belong_to_same_cell<2,1>(d1, d4) || + belong_to_same_cell<2,1>(d1, d5) || + belong_to_same_cell<2,1>(d2, d3) || + belong_to_same_cell<2,1>(d2, d4) || + belong_to_same_cell<2,1>(d2, d5) || + belong_to_same_cell<2,1>(d3, d4) || + belong_to_same_cell<2,1>(d3, d5) || + belong_to_same_cell<2,1>(d4, d5)) + { return false; } + + if (beta(d2,1,2)!=beta(d3,0) || + beta(d2,0,2)!=beta(d5,1) || + beta(d5,0,2)!=beta(d4,1) || + beta(d4,0,2)!=beta(d3,1)) { return false; } + + return true; + } + + /** Create a combinatorial pyramid from 1 square and 4 triangles. + * @param d1 a dart onto the square. + * @param d2 a dart onto a first triangle. + * @param d3 a dart onto a second triangle. + * @param d4 a dart onto a thirth triangle. + * @param d5 a dart onto a fourth triangle. + * @return a new dart. + */ + Dart_descriptor make_combinatorial_pyramid(Dart_descriptor d1, + Dart_descriptor d2, + Dart_descriptor d3, + Dart_descriptor d4, + Dart_descriptor d5) + { + // 2-link for the square + basic_link_beta_for_involution(d1, d2, 2); + basic_link_beta_for_involution(beta(d1, 1), d5, 2); + basic_link_beta_for_involution(beta(d1, 1, 1), d4, 2); + basic_link_beta_for_involution(beta(d1, 0), d3, 2); + + // 2-link for first triangle + basic_link_beta_for_involution(beta(d2, 1), beta(d3, 0), 2); + basic_link_beta_for_involution(beta(d2, 0), beta(d5, 1), 2); + + // 2-link for triangles between them + basic_link_beta_for_involution(beta(d5, 0), beta(d4, 1), 2); + basic_link_beta_for_involution(beta(d4, 0), beta(d3, 1), 2); + + return d1; + } + + /** Create a new combinatorial pyramid. + * @return a new dart. + */ + Dart_descriptor make_combinatorial_pyramid() + { + Dart_descriptor d1=make_combinatorial_polygon(4); + Dart_descriptor d2=make_combinatorial_polygon(3); + Dart_descriptor d3=make_combinatorial_polygon(3); + Dart_descriptor d4=make_combinatorial_polygon(3); + Dart_descriptor d5=make_combinatorial_polygon(3); + + return make_combinatorial_pyramid(d1, d2, d3, d4, d5); + } + /** Test if an i-cell can be removed. * An i-cell can be removed if i==dimension or i==dimension-1, * or if there are at most two (i+1)-cell incident to it. diff --git a/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h b/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h index b1943bca3c4..7b9dcec4f5e 100644 --- a/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h +++ b/Linear_cell_complex/include/CGAL/Linear_cell_complex_base.h @@ -660,13 +660,13 @@ namespace CGAL { * h0,h5 and to the facet (h0,h5,h6,h1). */ Dart_descriptor make_hexahedron(Vertex_attribute_descriptor h0, - Vertex_attribute_descriptor h1, - Vertex_attribute_descriptor h2, - Vertex_attribute_descriptor h3, - Vertex_attribute_descriptor h4, - Vertex_attribute_descriptor h5, - Vertex_attribute_descriptor h6, - Vertex_attribute_descriptor h7) + Vertex_attribute_descriptor h1, + Vertex_attribute_descriptor h2, + Vertex_attribute_descriptor h3, + Vertex_attribute_descriptor h4, + Vertex_attribute_descriptor h5, + Vertex_attribute_descriptor h6, + Vertex_attribute_descriptor h7) { Dart_descriptor d1 = make_quadrangle(h0, h5, h6, h1); Dart_descriptor d2 = make_quadrangle(h1, h6, h7, h2); @@ -717,6 +717,133 @@ namespace CGAL { create_vertex_attribute(p7)); } + /** Create an prism given 6 Vertex_attribute_descriptor. + * (6 vertices, 9 edges and 5 facets) + * \verbatim + * 3---4 + * |\ /| + * 0-5-1 + * \|/ + * 2 + * \endverbatim + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @param h2 the third vertex handle. + * @param h3 the fourth vertex handle. + * @param h4 the fifth vertex handle. + * @param h5 the sixth vertex handle. + * @return the dart of the new prism incident to h0 and to + * the facet (h0,h1,h2). + */ + Dart_descriptor make_prism(Vertex_attribute_descriptor h0, + Vertex_attribute_descriptor h1, + Vertex_attribute_descriptor h2, + Vertex_attribute_descriptor h3, + Vertex_attribute_descriptor h4, + Vertex_attribute_descriptor h5) + { + Dart_descriptor d1=make_triangle(h0, h1, h2); + Dart_descriptor d2=make_quadrangle(h1, h0, h3, h4); + Dart_descriptor d3=make_quadrangle(h2, h1, h4, h5); + Dart_descriptor d4=make_quadrangle(h0, h2, h5, h3); + Dart_descriptor d5=make_triangle(h4, h3, h5); + + return make_combinatorial_prism(d1, d2, d3, d4, d5); + } + + /** Create an prism given 6 points. + * \verbatim + * 3---4 + * |\ /| + * 0-5-1 + * \|/ + * 2 + * \endverbatim + * @param p0 the first point. + * @param p1 the second point. + * @param p2 the third point. + * @param p3 the fourth point. + * @param p4 the fifth point. + * @param p5 the sixth point. + * @return the dart of the new prism incident to p0 and to + * the facet (p0,p1,p2). + */ + Dart_descriptor make_prism(const Point& p0, + const Point& p1, + const Point& p2, + const Point& p3, + const Point& p4, + const Point& p5) + { + return make_prism(create_vertex_attribute(p0), + create_vertex_attribute(p1), + create_vertex_attribute(p2), + create_vertex_attribute(p3), + create_vertex_attribute(p4), + create_vertex_attribute(p5)); + } + + /** Create an pyramid given 5 Vertex_attribute_descriptor. + * (5 vertices, 8 edges and 5 facets) + * \verbatim + * 4 + * /|\ + * 0-|-1 + * | | | + * 3---2 + * \endverbatim + * @param h0 the first vertex handle. + * @param h1 the second vertex handle. + * @param h2 the third vertex handle. + * @param h3 the fourth vertex handle. + * @param h4 the fifth vertex handle. + * @return the dart of the new pyramid incident to h0 and to + * the facet (h0,h1,h2,h3). + */ + Dart_descriptor make_pyramid(Vertex_attribute_descriptor h0, + Vertex_attribute_descriptor h1, + Vertex_attribute_descriptor h2, + Vertex_attribute_descriptor h3, + Vertex_attribute_descriptor h4) + { + Dart_descriptor d1=make_quadrangle(h0, h1, h2, h3); + Dart_descriptor d2=make_triangle(h1, h0, h4); + Dart_descriptor d3=make_triangle(h0, h3, h4); + Dart_descriptor d4=make_triangle(h3, h2, h4); + Dart_descriptor d5=make_triangle(h2, h1, h4); + + return make_combinatorial_pyramid(d1, d2, d3, d4, d5); + } + + /** Create an pyramid given 5 points. + * \verbatim + * 4 + * /|\ + * 0-|-1 + * | | | + * 3---2 + * \endverbatim + * @param p0 the first point. + * @param p1 the second point. + * @param p2 the third point. + * @param p3 the fourth point. + * @param p4 the fifth point. + * @return the dart of the new pyramid incident to p0 and to + * the facet (p0,p1,p2,p3). + */ + Dart_descriptor make_pyramid(const Point& p0, + const Point& p1, + const Point& p2, + const Point& p3, + const Point& p4) + { + return make_pyramid(create_vertex_attribute(p0), + create_vertex_attribute(p1), + create_vertex_attribute(p2), + create_vertex_attribute(p3), + create_vertex_attribute(p4)); + } + /** Compute the barycenter of a given cell. * @param adart a dart incident to the cell. * @param adim the dimension of the cell.