Merge branch 'master' into compile-time-connectivity-type
This commit is contained in:
@@ -1,43 +0,0 @@
|
||||
################################################################################
|
||||
#
|
||||
################################################################################
|
||||
|
||||
include( $$TOPDIR/qmake/all.include )
|
||||
|
||||
Library()
|
||||
|
||||
contains( OPENFLIPPER , OpenFlipper ){
|
||||
DESTDIR = $${TOPDIR}/OpenMesh/lib
|
||||
} else {
|
||||
DESTDIR = $${TOPDIR}/lib
|
||||
}
|
||||
|
||||
|
||||
DIRECTORIES = . Geometry IO IO/exporter IO/importer IO/reader IO/writer \
|
||||
Mesh Mesh/gen System Utils
|
||||
|
||||
INCLUDEPATH += ../..
|
||||
|
||||
CONFIG( debug, debug|release ){
|
||||
TARGET = OpenMeshCored
|
||||
} else {
|
||||
TARGET = OpenMeshCore
|
||||
}
|
||||
|
||||
win32 {
|
||||
DEFINES += _USE_MATH_DEFINES NOMINMAX
|
||||
CONFIG += static
|
||||
}
|
||||
|
||||
macx {
|
||||
# Set library binary header to the correct path
|
||||
QMAKE_LFLAGS_SONAME = -install_name$${LITERAL_WHITESPACE}$${DESTDIR}/
|
||||
export(QMAKE_LFLAGS_SONAME)
|
||||
}
|
||||
|
||||
# Input
|
||||
HEADERS += $$getFilesFromDir($$DIRECTORIES,*.hh)
|
||||
SOURCES += $$getFilesFromDir($$DIRECTORIES,*.cc)
|
||||
FORMS += $$getFilesFromDir($$DIRECTORIES,*.ui)
|
||||
|
||||
################################################################################
|
||||
@@ -718,6 +718,47 @@ noexcept(noexcept(_v1.swap(_v2))) {
|
||||
_v1.swap(_v2);
|
||||
}
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member norm
|
||||
template<typename Scalar, int DIM>
|
||||
Scalar norm(const VectorT<Scalar, DIM>& _v) {
|
||||
return _v.norm();
|
||||
}
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member sqrnorm
|
||||
template<typename Scalar, int DIM>
|
||||
Scalar sqrnorm(const VectorT<Scalar, DIM>& _v) {
|
||||
return _v.sqrnorm();
|
||||
}
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member vectorize
|
||||
template<typename Scalar, int DIM, typename OtherScalar>
|
||||
VectorT<Scalar, DIM>& vectorize(VectorT<Scalar, DIM>& _v, OtherScalar const& _val) {
|
||||
return _v.vectorize(_val);
|
||||
}
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member normalize
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM>& normalize(VectorT<Scalar, DIM>& _v) {
|
||||
return _v.normalize();
|
||||
}
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member maximize
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM>& maximize(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
|
||||
return _v1.maximize(_v2);
|
||||
}
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member minimize
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM>& minimize(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
|
||||
return _v1.minimize(_v2);
|
||||
}
|
||||
|
||||
//== TYPEDEFS =================================================================
|
||||
|
||||
/** 1-byte signed vector */
|
||||
|
||||
@@ -274,6 +274,52 @@ cross(const VectorT<Scalar,N>& _v1, const VectorT<Scalar,N>& _v2) {
|
||||
}
|
||||
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member norm
|
||||
template<typename Scalar, int DIM>
|
||||
Scalar norm(const VectorT<Scalar, DIM>& _v) {
|
||||
return _v.norm();
|
||||
}
|
||||
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member sqrnorm
|
||||
template<typename Scalar, int DIM>
|
||||
Scalar sqrnorm(const VectorT<Scalar, DIM>& _v) {
|
||||
return _v.sqrnorm();
|
||||
}
|
||||
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member vectorize
|
||||
template<typename Scalar, int DIM, typename OtherScalar>
|
||||
VectorT<Scalar, DIM>& vectorize(VectorT<Scalar, DIM>& _v, OtherScalar const& _val) {
|
||||
return _v.vectorize(_val);
|
||||
}
|
||||
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member normalize
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM>& normalize(VectorT<Scalar, DIM>& _v) {
|
||||
return _v.normalize();
|
||||
}
|
||||
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member maximize
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM>& maximize(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
|
||||
return _v1.maximize(_v2);
|
||||
}
|
||||
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member minimize
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM>& minimize(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
|
||||
return _v1.minimize(_v2);
|
||||
}
|
||||
|
||||
|
||||
//== TYPEDEFS =================================================================
|
||||
|
||||
@@ -55,11 +55,24 @@
|
||||
|
||||
// -------------------- system settings
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
|
||||
// -------------------- check include order
|
||||
#if defined (OPENMESH_TRIMESH_ARRAY_KERNEL_HH) || \
|
||||
defined (OPENMESH_POLYMESH_ARRAY_KERNEL_HH)
|
||||
# error "Include MeshIO.hh before including a mesh type!"
|
||||
|
||||
// Issue warning if MeshIO was not included before Mesh Type
|
||||
// Nobody knows why this order was enforced.
|
||||
// If somebody encounters an error resulting from a wrong order, please report it to the OpenMesh developers.
|
||||
// If we don't here about any errors, this check will be removed
|
||||
// @TODO: Remove after reasonable time
|
||||
#ifdef WIN32
|
||||
#pragma message("MeshIO.hh was included after Mesh Type. You may ignore this warning. Please report errors resulting ifrom this order to the developers!")
|
||||
#else
|
||||
#warning "MeshIO.hh was included after Mesh Type. You may ignore this warning. Please report errors resulting from this order to the developers!"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// -------------------- OpenMesh
|
||||
#include <OpenMesh/Core/IO/SR_store.hh>
|
||||
#include <OpenMesh/Core/IO/IOManager.hh>
|
||||
|
||||
@@ -315,16 +315,16 @@ namespace OMFormat {
|
||||
/// Return the size of chunk data in bytes
|
||||
inline size_t chunk_data_size( Header& _hdr, Chunk::Header& _chunk_hdr )
|
||||
{
|
||||
size_t C = 0;
|
||||
|
||||
size_t C;
|
||||
switch( _chunk_hdr.entity_ )
|
||||
{
|
||||
case Chunk::Entity_Vertex: C = _hdr.n_vertices_; break;
|
||||
case Chunk::Entity_Face: C = _hdr.n_faces_; break;
|
||||
case Chunk::Entity_Halfedge: C = _hdr.n_edges_; // no break!
|
||||
case Chunk::Entity_Edge: C += _hdr.n_edges_; break;
|
||||
case Chunk::Entity_Halfedge: C = _hdr.n_edges_*2; break;
|
||||
case Chunk::Entity_Edge: C = _hdr.n_edges_; break;
|
||||
case Chunk::Entity_Mesh: C = 1; break;
|
||||
default:
|
||||
C = 0;
|
||||
std::cerr << "Invalid value in _chunk_hdr.entity_\n";
|
||||
assert( false );
|
||||
break;
|
||||
|
||||
@@ -145,7 +145,7 @@ namespace IO {
|
||||
}
|
||||
|
||||
|
||||
// helper to store a an integer
|
||||
// helper to restore a an integer
|
||||
template< typename T >
|
||||
size_t
|
||||
restore( std::istream& _is,
|
||||
@@ -171,25 +171,28 @@ namespace IO {
|
||||
OMFormat::int16 v;
|
||||
bytes = restore( _is, v, _swap );
|
||||
_val = static_cast<T>(v);
|
||||
break;
|
||||
}
|
||||
case OMFormat::Chunk::Integer_32:
|
||||
{
|
||||
OMFormat::int32 v;
|
||||
bytes = restore( _is, v, _swap );
|
||||
_val = static_cast<T>(v);
|
||||
break;
|
||||
}
|
||||
case OMFormat::Chunk::Integer_64:
|
||||
{
|
||||
OMFormat::int64 v;
|
||||
bytes = restore( _is, v, _swap );
|
||||
_val = static_cast<T>(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
|
||||
|
||||
// helper to store a an unsigned integer
|
||||
// helper to restore a an unsigned integer
|
||||
template< typename T >
|
||||
size_t
|
||||
restore( std::istream& _is,
|
||||
|
||||
@@ -156,7 +156,16 @@ protected:
|
||||
* @return trimmed string
|
||||
*/
|
||||
static inline std::string &left_trim(std::string &_string) {
|
||||
_string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
|
||||
// Find out if the compiler supports CXX11
|
||||
#if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L )
|
||||
// as with CXX11 we can use lambda expressions
|
||||
_string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), [](int i)->int { return ! std::isspace(i); }));
|
||||
#else
|
||||
// we do what we did before
|
||||
_string.erase(_string.begin(), std::find_if(_string.begin(), _string.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
|
||||
#endif
|
||||
|
||||
return _string;
|
||||
}
|
||||
|
||||
@@ -168,7 +177,18 @@ static inline std::string &left_trim(std::string &_string) {
|
||||
* @return trimmed string
|
||||
*/
|
||||
static inline std::string &right_trim(std::string &_string) {
|
||||
_string.erase(std::find_if(_string.rbegin(), _string.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _string.end());
|
||||
|
||||
// Find out if the compiler supports CXX11
|
||||
#if ( __cplusplus >= 201103L || _MSVC_LANG >= 201103L )
|
||||
// as with CXX11 we can use lambda expressions
|
||||
_string.erase(std::find_if(_string.rbegin(), _string.rend(), [](int i)->int { return ! std::isspace(i); } ).base(), _string.end());
|
||||
#else
|
||||
// we do what we did before
|
||||
_string.erase(std::find_if(_string.rbegin(), _string.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _string.end());
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
return _string;
|
||||
}
|
||||
|
||||
|
||||
@@ -540,6 +540,7 @@ read(std::istream& _in, BaseImporter& _bi, Options& _opt)
|
||||
|
||||
vhandles.clear();
|
||||
face_texcoords.clear();
|
||||
face_texcoords3d.clear();
|
||||
|
||||
// read full line after detecting a face
|
||||
std::string faceLine;
|
||||
|
||||
@@ -1062,7 +1062,7 @@ std::string get_property_name(std::string _string1, std::string _string2) {
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
_PLYReader_::ValueType get_property_type(std::string _string1, std::string _string2) {
|
||||
_PLYReader_::ValueType get_property_type(std::string& _string1, std::string& _string2) {
|
||||
|
||||
if (_string1 == "float32" || _string2 == "float32")
|
||||
|
||||
@@ -1270,6 +1270,8 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
|
||||
omerr() << "Custom face Properties defined, before 'vertex_indices' property was defined. They will be skipped" << std::endl;
|
||||
elements_.back().properties_.clear();
|
||||
}
|
||||
} else {
|
||||
options_ += Options::Custom;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ class CmpVec
|
||||
{
|
||||
public:
|
||||
|
||||
CmpVec(float _eps=FLT_MIN) : eps_(_eps) {}
|
||||
explicit CmpVec(float _eps=FLT_MIN) : eps_(_eps) {}
|
||||
|
||||
bool operator()( const Vec3f& _v0, const Vec3f& _v1 ) const
|
||||
{
|
||||
|
||||
@@ -224,12 +224,22 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
if (!check( _be, _opt))
|
||||
return false;
|
||||
|
||||
// No binary mode for OBJ
|
||||
if ( _opt.check(Options::Binary) ) {
|
||||
omout() << "[OBJWriter] : Warning, Binary mode requested for OBJ Writer (No support for Binary mode), falling back to standard." << std::endl;
|
||||
}
|
||||
|
||||
// check writer features
|
||||
if ( _opt.check(Options::Binary) || // not supported by format
|
||||
_opt.check(Options::FaceNormal))
|
||||
return false;
|
||||
// check for unsupported writer features
|
||||
if (_opt.check(Options::FaceNormal) ) {
|
||||
omerr() << "[OBJWriter] : FaceNormal not supported by OBJ Writer" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
// check for unsupported writer features
|
||||
if (_opt.check(Options::VertexColor) ) {
|
||||
omerr() << "[OBJWriter] : VertexColor not supported by OBJ Writer" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
//create material file if needed
|
||||
if ( _opt.check(Options::FaceColor) ){
|
||||
@@ -270,10 +280,10 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
}
|
||||
}
|
||||
|
||||
//collect Texturevertices from vertices
|
||||
//collect Texture coordinates from vertices
|
||||
if(_opt.check(Options::VertexTexCoord))
|
||||
{
|
||||
for (size_t i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
for (size_t i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
{
|
||||
vh = VertexHandle(static_cast<int>(i));
|
||||
t = _be.texcoord(vh);
|
||||
@@ -363,7 +373,7 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
{
|
||||
// write vertex texture coordinate index
|
||||
if (_opt.check(Options::VertexTexCoord))
|
||||
_out << texMap[_be.texcoord(vh)];
|
||||
_out << texMap[_be.texcoord(vhandles[j])];
|
||||
}
|
||||
|
||||
// write vertex normal index
|
||||
|
||||
@@ -163,7 +163,7 @@ _OMWriter_::write(std::ostream& _os, BaseExporter& _be, Options _opt, std::strea
|
||||
#ifndef DOXY_IGNORE_THIS
|
||||
template <typename T> struct Enabler
|
||||
{
|
||||
Enabler( T& obj ) : obj_(obj)
|
||||
explicit Enabler( T& obj ) : obj_(obj)
|
||||
{}
|
||||
|
||||
~Enabler() { obj_.enable(); }
|
||||
@@ -302,7 +302,8 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
|
||||
for (i=0, nF=header.n_faces_; i<nF; ++i)
|
||||
{
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
//nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
_be.get_vhandles(FaceHandle(i), vhandles);
|
||||
if ( header.mesh_ == 'P' )
|
||||
bytes += store( _os, vhandles.size(), OMFormat::Chunk::Integer_16, swap );
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@ write_stla(const std::string& _filename, BaseExporter& _be, Options /* _opt */)
|
||||
|
||||
|
||||
|
||||
int i, nF(int(_be.n_faces())), nV;
|
||||
int i, nF(int(_be.n_faces()));
|
||||
Vec3f a, b, c, n;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
FaceHandle fh;
|
||||
@@ -172,7 +172,7 @@ write_stla(const std::string& _filename, BaseExporter& _be, Options /* _opt */)
|
||||
for (i=0; i<nF; ++i)
|
||||
{
|
||||
fh = FaceHandle(i);
|
||||
nV = _be.get_vhandles(fh, vhandles);
|
||||
const int nV = _be.get_vhandles(fh, vhandles);
|
||||
|
||||
if (nV == 3)
|
||||
{
|
||||
@@ -211,7 +211,7 @@ write_stla(std::ostream& _out, BaseExporter& _be, Options /* _opt */, std::strea
|
||||
{
|
||||
omlog() << "[STLWriter] : write ascii file\n";
|
||||
|
||||
int i, nF(int(_be.n_faces())), nV;
|
||||
int i, nF(int(_be.n_faces()));
|
||||
Vec3f a, b, c, n;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
FaceHandle fh;
|
||||
@@ -226,7 +226,7 @@ write_stla(std::ostream& _out, BaseExporter& _be, Options /* _opt */, std::strea
|
||||
for (i=0; i<nF; ++i)
|
||||
{
|
||||
fh = FaceHandle(i);
|
||||
nV = _be.get_vhandles(fh, vhandles);
|
||||
const int nV = _be.get_vhandles(fh, vhandles);
|
||||
|
||||
if (nV == 3)
|
||||
{
|
||||
@@ -273,7 +273,7 @@ write_stlb(const std::string& _filename, BaseExporter& _be, Options /* _opt */)
|
||||
}
|
||||
|
||||
|
||||
int i, nF(int(_be.n_faces())), nV;
|
||||
int i, nF(int(_be.n_faces()));
|
||||
Vec3f a, b, c, n;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
FaceHandle fh;
|
||||
@@ -294,7 +294,7 @@ write_stlb(const std::string& _filename, BaseExporter& _be, Options /* _opt */)
|
||||
for (i=0; i<nF; ++i)
|
||||
{
|
||||
fh = FaceHandle(i);
|
||||
nV = _be.get_vhandles(fh, vhandles);
|
||||
const int nV = _be.get_vhandles(fh, vhandles);
|
||||
|
||||
if (nV == 3)
|
||||
{
|
||||
@@ -344,7 +344,7 @@ write_stlb(std::ostream& _out, BaseExporter& _be, Options /* _opt */, std::strea
|
||||
omlog() << "[STLWriter] : write binary file\n";
|
||||
|
||||
|
||||
int i, nF(int(_be.n_faces())), nV;
|
||||
int i, nF(int(_be.n_faces()));
|
||||
Vec3f a, b, c, n;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
FaceHandle fh;
|
||||
@@ -366,7 +366,7 @@ write_stlb(std::ostream& _out, BaseExporter& _be, Options /* _opt */, std::strea
|
||||
for (i=0; i<nF; ++i)
|
||||
{
|
||||
fh = FaceHandle(i);
|
||||
nV = _be.get_vhandles(fh, vhandles);
|
||||
const int nV = _be.get_vhandles(fh, vhandles);
|
||||
|
||||
if (nV == 3)
|
||||
{
|
||||
|
||||
@@ -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_);
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -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_;
|
||||
|
||||
@@ -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 ;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@@ -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<
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -65,15 +65,11 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#define OM_VERSION 0x70000
|
||||
//#define OM_VERSION 0x60300
|
||||
#define OM_VERSION 0x70200
|
||||
|
||||
// only defined, if it is a beta version
|
||||
//#define OM_VERSION_BETA 4
|
||||
|
||||
#define OM_GET_VER ((OM_VERSION && 0xf0000) >> 16)
|
||||
#define OM_GET_MAJ ((OM_VERSION && 0x0ff00) >> 8)
|
||||
#define OM_GET_MIN (OM_VERSION && 0x000ff)
|
||||
#define OM_GET_VER ((OM_VERSION & 0xf0000) >> 16)
|
||||
#define OM_GET_MAJ ((OM_VERSION & 0x0ff00) >> 8)
|
||||
#define OM_GET_MIN (OM_VERSION & 0x000ff)
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef min
|
||||
|
||||
@@ -95,7 +95,6 @@ inline void vector_cast( const src_t & /*_src*/, dst_t & /*_dst*/, GenProg::Int2
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
template <typename src_t, typename dst_t, int n>
|
||||
inline void vector_copy( const src_t &_src, dst_t &_dst, GenProg::Int2Type<n> )
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user