Improve basic viewer to draw consistent orientated faces for generalized maps.

This commit is contained in:
Guillaume Damiand 2020-04-10 17:40:30 +02:00
parent 584a033e61
commit 3fb644e566
7 changed files with 261 additions and 17 deletions

View File

@ -76,6 +76,7 @@ namespace CGAL {
*/
struct Combinatorial_map_tag {};
struct Generalized_map_tag;
/** Generic definition of combinatorial map in dD.
* The Combinatorial_map class describes an dD combinatorial map. It allows
@ -1212,6 +1213,19 @@ namespace CGAL {
size_type unmark_cell(Dart_const_handle adart, size_type amark) const
{ return CGAL::unmark_cell<Self, i, d>(*this, adart, amark); }
template <unsigned int i, unsigned int d=dimension>
size_type mark_oriented_cell(Dart_const_handle adart, size_type amark,
size_type amark2=INVALID_MARK) const
{ return CGAL::mark_oriented_cell<Self, i, d>(*this, adart, amark, amark2); }
template <unsigned int i, unsigned int d=dimension>
size_type unmark_oriented_cell(Dart_const_handle adart, size_type amark,
size_type amark2=INVALID_MARK) const
{ return CGAL::unmark_oriented_cell<Self, i, d>(*this, adart, amark, amark2); }
std::size_t orient(size_type amark) const
{ negate_mark(amark); }
/** Test if this map is without boundary for a given dimension.
* @param i the dimension.
* @return true iff all the darts are not i-free.

View File

@ -81,7 +81,7 @@ namespace CGAL
typename Map::size_type amark)
{
amap.negate_mark(amark);
bool res=CGAL::is_whole_orbit_marked<Map,Iterator>(amap, adart, amark);
bool res=CGAL::template is_whole_orbit_marked<Map,Iterator>(amap, adart, amark);
amap.negate_mark(amark);
return res;
}
@ -128,7 +128,7 @@ namespace CGAL
{
amap.negate_mark(amark);
typename Map::size_type
res=CGAL::mark_orbit<Map, Iterator>(amap, adart, amark);
res=CGAL::template mark_orbit<Map, Iterator>(amap, adart, amark);
amap.negate_mark(amark);
return res;
}
@ -154,7 +154,7 @@ namespace CGAL
typename Map::Dart_const_handle adart1,
typename Map::Dart_const_handle adart2)
{
return CGAL::belong_to_same_cell<Map,i,Map::dimension>(amap,adart1,adart2);
return CGAL::template belong_to_same_cell<Map,i,Map::dimension>(amap,adart1,adart2);
}
@ -169,7 +169,7 @@ namespace CGAL
typename Map::Dart_const_handle adart,
typename Map::size_type amark)
{
return CGAL::is_whole_orbit_marked<Map,
return CGAL::template is_whole_orbit_marked<Map,
typename Map::template Dart_of_cell_range<i,d>::const_iterator>
(amap, adart, amark);
}
@ -179,7 +179,8 @@ namespace CGAL
typename Map::Dart_const_handle adart,
typename Map::size_type amark)
{
return CGAL::is_whole_cell_marked<Map,i,Map::dimension>(amap,adart,amark);
return CGAL::template is_whole_cell_marked<Map,i,Map::dimension>
(amap,adart,amark);
}
/** Test if all the darts of a given cell are unmarked.
@ -193,7 +194,7 @@ namespace CGAL
typename Map::Dart_const_handle adart,
typename Map::size_type amark)
{
return CGAL::is_whole_orbit_unmarked<Map,
return CGAL::template is_whole_orbit_unmarked<Map,
typename Map::template Dart_of_cell_range<i,d>::const_iterator>
(amap, adart, amark);
}
@ -203,7 +204,7 @@ namespace CGAL
typename Map::Dart_const_handle adart,
typename Map::size_type amark)
{
return CGAL::is_whole_cell_unmarked<Map,i,Map::dimension>
return CGAL::template is_whole_cell_unmarked<Map,i,Map::dimension>
(amap,adart,amark);
}
@ -218,7 +219,7 @@ namespace CGAL
typename Map::size_type mark_cell(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark)
{ return CGAL::mark_orbit<Map,
{ return CGAL::template mark_orbit<Map,
typename Map::template Dart_of_cell_basic_range<i,d>::const_iterator>
(amap, adart, amark); }
@ -226,9 +227,9 @@ namespace CGAL
typename Map::size_type mark_cell(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark)
{ return CGAL::mark_cell<Map,i,Map::dimension>(amap, adart, amark);}
{ return CGAL::template mark_cell<Map,i,Map::dimension>(amap, adart, amark);}
/** Unmark a given orbit with a given mark.
/** Unmark a given cell with a given mark.
* @param amap a combinatorial map.
* @param adart a dart of the cell.
* @param amark the mark.
@ -239,7 +240,7 @@ namespace CGAL
typename Map::size_type unmark_cell(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark)
{ return CGAL::unmark_orbit<Map,
{ return CGAL::template unmark_orbit<Map,
typename Map::template Dart_of_cell_basic_range<i,d>::const_iterator>
(amap, adart, amark);}
@ -247,7 +248,156 @@ namespace CGAL
typename Map::size_type unmark_cell(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark)
{ return CGAL::unmark_cell<Map,i,Map::dimension>(amap, adart, amark); }
{ return CGAL::template unmark_cell<Map,i,Map::dimension>(amap, adart, amark); }
/// Functor to test if the given dart must be marked, when we want
/// to mark an oriented orbit. By default (for CMap), return true.
template<class Map, class T=typename Map::Combinatorial_data_structure>
struct Need_to_mark_for_oriented_cell
{
static bool run(const Map & /*amap*/,
typename Map::Dart_const_handle /*adart*/,
typename Map::size_type /*amark*/,
OperationState /*op*/)
{ return true; }
};
struct Generalized_map_tag;
/// Specialization for GMap. We mark one out of two darts.
template<class Map>
struct Need_to_mark_for_oriented_cell<Map, CGAL::Generalized_map_tag>
{
static bool run(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark,
OperationState op)
{
CGAL_assertion(op!=OP_END);
if (op==OP_NONE) return true;
bool all_darts_unmarked=true;
for (int i=0; all_darts_unmarked && i<=(int)Map::dimension; ++i)
{
if (!amap.is_free(adart, i) &&
amap.is_marked(amap.alpha(adart, i), amark))
{ all_darts_unmarked=false; }
}
return all_darts_unmarked;
}
};
/** Mark a given oriented orbit with a given mark. For combinatorial map,
* equivalent to mark_orbit. For generalized map, mark one out of two dart
* if the orbit is orientable. If amark2!=INVALID_MARK, mark also all the darts
* of the orbit with amark2.
* @param amap a combinatorial map / generalized.
* @param adart a dart of the orbit.
* @param amark the mark.
* @param amark2 a second mark.
* @return the number of darts of the marked orbit.
* @pre The whole orbit must be unmarked.
*/
template < class Map, class Iterator >
typename Map::size_type mark_oriented_orbit(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark,
typename Map::size_type amark2=Map::INVALID_MARK)
{
CGAL_static_assertion( (boost::is_same<typename Iterator::Basic_iterator,
Tag_true>::value) );
CGAL_assertion( (is_whole_orbit_unmarked<Map,
CMap_non_basic_iterator<Map,Iterator> >
(amap, adart, amark)) );
typename Map::size_type res=0;
typename Map::size_type amark3=(amark2==Map::INVALID_MARK?amap.get_new_mark():amark2);
for (Iterator it(amap, adart, amark3); it.cont(); ++it)
{
amap.mark(it, amark3);
if (CGAL::template Need_to_mark_for_oriented_cell<Map>::
run(amap, it, amark, it.prev_operation()))
{
amap.mark(it, amark);
++res;
}
}
if (amark2==Map::INVALID_MARK)
{
CGAL::template unmark_orbit<Map, Iterator>(amap, adart, amark3);
amap.free_mark(amark3);
}
return res;
}
template < class Map, class Iterator >
typename Map::size_type unmark_oriented_orbit(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark,
typename Map::size_type amark2=Map::INVALID_MARK)
{
amap.negate_mark(amark);
if (amark2!=Map::INVALID_MARK) { amap.negate_mark(amark2); }
typename Map::size_type
res=CGAL::template mark_oriented_orbit<Map, Iterator>(amap, adart, amark, amark2);
amap.negate_mark(amark);
if (amark2!=Map::INVALID_MARK) { amap.negate_mark(amark2); }
return res;
}
/** Mark a given oriented cell with a given mark. For combinatorial map,
* equivalent to mark_cell. For generalized map, mark one out of two dart
* if the cell is orientable. If amark2!=INVALID_MARK, mark also all the darts
* of the cell with amark2.
* @param amap a combinatorial map / generalized.
* @param adart a dart of the cell.
* @param amark the mark.
* @param amark2 a second mark.
* @return the number of darts of the marked cell.
* @pre The whole cell must be unmarked.
*/
template < class Map, unsigned int i, unsigned int d >
typename Map::size_type mark_oriented_cell(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark,
typename Map::size_type amark2=Map::INVALID_MARK)
{ return CGAL::template mark_oriented_orbit
<Map, typename Map::template Dart_of_cell_basic_range<i,d>::const_iterator>
(amap, adart, amark, amark2); }
template < class Map, unsigned int i>
typename Map::size_type mark_oriented_cell(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark,
typename Map::size_type amark2=Map::INVALID_MARK)
{ return CGAL::template mark_oriented_cell<Map,i,Map::dimension>
(amap, adart, amark, amark2);}
/** Unmark a given oriented cell with a given mark.
* @param amap a combinatorial map.
* @param adart a dart of the cell.
* @param amark the mark.
* @return the number of darts of the unmarked cell.
* @pre The whole cell must be marked.
*/
template < class Map, unsigned int i, unsigned int d >
typename Map::size_type unmark_oriented_cell(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark,
typename Map::size_type amark2=Map::INVALID_MARK)
{ return CGAL::template unmark_oriented_orbit
<Map, typename Map::template Dart_of_cell_basic_range<i,d>::const_iterator>
(amap, adart, amark, amark2);}
template < class Map, unsigned int i >
typename Map::size_type unmark_oriented_cell(const Map & amap,
typename Map::Dart_const_handle adart,
typename Map::size_type amark,
typename Map::size_type amark2=Map::INVALID_MARK)
{ return CGAL::template unmark_oriented_cell<Map,i,Map::dimension>
(amap, adart, amark, amark2); }
/** Compute the degree of a given i-cell c.
* The degree is the number of distinct i+1 cells incident to c.

View File

@ -52,6 +52,7 @@ namespace CGAL {
* Definition of generic dD Generalized map.
*/
struct Combinatorial_map_tag;
struct Generalized_map_tag {};
/** Generic definition of generalized map in dD.
@ -1035,6 +1036,31 @@ namespace CGAL {
size_type unmark_cell(Dart_const_handle adart, size_type amark) const
{ return CGAL::unmark_cell<Self, i, d>(*this, adart, amark); }
template <unsigned int i, unsigned int d=dimension>
size_type mark_oriented_cell(Dart_const_handle adart, size_type amark,
size_type amark2=INVALID_MARK) const
{ return CGAL::mark_oriented_cell<Self, i, d>(*this, adart, amark, amark2); }
template <unsigned int i, unsigned int d=dimension>
size_type unmark_oriented_cell(Dart_const_handle adart, size_type amark,
size_type amark2=INVALID_MARK) const
{ return CGAL::unmark_oriented_cell<Self, i, d>(*this, adart, amark, amark2); }
std::size_t orient(size_type amark) const
{
size_type amark2=get_new_mark();
std::size_t res=0;
for (auto it=darts().begin(), itend=darts().end(); it!=itend; ++it)
{
if (!is_marked(it, amark2))
{ res+=mark_oriented_cell<dimension+1>(it, amark, amark2); } // Mark the connected componend
}
CGAL_assertion(is_whole_map_marked(amark2));
free_mark(amark2);
return res;
}
/** Test if this map is without boundary for a given dimension.
* @param i the dimension.
* @return true iff all the darts are not i-free.

View File

@ -170,17 +170,28 @@ public:
// First draw: vertices; edges, faces; multi-color; inverse normal
Base(parent, title, true, true, true, false, false),
lcc(alcc),
m_oriented_mark(lcc->get_new_mark()),
m_nofaces(anofaces),
m_random_face_color(false),
m_drawing_functor(drawing_functor)
{
lcc->orient(m_oriented_mark);
compute_elements();
}
~SimpleLCCViewerQt()
{ lcc->free_mark(m_oriented_mark); }
protected:
void set_lcc(const LCC* alcc, bool doredraw=true)
{
if (lcc!=nullptr)
{ lcc->free_mark(m_oriented_mark); }
lcc=alcc;
m_oriented_mark=lcc->get_new_mark();
lcc->orient(m_oriented_mark);
compute_elements();
if (doredraw) { redraw(); }
}
@ -279,6 +290,7 @@ protected:
{
lcc->mark(itv, markvolumes); // To be sure that all darts of the basic iterator will be marked
if (!lcc->is_marked(itv, markfaces) &&
lcc->is_marked(itv, m_oriented_mark) &&
m_drawing_functor.draw_face(*lcc, itv))
{
if (!m_drawing_functor.volume_wireframe(*lcc, itv) &&
@ -360,6 +372,7 @@ protected:
protected:
const LCC* lcc;
typename LCC::size_type m_oriented_mark;
bool m_nofaces;
bool m_random_face_color;
const DrawingFunctorLCC& m_drawing_functor;

View File

@ -557,6 +557,37 @@ public:
return res;
}
template <unsigned int i>
size_type mark_oriented_cell(Dart_const_handle adart, size_type amark,
size_type amark2=INVALID_MARK) const
{
size_type res=0;
for (typename Dart_of_cell_range<i>::iterator it=darts_of_cell<i>(adart).begin(),
itend=darts_of_cell<i>(adart).end(); it!=itend; ++it)
{
mark(*it, amark); ++res;
if (amark2!=INVALID_MARK) { mark(*it, amark2); }
}
return res;
}
template <unsigned int i>
size_type unmark_oriented_cell(Dart_const_handle adart, size_type amark,
size_type amark2=INVALID_MARK) const
{
size_type res=0;
for (typename Dart_of_cell_range<i>::iterator it=darts_of_cell<i>(adart).begin(),
itend=darts_of_cell<i>(adart).end(); it!=itend; ++it)
{
unmark(*it, amark); ++res;
if (amark2!=INVALID_MARK) { unmark(*it, amark2); }
}
return res;
}
std::size_t orient(size_type amark) const
{ negate_mark(amark); }
std::vector<unsigned int>
count_marked_cells(size_type amark, const std::vector<unsigned int>& acells) const
{

View File

@ -76,7 +76,7 @@ struct Index_from_halfedge_descriptor
halfedge_descriptor;
static size_type run(const Mesh& m, halfedge_descriptor h)
{ std::cout<<"V1"<<std::endl;
{
size_type res=0;
for (typename boost::template graph_traits<Mesh>::halfedge_iterator
it=halfedges(m).begin(), itend=halfedges(m).end(); it!=itend; ++it, ++res)
@ -93,7 +93,7 @@ struct Index_from_halfedge_descriptor<CGAL::Surface_mesh<P> >
halfedge_descriptor;
static size_type run(const Mesh& /*m*/, halfedge_descriptor h)
{ std::cout<<"V2"<<std::endl; return (size_type)(h); }
{ return (size_type)(h); }
};
////////////////////////////////////////////////////////////////////////////////
template<typename Mesh>
@ -120,7 +120,7 @@ struct Halfedge_descriptor_from_index<CGAL::Surface_mesh<P> >
halfedge_descriptor;
static halfedge_descriptor run(const Mesh& /*m*/, size_type i)
{ std::cout<<"V2"<<std::endl; return halfedge_descriptor(i); }
{ return halfedge_descriptor(i); }
};
////////////////////////////////////////////////////////////////////////////////
template<typename Mesh>

