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_msg(Helper::template Dimension_index<i>::value>=0,
"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);
}
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
@ -4410,7 +4413,8 @@ namespace CGAL {
bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1,
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);
it.cont(); ++it )
{
@ -4430,12 +4434,78 @@ namespace CGAL {
Dart_descriptor adart2,
bool update_attributes=true)
{
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2));
if ( adart2==null_descriptor )
return insert_dangling_cell_1_in_cell_2(adart1, null_descriptor,
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();
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)
{
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);

View File

@ -1469,6 +1469,9 @@ namespace CGAL {
{
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
@ -3512,7 +3515,9 @@ namespace CGAL {
bool is_insertable_cell_1_in_cell_2(Dart_const_descriptor adart1,
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;
for ( CGAL::GMap_dart_const_iterator_of_orbit<Self,0,1> it(*this,adart1);
it.cont(); ++it )
@ -3525,29 +3530,104 @@ namespace CGAL {
/** 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 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
* same vertex than adart1.
*/
Dart_descriptor insert_cell_1_in_cell_2(Dart_descriptor adart1,
Dart_descriptor adart2,
typename Attribute_descriptor<0>::
type ah=null_descriptor,
bool update_attributes=true)
{
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2));
return generic_insert_cell_1(adart1, adart2, false, update_attributes, ah);
}
/** 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)
{
if ( adart2!=null_descriptor)
{
CGAL_assertion(is_insertable_cell_1_in_cell_2(adart1, adart2));
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
* alpha_i except alpha_0, alpha_1 and alpha_2, i.e. this is
* <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();
CGAL::GMap_dart_iterator_basic_of_involution<Self,1> it1(*this, adart1, m1);
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 d2=null_descriptor;
@ -3563,13 +3643,10 @@ namespace CGAL {
d2 = create_dart();
mark(it1,treated);
if (!isfree1)
{
d3 = create_dart();
d4 = create_dart();
this->template basic_link_alpha<2>(d1, d3);
this->template basic_link_alpha<2>(d2, d4);
}
for (unsigned int dim=3; dim<=dimension; ++dim)
{
@ -3577,30 +3654,21 @@ namespace CGAL {
is_marked(alpha(it1, dim), treated) )
{
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, 1, dim, 1), d3, dim);
basic_link_alpha(alpha(d3, dim, 0), d4, dim);
}
basic_link_alpha(alpha(it1, dim, 1, 2), d3, dim);
basic_link_alpha(alpha(it1, dim, 1, 2, 0), d4, dim);
}
}
if (!isfree1)
{
this->template link_alpha<1>(this->template alpha<1>(it1), d3);
{ this->template link_alpha<1>(this->template alpha<1>(it1), d3); }
this->template link_alpha<1>(it1, d1);
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);
if ( adart2!=null_descriptor )
{
CGAL_assertion (it2.cont());
this->template link_alpha<1>(it2, d2);
++it2;
}
@ -3610,25 +3678,31 @@ namespace CGAL {
update_attributes && ah!=null_descriptor)
{
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);
}
}
}
// We do the link_alpha<0> after the link_alpha<1> to update the
// possible attributes of 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 ( !this->template is_free<2>(d1) && d2!=null_descriptor )
CGAL::internal::GMap_degroup_attribute_functor_run<Self, 2>::
run(*this, d1, this->template alpha<2>(d1));
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
{
// 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);
@ -3673,7 +3747,8 @@ namespace CGAL {
typename Attribute_descriptor<0>::
type ah=null_descriptor,
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
* a path of edges.