Merge branch 'master' into compile-time-connectivity-type

This commit is contained in:
Jan Möbius
2018-05-30 10:59:40 +02:00
149 changed files with 2217 additions and 10039 deletions

View File

@@ -37,146 +37,145 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
* *
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#include <OpenMesh/Core/Mesh/ArrayKernel.hh>
namespace OpenMesh
{
ArrayKernel::ArrayKernel()
: refcount_vstatus_(0), refcount_hstatus_(0),
refcount_estatus_(0), refcount_fstatus_(0)
{
init_bit_masks(); //Status bit masks initialization
}
ArrayKernel::~ArrayKernel()
{
clear();
}
// ArrayKernel::ArrayKernel(const ArrayKernel& _rhs)
// : BaseKernel(_rhs),
// vertices_(_rhs.vertices_), edges_(_rhs.edges_), faces_(_rhs.faces_),
// vertex_status_(_rhs.vertex_status_), halfedge_status_(_rhs.halfedge_status_),
// edge_status_(_rhs.edge_status_), face_status_(_rhs.face_status_),
// refcount_vstatus_(_rhs.refcount_vstatus_), refcount_hstatus_(_rhs.refcount_hstatus_),
// refcount_estatus_(_rhs.refcount_estatus_), refcount_fstatus_(_rhs.refcount_fstatus_)
// {}
void ArrayKernel::assign_connectivity(const ArrayKernel& _other)
{
vertices_ = _other.vertices_;
edges_ = _other.edges_;
faces_ = _other.faces_;
vprops_resize(n_vertices());
hprops_resize(n_halfedges());
eprops_resize(n_edges());
fprops_resize(n_faces());
#define COPY_STATUS_PROPERTY(ENTITY) \
if (_other.ENTITY##_status_.is_valid()) \
{ \
if (!ENTITY##_status_.is_valid()) \
{ \
request_##ENTITY##_status(); \
} \
property(ENTITY##_status_) = _other.property(_other.ENTITY##_status_); \
}
COPY_STATUS_PROPERTY(vertex)
COPY_STATUS_PROPERTY(halfedge)
COPY_STATUS_PROPERTY(edge)
COPY_STATUS_PROPERTY(face)
#undef COPY_STATUS_PROPERTY
}
// --- handle -> item ---
VertexHandle ArrayKernel::handle(const Vertex& _v) const
{
return VertexHandle( int( &_v - &vertices_.front()));
}
HalfedgeHandle ArrayKernel::handle(const Halfedge& _he) const
{
// Calculate edge belonging to given halfedge
// There are two halfedges stored per edge
// Get memory position inside edge vector and devide by size of an edge
// to get the corresponding edge for the requested halfedge
size_t eh = ( (char*)&_he - (char*)&edges_.front() ) / sizeof(Edge) ;
assert((&_he == &edges_[eh].halfedges_[0]) ||
(&_he == &edges_[eh].halfedges_[1]));
return ((&_he == &edges_[eh].halfedges_[0]) ?
HalfedgeHandle( int(eh)<<1) : HalfedgeHandle((int(eh)<<1)+1));
}
EdgeHandle ArrayKernel::handle(const Edge& _e) const
{
return EdgeHandle( int(&_e - &edges_.front() ) );
}
FaceHandle ArrayKernel::handle(const Face& _f) const
{
return FaceHandle( int(&_f - &faces_.front()) );
}
#define SIGNED(x) signed( (x) )
bool ArrayKernel::is_valid_handle(VertexHandle _vh) const
{
return 0 <= _vh.idx() && _vh.idx() < SIGNED(n_vertices());
}
bool ArrayKernel::is_valid_handle(HalfedgeHandle _heh) const
{
return 0 <= _heh.idx() && _heh.idx() < SIGNED(n_edges()*2);
}
bool ArrayKernel::is_valid_handle(EdgeHandle _eh) const
{
return 0 <= _eh.idx() && _eh.idx() < SIGNED(n_edges());
}
bool ArrayKernel::is_valid_handle(FaceHandle _fh) const
{
return 0 <= _fh.idx() && _fh.idx() < SIGNED(n_faces());
}
#undef SIGNED
unsigned int ArrayKernel::delete_isolated_vertices()
{
assert(has_vertex_status());//this function requires vertex status property
unsigned int n_isolated = 0;
for (KernelVertexIter v_it = vertices_begin(); v_it != vertices_end(); ++v_it)
{
if (is_isolated(handle(*v_it)))
{
status(handle(*v_it)).set_deleted(true);
n_isolated++;
}
}
return n_isolated;
}
void ArrayKernel::garbage_collection(bool _v, bool _e, bool _f)
{
std::vector<VertexHandle*> empty_vh;
std::vector<HalfedgeHandle*> empty_hh;
std::vector<FaceHandle*> empty_fh;
garbage_collection( empty_vh,empty_hh,empty_fh,_v, _e, _f);
}
* ========================================================================= */
/*===========================================================================*\
* *
* $Revision$ *
* $Date$ *
* *
\*===========================================================================*/
#include <OpenMesh/Core/Mesh/ArrayKernel.hh>
namespace OpenMesh
{
ArrayKernel::ArrayKernel()
: refcount_vstatus_(0), refcount_hstatus_(0),
refcount_estatus_(0), refcount_fstatus_(0)
{
init_bit_masks(); //Status bit masks initialization
}
ArrayKernel::~ArrayKernel()
{
clear();
}
// ArrayKernel::ArrayKernel(const ArrayKernel& _rhs)
// : BaseKernel(_rhs),
// vertices_(_rhs.vertices_), edges_(_rhs.edges_), faces_(_rhs.faces_),
// vertex_status_(_rhs.vertex_status_), halfedge_status_(_rhs.halfedge_status_),
// edge_status_(_rhs.edge_status_), face_status_(_rhs.face_status_),
// refcount_vstatus_(_rhs.refcount_vstatus_), refcount_hstatus_(_rhs.refcount_hstatus_),
// refcount_estatus_(_rhs.refcount_estatus_), refcount_fstatus_(_rhs.refcount_fstatus_)
// {}
void ArrayKernel::assign_connectivity(const ArrayKernel& _other)
{
vertices_ = _other.vertices_;
edges_ = _other.edges_;
faces_ = _other.faces_;
vprops_resize(n_vertices());
hprops_resize(n_halfedges());
eprops_resize(n_edges());
fprops_resize(n_faces());
//just copy status properties for now,
//until a proper solution for refcounted
//properties is available
vertex_status_ = _other.vertex_status_;
halfedge_status_ = _other.halfedge_status_;
edge_status_ = _other.edge_status_;
face_status_ = _other.face_status_;
//initialize refcounter to 1 for the new mesh,
//if status is available.
refcount_estatus_ = _other.refcount_estatus_ > 0 ? 1 : 0;
refcount_vstatus_ = _other.refcount_vstatus_ > 0 ? 1 : 0;
refcount_hstatus_ = _other.refcount_hstatus_ > 0 ? 1 : 0;
refcount_fstatus_ = _other.refcount_fstatus_ > 0 ? 1 : 0;
}
// --- handle -> item ---
VertexHandle ArrayKernel::handle(const Vertex& _v) const
{
return VertexHandle( int( &_v - &vertices_.front()));
}
HalfedgeHandle ArrayKernel::handle(const Halfedge& _he) const
{
// Calculate edge belonging to given halfedge
// There are two halfedges stored per edge
// Get memory position inside edge vector and devide by size of an edge
// to get the corresponding edge for the requested halfedge
size_t eh = ( (char*)&_he - (char*)&edges_.front() ) / sizeof(Edge) ;
assert((&_he == &edges_[eh].halfedges_[0]) ||
(&_he == &edges_[eh].halfedges_[1]));
return ((&_he == &edges_[eh].halfedges_[0]) ?
HalfedgeHandle( int(eh)<<1) : HalfedgeHandle((int(eh)<<1)+1));
}
EdgeHandle ArrayKernel::handle(const Edge& _e) const
{
return EdgeHandle( int(&_e - &edges_.front() ) );
}
FaceHandle ArrayKernel::handle(const Face& _f) const
{
return FaceHandle( int(&_f - &faces_.front()) );
}
#define SIGNED(x) signed( (x) )
bool ArrayKernel::is_valid_handle(VertexHandle _vh) const
{
return 0 <= _vh.idx() && _vh.idx() < SIGNED(n_vertices());
}
bool ArrayKernel::is_valid_handle(HalfedgeHandle _heh) const
{
return 0 <= _heh.idx() && _heh.idx() < SIGNED(n_edges()*2);
}
bool ArrayKernel::is_valid_handle(EdgeHandle _eh) const
{
return 0 <= _eh.idx() && _eh.idx() < SIGNED(n_edges());
}
bool ArrayKernel::is_valid_handle(FaceHandle _fh) const
{
return 0 <= _fh.idx() && _fh.idx() < SIGNED(n_faces());
}
#undef SIGNED
unsigned int ArrayKernel::delete_isolated_vertices()
{
assert(has_vertex_status());//this function requires vertex status property
unsigned int n_isolated = 0;
for (KernelVertexIter v_it = vertices_begin(); v_it != vertices_end(); ++v_it)
{
if (is_isolated(handle(*v_it)))
{
status(handle(*v_it)).set_deleted(true);
n_isolated++;
}
}
return n_isolated;
}
void ArrayKernel::garbage_collection(bool _v, bool _e, bool _f)
{
std::vector<VertexHandle*> empty_vh;
std::vector<HalfedgeHandle*> empty_hh;
std::vector<FaceHandle*> empty_fh;
garbage_collection( empty_vh,empty_hh,empty_fh,_v, _e, _f);
}
void ArrayKernel::clean_keep_reservation()
{
vertices_.clear();
@@ -187,74 +186,74 @@ void ArrayKernel::clean_keep_reservation()
}
void ArrayKernel::clean()
{
vertices_.clear();
VertexContainer().swap( vertices_ );
edges_.clear();
EdgeContainer().swap( edges_ );
faces_.clear();
FaceContainer().swap( faces_ );
}
void ArrayKernel::clear()
{
vprops_clear();
eprops_clear();
hprops_clear();
fprops_clear();
clean();
}
void ArrayKernel::resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces )
{
vertices_.resize(_n_vertices);
edges_.resize(_n_edges);
faces_.resize(_n_faces);
vprops_resize(n_vertices());
hprops_resize(n_halfedges());
eprops_resize(n_edges());
fprops_resize(n_faces());
}
void ArrayKernel::reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces )
{
vertices_.reserve(_n_vertices);
edges_.reserve(_n_edges);
faces_.reserve(_n_faces);
vprops_reserve(_n_vertices);
hprops_reserve(_n_edges*2);
eprops_reserve(_n_edges);
fprops_reserve(_n_faces);
}
// Status Sets API
void ArrayKernel::init_bit_masks(BitMaskContainer& _bmc)
{
for (unsigned int i = Attributes::UNUSED; i != 0; i <<= 1)
{
_bmc.push_back(i);
}
}
void ArrayKernel::init_bit_masks()
{
init_bit_masks(vertex_bit_masks_);
edge_bit_masks_ = vertex_bit_masks_;//init_bit_masks(edge_bit_masks_);
face_bit_masks_ = vertex_bit_masks_;//init_bit_masks(face_bit_masks_);
halfedge_bit_masks_= vertex_bit_masks_;//init_bit_masks(halfedge_bit_masks_);
}
};
void ArrayKernel::clean()
{
vertices_.clear();
VertexContainer().swap( vertices_ );
edges_.clear();
EdgeContainer().swap( edges_ );
faces_.clear();
FaceContainer().swap( faces_ );
}
void ArrayKernel::clear()
{
vprops_clear();
eprops_clear();
hprops_clear();
fprops_clear();
clean();
}
void ArrayKernel::resize( size_t _n_vertices, size_t _n_edges, size_t _n_faces )
{
vertices_.resize(_n_vertices);
edges_.resize(_n_edges);
faces_.resize(_n_faces);
vprops_resize(n_vertices());
hprops_resize(n_halfedges());
eprops_resize(n_edges());
fprops_resize(n_faces());
}
void ArrayKernel::reserve(size_t _n_vertices, size_t _n_edges, size_t _n_faces )
{
vertices_.reserve(_n_vertices);
edges_.reserve(_n_edges);
faces_.reserve(_n_faces);
vprops_reserve(_n_vertices);
hprops_reserve(_n_edges*2);
eprops_reserve(_n_edges);
fprops_reserve(_n_faces);
}
// Status Sets API
void ArrayKernel::init_bit_masks(BitMaskContainer& _bmc)
{
for (unsigned int i = Attributes::UNUSED; i != 0; i <<= 1)
{
_bmc.push_back(i);
}
}
void ArrayKernel::init_bit_masks()
{
init_bit_masks(vertex_bit_masks_);
edge_bit_masks_ = vertex_bit_masks_;//init_bit_masks(edge_bit_masks_);
face_bit_masks_ = vertex_bit_masks_;//init_bit_masks(face_bit_masks_);
halfedge_bit_masks_= vertex_bit_masks_;//init_bit_masks(halfedge_bit_masks_);
}
};

View File

@@ -879,10 +879,7 @@ private:
void init_bit_masks(BitMaskContainer& _bmc);
void init_bit_masks();
private:
VertexContainer vertices_;
EdgeContainer edges_;
FaceContainer faces_;
protected:
VertexStatusPropertyHandle vertex_status_;
HalfedgeStatusPropertyHandle halfedge_status_;
@@ -894,6 +891,11 @@ private:
unsigned int refcount_estatus_;
unsigned int refcount_fstatus_;
private:
VertexContainer vertices_;
EdgeContainer edges_;
FaceContainer faces_;
BitMaskContainer halfedge_bit_masks_;
BitMaskContainer edge_bit_masks_;
BitMaskContainer vertex_bit_masks_;

View File

@@ -744,48 +744,34 @@ private:
{
//mesh has no points?
}
if(this->get_property_handle(vertex_normals_,
"v:normals"))
refcount_vnormals_ = 1;
if(this->get_property_handle(vertex_colors_,
"v:colors"))
refcount_vcolors_ = 1;
if(this->get_property_handle(vertex_texcoords1D_,
"v:texcoords1D"))
refcount_vtexcoords1D_ = 1;
if(this->get_property_handle(vertex_texcoords2D_,
"v:texcoords2D"))
refcount_vtexcoords2D_ = 1;
if(this->get_property_handle(vertex_texcoords3D_,
"v:texcoords3D"))
refcount_vtexcoords3D_ = 1;
if(this->get_property_handle(halfedge_texcoords1D_,
"h:texcoords1D"))
refcount_htexcoords1D_ = 1;
if(this->get_property_handle(halfedge_texcoords2D_,
"h:texcoords2D"))
refcount_htexcoords2D_ = 1;
if(this->get_property_handle(halfedge_texcoords3D_,
"h:texcoords3D"))
refcount_htexcoords3D_ = 1;
if(this->get_property_handle(halfedge_normals_,
"h:normals"))
refcount_henormals_ = 1;
if(this->get_property_handle(halfedge_colors_,
"h:colors"))
refcount_hecolors_ = 1;
if(this->get_property_handle(edge_colors_,
"e:colors"))
refcount_ecolors_ = 1;
if(this->get_property_handle(face_normals_,
"f:normals"))
refcount_fnormals_ = 1;
if(this->get_property_handle(face_colors_,
"f:colors"))
refcount_fcolors_ = 1;
if(this->get_property_handle(face_texture_index_,
"f:textureindex"))
refcount_ftextureIndex_ = 1;
refcount_vnormals_ = this->get_property_handle(vertex_normals_,
"v:normals") ? 1 : 0 ;
refcount_vcolors_ = this->get_property_handle(vertex_colors_,
"v:colors") ? 1 : 0 ;
refcount_vtexcoords1D_ = this->get_property_handle(vertex_texcoords1D_,
"v:texcoords1D") ? 1 : 0 ;
refcount_vtexcoords2D_ = this->get_property_handle(vertex_texcoords2D_,
"v:texcoords2D") ? 1 : 0 ;
refcount_vtexcoords3D_ = this->get_property_handle(vertex_texcoords3D_,
"v:texcoords3D") ? 1 : 0 ;
refcount_htexcoords1D_ = this->get_property_handle(halfedge_texcoords1D_,
"h:texcoords1D") ? 1 : 0 ;
refcount_htexcoords2D_ = this->get_property_handle(halfedge_texcoords2D_,
"h:texcoords2D") ? 1 : 0 ;
refcount_htexcoords3D_ = this->get_property_handle(halfedge_texcoords3D_,
"h:texcoords3D") ? 1 : 0 ;
refcount_henormals_ = this->get_property_handle(halfedge_normals_,
"h:normals") ? 1 : 0 ;
refcount_hecolors_ = this->get_property_handle(halfedge_colors_,
"h:colors") ? 1 : 0 ;
refcount_ecolors_ = this->get_property_handle(edge_colors_,
"e:colors") ? 1 : 0 ;
refcount_fnormals_ = this->get_property_handle(face_normals_,
"f:normals") ? 1 : 0 ;
refcount_fcolors_ = this->get_property_handle(face_colors_,
"f:colors") ? 1 : 0 ;
refcount_ftextureIndex_ = this->get_property_handle(face_texture_index_,
"f:textureindex") ? 1 : 0 ;
}
};