View File

@ -110,6 +110,7 @@ public:
Base(parent, title, true, true, true, false, true),
mesh(amesh),
lcc(amesh),
m_oriented_mark(lcc.get_new_mark()),
m_nofaces(anofaces),
m_drawing_functor(drawing_functor),
m_paths(paths),
@ -118,7 +119,15 @@ public:
m_draw_marked_darts(true),
m_amark(amark==std::numeric_limits<std::size_t>::max()?
LCC::INVALID_MARK:amark)
{ compute_elements(); }
{
lcc.orient(m_oriented_mark);
compute_elements();
}
~Face_graph_with_path_viewer()
{
lcc.free_mark(m_oriented_mark);
}
protected:
@ -167,7 +176,7 @@ protected:
itend=lcc.darts().end(); it!=itend; ++it )
{
if (!m_nofaces && !lcc.is_marked(it, markfaces) &&
!lcc.is_perforated(it))
!lcc.is_perforated(it) && lcc.is_marked(it, m_oriented_mark))
{
compute_face(it);
lcc.template mark_cell<2>(it, markfaces);
@ -371,6 +380,7 @@ protected:
protected:
const Mesh& mesh;
const typename Get_map<Mesh, Mesh>::storage_type lcc;
typename LCC::size_type m_oriented_mark;
bool m_nofaces;
const DrawingFunctorLCC& m_drawing_functor;
const std::vector<Surface_mesh_topology::Path_on_surface<Mesh> >* m_paths;