mirror of https://github.com/CGAL/cgal
637 lines
23 KiB
C++
637 lines
23 KiB
C++
// Copyright (c) 2005 INRIA (France).
|
|
// All rights reserved.
|
|
//
|
|
// This file is part of CGAL (www.cgal.org); you may redistribute it under
|
|
// the terms of the Q Public License version 1.0.
|
|
// See the file LICENSE.QPL distributed with CGAL.
|
|
//
|
|
// Licensees holding a valid commercial license may use this file in
|
|
// accordance with the commercial license agreement provided with the software.
|
|
//
|
|
// This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
|
|
// WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
|
//
|
|
// $URL$
|
|
// $Id$
|
|
//
|
|
//
|
|
// Author(s) : Laurent Saboret, Pierre Alliez
|
|
|
|
|
|
#ifndef CGAL_PARAM_MESH_PATCH_CIRCULATORS_H
|
|
#define CGAL_PARAM_MESH_PATCH_CIRCULATORS_H
|
|
|
|
#include <CGAL/iterator.h>
|
|
#include <CGAL/circulator.h>
|
|
#include <CGAL/Convertible_iterator_project.h>
|
|
#include <CGAL/Convertible_circulator_project.h>
|
|
#include <CGAL/function_objects.h>
|
|
#include <CGAL/HalfedgeDS_iterator.h>
|
|
#include <CGAL/Param_mesh_patch_vertex.h>
|
|
|
|
#include <CGAL/parameterization_assertions.h>
|
|
|
|
CGAL_BEGIN_NAMESPACE
|
|
|
|
|
|
/// Class Mesh_patch_vertex_around_vertex_cir
|
|
/// represents a (clockwise) circulator around a vertex
|
|
/// of a Parameterization_mesh_patch_3<ParameterizationPatchableMesh_3> mesh
|
|
template<class MeshPatchPtrType, ///< = [const] Parameterization_mesh_patch_3*
|
|
class VertexHandleType, ///< = Parameterization_mesh_patch_3::Vertex_[const_]handle
|
|
class AdaptorVertexAroundVertexCirculatorType,
|
|
///< = Adaptor::Vertex_around_vertex_[const_]circulator
|
|
class AdaptorVertexHandleType>
|
|
///< = Adaptor::Vertex_[const_]handle
|
|
class Mesh_patch_vertex_around_vertex_cir
|
|
: public VertexHandleType
|
|
{
|
|
// PRIVATE TYPES
|
|
// -------------
|
|
|
|
/// Base and self classes
|
|
typedef VertexHandleType Base;
|
|
typedef Mesh_patch_vertex_around_vertex_cir Self;
|
|
|
|
/// Mesh_patch types
|
|
typedef typename std::iterator_traits<MeshPatchPtrType>::value_type
|
|
Mesh_patch;
|
|
typedef typename Mesh_patch::Adaptor Adaptor;
|
|
|
|
public:
|
|
|
|
// PUBLIC TYPES
|
|
// ------------
|
|
|
|
// Export template parameter types
|
|
typedef MeshPatchPtrType Mesh_patch_c_ptr;
|
|
typedef VertexHandleType Vertex_c_handle;
|
|
typedef AdaptorVertexAroundVertexCirculatorType
|
|
Adaptor_vertex_around_vertex_c_cir;
|
|
typedef AdaptorVertexHandleType Adaptor_vertex_c_handle;
|
|
|
|
// Iterator types
|
|
typedef typename Adaptor_vertex_around_vertex_c_cir::iterator_category
|
|
iterator_category;
|
|
typedef typename Vertex_c_handle::value_type value_type;
|
|
typedef std::ptrdiff_t difference_type;
|
|
typedef std::size_t size_type;
|
|
typedef typename Vertex_c_handle::reference reference;
|
|
typedef typename Vertex_c_handle::pointer pointer;
|
|
|
|
/// CREATION
|
|
/// --------
|
|
|
|
/// Circulator pointing to NULL
|
|
Mesh_patch_vertex_around_vertex_cir() {}
|
|
|
|
/// Get circulator over the vertices incident to 'vertex'
|
|
/// 'start_position' defines the initial position of the circulator [required}
|
|
Mesh_patch_vertex_around_vertex_cir(Mesh_patch_c_ptr mesh,
|
|
Vertex_c_handle vertex,
|
|
Vertex_c_handle start_position)
|
|
: Base(start_position),
|
|
m_mesh_patch(mesh),
|
|
m_center(vertex)
|
|
{
|
|
CGAL_parameterization_assertion(m_mesh_patch != NULL);
|
|
CGAL_parameterization_assertion(m_mesh_patch->m_mesh_adaptor != NULL);
|
|
CGAL_parameterization_assertion(m_mesh_patch->is_valid(vertex));
|
|
CGAL_parameterization_assertion(m_mesh_patch->is_valid(start_position));
|
|
|
|
//#ifdef DEBUG_TRACE
|
|
// std::cerr << " Mesh_patch_vertex_around_vertex_cir(";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(vertex) << ",";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(start_position) << ")\n";
|
|
//#endif
|
|
|
|
// Construct an adaptor circulator over the vertices
|
|
// incident to vertex->vertex()
|
|
m_adaptor_circulator = m_mesh_patch->m_mesh_adaptor->vertices_around_vertex_begin(
|
|
vertex->vertex(), start_position->vertex());
|
|
}
|
|
|
|
/// Copy constructor
|
|
Mesh_patch_vertex_around_vertex_cir(const Self& cir)
|
|
: Base(cir),
|
|
m_mesh_patch(cir.m_mesh_patch),
|
|
m_center(cir.m_center),
|
|
m_adaptor_circulator(cir.m_adaptor_circulator)
|
|
{
|
|
}
|
|
|
|
/// operator =()
|
|
Self& operator =(const Self& cir)
|
|
{
|
|
Base::operator=(cir);
|
|
m_mesh_patch = cir.m_mesh_patch;
|
|
m_center = cir.m_center;
|
|
m_adaptor_circulator = cir.m_adaptor_circulator;
|
|
|
|
return *this;
|
|
}
|
|
|
|
/// OPERATIONS Forward Category
|
|
/// ---------------------------
|
|
|
|
bool operator==(const Self& cir) const { return Base::operator==(cir); }
|
|
bool operator!=(const Self& cir) const { return !(*this == cir); }
|
|
bool operator==(CGAL_NULL_TYPE ptr) const { return Base::operator==(ptr); }
|
|
bool operator!=(CGAL_NULL_TYPE ptr) const { return !(*this == ptr); }
|
|
|
|
/// operator*() and operator->() are inherited
|
|
|
|
/// Clockwise rotation
|
|
Self& operator++()
|
|
{
|
|
//#ifdef DEBUG_TRACE
|
|
// std::cerr << " Mesh_patch_vertex_around_vertex_cir ++\n";
|
|
//#endif
|
|
|
|
// Check that the inherited vertex handle is valid
|
|
assert((*this)->vertex() == m_adaptor_circulator);
|
|
|
|
// If m_center is an inner vertex, m_adaptor_circulator
|
|
// already circulates over m_center's vertices
|
|
if (m_center->first_cw_neighbor() == NULL)
|
|
{
|
|
m_adaptor_circulator++;
|
|
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
|
|
// If m_center is a border/seam vertex (except a seam extremity),
|
|
// *this must circulate only from
|
|
// first_cw_neighbor() to last_cw_neighbor() (included)
|
|
if (m_center->last_cw_neighbor() != m_center->first_cw_neighbor())
|
|
{
|
|
// if the previous position m_adaptor_circulator
|
|
// is m_center's last clockwise neighbor
|
|
if (m_center->last_cw_neighbor() == m_adaptor_circulator)
|
|
{
|
|
// Skip the outer part of the seam
|
|
while (m_center->first_cw_neighbor() != m_adaptor_circulator)
|
|
m_adaptor_circulator++;
|
|
}
|
|
else // if the previous position is inner,
|
|
{ // simply rotate the adaptor circulator
|
|
m_adaptor_circulator++;
|
|
}
|
|
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Special case: m_center is the extremity of the seam.
|
|
// Its seam adaptor neighbor vertex is "virtually" duplicated.
|
|
assert(m_center->last_cw_neighbor() == m_center->first_cw_neighbor());
|
|
|
|
// If the previous position is the last "virtual" clockwise neighbor,
|
|
// move to first "virtual" clockwise neighbor
|
|
// without rotating m_adaptor_circulator.
|
|
if (m_center->last_cw_neighbor() == m_adaptor_circulator
|
|
&& (*this)->first_cw_neighbor() == m_center->vertex())
|
|
{
|
|
// Update directly the inherited vertex handle
|
|
// because this case is ambiguous for update_inherited_handle()
|
|
Vertex_c_handle current_decorated_vertex((*this)->vertex(),
|
|
(*this)->first_cw_neighbor(), // order...
|
|
(*this)->last_cw_neighbor()); // ...inverted!
|
|
//#ifdef DEBUG_TRACE
|
|
// std::cerr << " Mesh_patch_vertex_around_vertex_cir = (";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ",";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(current_decorated_vertex);
|
|
// std::cerr << ")\n";
|
|
//#endif
|
|
assert(m_mesh_patch->is_valid(current_decorated_vertex));
|
|
Base::operator=(current_decorated_vertex);
|
|
|
|
return *this;
|
|
}
|
|
|
|
// If the previous position is NOT the last "virtual" clockwise neighbor,
|
|
// simply rotate the adaptor circulator
|
|
m_adaptor_circulator++;
|
|
|
|
// Update the inherited vertex handle
|
|
//
|
|
// If the new position is the last "virtual" clockwise neighbor,
|
|
// update directly the inherited vertex handle
|
|
// because this case is ambiguous for update_inherited_handle()
|
|
if (m_center->last_cw_neighbor() == m_adaptor_circulator)
|
|
{
|
|
Vertex_c_handle current_decorated_vertex
|
|
= m_mesh_patch->get_decorated_border_vertex(m_adaptor_circulator,
|
|
NULL,
|
|
m_center->vertex());
|
|
//#ifdef DEBUG_TRACE
|
|
// std::cerr << " Mesh_patch_vertex_around_vertex_cir = (";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ",";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(current_decorated_vertex);
|
|
// std::cerr << ")\n";
|
|
//#endif
|
|
assert(m_mesh_patch->is_valid(current_decorated_vertex));
|
|
Base::operator=(current_decorated_vertex);
|
|
|
|
return *this;
|
|
}
|
|
else
|
|
{
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
|
|
}
|
|
Self operator++(int) {
|
|
Self tmp = *this;
|
|
++*this;
|
|
return tmp;
|
|
}
|
|
|
|
/// OPERATIONS Bidirectional Category
|
|
/// ---------------------------------
|
|
|
|
/// Counter-clockwise rotation
|
|
Self& operator--()
|
|
{
|
|
//#ifdef DEBUG_TRACE
|
|
// std::cerr << " Mesh_patch_vertex_around_vertex_cir --\n";
|
|
//#endif
|
|
|
|
// Check that the inherited vertex handle is valid
|
|
assert((*this)->vertex() == m_adaptor_circulator);
|
|
|
|
// If m_center is an inner vertex, m_adaptor_circulator
|
|
// already circulates over m_center's vertices
|
|
if (m_center->first_cw_neighbor() == NULL)
|
|
{
|
|
m_adaptor_circulator--;
|
|
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
|
|
// If m_center is a border/seam vertex (except a seam extremity),
|
|
// *this must circulate only from
|
|
// last_cw_neighbor() to first_cw_neighbor() (included)
|
|
if (m_center->last_cw_neighbor() != m_center->first_cw_neighbor())
|
|
{
|
|
// if the previous position m_adaptor_circulator
|
|
// is m_center's last counter-clockwise neighbor
|
|
if (m_center->first_cw_neighbor() == m_adaptor_circulator)
|
|
{
|
|
// Skip the outer part of the seam
|
|
while (m_center->last_cw_neighbor() != m_adaptor_circulator)
|
|
m_adaptor_circulator--;
|
|
}
|
|
else // if the previous position is inner,
|
|
{ // simply rotate the adaptor circulator
|
|
m_adaptor_circulator--;
|
|
}
|
|
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
|
|
// Special case: m_center is the extremity of the seam.
|
|
// Its seam adaptor neighbor vertex is "virtually" duplicated.
|
|
assert(m_center->last_cw_neighbor() == m_center->first_cw_neighbor());
|
|
|
|
// If the previous position is on the last "virtual" counter-clockwise
|
|
// neighbor, move to first "virtual" counter-clockwise neighbor
|
|
// without rotating m_adaptor_circulator.
|
|
if (m_center->last_cw_neighbor() == m_adaptor_circulator
|
|
&& (*this)->last_cw_neighbor() == m_center->vertex())
|
|
{
|
|
// Update directly the inherited vertex handle
|
|
// because this case is ambiguous for update_inherited_handle()
|
|
Vertex_c_handle current_decorated_vertex((*this)->vertex(),
|
|
(*this)->first_cw_neighbor(), // order...
|
|
(*this)->last_cw_neighbor()); // ...inverted!
|
|
//#ifdef DEBUG_TRACE
|
|
// std::cerr << " Mesh_patch_vertex_around_vertex_cir = (";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ",";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(current_decorated_vertex);
|
|
// std::cerr << ")\n";
|
|
//#endif
|
|
assert(m_mesh_patch->is_valid(current_decorated_vertex));
|
|
Base::operator=(current_decorated_vertex);
|
|
|
|
return *this;
|
|
}
|
|
|
|
// If the previous position is NOT the last "virtual" counter-clockwise
|
|
// neighbor, simply rotate the adaptor circulator
|
|
m_adaptor_circulator--;
|
|
|
|
// Update the inherited vertex handle
|
|
//
|
|
// If the new position is the last "virtual" counter-clockwise neighbor,
|
|
// update directly the inherited vertex handle
|
|
// because this case is ambiguous for update_inherited_handle()
|
|
if (m_center->last_cw_neighbor() == m_adaptor_circulator)
|
|
{
|
|
Vertex_c_handle current_decorated_vertex
|
|
= m_mesh_patch->get_decorated_border_vertex(m_adaptor_circulator,
|
|
m_center->vertex(),
|
|
NULL);
|
|
//#ifdef DEBUG_TRACE
|
|
// std::cerr << " Mesh_patch_vertex_around_vertex_cir = (";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ",";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(current_decorated_vertex);
|
|
// std::cerr << ")\n";
|
|
//#endif
|
|
assert(m_mesh_patch->is_valid(current_decorated_vertex));
|
|
Base::operator=(current_decorated_vertex);
|
|
|
|
return *this;
|
|
}
|
|
else
|
|
{
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
|
|
}
|
|
Self operator--(int) {
|
|
Self tmp = *this;
|
|
--*this;
|
|
return tmp;
|
|
}
|
|
|
|
private:
|
|
/// Update the inherited vertex handle
|
|
///
|
|
/// Precondition: m_adaptor_circulator and m_center are valid
|
|
void update_inherited_handle()
|
|
{
|
|
Vertex_c_handle current_decorated_vertex = NULL;
|
|
|
|
// Easy case: if m_adaptor_circulator is an inner vertex
|
|
if (m_mesh_patch->m_mesh_adaptor->get_vertex_seaming(
|
|
m_adaptor_circulator) != Mesh_patch::BORDER)
|
|
{
|
|
// No extra information needed if inner vertex
|
|
current_decorated_vertex = Vertex_c_handle(m_adaptor_circulator);
|
|
}
|
|
else // if seam vertex
|
|
{
|
|
// Ambiguous case: m_center is the extremity of the seam
|
|
// and m_adaptor_circulator is on the seam
|
|
assert(m_center->last_cw_neighbor() != m_adaptor_circulator
|
|
|| m_center->first_cw_neighbor() != m_adaptor_circulator);
|
|
|
|
// Get next vertex on facet
|
|
Adaptor_vertex_c_handle next_vertex = NULL;
|
|
Adaptor_vertex_around_vertex_c_cir ccw_neighbor = m_adaptor_circulator;
|
|
ccw_neighbor--;
|
|
if (m_center->first_cw_neighbor() == NULL) // if inner vertex
|
|
{
|
|
next_vertex = ccw_neighbor;
|
|
}
|
|
else // if border/seam vertex, circulates only from
|
|
{ // first_cw_neighbor() to last_cw_neighbor() (included)
|
|
if (m_center->first_cw_neighbor() == m_adaptor_circulator)
|
|
next_vertex = m_center->vertex();
|
|
else
|
|
next_vertex = ccw_neighbor;
|
|
}
|
|
|
|
// If (m_adaptor_circulator, next_vertex) isn't a seam (non-oriented) edge
|
|
if (m_mesh_patch->m_mesh_adaptor->get_halfedge_seaming(
|
|
m_adaptor_circulator, next_vertex) != Mesh_patch::BORDER
|
|
|| m_mesh_patch->m_mesh_adaptor->get_halfedge_seaming(
|
|
next_vertex, m_adaptor_circulator) != Mesh_patch::BORDER)
|
|
{
|
|
current_decorated_vertex
|
|
= m_mesh_patch->get_decorated_inner_vertex(m_adaptor_circulator,
|
|
next_vertex);
|
|
}
|
|
// Special case: both vertices belong to the seam
|
|
else
|
|
{
|
|
current_decorated_vertex
|
|
= m_mesh_patch->get_decorated_border_vertex(m_adaptor_circulator,
|
|
next_vertex,
|
|
NULL);
|
|
}
|
|
}
|
|
|
|
//#ifdef DEBUG_TRACE
|
|
// std::cerr << " Mesh_patch_vertex_around_vertex_cir = (";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(m_center) << ",";
|
|
// std::cerr << "#" << m_mesh_patch->get_vertex_index(current_decorated_vertex);
|
|
// std::cerr << ")\n";
|
|
//#endif
|
|
|
|
// Update the inherited vertex handle
|
|
assert(m_mesh_patch->is_valid(current_decorated_vertex));
|
|
Base::operator=(current_decorated_vertex);
|
|
}
|
|
|
|
private:
|
|
/// The mesh that we are circulating on:
|
|
Mesh_patch_c_ptr m_mesh_patch;
|
|
|
|
/// Vertex center of the circulation (+ circulator range for a border vertex)
|
|
Vertex_c_handle m_center;
|
|
|
|
/// Internal circulator
|
|
Adaptor_vertex_around_vertex_c_cir m_adaptor_circulator;
|
|
|
|
}; // Mesh_patch_vertex_around_vertex_cir
|
|
|
|
|
|
/// Class Mesh_patch_vertex_around_facet_cir
|
|
/// represents a (clockwise) circulator around a facet
|
|
/// of a Parameterization_mesh_patch_3<ParameterizationPatchableMesh_3> mesh
|
|
|
|
template<class MeshPatchPtrType, ///< = [const] Parameterization_mesh_patch_3*
|
|
class VertexHandleType, ///< = Parameterization_mesh_patch_3::Vertex_[const_]handle
|
|
class AdaptorVertexAroundFacetCirculatorType>
|
|
///< = Adaptor::Vertex_around_facet_[const_]circulator
|
|
class Mesh_patch_vertex_around_facet_cir
|
|
: public VertexHandleType
|
|
{
|
|
// PRIVATE TYPES
|
|
// -------------
|
|
|
|
/// Base and self classes
|
|
typedef VertexHandleType Base;
|
|
typedef Mesh_patch_vertex_around_facet_cir Self;
|
|
|
|
/// Mesh_patch types
|
|
typedef typename std::iterator_traits<MeshPatchPtrType>::value_type
|
|
Mesh_patch;
|
|
typedef typename Mesh_patch::Adaptor Adaptor;
|
|
|
|
public:
|
|
|
|
// PUBLIC TYPES
|
|
// ------------
|
|
|
|
// Export template parameter types
|
|
typedef MeshPatchPtrType Mesh_patch_c_ptr;
|
|
typedef VertexHandleType Vertex_c_handle;
|
|
typedef AdaptorVertexAroundFacetCirculatorType
|
|
Adaptor_vertex_around_facet_c_cir;
|
|
|
|
// Iterator types
|
|
typedef typename Adaptor_vertex_around_facet_c_cir::iterator_category
|
|
iterator_category;
|
|
typedef typename Vertex_c_handle::value_type value_type;
|
|
typedef std::ptrdiff_t difference_type;
|
|
typedef std::size_t size_type;
|
|
typedef typename Vertex_c_handle::reference reference;
|
|
typedef typename Vertex_c_handle::pointer pointer;
|
|
|
|
/// CREATION
|
|
/// --------
|
|
|
|
/// Circulator pointing to NULL
|
|
Mesh_patch_vertex_around_facet_cir() {}
|
|
|
|
Mesh_patch_vertex_around_facet_cir(Mesh_patch_c_ptr mesh,
|
|
Adaptor_vertex_around_facet_c_cir adaptor_circulator)
|
|
: m_mesh_patch(mesh),
|
|
m_adaptor_circulator(adaptor_circulator)
|
|
{
|
|
CGAL_parameterization_assertion(m_mesh_patch != NULL);
|
|
CGAL_parameterization_assertion(adaptor_circulator != NULL);
|
|
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
}
|
|
|
|
/// Copy constructor
|
|
Mesh_patch_vertex_around_facet_cir(const Self& cir)
|
|
: Base(cir),
|
|
m_mesh_patch(cir.m_mesh_patch),
|
|
m_adaptor_circulator(cir.m_adaptor_circulator)
|
|
{
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
}
|
|
|
|
/// operator =()
|
|
Self& operator =(const Self& cir)
|
|
{
|
|
Base::operator=(cir);
|
|
m_mesh_patch = cir.m_mesh_patch;
|
|
m_adaptor_circulator = cir.m_adaptor_circulator;
|
|
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
|
|
/// OPERATIONS Forward Category
|
|
/// ---------------------------
|
|
|
|
bool operator==(CGAL_NULL_TYPE ptr) const { return Base::operator==(ptr); }
|
|
bool operator!=(CGAL_NULL_TYPE ptr) const { return !(*this == ptr); }
|
|
bool operator==(const Self& cir) const { return Base::operator==(cir); }
|
|
bool operator!=(const Self& cir) const { return !(*this == cir); }
|
|
|
|
/// operator*() and operator->() are inherited
|
|
|
|
/// Clockwise rotation
|
|
Self& operator++()
|
|
{
|
|
// Increment m_adaptor_circulator
|
|
m_adaptor_circulator++;
|
|
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
Self operator++(int) {
|
|
Self tmp = *this;
|
|
++*this;
|
|
return tmp;
|
|
}
|
|
|
|
/// OPERATIONS Bidirectional Category
|
|
/// ---------------------------------
|
|
|
|
/// Counterclockwise rotation
|
|
Self& operator--()
|
|
{
|
|
// Decrement m_adaptor_circulator
|
|
m_adaptor_circulator--;
|
|
|
|
// Update the inherited vertex handle
|
|
update_inherited_handle();
|
|
|
|
return *this;
|
|
}
|
|
Self operator--(int) {
|
|
Self tmp = *this;
|
|
--*this;
|
|
return tmp;
|
|
}
|
|
|
|
private:
|
|
/// Update the inherited vertex handle
|
|
///
|
|
/// Precondition: m_adaptor_circulator is valid
|
|
void update_inherited_handle()
|
|
{
|
|
Vertex_c_handle current_decorated_vertex = NULL;
|
|
|
|
// Get next vertex on facet
|
|
Adaptor_vertex_around_facet_c_cir next_vertex = m_adaptor_circulator;
|
|
next_vertex++;
|
|
|
|
// If (m_adaptor_circulator, next_vertex) isn't a seam (non-oriented) edge
|
|
if (m_mesh_patch->m_mesh_adaptor->get_halfedge_seaming(
|
|
m_adaptor_circulator, next_vertex) != Mesh_patch::BORDER
|
|
|| m_mesh_patch->m_mesh_adaptor->get_halfedge_seaming(
|
|
next_vertex, m_adaptor_circulator) != Mesh_patch::BORDER)
|
|
{
|
|
current_decorated_vertex
|
|
= m_mesh_patch->get_decorated_inner_vertex(m_adaptor_circulator,
|
|
next_vertex);
|
|
}
|
|
// Special case: both vertices belong to the seam
|
|
else
|
|
{
|
|
current_decorated_vertex
|
|
= m_mesh_patch->get_decorated_border_vertex(m_adaptor_circulator,
|
|
next_vertex,
|
|
NULL);
|
|
}
|
|
|
|
// Update the inherited vertex handle
|
|
assert(m_mesh_patch->is_valid(current_decorated_vertex));
|
|
Base::operator=(current_decorated_vertex);
|
|
}
|
|
|
|
private:
|
|
/// The mesh that we are circulating on:
|
|
Mesh_patch_c_ptr m_mesh_patch;
|
|
|
|
/// Internal circulator
|
|
Adaptor_vertex_around_facet_c_cir m_adaptor_circulator;
|
|
|
|
}; // Mesh_patch_vertex_around_facet_cir
|
|
|
|
|
|
CGAL_END_NAMESPACE
|
|
|
|
#endif //CGAL_PARAM_MESH_PATCH_CIRCULATORS_H
|
|
|