View File

@@ -165,8 +165,9 @@ namespace std {
template <>
struct hash<OpenMesh::BaseHandle >
: public std::unary_function<OpenMesh::BaseHandle, std::size_t>
{
typedef OpenMesh::BaseHandle argument_type;
typedef std::size_t result_type;
std::size_t operator()(const OpenMesh::BaseHandle& h) const
{
@@ -176,8 +177,9 @@ struct hash<OpenMesh::BaseHandle >
template <>
struct hash<OpenMesh::VertexHandle >
: public std::unary_function<OpenMesh::VertexHandle, std::size_t>
{
typedef OpenMesh::VertexHandle argument_type;
typedef std::size_t result_type;
std::size_t operator()(const OpenMesh::VertexHandle& h) const
{
@@ -187,9 +189,11 @@ struct hash<OpenMesh::VertexHandle >
template <>
struct hash<OpenMesh::HalfedgeHandle >
: public std::unary_function<OpenMesh::HalfedgeHandle, std::size_t>
{
typedef OpenMesh::HalfedgeHandle argument_type;
typedef std::size_t result_type;
std::size_t operator()(const OpenMesh::HalfedgeHandle& h) const
{
return h.idx();
@@ -198,9 +202,11 @@ struct hash<OpenMesh::HalfedgeHandle >
template <>
struct hash<OpenMesh::EdgeHandle >
: public std::unary_function<OpenMesh::EdgeHandle, std::size_t>
{
typedef OpenMesh::EdgeHandle argument_type;
typedef std::size_t result_type;
std::size_t operator()(const OpenMesh::EdgeHandle& h) const
{
return h.idx();
@@ -209,9 +215,11 @@ struct hash<OpenMesh::EdgeHandle >
template <>
struct hash<OpenMesh::FaceHandle >
: public std::unary_function<OpenMesh::FaceHandle, std::size_t>
{
typedef OpenMesh::FaceHandle argument_type;
typedef std::size_t result_type;
std::size_t operator()(const OpenMesh::FaceHandle& h) const
{
return h.idx();

View File

@@ -109,9 +109,6 @@ class GenericIteratorT {
: mesh_(&_mesh), hnd_(_hnd), skip_bits_(0)
{
if (_skip) enable_skipping();
// Set vertex handle invalid if the mesh contains no vertex
if((mesh_->*PrimitiveCountMember)() == 0) hnd_ = value_handle(-1);
}
/// Standard dereferencing operator.

View File

@@ -777,6 +777,11 @@ void PolyConnectivity::collapse_edge(HalfedgeHandle _hh)
// delete stuff
status(edge_handle(h)).set_deleted(true);
status(vo).set_deleted(true);
if (has_halfedge_status())
{
status(h).set_deleted(true);
status(o).set_deleted(true);
}
}
//-----------------------------------------------------------------------------
@@ -827,6 +832,11 @@ void PolyConnectivity::collapse_loop(HalfedgeHandle _hh)
status(fh).set_deleted(true);
}
status(edge_handle(h0)).set_deleted(true);
if (has_halfedge_status())
{
status(h0).set_deleted(true);
status(o0).set_deleted(true);
}
}
//-----------------------------------------------------------------------------

View File

@@ -1138,45 +1138,89 @@ public:
PolyConnectivity::ConstVertexIter,
&PolyConnectivity::vertices_begin,
&PolyConnectivity::vertices_end> ConstVertexRange;
typedef EntityRange<
const PolyConnectivity,
PolyConnectivity::ConstVertexIter,
&PolyConnectivity::vertices_sbegin,
&PolyConnectivity::vertices_end> ConstVertexRangeSkipping;
typedef EntityRange<
const PolyConnectivity,
PolyConnectivity::ConstHalfedgeIter,
&PolyConnectivity::halfedges_begin,
&PolyConnectivity::halfedges_end> ConstHalfedgeRange;
typedef EntityRange<
const PolyConnectivity,
PolyConnectivity::ConstHalfedgeIter,
&PolyConnectivity::halfedges_sbegin,
&PolyConnectivity::halfedges_end> ConstHalfedgeRangeSkipping;
typedef EntityRange<
const PolyConnectivity,
PolyConnectivity::ConstEdgeIter,
&PolyConnectivity::edges_begin,
&PolyConnectivity::edges_end> ConstEdgeRange;
typedef EntityRange<
const PolyConnectivity,
PolyConnectivity::ConstEdgeIter,
&PolyConnectivity::edges_sbegin,
&PolyConnectivity::edges_end> ConstEdgeRangeSkipping;
typedef EntityRange<
const PolyConnectivity,
PolyConnectivity::ConstFaceIter,
&PolyConnectivity::faces_begin,
&PolyConnectivity::faces_end> ConstFaceRange;
typedef EntityRange<
const PolyConnectivity,
PolyConnectivity::ConstFaceIter,
&PolyConnectivity::faces_sbegin,
&PolyConnectivity::faces_end> ConstFaceRangeSkipping;
/**
* @return The vertices as a range object suitable
* for C++11 range based for loops.
* for C++11 range based for loops. Will skip deleted vertices.
*/
ConstVertexRange vertices() const { return ConstVertexRange(*this); }
ConstVertexRangeSkipping vertices() const { return ConstVertexRangeSkipping(*this); }
/**
* @return The vertices as a range object suitable
* for C++11 range based for loops. Will include deleted vertices.
*/
ConstVertexRange all_vertices() const { return ConstVertexRange(*this); }
/**
* @return The halfedges as a range object suitable
* for C++11 range based for loops.
* for C++11 range based for loops. Will skip deleted halfedges.
*/
ConstHalfedgeRange halfedges() const { return ConstHalfedgeRange(*this); }
ConstHalfedgeRangeSkipping halfedges() const { return ConstHalfedgeRangeSkipping(*this); }
/**
* @return The edges as a range object suitabl
* for C++11 range based for loops.
* @return The halfedges as a range object suitable
* for C++11 range based for loops. Will include deleted halfedges.
*/
ConstEdgeRange edges() const { return ConstEdgeRange(*this); }
ConstHalfedgeRange all_halfedges() const { return ConstHalfedgeRange(*this); }
/**
* @return The edges as a range object suitable
* for C++11 range based for loops. Will skip deleted edges.
*/
ConstEdgeRangeSkipping edges() const { return ConstEdgeRangeSkipping(*this); }
/**
* @return The edges as a range object suitable
* for C++11 range based for loops. Will include deleted edges.
*/
ConstEdgeRange all_edges() const { return ConstEdgeRange(*this); }
/**
* @return The faces as a range object suitable
* for C++11 range based for loops.
* for C++11 range based for loops. Will skip deleted faces.
*/
ConstFaceRange faces() const { return ConstFaceRange(*this); }
ConstFaceRangeSkipping faces() const { return ConstFaceRangeSkipping(*this); }
/**
* @return The faces as a range object suitable
* for C++11 range based for loops. Will include deleted faces.
*/
ConstFaceRange all_faces() const { return ConstFaceRange(*this); }
/// Generic class for iterator ranges.
template<

View File

@@ -139,18 +139,18 @@ PolyMeshT<Kernel>::calc_face_normal_impl(FaceHandle _fh, PointIs3DTag) const
// Due to traits, the value types of normals and points can be different.
// Therefore we cast them here.
n[0] += static_cast<typename Normal::value_type>(a[1] * b[2]);
n[1] += static_cast<typename Normal::value_type>(a[2] * b[0]);
n[2] += static_cast<typename Normal::value_type>(a[0] * b[1]);
n[0] += static_cast<typename vector_traits<Normal>::value_type>(a[1] * b[2]);
n[1] += static_cast<typename vector_traits<Normal>::value_type>(a[2] * b[0]);
n[2] += static_cast<typename vector_traits<Normal>::value_type>(a[0] * b[1]);
}
const typename vector_traits<Normal>::value_type norm = n.length();
const typename vector_traits<Normal>::value_type length = norm(n);
// The expression ((n *= (1.0/norm)),n) is used because the OpenSG
// vector class does not return self after component-wise
// self-multiplication with a scalar!!!
return (norm != typename vector_traits<Normal>::value_type(0))
? ((n *= (typename vector_traits<Normal>::value_type(1)/norm)), n)
return (length != typename vector_traits<Normal>::value_type(0))
? ((n *= (typename vector_traits<Normal>::value_type(1)/length)), n)
: Normal(0, 0, 0);
}
@@ -194,20 +194,22 @@ calc_face_normal_impl(const Point& _p0,
Normal p1p2(vector_cast<Normal>(_p2)); p1p2 -= vector_cast<Normal>(_p1);
Normal n = cross(p1p2, p1p0);
typename vector_traits<Normal>::value_type norm = n.length();
typename vector_traits<Normal>::value_type length = norm(n);
// The expression ((n *= (1.0/norm)),n) is used because the OpenSG
// vector class does not return self after component-wise
// self-multiplication with a scalar!!!
return (norm != typename vector_traits<Normal>::value_type(0)) ? ((n *= (typename vector_traits<Normal>::value_type(1)/norm)),n) : Normal(0,0,0);
return (length != typename vector_traits<Normal>::value_type(0))
? ((n *= (typename vector_traits<Normal>::value_type(1)/length)),n)
: Normal(0,0,0);
#else
Point p1p0 = _p0; p1p0 -= _p1;
Point p1p2 = _p2; p1p2 -= _p1;
Normal n = vector_cast<Normal>(cross(p1p2, p1p0));
typename vector_traits<Normal>::value_type norm = n.length();
typename vector_traits<Normal>::value_type length = norm(n);
return (norm != 0.0) ? n *= (1.0/norm) : Normal(0,0,0);
return (length != 0.0) ? n *= (1.0/length) : Normal(0,0,0);
#endif
}
@@ -226,7 +228,7 @@ PolyMeshT<Kernel>::
calc_face_centroid(FaceHandle _fh) const
{
Point _pt;
_pt.vectorize(0);
vectorize(_pt, 0);
Scalar valence = 0.0;
for (ConstFaceVertexIter cfv_it = this->cfv_iter(_fh); cfv_it.is_valid(); ++cfv_it, valence += 1.0)
{
@@ -261,7 +263,7 @@ void
PolyMeshT<Kernel>::
update_face_normals()
{
FaceIter f_it(Kernel::faces_begin()), f_end(Kernel::faces_end());
FaceIter f_it(Kernel::faces_sbegin()), f_end(Kernel::faces_end());
for (; f_it != f_end; ++f_it)
this->set_normal(*f_it, calc_face_normal(*f_it));
@@ -331,7 +333,7 @@ calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle) const
for(unsigned int i=0; i<fhs.size(); ++i)
n += Kernel::normal(fhs[i]);
return n.normalize();
return normalize(n);
}
}
@@ -378,8 +380,8 @@ calc_vertex_normal(VertexHandle _vh) const
Normal n;
calc_vertex_normal_fast(_vh,n);
Scalar norm = n.length();
if (norm != 0.0) n *= (Scalar(1.0)/norm);
Scalar length = norm(n);
if (length != 0.0) n *= (Scalar(1.0)/length);
return n;
}
@@ -389,7 +391,7 @@ template <class Kernel>
void PolyMeshT<Kernel>::
calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const
{
_n.vectorize(0.0);
vectorize(_n, 0.0);
for (ConstVertexFaceIter vf_it = this->cvf_iter(_vh); vf_it.is_valid(); ++vf_it)
_n += this->normal(*vf_it);
}
@@ -399,7 +401,7 @@ template <class Kernel>
void PolyMeshT<Kernel>::
calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const
{
_n.vectorize(0.0);
vectorize(_n, 0.0);
ConstVertexIHalfedgeIter cvih_it = this->cvih_iter(_vh);
if (! cvih_it.is_valid() )
{//don't crash on isolated vertices

View File

@@ -408,7 +408,7 @@ public:
{
Normal edge_vec;
calc_edge_vector(_heh, edge_vec);
return edge_vec.sqrnorm();
return sqrnorm(edge_vec);
}
/** Calculates the midpoint of the halfedge _heh, defined by the positions of
@@ -446,8 +446,8 @@ public:
{
Normal v0, v1;
calc_sector_vectors(_in_heh, v0, v1);
Scalar denom = v0.norm()*v1.norm();
if (is_zero(denom))
Scalar denom = norm(v0)*norm(v1);
if ( denom == Scalar(0))
{
return 0;
}
@@ -472,7 +472,7 @@ public:
Normal in_vec, out_vec;
calc_edge_vector(_in_heh, in_vec);
calc_edge_vector(next_halfedge_handle(_in_heh), out_vec);
Scalar denom = in_vec.norm()*out_vec.norm();
Scalar denom = norm(in_vec)*norm(out_vec);
if (is_zero(denom))
{
_cos_a = 1;
@@ -481,7 +481,7 @@ public:
else
{
_cos_a = dot(in_vec, out_vec)/denom;
_sin_a = cross(in_vec, out_vec).norm()/denom;
_sin_a = norm(cross(in_vec, out_vec))/denom;
}
}
*/
@@ -501,7 +501,7 @@ public:
{
Normal sector_normal;
calc_sector_normal(_in_heh, sector_normal);
return sector_normal.norm()/2;
return norm(sector_normal)/2;
}
/** calculates the dihedral angle on the halfedge _heh
@@ -541,7 +541,7 @@ public:
calc_sector_normal(_heh, n0);
calc_sector_normal(this->opposite_halfedge_handle(_heh), n1);
calc_edge_vector(_heh, he);
Scalar denom = n0.norm()*n1.norm();
Scalar denom = norm(n0)*norm(n1);
if (denom == Scalar(0))
{
return 0;

View File

@@ -488,6 +488,11 @@ void TriConnectivity::split(EdgeHandle _eh, VertexHandle _vh)
void TriConnectivity::split_copy(EdgeHandle _eh, VertexHandle _vh)
{
const VertexHandle v0 = to_vertex_handle(halfedge_handle(_eh, 0));
const VertexHandle v1 = to_vertex_handle(halfedge_handle(_eh, 1));
const int nf = n_faces();
// Split the halfedge ( handle will be preserved)
split(_eh, _vh);
@@ -495,6 +500,22 @@ void TriConnectivity::split_copy(EdgeHandle _eh, VertexHandle _vh)
// have been created
for(VEIter ve_it = ve_iter(_vh); ve_it.is_valid(); ++ve_it)
copy_all_properties(_eh, *ve_it, true);
for (auto vh : {v0, v1})
{
// get the halfedge pointing from new vertex to old vertex
const HalfedgeHandle h = find_halfedge(_vh, vh);
if (!is_boundary(h)) // for boundaries there are no faces whose properties need to be copied
{
FaceHandle fh0 = face_handle(h);
FaceHandle fh1 = face_handle(opposite_halfedge_handle(prev_halfedge_handle(h)));
if (fh0.idx() >= nf) // is fh0 the new face?
std::swap(fh0, fh1);
// copy properties from old face to new face
copy_all_properties(fh0, fh1, true);
}
}
}
}// namespace OpenMesh

View File

@@ -361,9 +361,9 @@ public:
VertexHandle p2 = this->to_vertex_handle(he2);
// Calculate midpoint coordinates
const Point new0 = (this->point(p0) + this->point(p2)) * static_cast< typename Point::value_type >(0.5);
const Point new1 = (this->point(p0) + this->point(p1)) * static_cast< typename Point::value_type >(0.5);
const Point new2 = (this->point(p1) + this->point(p2)) * static_cast< typename Point::value_type >(0.5);
const Point new0 = (this->point(p0) + this->point(p2)) * static_cast<typename vector_traits<Point>::value_type >(0.5);
const Point new1 = (this->point(p0) + this->point(p1)) * static_cast<typename vector_traits<Point>::value_type >(0.5);
const Point new2 = (this->point(p1) + this->point(p2)) * static_cast<typename vector_traits<Point>::value_type >(0.5);
// Add vertices at midpoint coordinates
VertexHandle v0 = this->add_vertex(new0);