add insert_cell_1_between_two_cells_2 method in CMap and GMap

This commit is contained in:
Guillaume Damiand 2022-11-25 13:06:50 +01:00
parent 01c05d8f1b
commit bb263e009e
2 changed files with 205 additions and 54 deletions

View File

@ -1639,11 +1639,14 @@ namespace CGAL {
CGAL_static_assertion(i<=dimension); CGAL_static_assertion(i<=dimension);
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0, CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
"set_attribute<i> but i-attributes are disabled"); "set_attribute<i> but i-attributes are disabled");
for ( typename Dart_of_cell_range<i>::iterator it(*this, dh);
it.cont(); ++it) for (typename Dart_of_cell_range<i>::iterator it(*this, dh); it.cont(); ++it)
{ {
this->template set_dart_attribute<i>(it, ah); this->template set_dart_attribute<i>(it, ah);
} }
if(ah!=null_descriptor)
// To ensure that the dart of this attribute is dh
{ this->template set_dart_of_attribute<i>(ah, dh); }
} }
/// @return a Attributes_range<i> (range through all the /// @return a Attributes_range<i> (range through all the
@ -4410,7 +4413,8 @@ namespace CGAL {
bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1, bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1,
Dart_const_descriptor adart2) const Dart_const_descriptor adart2) const
{ {
if ( adart1==adart2 ) return false; if (adart1==adart2 || adart1==null_descriptor) return false;
if (adart2==null_descriptor) return true;
for ( CMap_dart_const_iterator_of_orbit<Self,1> it(*this,adart1); for ( CMap_dart_const_iterator_of_orbit<Self,1> it(*this,adart1);
it.cont(); ++it ) it.cont(); ++it )
{ {
@ -4427,15 +4431,81 @@ namespace CGAL {
* same vertex than adart1. * same vertex than adart1.
*/ */
Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1, Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1,
Dart_descriptor adart2, Dart_descriptor adart2,
bool update_attributes=true) bool update_attributes=true)
{ {
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2));
if ( adart2==null_descriptor ) if ( adart2==null_descriptor )
return insert_dangling_cell_1_in_cell_2(adart1, null_descriptor, return insert_dangling_cell_1_in_cell_2(adart1, null_descriptor,
update_attributes); update_attributes);
return generic_insert_cell_1(adart1, adart2, false, update_attributes);
}
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2)); /** Test if an edge can be inserted between two different 2-cells
* between two given darts.
* @param adart1 a first dart.
* @param adart2 a second dart.
* @return true iff an edge can be inserted between adart1 and adart2.
*/
bool is_insertable_cell_1_between_two_cells_2(Dart_const_descriptor adart1,
Dart_const_descriptor adart2) const
{
if (adart1==adart2 || adart1==null_descriptor || adart2==null_descriptor)
{ return false; }
for ( CMap_dart_const_iterator_of_orbit<Self,1> it(*this,adart1);
it.cont(); ++it )
{
if ( it==adart2 ) return false;
}
return true;
}
/** Insert an edge between two different 2-cells, between two given darts.
* @param adart1 a first dart of the first facet (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart of the second facet (!=null_descriptor && !=null_dart_descriptor).
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1_between_two_cells_2(Dart_descriptor adart1,
Dart_descriptor adart2,
bool update_attributes=true)
{
CGAL_assertion(is_insertable_cell_1_between_two_cells_2(adart1, adart2));
return generic_insert_cell_1(adart1, adart2, true, update_attributes);
}
/** Insert an edge between two given darts. If the two darts belong to the same facet, call
* insert_cell_1_in_cell_2, otherwise call insert_cell_1_between_two_cells_2.
* @param adart1 a first dart (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart.
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1(Dart_descriptor adart1,
Dart_descriptor adart2,
bool update_attributes=true)
{
if(is_insertable_cell_1_in_cell_2(adart1, adart2))
{ return insert_cell_1_in_cell_2(adart1, adart2, update_attributes); }
return insert_cell_1_between_two_cells_2(adart1, adart2, update_attributes);
}
/** Generic method to insert a 1-cell, either in a 2-cell (cf. insert_cell_1_in_cell_2)
* or between two different 2-cells (cf. insert_cell_1_between_two_cells_2).
* Indeed the code is the same, except for the group/degroup attribute.
* merge is true if adart1 and adart2 belongs to two different facets; in this case
* the two facets should be merged (they are now linked by the new edge);
* merge is false it adart1 and adart2 belongs to the same facet; in this case
* the facet is split in two.
* Internal method not supposed to be called by users.
*/
Dart_descriptor generic_insert_cell_1(Dart_descriptor adart1,
Dart_descriptor adart2,
bool merge,
bool update_attributes)
{
size_type m1=get_new_mark(); size_type m1=get_new_mark();
CMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1); CMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1);
@ -4509,7 +4579,13 @@ namespace CGAL {
if (are_attributes_automatically_managed() && update_attributes) if (are_attributes_automatically_managed() && update_attributes)
{ {
internal::Degroup_attribute_functor_run<Self, 2>::run(*this, d1, d2); if(merge)
{ // Here we group all enabled attributes starting from 2 to dimension
Helper::template Foreach_enabled_attributes
<internal::Group_attribute_functor<Self>, 2>::run(*this, adart1, adart2);
}
else // Here we degroup 2-attributes
{ internal::Degroup_attribute_functor_run<Self, 2>::run(*this, adart1, adart2); }
} }
negate_mark(m1); negate_mark(m1);

View File

@ -1464,11 +1464,14 @@ namespace CGAL {
CGAL_static_assertion(i<=dimension); CGAL_static_assertion(i<=dimension);
CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0, CGAL_static_assertion_msg(Helper::template Dimension_index<i>::value>=0,
"set_attribute<i> but i-attributes are disabled"); "set_attribute<i> but i-attributes are disabled");
for ( typename Dart_of_cell_range<i>::iterator it(*this, dh); for (typename Dart_of_cell_range<i>::iterator it(*this, dh);
it.cont(); ++it) it.cont(); ++it)
{ {
this->template set_dart_attribute<i>(it, ah); this->template set_dart_attribute<i>(it, ah);
} }
if(ah!=null_descriptor)
// To ensure that the dart of this attribute is dh
{ this->template set_dart_of_attribute<i>(ah, dh); }
} }
/// @return a Attributes_range<i> (range through all the /// @return a Attributes_range<i> (range through all the
@ -3512,7 +3515,9 @@ namespace CGAL {
bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1, bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1,
Dart_const_descriptor adart2) Dart_const_descriptor adart2)
{ {
if ( adart1==adart2 || adart1==this->template alpha<0>(adart2) ) if (adart2==null_descriptor) return true;
if (adart1==adart2 || adart1==this->template alpha<0>(adart2) ||
adart1==null_descriptor || this->template is_free<1>(adart2))
return false; return false;
for ( CGAL::GMap_dart_const_iterator_of_orbit<Self,0,1> it(*this,adart1); for ( CGAL::GMap_dart_const_iterator_of_orbit<Self,0,1> it(*this,adart1);
it.cont(); ++it ) it.cont(); ++it )
@ -3525,29 +3530,104 @@ namespace CGAL {
/** Insert an edge in a 2-cell between two given darts. /** Insert an edge in a 2-cell between two given darts.
* @param adart1 a first dart of the facet (!=null_descriptor && !=null_dart_descriptor). * @param adart1 a first dart of the facet (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart of the facet. If null_descriptor insert a dangling edge. * @param adart2 a second dart of the facet. If null_descriptor insert a dangling edge.
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the * @return a dart of the new edge, and not incident to the
* same vertex than adart1. * same vertex than adart1.
*/ */
Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1, Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1,
Dart_descriptor adart2, Dart_descriptor adart2,
bool update_attributes=true, typename Attribute_descriptor<0>::
typename Attribute_descriptor<0>::type type ah=null_descriptor,
ah=null_descriptor) bool update_attributes=true)
{ {
if ( adart2!=null_descriptor) CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2));
{ return generic_insert_cell_1(adart1, adart2, false, update_attributes, ah);
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2)); }
}
/** Test if an edge can be inserted between two different 2-cells
* between two given darts.
* @param adart1 a first dart.
* @param adart2 a second dart.
* @return true iff an edge can be inserted between adart1 and adart2.
*/
bool is_insertable_cell_1_between_two_cells_2(Dart_const_descriptor adart1,
Dart_const_descriptor adart2) const
{
if (adart1==adart2 || adart1==null_descriptor || adart2==null_descriptor)
{ return false; }
for ( CGAL::GMap_dart_const_iterator_of_orbit<Self,0,1> it(*this,adart1);
it.cont(); ++it )
{
if ( it==adart2 ) return false;
}
for(unsigned int d=3; d<=dimension; ++d)
{ if(is_free(adart1, d)!=is_free(adart2, d)) { return false; }}
return true;
}
/** Insert an edge between two different 2-cells, between two given darts.
* @param adart1 a first dart of the first facet (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart of the second facet (!=null_descriptor && !=null_dart_descriptor).
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1_between_two_cells_2(Dart_descriptor adart1,
Dart_descriptor adart2,
bool update_attributes=true)
{
CGAL_assertion(is_insertable_cell_1_between_two_cells_2(adart1, adart2));
return generic_insert_cell_1(adart1, adart2, true, update_attributes);
}
/** Insert an edge between two given darts. If the two darts belong to the same facet, call
* insert_cell_1_in_cell_2, otherwise call insert_cell_1_between_two_cells_2.
* @param adart1 a first dart (!=null_descriptor && !=null_dart_descriptor).
* @param adart2 a second dart.
* @param update_attributes a boolean to update the enabled attributes
* @return a dart of the new edge, and not incident to the
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1(Dart_descriptor adart1,
Dart_descriptor adart2,
bool update_attributes=true,
typename Attribute_descriptor<0>::type
ah=null_descriptor)
{
CGAL_assertion(adart1!=null_descriptor);
if(is_insertable_cell_1_in_cell_2(adart1, adart2))
{ return insert_cell_1_in_cell_2(adart1, adart2, update_attributes, ah); }
return insert_cell_1_between_two_cells_2(adart1, adart2, update_attributes);
}
/** Generic method to insert a 1-cell, either in a 2-cell (cf. insert_cell_1_in_cell_2)
* or between two different 2-cells (cf. insert_cell_1_between_two_cells_2).
* Indeed the code is the same, except for the group/degroup attribute.
* merge is true if adart1 and adart2 belongs to two different facets; in this case
* the two facets should be merged (they are now linked by the new edge);
* merge is false it adart1 and adart2 belongs to the same facet; in this case
* the facet is split in two.
* Internal method not supposed to be called by users.
*/
Dart_descriptor generic_insert_cell_1(Dart_descriptor adart1,
Dart_descriptor adart2,
bool merge,
bool update_attributes=true,
typename Attribute_descriptor<0>::type
ah=null_descriptor)
{
/* CGAL::GMap_dart_iterator_basic_of_involution<Self,1> will contain all /* CGAL::GMap_dart_iterator_basic_of_involution<Self,1> will contain all
* alpha_i except alpha_0, alpha_1 and alpha_2, i.e. this is * alpha_i except alpha_0, alpha_1 and alpha_2, i.e. this is
* <alpha_3,...,alpha_d> * <alpha_3,...,alpha_d>
*/ */
Dart_descriptor dart2_a1=null_descriptor;
if(adart2!=null_descriptor) { dart2_a1=alpha<1>(adart2); }
size_type m1=get_new_mark(); size_type m1=get_new_mark();
CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1); CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1);
size_type m2=get_new_mark(); size_type m2=get_new_mark();
CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it2(*this, adart2, m2); CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it2(*this, dart2_a1, m2);
Dart_descriptor d1=null_descriptor; Dart_descriptor d1=null_descriptor;
Dart_descriptor d2=null_descriptor; Dart_descriptor d2=null_descriptor;
@ -3563,44 +3643,32 @@ namespace CGAL {
d2 = create_dart(); d2 = create_dart();
mark(it1,treated); mark(it1,treated);
if (!isfree1) d3 = create_dart();
{ d4 = create_dart();
d3 = create_dart(); this->template basic_link_alpha<2>(d1, d3);
d4 = create_dart(); this->template basic_link_alpha<2>(d2, d4);
this->template basic_link_alpha<2>(d1, d3);
this->template basic_link_alpha<2>(d2, d4);
}
for ( unsigned int dim=3; dim<=dimension; ++dim) for (unsigned int dim=3; dim<=dimension; ++dim)
{ {
if ( !is_free(it1, dim) && if ( !is_free(it1, dim) &&
is_marked(alpha(it1, dim), treated) ) is_marked(alpha(it1, dim), treated) )
{ {
basic_link_alpha(alpha(it1, dim, 1), d1, dim); basic_link_alpha(alpha(it1, dim, 1), d1, dim);
basic_link_alpha(alpha(d1, dim, 0), d2, dim); basic_link_alpha(alpha(it1, dim, 1, 0), d2, dim);
if (!isfree1) basic_link_alpha(alpha(it1, dim, 1, 2), d3, dim);
{ basic_link_alpha(alpha(it1, dim, 1, 2, 0), d4, dim);
basic_link_alpha(alpha(it1, 1, dim, 1), d3, dim);
basic_link_alpha(alpha(d3, dim, 0), d4, dim);
}
} }
} }
if (!isfree1) if (!isfree1)
{ { this->template link_alpha<1>(this->template alpha<1>(it1), d3); }
this->template link_alpha<1>(this->template alpha<1>(it1), d3);
if ( adart2!=null_descriptor )
{
CGAL_assertion (it2.cont());
this->template link_alpha<1>(this->template alpha<1>(it2), d4);
}
}
this->template link_alpha<1>(it1, d1); this->template link_alpha<1>(it1, d1);
if ( adart2!=null_descriptor )
if (adart2!=null_descriptor)
{ {
CGAL_assertion (it2.cont()); CGAL_assertion (it2.cont());
this->template link_alpha<1>(this->template alpha<1>(it2), d4);
this->template link_alpha<1>(it2, d2); this->template link_alpha<1>(it2, d2);
++it2; ++it2;
} }
@ -3610,25 +3678,31 @@ namespace CGAL {
update_attributes && ah!=null_descriptor) update_attributes && ah!=null_descriptor)
{ {
internal::Set_i_attribute_of_dart_functor<Self, 0>::run(*this, d2, ah); internal::Set_i_attribute_of_dart_functor<Self, 0>::run(*this, d2, ah);
if (!isfree1) internal::Set_i_attribute_of_dart_functor<Self, 0>::run(*this, d4, ah);
{
internal::Set_i_attribute_of_dart_functor<Self, 0>::run(*this, d4, ah);
}
} }
} }
// We do the link_alpha<0> after the link_alpha<1> to update the // We do the link_alpha<0> after the link_alpha<1> to update the
// possible attributes of d2. // possible attributes of d2.
this->template link_alpha<0>(d1, d2); this->template link_alpha<0>(d1, d2);
if (!isfree1) this->template link_alpha<0>(d3, d4);
{ this->template link_alpha<0>(d3, d4); }
} }
if (are_attributes_automatically_managed() && update_attributes) if (are_attributes_automatically_managed() && update_attributes)
{ {
if ( !this->template is_free<2>(d1) && d2!=null_descriptor ) if(merge)
CGAL::internal::GMap_degroup_attribute_functor_run<Self, 2>:: { // Here we group all enabled attributes starting from 2 to dimension
run(*this, d1, this->template alpha<2>(d1)); Helper::template Foreach_enabled_attributes
<internal::Group_attribute_functor<Self>, 2>::
run(*this, adart1, adart2);
}
else // Here we degroup 2-attributes
{
// TODO if ( !this->template is_free<2>(d1) && d2!=null_descriptor )
if (adart2!=null_descriptor)
{ CGAL::internal::GMap_degroup_attribute_functor_run<Self, 2>::
run(*this, adart1, adart2); }
}
} }
negate_mark(m1); negate_mark(m1);
@ -3673,7 +3747,8 @@ namespace CGAL {
typename Attribute_descriptor<0>:: typename Attribute_descriptor<0>::
type ah=null_descriptor, type ah=null_descriptor,
bool update_attributes=true ) bool update_attributes=true )
{ return insert_cell_1_in_cell_2(adart1, null_descriptor, update_attributes, ah); } { return insert_cell_1_in_cell_2(adart1, null_descriptor, ah,
update_attributes); }
/** Test if a 2-cell can be inserted onto a given 3-cell along /** Test if a 2-cell can be inserted onto a given 3-cell along
* a path of edges. * a path of edges.