Merge branch 'master' into remove_compile_order_check
This commit is contained in:
@@ -24,10 +24,6 @@ set (directories
|
||||
acg_append_files (headers "*.hh" ${directories})
|
||||
acg_append_files (sources "*.cc" ${directories})
|
||||
|
||||
#Drop the template only cc files
|
||||
acg_drop_templates(sources)
|
||||
|
||||
|
||||
# Disable Library installation when not building OpenMesh on its own but as part of another project!
|
||||
if ( NOT ${PROJECT_NAME} MATCHES "OpenMesh")
|
||||
set(ACG_NO_LIBRARY_INSTALL true)
|
||||
@@ -81,16 +77,16 @@ endif()
|
||||
|
||||
# Install Header Files (Apple)
|
||||
if ( NOT ACG_PROJECT_MACOS_BUNDLE AND APPLE )
|
||||
FILE(GLOB files_install_Geometry "${CMAKE_CURRENT_SOURCE_DIR}/Geometry/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Geometry/*T.cc" )
|
||||
FILE(GLOB files_install_IO "${CMAKE_CURRENT_SOURCE_DIR}/IO/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/*T.cc" "${CMAKE_CURRENT_SOURCE_DIR}/IO/*.inl" )
|
||||
FILE(GLOB files_install_IO_importer "${CMAKE_CURRENT_SOURCE_DIR}/IO/importer/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/importer/*T.cc" )
|
||||
FILE(GLOB files_install_IO_exporter "${CMAKE_CURRENT_SOURCE_DIR}/IO/exporter/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/exporter/*T.cc" )
|
||||
FILE(GLOB files_install_IO_reader "${CMAKE_CURRENT_SOURCE_DIR}/IO/reader/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/reader/*T.cc" )
|
||||
FILE(GLOB files_install_IO_writer "${CMAKE_CURRENT_SOURCE_DIR}/IO/writer/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/writer/*T.cc" )
|
||||
FILE(GLOB files_install_Mesh "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/*T.cc" )
|
||||
FILE(GLOB files_install_Mesh_Gen "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/gen/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/gen/*T.cc" )
|
||||
FILE(GLOB files_install_System "${CMAKE_CURRENT_SOURCE_DIR}/System/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/System/*T.cc" "${CMAKE_CURRENT_SOURCE_DIR}/System/config.h" )
|
||||
FILE(GLOB files_install_Utils "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*T.cc" )
|
||||
FILE(GLOB files_install_Geometry "${CMAKE_CURRENT_SOURCE_DIR}/Geometry/*.hh" )
|
||||
FILE(GLOB files_install_IO "${CMAKE_CURRENT_SOURCE_DIR}/IO/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/IO/*.inl" )
|
||||
FILE(GLOB files_install_IO_importer "${CMAKE_CURRENT_SOURCE_DIR}/IO/importer/*.hh" )
|
||||
FILE(GLOB files_install_IO_exporter "${CMAKE_CURRENT_SOURCE_DIR}/IO/exporter/*.hh" )
|
||||
FILE(GLOB files_install_IO_reader "${CMAKE_CURRENT_SOURCE_DIR}/IO/reader/*.hh" )
|
||||
FILE(GLOB files_install_IO_writer "${CMAKE_CURRENT_SOURCE_DIR}/IO/writer/*.hh" )
|
||||
FILE(GLOB files_install_Mesh "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/*.hh" )
|
||||
FILE(GLOB files_install_Mesh_Gen "${CMAKE_CURRENT_SOURCE_DIR}/Mesh/gen/*.hh" )
|
||||
FILE(GLOB files_install_System "${CMAKE_CURRENT_SOURCE_DIR}/System/*.hh" "${CMAKE_CURRENT_SOURCE_DIR}/System/config.h" )
|
||||
FILE(GLOB files_install_Utils "${CMAKE_CURRENT_SOURCE_DIR}/Utils/*.hh" )
|
||||
INSTALL(FILES ${files_install_Geometry} DESTINATION include/OpenMesh/Core/Geometry )
|
||||
INSTALL(FILES ${files_install_IO} DESTINATION include/OpenMesh/Core/IO )
|
||||
INSTALL(FILES ${files_install_IO_importer} DESTINATION include/OpenMesh/Core/IO/importer )
|
||||
@@ -118,17 +114,6 @@ install(DIRECTORY .
|
||||
PATTERN "Templates" EXCLUDE
|
||||
PATTERN "Debian*" EXCLUDE)
|
||||
|
||||
#install Template cc files (required by headers)
|
||||
install(DIRECTORY .
|
||||
DESTINATION include/OpenMesh/Core
|
||||
FILES_MATCHING
|
||||
PATTERN "*T.cc"
|
||||
PATTERN "CVS" EXCLUDE
|
||||
PATTERN ".svn" EXCLUDE
|
||||
PATTERN "tmp" EXCLUDE
|
||||
PATTERN "Templates" EXCLUDE
|
||||
PATTERN "Debian*" EXCLUDE)
|
||||
|
||||
#install the config file
|
||||
install(FILES System/config.h DESTINATION include/OpenMesh/Core/System)
|
||||
|
||||
@@ -138,14 +123,21 @@ install(DIRECTORY IO/
|
||||
FILES_MATCHING
|
||||
PATTERN "*.inl"
|
||||
PATTERN "CVS" EXCLUDE
|
||||
PATTERN ".svn" EXCLUDE
|
||||
PATTERN "reader" EXCLUDE
|
||||
PATTERN "writer" EXCLUDE
|
||||
PATTERN "importer" EXCLUDE
|
||||
PATTERN "exporter" EXCLUDE
|
||||
PATTERN "tmp" EXCLUDE
|
||||
PATTERN "Debian*" EXCLUDE )
|
||||
|
||||
PATTERN ".svn" EXCLUDE
|
||||
PATTERN "reader" EXCLUDE
|
||||
PATTERN "writer" EXCLUDE
|
||||
PATTERN "importer" EXCLUDE
|
||||
PATTERN "exporter" EXCLUDE
|
||||
PATTERN "tmp" EXCLUDE
|
||||
PATTERN "Debian*" EXCLUDE )
|
||||
endif ()
|
||||
|
||||
target_include_directories(OpenMeshCore PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/../..>
|
||||
$<INSTALL_INTERFACE:include>)
|
||||
|
||||
install(TARGETS OpenMeshCore EXPORT OpenMeshConfig
|
||||
ARCHIVE DESTINATION ${ACG_PROJECT_LIBDIR}
|
||||
LIBRARY DESTINATION ${ACG_PROJECT_LIBDIR}
|
||||
RUNTIME DESTINATION ${ACG_PROJECT_BINDIR})
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
################################################################################
|
||||
@@ -40,12 +40,7 @@
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
104
src/OpenMesh/Core/Geometry/EigenVectorT.hh
Normal file
104
src/OpenMesh/Core/Geometry/EigenVectorT.hh
Normal file
@@ -0,0 +1,104 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. Redistributions in binary form must reproduce the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer in the *
|
||||
* documentation and/or other materials provided with the distribution. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder nor the names of its *
|
||||
* contributors may be used to endorse or promote products derived from *
|
||||
* this software without specific prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/** This file contains all code required to use Eigen3 vectors as Mesh
|
||||
* vectors
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#include <Eigen/Core>
|
||||
#include <Eigen/Dense>
|
||||
#include <Eigen/Geometry>
|
||||
|
||||
|
||||
namespace OpenMesh {
|
||||
template <typename _Scalar, int _Rows, int _Cols, int _Options>
|
||||
struct vector_traits<Eigen::Matrix<_Scalar, _Rows, _Cols, _Options>> {
|
||||
static_assert(_Rows != Eigen::Dynamic && _Cols != Eigen::Dynamic,
|
||||
"Should not use dynamic vectors.");
|
||||
static_assert(_Rows == 1 || _Cols == 1, "Should not use matrices.");
|
||||
|
||||
using vector_type = Eigen::Matrix<_Scalar, _Rows, _Cols, _Options>;
|
||||
using value_type = _Scalar;
|
||||
static const size_t size_ = _Rows * _Cols;
|
||||
static size_t size() { return size_; }
|
||||
};
|
||||
|
||||
} // namespace OpenMesh
|
||||
|
||||
namespace Eigen {
|
||||
|
||||
template <typename Derived>
|
||||
typename Derived::Scalar dot(const MatrixBase<Derived> &x,
|
||||
const MatrixBase<Derived> &y) {
|
||||
return x.dot(y);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
typename MatrixBase< Derived >::PlainObject cross(const MatrixBase<Derived> &x, const MatrixBase<Derived> &y) {
|
||||
return x.cross(y);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
typename Derived::Scalar norm(const MatrixBase<Derived> &x) {
|
||||
return x.norm();
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
typename Derived::Scalar sqrnorm(const MatrixBase<Derived> &x) {
|
||||
return x.dot(x);
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
MatrixBase<Derived> &normalize(MatrixBase<Derived> &x) {
|
||||
x /= x.norm();
|
||||
return x;
|
||||
}
|
||||
|
||||
template <typename Derived>
|
||||
MatrixBase<Derived> &vectorize(MatrixBase<Derived> &x,
|
||||
typename Derived::Scalar const &val) {
|
||||
x.fill(val);
|
||||
return x;
|
||||
}
|
||||
|
||||
} // namespace Eigen
|
||||
|
||||
@@ -40,12 +40,7 @@
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef LOOPSCHEMEMASKT_HH
|
||||
#define LOOPSCHEMEMASKT_HH
|
||||
@@ -94,17 +89,17 @@ protected:
|
||||
|
||||
inline static Scalar compute_limit_weight(uint _valence)
|
||||
{
|
||||
double proj_weight = compute_proj_weight(_valence);
|
||||
proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight
|
||||
double weight = (3.0/8.0)/(1.0 - proj_weight + (3.0/8.0));
|
||||
double proj_weight_value = compute_proj_weight(_valence);
|
||||
proj_weight_value = proj_weight_value/(proj_weight_value + _valence);//normalize the proj_weight
|
||||
double weight = (3.0/8.0)/(1.0 - proj_weight_value + (3.0/8.0));
|
||||
return (Scalar)weight;
|
||||
}
|
||||
|
||||
inline static Scalar compute_step_weight(uint _valence)
|
||||
{
|
||||
double proj_weight = compute_proj_weight(_valence);
|
||||
proj_weight = proj_weight/(proj_weight + _valence);//normalize the proj_weight
|
||||
double weight = proj_weight - (3.0/8.0);
|
||||
double proj_weight_value = compute_proj_weight(_valence);
|
||||
proj_weight_value = proj_weight_value/(proj_weight_value + _valence);//normalize the proj_weight
|
||||
double weight = proj_weight_value - (3.0/8.0);
|
||||
return (Scalar)weight;
|
||||
}
|
||||
|
||||
|
||||
@@ -40,12 +40,7 @@
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef MATHDEFS_HH
|
||||
#define MATHDEFS_HH
|
||||
|
||||
@@ -40,12 +40,7 @@
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -65,6 +60,7 @@
|
||||
|
||||
|
||||
#include <OpenMesh/Core/Geometry/VectorT.hh>
|
||||
#include <OpenMesh/Core/Utils/vector_traits.hh>
|
||||
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
@@ -82,13 +78,14 @@ namespace OpenMesh {
|
||||
the center normal and the opening angle.
|
||||
**/
|
||||
|
||||
template <typename Scalar>
|
||||
template <typename Vector>
|
||||
class NormalConeT
|
||||
{
|
||||
public:
|
||||
|
||||
// typedefs
|
||||
typedef VectorT<Scalar, 3> Vec3;
|
||||
typedef typename vector_traits<Vector>::value_type Scalar;
|
||||
typedef Vector Vec3;
|
||||
|
||||
|
||||
//! default constructor (not initialized)
|
||||
@@ -124,7 +121,7 @@ private:
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_NORMALCONE_C)
|
||||
#define OPENMESH_NORMALCONE_TEMPLATES
|
||||
#include "NormalConeT.cc"
|
||||
#include "NormalConeT_impl.hh"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_NORMALCONE_HH defined
|
||||
|
||||
@@ -40,16 +40,6 @@
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS NormalConeT - IMPLEMENTATION
|
||||
@@ -80,8 +70,8 @@ namespace OpenMesh {
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
template <typename Scalar>
|
||||
NormalConeT<Scalar>::
|
||||
template <typename Vector>
|
||||
NormalConeT<Vector>::
|
||||
NormalConeT(const Vec3& _center_normal, Scalar _angle)
|
||||
: center_normal_(_center_normal), angle_(_angle)
|
||||
{
|
||||
@@ -91,9 +81,9 @@ NormalConeT(const Vec3& _center_normal, Scalar _angle)
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <typename Scalar>
|
||||
Scalar
|
||||
NormalConeT<Scalar>::
|
||||
template <typename Vector>
|
||||
typename NormalConeT<Vector>::Scalar
|
||||
NormalConeT<Vector>::
|
||||
max_angle(const Vec3& _norm) const
|
||||
{
|
||||
Scalar dotp = (center_normal_ | _norm);
|
||||
@@ -105,9 +95,9 @@ max_angle(const Vec3& _norm) const
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <typename Scalar>
|
||||
Scalar
|
||||
NormalConeT<Scalar>::
|
||||
template <typename Vector>
|
||||
typename NormalConeT<Vector>::Scalar
|
||||
NormalConeT<Vector>::
|
||||
max_angle(const NormalConeT& _cone) const
|
||||
{
|
||||
Scalar dotp = (center_normal_ | _cone.center_normal_);
|
||||
@@ -122,12 +112,12 @@ max_angle(const NormalConeT& _cone) const
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <typename Scalar>
|
||||
template <typename Vector>
|
||||
void
|
||||
NormalConeT<Scalar>::
|
||||
NormalConeT<Vector>::
|
||||
merge(const NormalConeT& _cone)
|
||||
{
|
||||
Scalar dotp = (center_normal_ | _cone.center_normal_);
|
||||
Scalar dotp = dot(center_normal_, _cone.center_normal_);
|
||||
|
||||
if (fabs(dotp) < 0.99999f)
|
||||
{
|
||||
@@ -41,12 +41,7 @@
|
||||
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
|
||||
@@ -41,12 +41,7 @@
|
||||
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
/** \file Core/Geometry/QuadricT.hh
|
||||
|
||||
@@ -117,7 +112,7 @@ public:
|
||||
{}
|
||||
|
||||
template <class _Point>
|
||||
QuadricT(const _Point& _pt)
|
||||
explicit QuadricT(const _Point& _pt)
|
||||
{
|
||||
set_distance_to_point(_pt);
|
||||
}
|
||||
|
||||
@@ -169,6 +169,11 @@ class VectorT {
|
||||
std::copy_n(it, DIM, values_.begin());
|
||||
}
|
||||
|
||||
/// construct from an array
|
||||
explicit VectorT(container&& _array) {
|
||||
values_ = _array;
|
||||
}
|
||||
|
||||
/// copy & cast constructor (explicit)
|
||||
template<typename otherScalarType,
|
||||
typename = typename std::enable_if<
|
||||
@@ -364,7 +369,7 @@ class VectorT {
|
||||
}
|
||||
|
||||
/// cross product: only defined for Vec3* as specialization
|
||||
/// \see OpenMesh::cross
|
||||
/// \see OpenMesh::cross and .cross()
|
||||
template<typename OtherScalar>
|
||||
auto operator% (const VectorT<OtherScalar, DIM> &_rhs) const ->
|
||||
typename std::enable_if<DIM == 3,
|
||||
@@ -377,8 +382,18 @@ class VectorT {
|
||||
};
|
||||
}
|
||||
|
||||
/// cross product: only defined for Vec3* as specialization
|
||||
/// \see OpenMesh::cross and .operator%
|
||||
template<typename OtherScalar>
|
||||
auto cross (const VectorT<OtherScalar, DIM> &_rhs) const ->
|
||||
decltype(*this % _rhs)
|
||||
{
|
||||
return *this % _rhs;
|
||||
}
|
||||
|
||||
|
||||
/// compute scalar product
|
||||
/// \see OpenMesh::dot
|
||||
/// \see OpenMesh::dot and .dot()
|
||||
template<typename OtherScalar>
|
||||
auto operator|(const VectorT<OtherScalar, DIM>& _rhs) const ->
|
||||
decltype(*this->data() * *_rhs.data()) {
|
||||
@@ -387,6 +402,15 @@ class VectorT {
|
||||
*begin() * *_rhs.begin());
|
||||
}
|
||||
|
||||
/// compute scalar product
|
||||
/// \see OpenMesh::dot and .operator|
|
||||
template<typename OtherScalar>
|
||||
auto dot(const VectorT<OtherScalar, DIM>& _rhs) const ->
|
||||
decltype(*this | _rhs)
|
||||
{
|
||||
return *this | _rhs;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------ euclidean norm
|
||||
|
||||
/// \name Euclidean norm calculations
|
||||
@@ -718,6 +742,62 @@ 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);
|
||||
}
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member max
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM> max(const VectorT<Scalar, DIM>& _v1, const VectorT<Scalar, DIM>& _v2) {
|
||||
return _v1.max(_v2);
|
||||
}
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member min
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM> min(const VectorT<Scalar, DIM>& _v1, const VectorT<Scalar, DIM>& _v2) {
|
||||
return _v1.min(_v2);
|
||||
}
|
||||
|
||||
|
||||
//== TYPEDEFS =================================================================
|
||||
|
||||
/** 1-byte signed vector */
|
||||
|
||||
@@ -40,12 +40,7 @@
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -274,6 +269,68 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member max
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM> max(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
|
||||
return VectorT<Scalar, DIM>(_v1).maximize(_v2);
|
||||
}
|
||||
|
||||
|
||||
/// \relates OpenMesh::VectorT
|
||||
/// non-member min
|
||||
template<typename Scalar, int DIM>
|
||||
VectorT<Scalar, DIM> min(VectorT<Scalar, DIM>& _v1, VectorT<Scalar, DIM>& _v2) {
|
||||
return VectorT<Scalar, DIM>(_v1).minimize(_v2);
|
||||
}
|
||||
|
||||
|
||||
//== TYPEDEFS =================================================================
|
||||
|
||||
@@ -41,12 +41,7 @@
|
||||
|
||||
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
// Set template keywords and class names properly when
|
||||
// parsing with doxygen. This only seems to work this way since
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -82,6 +77,7 @@
|
||||
#include <OpenMesh/Core/IO/writer/STLWriter.hh>
|
||||
#include <OpenMesh/Core/IO/writer/OMWriter.hh>
|
||||
#include <OpenMesh/Core/IO/writer/PLYWriter.hh>
|
||||
#include <OpenMesh/Core/IO/writer/VTKWriter.hh>
|
||||
|
||||
//=== NAMESPACES ==============================================================
|
||||
|
||||
@@ -104,6 +100,7 @@ static BaseWriter* OFFWriterInstance = &OFFWriter();
|
||||
static BaseWriter* STLWriterInstance = &STLWriter();
|
||||
static BaseWriter* OMWriterInstance = &OMWriter();
|
||||
static BaseWriter* PLYWriterInstance = &PLYWriter();
|
||||
static BaseWriter* VTKWriterInstance = &VTKWriter();
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -263,7 +258,7 @@ find_writer(const std::string& _format)
|
||||
if ((*it)->can_u_write(filename))
|
||||
return *it;
|
||||
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
@@ -152,7 +147,7 @@ public:
|
||||
bool write(const std::string& _filename,
|
||||
BaseExporter& _be,
|
||||
Options _opt=Options::Default,
|
||||
std::streamsize _precision = 6);
|
||||
std::streamsize _precision = 6);
|
||||
|
||||
/** Write a mesh to open std::ostream _os. The source data structure is specified
|
||||
by the given BaseExporter. The \c save method consecutively queries all
|
||||
@@ -164,7 +159,7 @@ public:
|
||||
const std::string& _ext,
|
||||
BaseExporter& _be,
|
||||
Options _opt=Options::Default,
|
||||
std::streamsize _precision = 6);
|
||||
std::streamsize _precision = 6);
|
||||
|
||||
|
||||
/// Returns true if the format is supported by one of the reader modules.
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#ifndef OM_MESHIO_HH
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#ifndef OPENMESH_IO_OFFFORMAT_HH
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -113,6 +108,19 @@ namespace OMFormat {
|
||||
return hdr;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
std::string as_string(uint8 version)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << major_version(version);
|
||||
ss << ".";
|
||||
ss << minor_version(version);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
const char *as_string(Chunk::Entity e)
|
||||
@@ -127,7 +135,7 @@ namespace OMFormat {
|
||||
default:
|
||||
std::clog << "as_string(Chunk::Entity): Invalid value!";
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -145,7 +153,7 @@ namespace OMFormat {
|
||||
case Chunk::Type_Custom: return "Custom";
|
||||
case Chunk::Type_Topology: return "Topology";
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,7 +172,7 @@ namespace OMFormat {
|
||||
case Chunk::Dim_7D: return "7D";
|
||||
case Chunk::Dim_8D: return "8D";
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -179,7 +187,7 @@ namespace OMFormat {
|
||||
case Chunk::Integer_32 : return "32";
|
||||
case Chunk::Integer_64 : return "64";
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *as_string(Chunk::Float_Size d)
|
||||
@@ -190,7 +198,7 @@ namespace OMFormat {
|
||||
case Chunk::Float_64 : return "64";
|
||||
case Chunk::Float_128: return "128";
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
@@ -238,6 +246,9 @@ namespace OMFormat {
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
} // namespace OMFormat
|
||||
// --------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#ifndef OPENMESH_IO_OMFORMAT_HH
|
||||
@@ -257,7 +252,7 @@ namespace OMFormat {
|
||||
|
||||
PropertyName( ) { }
|
||||
|
||||
PropertyName( const std::string& _name ) { *this = _name; }
|
||||
explicit PropertyName( const std::string& _name ) { *this = _name; }
|
||||
|
||||
bool is_valid() const { return is_valid( size() ); }
|
||||
|
||||
@@ -294,7 +289,7 @@ namespace OMFormat {
|
||||
inline size_t chunk_header_size( void ) { return sizeof(uint16); }
|
||||
|
||||
|
||||
/// Return the size of a scale in bytes.
|
||||
/// Return the size of a scaler in bytes.
|
||||
inline size_t scalar_size( const Chunk::Header& _hdr )
|
||||
{
|
||||
return _hdr.float_ ? (0x01 << _hdr.bits_) : (0x04 << _hdr.bits_);
|
||||
@@ -355,6 +350,16 @@ namespace OMFormat {
|
||||
#endif
|
||||
}
|
||||
|
||||
template <typename T> bool is_double(const T&)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
template <> inline bool is_double(const double&)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename T> bool is_integer(const T)
|
||||
{
|
||||
#if defined(OM_MISSING_HEADER_LIMITS)
|
||||
@@ -469,6 +474,8 @@ namespace OMFormat {
|
||||
|
||||
// ---------------------------------------- convenience functions
|
||||
|
||||
std::string as_string(uint8 version);
|
||||
|
||||
const char *as_string(Chunk::Type t);
|
||||
const char *as_string(Chunk::Entity e);
|
||||
const char *as_string(Chunk::Dim d);
|
||||
@@ -744,7 +751,7 @@ namespace OMFormat {
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_IO_OMFORMAT_CC)
|
||||
# define OPENMESH_IO_OMFORMAT_TEMPLATES
|
||||
# include "OMFormatT.cc"
|
||||
# include "OMFormatT_impl.hh"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#ifndef OPENMESH_IO_OPTIONS_HH
|
||||
@@ -115,7 +110,8 @@ public:
|
||||
FaceTexCoord = 0x0400, ///< Has (r) / store (w) face texture coordinates
|
||||
ColorAlpha = 0x0800, ///< Has (r) / store (w) alpha values for colors
|
||||
ColorFloat = 0x1000, ///< Has (r) / store (w) float values for colors (currently only implemented for PLY and OFF files)
|
||||
Custom = 0x2000 ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version)
|
||||
Custom = 0x2000, ///< Has (r) custom properties (currently only implemented in PLY Reader ASCII version)
|
||||
Status = 0x4000 ///< Has (r) / store (w) status properties
|
||||
};
|
||||
|
||||
public:
|
||||
@@ -206,10 +202,14 @@ public:
|
||||
bool vertex_has_normal() const { return check(VertexNormal); }
|
||||
bool vertex_has_color() const { return check(VertexColor); }
|
||||
bool vertex_has_texcoord() const { return check(VertexTexCoord); }
|
||||
bool vertex_has_status() const { return check(Status); }
|
||||
bool edge_has_color() const { return check(EdgeColor); }
|
||||
bool edge_has_status() const { return check(Status); }
|
||||
bool halfedge_has_status() const { return check(Status); }
|
||||
bool face_has_normal() const { return check(FaceNormal); }
|
||||
bool face_has_color() const { return check(FaceColor); }
|
||||
bool face_has_texcoord() const { return check(FaceTexCoord); }
|
||||
bool face_has_status() const { return check(Status); }
|
||||
bool color_has_alpha() const { return check(ColorAlpha); }
|
||||
bool color_is_float() const { return check(ColorFloat); }
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -95,21 +90,27 @@ public:
|
||||
|
||||
// get vertex data
|
||||
virtual Vec3f point(VertexHandle _vh) const = 0;
|
||||
virtual Vec3d pointd(VertexHandle _vh) const = 0;
|
||||
virtual bool is_point_double() const = 0;
|
||||
virtual Vec3f normal(VertexHandle _vh) const = 0;
|
||||
virtual Vec3d normald(VertexHandle _vh) const = 0;
|
||||
virtual bool is_normal_double() const = 0;
|
||||
virtual Vec3uc color(VertexHandle _vh) const = 0;
|
||||
virtual Vec4uc colorA(VertexHandle _vh) const = 0;
|
||||
virtual Vec3ui colori(VertexHandle _vh) const = 0;
|
||||
virtual Vec4ui colorAi(VertexHandle _vh) const = 0;
|
||||
virtual Vec3ui colori(VertexHandle _vh) const = 0;
|
||||
virtual Vec4ui colorAi(VertexHandle _vh) const = 0;
|
||||
virtual Vec3f colorf(VertexHandle _vh) const = 0;
|
||||
virtual Vec4f colorAf(VertexHandle _vh) const = 0;
|
||||
virtual Vec2f texcoord(VertexHandle _vh) const = 0;
|
||||
virtual Vec2f texcoord(HalfedgeHandle _heh) const = 0;
|
||||
virtual OpenMesh::Attributes::StatusInfo status(VertexHandle _vh) const = 0;
|
||||
|
||||
|
||||
// get face data
|
||||
virtual unsigned int
|
||||
get_vhandles(FaceHandle _fh,
|
||||
std::vector<VertexHandle>& _vhandles) const=0;
|
||||
|
||||
///
|
||||
/// \brief getHeh returns the HalfEdgeHandle that belongs to the face
|
||||
/// specified by _fh and has a toVertexHandle that corresponds to _vh.
|
||||
@@ -121,12 +122,14 @@ public:
|
||||
virtual unsigned int
|
||||
get_face_texcoords(std::vector<Vec2f>& _hehandles) const = 0;
|
||||
virtual Vec3f normal(FaceHandle _fh) const = 0;
|
||||
virtual Vec3d normald(FaceHandle _fh) const = 0;
|
||||
virtual Vec3uc color (FaceHandle _fh) const = 0;
|
||||
virtual Vec4uc colorA(FaceHandle _fh) const = 0;
|
||||
virtual Vec3ui colori(FaceHandle _fh) const = 0;
|
||||
virtual Vec4ui colorAi(FaceHandle _fh) const = 0;
|
||||
virtual Vec3f colorf(FaceHandle _fh) const = 0;
|
||||
virtual Vec4f colorAf(FaceHandle _fh) const = 0;
|
||||
virtual OpenMesh::Attributes::StatusInfo status(FaceHandle _fh) const = 0;
|
||||
|
||||
// get edge data
|
||||
virtual Vec3uc color(EdgeHandle _eh) const = 0;
|
||||
@@ -135,9 +138,18 @@ public:
|
||||
virtual Vec4ui colorAi(EdgeHandle _eh) const = 0;
|
||||
virtual Vec3f colorf(EdgeHandle _eh) const = 0;
|
||||
virtual Vec4f colorAf(EdgeHandle _eh) const = 0;
|
||||
virtual OpenMesh::Attributes::StatusInfo status(EdgeHandle _eh) const = 0;
|
||||
|
||||
// get halfedge data
|
||||
virtual int get_halfedge_id(VertexHandle _vh) = 0;
|
||||
virtual int get_halfedge_id(FaceHandle _vh) = 0;
|
||||
virtual int get_next_halfedge_id(HalfedgeHandle _heh) = 0;
|
||||
virtual int get_to_vertex_id(HalfedgeHandle _heh) = 0;
|
||||
virtual int get_face_id(HalfedgeHandle _heh) = 0;
|
||||
virtual OpenMesh::Attributes::StatusInfo status(HalfedgeHandle _heh) const = 0;
|
||||
|
||||
// get reference to base kernel
|
||||
virtual const BaseKernel* kernel() { return 0; }
|
||||
virtual const BaseKernel* kernel() { return nullptr; }
|
||||
|
||||
|
||||
// query number of faces, vertices, normals, texcoords
|
||||
@@ -150,10 +162,14 @@ public:
|
||||
virtual bool is_triangle_mesh() const { return false; }
|
||||
virtual bool has_vertex_normals() const { return false; }
|
||||
virtual bool has_vertex_colors() const { return false; }
|
||||
virtual bool has_vertex_status() const { return false; }
|
||||
virtual bool has_vertex_texcoords() const { return false; }
|
||||
virtual bool has_edge_colors() const { return false; }
|
||||
virtual bool has_edge_status() const { return false; }
|
||||
virtual bool has_halfedge_status() const { return false; }
|
||||
virtual bool has_face_normals() const { return false; }
|
||||
virtual bool has_face_colors() const { return false; }
|
||||
virtual bool has_face_status() const { return false; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -70,6 +65,7 @@
|
||||
#include <OpenMesh/Core/Utils/vector_cast.hh>
|
||||
#include <OpenMesh/Core/Utils/color_cast.hh>
|
||||
#include <OpenMesh/Core/IO/exporter/BaseExporter.hh>
|
||||
#include <OpenMesh/Core/IO/OMFormat.hh>
|
||||
|
||||
|
||||
//=== NAMESPACES ==============================================================
|
||||
@@ -89,66 +85,88 @@ class ExporterT : public BaseExporter
|
||||
public:
|
||||
|
||||
// Constructor
|
||||
ExporterT(const Mesh& _mesh) : mesh_(_mesh) {}
|
||||
explicit ExporterT(const Mesh& _mesh) : mesh_(_mesh) {}
|
||||
|
||||
|
||||
// get vertex data
|
||||
|
||||
Vec3f point(VertexHandle _vh) const
|
||||
Vec3f point(VertexHandle _vh) const override
|
||||
{
|
||||
return vector_cast<Vec3f>(mesh_.point(_vh));
|
||||
}
|
||||
|
||||
Vec3f normal(VertexHandle _vh) const
|
||||
Vec3d pointd(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_normals()
|
||||
? vector_cast<Vec3f>(mesh_.normal(_vh))
|
||||
: Vec3f(0.0f, 0.0f, 0.0f));
|
||||
return vector_cast<Vec3d>(mesh_.point(_vh));
|
||||
}
|
||||
|
||||
Vec3uc color(VertexHandle _vh) const
|
||||
bool is_point_double() const override
|
||||
{
|
||||
return OMFormat::is_double(typename Mesh::Point()[0]);
|
||||
}
|
||||
|
||||
bool is_normal_double() const override
|
||||
{
|
||||
return OMFormat::is_double(typename Mesh::Normal()[0]);
|
||||
}
|
||||
|
||||
Vec3f normal(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_normals()
|
||||
? vector_cast<Vec3f>(mesh_.normal(_vh))
|
||||
: Vec3f(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
Vec3d normald(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_normals()
|
||||
? vector_cast<Vec3d>(mesh_.normal(_vh))
|
||||
: Vec3d(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
Vec3uc color(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
? color_cast<Vec3uc>(mesh_.color(_vh))
|
||||
: Vec3uc(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4uc colorA(VertexHandle _vh) const
|
||||
Vec4uc colorA(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
? color_cast<Vec4uc>(mesh_.color(_vh))
|
||||
: Vec4uc(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
Vec3ui colori(VertexHandle _vh) const
|
||||
Vec3ui colori(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
? color_cast<Vec3ui>(mesh_.color(_vh))
|
||||
: Vec3ui(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4ui colorAi(VertexHandle _vh) const
|
||||
Vec4ui colorAi(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
? color_cast<Vec4ui>(mesh_.color(_vh))
|
||||
: Vec4ui(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
Vec3f colorf(VertexHandle _vh) const
|
||||
Vec3f colorf(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
? color_cast<Vec3f>(mesh_.color(_vh))
|
||||
: Vec3f(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4f colorAf(VertexHandle _vh) const
|
||||
Vec4f colorAf(VertexHandle _vh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
? color_cast<Vec4f>(mesh_.color(_vh))
|
||||
: Vec4f(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
Vec2f texcoord(VertexHandle _vh) const
|
||||
Vec2f texcoord(VertexHandle _vh) const override
|
||||
{
|
||||
#if defined(OM_CC_GCC) && (OM_CC_VERSION<30000)
|
||||
// Workaround!
|
||||
@@ -164,61 +182,109 @@ public:
|
||||
#endif
|
||||
}
|
||||
|
||||
Vec2f texcoord(HalfedgeHandle _heh) const
|
||||
Vec2f texcoord(HalfedgeHandle _heh) const override
|
||||
{
|
||||
return (mesh_.has_halfedge_texcoords2D()
|
||||
? vector_cast<Vec2f>(mesh_.texcoord2D(_heh))
|
||||
: Vec2f(0.0f, 0.0f));
|
||||
}
|
||||
|
||||
OpenMesh::Attributes::StatusInfo status(VertexHandle _vh) const override
|
||||
{
|
||||
if (mesh_.has_vertex_status())
|
||||
return mesh_.status(_vh);
|
||||
return OpenMesh::Attributes::StatusInfo();
|
||||
}
|
||||
|
||||
// get edge data
|
||||
|
||||
Vec3uc color(EdgeHandle _eh) const
|
||||
Vec3uc color(EdgeHandle _eh) const override
|
||||
{
|
||||
return (mesh_.has_edge_colors()
|
||||
? color_cast<Vec3uc>(mesh_.color(_eh))
|
||||
: Vec3uc(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4uc colorA(EdgeHandle _eh) const
|
||||
Vec4uc colorA(EdgeHandle _eh) const override
|
||||
{
|
||||
return (mesh_.has_edge_colors()
|
||||
? color_cast<Vec4uc>(mesh_.color(_eh))
|
||||
: Vec4uc(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
Vec3ui colori(EdgeHandle _eh) const
|
||||
Vec3ui colori(EdgeHandle _eh) const override
|
||||
{
|
||||
return (mesh_.has_edge_colors()
|
||||
? color_cast<Vec3ui>(mesh_.color(_eh))
|
||||
: Vec3ui(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4ui colorAi(EdgeHandle _eh) const
|
||||
Vec4ui colorAi(EdgeHandle _eh) const override
|
||||
{
|
||||
return (mesh_.has_edge_colors()
|
||||
? color_cast<Vec4ui>(mesh_.color(_eh))
|
||||
: Vec4ui(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
Vec3f colorf(EdgeHandle _eh) const
|
||||
Vec3f colorf(EdgeHandle _eh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
? color_cast<Vec3f>(mesh_.color(_eh))
|
||||
: Vec3f(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4f colorAf(EdgeHandle _eh) const
|
||||
Vec4f colorAf(EdgeHandle _eh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
? color_cast<Vec4f>(mesh_.color(_eh))
|
||||
: Vec4f(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
OpenMesh::Attributes::StatusInfo status(EdgeHandle _eh) const override
|
||||
{
|
||||
if (mesh_.has_edge_status())
|
||||
return mesh_.status(_eh);
|
||||
return OpenMesh::Attributes::StatusInfo();
|
||||
}
|
||||
|
||||
// get halfedge data
|
||||
|
||||
int get_halfedge_id(VertexHandle _vh) override
|
||||
{
|
||||
return mesh_.halfedge_handle(_vh).idx();
|
||||
}
|
||||
|
||||
int get_halfedge_id(FaceHandle _fh) override
|
||||
{
|
||||
return mesh_.halfedge_handle(_fh).idx();
|
||||
}
|
||||
|
||||
int get_next_halfedge_id(HalfedgeHandle _heh) override
|
||||
{
|
||||
return mesh_.next_halfedge_handle(_heh).idx();
|
||||
}
|
||||
|
||||
int get_to_vertex_id(HalfedgeHandle _heh) override
|
||||
{
|
||||
return mesh_.to_vertex_handle(_heh).idx();
|
||||
}
|
||||
|
||||
int get_face_id(HalfedgeHandle _heh) override
|
||||
{
|
||||
return mesh_.face_handle(_heh).idx();
|
||||
}
|
||||
|
||||
OpenMesh::Attributes::StatusInfo status(HalfedgeHandle _heh) const override
|
||||
{
|
||||
if (mesh_.has_halfedge_status())
|
||||
return mesh_.status(_heh);
|
||||
return OpenMesh::Attributes::StatusInfo();
|
||||
}
|
||||
|
||||
// get face data
|
||||
|
||||
unsigned int get_vhandles(FaceHandle _fh,
|
||||
std::vector<VertexHandle>& _vhandles) const
|
||||
std::vector<VertexHandle>& _vhandles) const override
|
||||
{
|
||||
unsigned int count(0);
|
||||
_vhandles.clear();
|
||||
@@ -230,7 +296,7 @@ public:
|
||||
return count;
|
||||
}
|
||||
|
||||
unsigned int get_face_texcoords(std::vector<Vec2f>& _hehandles) const
|
||||
unsigned int get_face_texcoords(std::vector<Vec2f>& _hehandles) const override
|
||||
{
|
||||
unsigned int count(0);
|
||||
_hehandles.clear();
|
||||
@@ -244,7 +310,7 @@ public:
|
||||
return count;
|
||||
}
|
||||
|
||||
HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const
|
||||
HalfedgeHandle getHeh(FaceHandle _fh, VertexHandle _vh) const override
|
||||
{
|
||||
typename Mesh::ConstFaceHalfedgeIter fh_it;
|
||||
for(fh_it = mesh_.cfh_iter(_fh); fh_it.is_valid();++fh_it)
|
||||
@@ -255,74 +321,92 @@ public:
|
||||
return *fh_it;
|
||||
}
|
||||
|
||||
Vec3f normal(FaceHandle _fh) const
|
||||
Vec3f normal(FaceHandle _fh) const override
|
||||
{
|
||||
return (mesh_.has_face_normals()
|
||||
? vector_cast<Vec3f>(mesh_.normal(_fh))
|
||||
: Vec3f(0.0f, 0.0f, 0.0f));
|
||||
}
|
||||
|
||||
Vec3uc color(FaceHandle _fh) const
|
||||
Vec3d normald(FaceHandle _fh) const override
|
||||
{
|
||||
return (mesh_.has_face_normals()
|
||||
? vector_cast<Vec3d>(mesh_.normal(_fh))
|
||||
: Vec3d(0.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
Vec3uc color(FaceHandle _fh) const override
|
||||
{
|
||||
return (mesh_.has_face_colors()
|
||||
? color_cast<Vec3uc>(mesh_.color(_fh))
|
||||
: Vec3uc(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4uc colorA(FaceHandle _fh) const
|
||||
Vec4uc colorA(FaceHandle _fh) const override
|
||||
{
|
||||
return (mesh_.has_face_colors()
|
||||
? color_cast<Vec4uc>(mesh_.color(_fh))
|
||||
: Vec4uc(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
Vec3ui colori(FaceHandle _fh) const
|
||||
Vec3ui colori(FaceHandle _fh) const override
|
||||
{
|
||||
return (mesh_.has_face_colors()
|
||||
? color_cast<Vec3ui>(mesh_.color(_fh))
|
||||
: Vec3ui(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4ui colorAi(FaceHandle _fh) const
|
||||
Vec4ui colorAi(FaceHandle _fh) const override
|
||||
{
|
||||
return (mesh_.has_face_colors()
|
||||
? color_cast<Vec4ui>(mesh_.color(_fh))
|
||||
: Vec4ui(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
Vec3f colorf(FaceHandle _fh) const
|
||||
Vec3f colorf(FaceHandle _fh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
return (mesh_.has_face_colors()
|
||||
? color_cast<Vec3f>(mesh_.color(_fh))
|
||||
: Vec3f(0, 0, 0));
|
||||
}
|
||||
|
||||
Vec4f colorAf(FaceHandle _fh) const
|
||||
Vec4f colorAf(FaceHandle _fh) const override
|
||||
{
|
||||
return (mesh_.has_vertex_colors()
|
||||
return (mesh_.has_face_colors()
|
||||
? color_cast<Vec4f>(mesh_.color(_fh))
|
||||
: Vec4f(0, 0, 0, 0));
|
||||
}
|
||||
|
||||
virtual const BaseKernel* kernel() { return &mesh_; }
|
||||
OpenMesh::Attributes::StatusInfo status(FaceHandle _fh) const override
|
||||
{
|
||||
if (mesh_.has_face_status())
|
||||
return mesh_.status(_fh);
|
||||
return OpenMesh::Attributes::StatusInfo();
|
||||
}
|
||||
|
||||
virtual const BaseKernel* kernel() override { return &mesh_; }
|
||||
|
||||
|
||||
// query number of faces, vertices, normals, texcoords
|
||||
size_t n_vertices() const { return mesh_.n_vertices(); }
|
||||
size_t n_faces() const { return mesh_.n_faces(); }
|
||||
size_t n_edges() const { return mesh_.n_edges(); }
|
||||
size_t n_vertices() const override { return mesh_.n_vertices(); }
|
||||
size_t n_faces() const override { return mesh_.n_faces(); }
|
||||
size_t n_edges() const override { return mesh_.n_edges(); }
|
||||
|
||||
|
||||
// property information
|
||||
bool is_triangle_mesh() const
|
||||
bool is_triangle_mesh() const override
|
||||
{ return Mesh::is_triangles(); }
|
||||
|
||||
bool has_vertex_normals() const { return mesh_.has_vertex_normals(); }
|
||||
bool has_vertex_colors() const { return mesh_.has_vertex_colors(); }
|
||||
bool has_vertex_texcoords() const { return mesh_.has_vertex_texcoords2D(); }
|
||||
bool has_edge_colors() const { return mesh_.has_edge_colors(); }
|
||||
bool has_face_normals() const { return mesh_.has_face_normals(); }
|
||||
bool has_face_colors() const { return mesh_.has_face_colors(); }
|
||||
bool has_vertex_normals() const override { return mesh_.has_vertex_normals(); }
|
||||
bool has_vertex_colors() const override { return mesh_.has_vertex_colors(); }
|
||||
bool has_vertex_texcoords() const override { return mesh_.has_vertex_texcoords2D(); }
|
||||
bool has_vertex_status() const override { return mesh_.has_vertex_status(); }
|
||||
bool has_edge_colors() const override { return mesh_.has_edge_colors(); }
|
||||
bool has_edge_status() const override { return mesh_.has_edge_status(); }
|
||||
bool has_halfedge_status() const override { return mesh_.has_halfedge_status(); }
|
||||
bool has_face_normals() const override { return mesh_.has_face_normals(); }
|
||||
bool has_face_colors() const override { return mesh_.has_face_colors(); }
|
||||
bool has_face_status() const override { return mesh_.has_face_status(); }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -96,13 +91,22 @@ public:
|
||||
// add a vertex with coordinate \c _point
|
||||
virtual VertexHandle add_vertex(const Vec3f& _point) = 0;
|
||||
|
||||
// add a vertex with coordinate \c _point
|
||||
virtual VertexHandle add_vertex(const Vec3d& _point) { return add_vertex(Vec3f(_point)); }
|
||||
|
||||
// add a vertex without coordinate. Use set_point to set the position deferred
|
||||
virtual VertexHandle add_vertex() = 0;
|
||||
|
||||
// add an edge. Use set_next, set_vertex and set_face to set corresponding entities for halfedges
|
||||
virtual HalfedgeHandle add_edge(VertexHandle _vh0, VertexHandle _vh1) = 0;
|
||||
|
||||
// add a face with indices _indices refering to vertices
|
||||
typedef std::vector<VertexHandle> VHandles;
|
||||
virtual FaceHandle add_face(const VHandles& _indices) = 0;
|
||||
|
||||
// add a face with incident halfedge
|
||||
virtual FaceHandle add_face(HalfedgeHandle _heh) = 0;
|
||||
|
||||
// add texture coordinates per face, _vh references the first texcoord
|
||||
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords) = 0;
|
||||
|
||||
@@ -115,9 +119,15 @@ public:
|
||||
// Set coordinate of the given vertex. Use this function, if you created a vertex without coordinate
|
||||
virtual void set_point(VertexHandle _vh, const Vec3f& _point) = 0;
|
||||
|
||||
// Set outgoing halfedge for the given vertex.
|
||||
virtual void set_halfedge(VertexHandle _vh, HalfedgeHandle _heh) = 0;
|
||||
|
||||
// set vertex normal
|
||||
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) = 0;
|
||||
|
||||
// set vertex normal
|
||||
virtual void set_normal(VertexHandle _vh, const Vec3d& _normal) = 0;
|
||||
|
||||
// set vertex color
|
||||
virtual void set_color(VertexHandle _vh, const Vec3uc& _color) = 0;
|
||||
|
||||
@@ -133,6 +143,15 @@ public:
|
||||
// set vertex texture coordinate
|
||||
virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) = 0;
|
||||
|
||||
// set vertex status
|
||||
virtual void set_status(VertexHandle _vh, const OpenMesh::Attributes::StatusInfo& _status) = 0;
|
||||
|
||||
// set next halfedge handle
|
||||
virtual void set_next(HalfedgeHandle _heh, HalfedgeHandle _next) = 0;
|
||||
|
||||
// set incident face handle for given halfedge
|
||||
virtual void set_face(HalfedgeHandle _heh, FaceHandle _fh) = 0;
|
||||
|
||||
// set vertex texture coordinate
|
||||
virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) = 0;
|
||||
|
||||
@@ -142,6 +161,9 @@ public:
|
||||
// set 3d vertex texture coordinate
|
||||
virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) = 0;
|
||||
|
||||
// set halfedge status
|
||||
virtual void set_status(HalfedgeHandle _heh, const OpenMesh::Attributes::StatusInfo& _status) = 0;
|
||||
|
||||
// set edge color
|
||||
virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) = 0;
|
||||
|
||||
@@ -154,9 +176,15 @@ public:
|
||||
// set edge color
|
||||
virtual void set_color(EdgeHandle _eh, const Vec4f& _color) = 0;
|
||||
|
||||
// set edge status
|
||||
virtual void set_status(EdgeHandle _eh, const OpenMesh::Attributes::StatusInfo& _status) = 0;
|
||||
|
||||
// set face normal
|
||||
virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) = 0;
|
||||
|
||||
// set face normal
|
||||
virtual void set_normal(FaceHandle _fh, const Vec3d& _normal) = 0;
|
||||
|
||||
// set face color
|
||||
virtual void set_color(FaceHandle _fh, const Vec3uc& _color) = 0;
|
||||
|
||||
@@ -169,12 +197,15 @@ public:
|
||||
// set face color
|
||||
virtual void set_color(FaceHandle _fh, const Vec4f& _color) = 0;
|
||||
|
||||
// set face status
|
||||
virtual void set_status(FaceHandle _fh, const OpenMesh::Attributes::StatusInfo& _status) = 0;
|
||||
|
||||
// Store a property in the mesh mapping from an int to a texture file
|
||||
// Use set_face_texindex to set the index for each face
|
||||
virtual void add_texture_information( int _id , std::string _name ) = 0;
|
||||
|
||||
// get reference to base kernel
|
||||
virtual BaseKernel* kernel() { return 0; }
|
||||
virtual BaseKernel* kernel() { return nullptr; }
|
||||
|
||||
virtual bool is_triangle_mesh() const { return false; }
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -94,20 +89,30 @@ public:
|
||||
typedef std::vector<VertexHandle> VHandles;
|
||||
|
||||
|
||||
ImporterT(Mesh& _mesh) : mesh_(_mesh), halfedgeNormals_() {}
|
||||
explicit ImporterT(Mesh& _mesh) : mesh_(_mesh), halfedgeNormals_() {}
|
||||
|
||||
|
||||
virtual VertexHandle add_vertex(const Vec3f& _point)
|
||||
virtual VertexHandle add_vertex(const Vec3f& _point) override
|
||||
{
|
||||
return mesh_.add_vertex(vector_cast<Point>(_point));
|
||||
}
|
||||
|
||||
virtual VertexHandle add_vertex()
|
||||
virtual VertexHandle add_vertex(const Vec3d& _point) override
|
||||
{
|
||||
return mesh_.add_vertex(vector_cast<Point>(_point));
|
||||
}
|
||||
|
||||
virtual VertexHandle add_vertex() override
|
||||
{
|
||||
return mesh_.new_vertex();
|
||||
}
|
||||
|
||||
virtual FaceHandle add_face(const VHandles& _indices)
|
||||
virtual HalfedgeHandle add_edge(VertexHandle _vh0, VertexHandle _vh1) override
|
||||
{
|
||||
return mesh_.new_edge(_vh0, _vh1);
|
||||
}
|
||||
|
||||
virtual FaceHandle add_face(const VHandles& _indices) override
|
||||
{
|
||||
FaceHandle fh;
|
||||
|
||||
@@ -192,14 +197,26 @@ public:
|
||||
return fh;
|
||||
}
|
||||
|
||||
virtual FaceHandle add_face(HalfedgeHandle _heh) override
|
||||
{
|
||||
auto fh = mesh_.new_face();
|
||||
mesh_.set_halfedge_handle(fh, _heh);
|
||||
return fh;
|
||||
}
|
||||
|
||||
// vertex attributes
|
||||
|
||||
virtual void set_point(VertexHandle _vh, const Vec3f& _point)
|
||||
virtual void set_point(VertexHandle _vh, const Vec3f& _point) override
|
||||
{
|
||||
mesh_.set_point(_vh,vector_cast<Point>(_point));
|
||||
}
|
||||
|
||||
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal)
|
||||
virtual void set_halfedge(VertexHandle _vh, HalfedgeHandle _heh) override
|
||||
{
|
||||
mesh_.set_halfedge_handle(_vh, _heh);
|
||||
}
|
||||
|
||||
virtual void set_normal(VertexHandle _vh, const Vec3f& _normal) override
|
||||
{
|
||||
if (mesh_.has_vertex_normals())
|
||||
mesh_.set_normal(_vh, vector_cast<Normal>(_normal));
|
||||
@@ -210,114 +227,169 @@ public:
|
||||
halfedgeNormals_[_vh] = vector_cast<Normal>(_normal);
|
||||
}
|
||||
|
||||
virtual void set_color(VertexHandle _vh, const Vec4uc& _color)
|
||||
virtual void set_normal(VertexHandle _vh, const Vec3d& _normal) override
|
||||
{
|
||||
if (mesh_.has_vertex_normals())
|
||||
mesh_.set_normal(_vh, vector_cast<Normal>(_normal));
|
||||
|
||||
//saves normals for half edges.
|
||||
//they will be written, when the face is added
|
||||
if (mesh_.has_halfedge_normals())
|
||||
halfedgeNormals_[_vh] = vector_cast<Normal>(_normal);
|
||||
}
|
||||
|
||||
virtual void set_color(VertexHandle _vh, const Vec4uc& _color) override
|
||||
{
|
||||
if (mesh_.has_vertex_colors())
|
||||
mesh_.set_color(_vh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(VertexHandle _vh, const Vec3uc& _color)
|
||||
virtual void set_color(VertexHandle _vh, const Vec3uc& _color) override
|
||||
{
|
||||
if (mesh_.has_vertex_colors())
|
||||
mesh_.set_color(_vh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(VertexHandle _vh, const Vec4f& _color)
|
||||
virtual void set_color(VertexHandle _vh, const Vec4f& _color) override
|
||||
{
|
||||
if (mesh_.has_vertex_colors())
|
||||
mesh_.set_color(_vh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(VertexHandle _vh, const Vec3f& _color)
|
||||
virtual void set_color(VertexHandle _vh, const Vec3f& _color) override
|
||||
{
|
||||
if (mesh_.has_vertex_colors())
|
||||
mesh_.set_color(_vh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord)
|
||||
virtual void set_texcoord(VertexHandle _vh, const Vec2f& _texcoord) override
|
||||
{
|
||||
if (mesh_.has_vertex_texcoords2D())
|
||||
mesh_.set_texcoord2D(_vh, vector_cast<TexCoord2D>(_texcoord));
|
||||
}
|
||||
|
||||
virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord)
|
||||
virtual void set_status(VertexHandle _vh, const OpenMesh::Attributes::StatusInfo& _status) override
|
||||
{
|
||||
if (!mesh_.has_vertex_status())
|
||||
mesh_.request_vertex_status();
|
||||
mesh_.status(_vh) = _status;
|
||||
}
|
||||
|
||||
virtual void set_next(HalfedgeHandle _heh, HalfedgeHandle _next) override
|
||||
{
|
||||
mesh_.set_next_halfedge_handle(_heh, _next);
|
||||
}
|
||||
|
||||
virtual void set_face(HalfedgeHandle _heh, FaceHandle _fh) override
|
||||
{
|
||||
mesh_.set_face_handle(_heh, _fh);
|
||||
}
|
||||
|
||||
|
||||
virtual void set_texcoord(HalfedgeHandle _heh, const Vec2f& _texcoord) override
|
||||
{
|
||||
if (mesh_.has_halfedge_texcoords2D())
|
||||
mesh_.set_texcoord2D(_heh, vector_cast<TexCoord2D>(_texcoord));
|
||||
}
|
||||
|
||||
virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord)
|
||||
virtual void set_texcoord(VertexHandle _vh, const Vec3f& _texcoord) override
|
||||
{
|
||||
if (mesh_.has_vertex_texcoords3D())
|
||||
mesh_.set_texcoord3D(_vh, vector_cast<TexCoord3D>(_texcoord));
|
||||
}
|
||||
|
||||
virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord)
|
||||
virtual void set_texcoord(HalfedgeHandle _heh, const Vec3f& _texcoord) override
|
||||
{
|
||||
if (mesh_.has_halfedge_texcoords3D())
|
||||
mesh_.set_texcoord3D(_heh, vector_cast<TexCoord3D>(_texcoord));
|
||||
}
|
||||
|
||||
virtual void set_status(HalfedgeHandle _heh, const OpenMesh::Attributes::StatusInfo& _status) override
|
||||
{
|
||||
if (!mesh_.has_halfedge_status())
|
||||
mesh_.request_halfedge_status();
|
||||
mesh_.status(_heh) = _status;
|
||||
}
|
||||
|
||||
// edge attributes
|
||||
|
||||
virtual void set_color(EdgeHandle _eh, const Vec4uc& _color)
|
||||
virtual void set_color(EdgeHandle _eh, const Vec4uc& _color) override
|
||||
{
|
||||
if (mesh_.has_edge_colors())
|
||||
mesh_.set_color(_eh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(EdgeHandle _eh, const Vec3uc& _color)
|
||||
virtual void set_color(EdgeHandle _eh, const Vec3uc& _color) override
|
||||
{
|
||||
if (mesh_.has_edge_colors())
|
||||
mesh_.set_color(_eh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(EdgeHandle _eh, const Vec4f& _color)
|
||||
virtual void set_color(EdgeHandle _eh, const Vec4f& _color) override
|
||||
{
|
||||
if (mesh_.has_edge_colors())
|
||||
mesh_.set_color(_eh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(EdgeHandle _eh, const Vec3f& _color)
|
||||
virtual void set_color(EdgeHandle _eh, const Vec3f& _color) override
|
||||
{
|
||||
if (mesh_.has_edge_colors())
|
||||
mesh_.set_color(_eh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_status(EdgeHandle _eh, const OpenMesh::Attributes::StatusInfo& _status) override
|
||||
{
|
||||
if (!mesh_.has_edge_status())
|
||||
mesh_.request_edge_status();
|
||||
mesh_.status(_eh) = _status;
|
||||
}
|
||||
|
||||
// face attributes
|
||||
|
||||
virtual void set_normal(FaceHandle _fh, const Vec3f& _normal)
|
||||
virtual void set_normal(FaceHandle _fh, const Vec3f& _normal) override
|
||||
{
|
||||
if (mesh_.has_face_normals())
|
||||
mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
|
||||
}
|
||||
|
||||
virtual void set_color(FaceHandle _fh, const Vec3uc& _color)
|
||||
virtual void set_normal(FaceHandle _fh, const Vec3d& _normal) override
|
||||
{
|
||||
if (mesh_.has_face_normals())
|
||||
mesh_.set_normal(_fh, vector_cast<Normal>(_normal));
|
||||
}
|
||||
|
||||
virtual void set_color(FaceHandle _fh, const Vec3uc& _color) override
|
||||
{
|
||||
if (mesh_.has_face_colors())
|
||||
mesh_.set_color(_fh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(FaceHandle _fh, const Vec4uc& _color)
|
||||
virtual void set_color(FaceHandle _fh, const Vec4uc& _color) override
|
||||
{
|
||||
if (mesh_.has_face_colors())
|
||||
mesh_.set_color(_fh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(FaceHandle _fh, const Vec3f& _color)
|
||||
virtual void set_color(FaceHandle _fh, const Vec3f& _color) override
|
||||
{
|
||||
if (mesh_.has_face_colors())
|
||||
mesh_.set_color(_fh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void set_color(FaceHandle _fh, const Vec4f& _color)
|
||||
virtual void set_color(FaceHandle _fh, const Vec4f& _color) override
|
||||
{
|
||||
if (mesh_.has_face_colors())
|
||||
mesh_.set_color(_fh, color_cast<Color>(_color));
|
||||
}
|
||||
|
||||
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords)
|
||||
virtual void set_status(FaceHandle _fh, const OpenMesh::Attributes::StatusInfo& _status) override
|
||||
{
|
||||
if (!mesh_.has_face_status())
|
||||
mesh_.request_face_status();
|
||||
mesh_.status(_fh) = _status;
|
||||
}
|
||||
|
||||
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec2f>& _face_texcoords) override
|
||||
{
|
||||
// get first halfedge handle
|
||||
HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
|
||||
@@ -334,7 +406,7 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec3f>& _face_texcoords)
|
||||
virtual void add_face_texcoords( FaceHandle _fh, VertexHandle _vh, const std::vector<Vec3f>& _face_texcoords) override
|
||||
{
|
||||
// get first halfedge handle
|
||||
HalfedgeHandle cur_heh = mesh_.halfedge_handle(_fh);
|
||||
@@ -351,13 +423,15 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
virtual void set_face_texindex( FaceHandle _fh, int _texId ) {
|
||||
virtual void set_face_texindex( FaceHandle _fh, int _texId ) override
|
||||
{
|
||||
if ( mesh_.has_face_texture_index() ) {
|
||||
mesh_.set_texture_index(_fh , _texId);
|
||||
}
|
||||
}
|
||||
|
||||
virtual void add_texture_information( int _id , std::string _name ) {
|
||||
virtual void add_texture_information( int _id , std::string _name ) override
|
||||
{
|
||||
OpenMesh::MPropHandleT< std::map< int, std::string > > property;
|
||||
|
||||
if ( !mesh_.get_property_handle(property,"TextureMapping") ) {
|
||||
@@ -370,26 +444,26 @@ public:
|
||||
|
||||
// low-level access to mesh
|
||||
|
||||
virtual BaseKernel* kernel() { return &mesh_; }
|
||||
virtual BaseKernel* kernel() override { return &mesh_; }
|
||||
|
||||
bool is_triangle_mesh() const
|
||||
bool is_triangle_mesh() const override
|
||||
{ return Mesh::is_triangles(); }
|
||||
|
||||
void reserve(unsigned int nV, unsigned int nE, unsigned int nF)
|
||||
void reserve(unsigned int nV, unsigned int nE, unsigned int nF) override
|
||||
{
|
||||
mesh_.reserve(nV, nE, nF);
|
||||
}
|
||||
|
||||
// query number of faces, vertices, normals, texcoords
|
||||
size_t n_vertices() const { return mesh_.n_vertices(); }
|
||||
size_t n_faces() const { return mesh_.n_faces(); }
|
||||
size_t n_edges() const { return mesh_.n_edges(); }
|
||||
size_t n_vertices() const override { return mesh_.n_vertices(); }
|
||||
size_t n_faces() const override { return mesh_.n_faces(); }
|
||||
size_t n_edges() const override { return mesh_.n_edges(); }
|
||||
|
||||
|
||||
void prepare() { }
|
||||
void prepare() override{ }
|
||||
|
||||
|
||||
void finish() { }
|
||||
void finish() override { }
|
||||
|
||||
|
||||
private:
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -53,10 +48,7 @@
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef __BASEREADER_HH__
|
||||
#define __BASEREADER_HH__
|
||||
|
||||
#pragma once
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
@@ -96,7 +88,7 @@ class OPENMESHDLLEXPORT BaseReader
|
||||
public:
|
||||
|
||||
/// Destructor
|
||||
virtual ~BaseReader() {};
|
||||
virtual ~BaseReader() {}
|
||||
|
||||
/// Returns a brief description of the file type that can be parsed.
|
||||
virtual std::string get_description() const = 0;
|
||||
@@ -156,7 +148,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 +169,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;
|
||||
}
|
||||
|
||||
@@ -189,5 +201,3 @@ static inline std::string &trim(std::string &_string) {
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -140,13 +135,13 @@ read(const std::string& _filename, BaseImporter& _bi, Options& _opt)
|
||||
|
||||
{
|
||||
#if defined(WIN32)
|
||||
std::string::size_type dot = _filename.find_last_of("\\/");
|
||||
std::string::size_type dot_pos = _filename.find_last_of("\\/");
|
||||
#else
|
||||
std::string::size_type dot = _filename.rfind("/");
|
||||
std::string::size_type dot_pos = _filename.rfind("/");
|
||||
#endif
|
||||
path_ = (dot == std::string::npos)
|
||||
path_ = (dot_pos == std::string::npos)
|
||||
? "./"
|
||||
: std::string(_filename.substr(0,dot+1));
|
||||
: std::string(_filename.substr(0,dot_pos+1));
|
||||
}
|
||||
|
||||
bool result = read(in, _bi, _opt);
|
||||
@@ -540,6 +535,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;
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -92,16 +87,16 @@ public:
|
||||
|
||||
virtual ~_OBJReader_() { }
|
||||
|
||||
std::string get_description() const { return "Alias/Wavefront"; }
|
||||
std::string get_extensions() const { return "obj"; }
|
||||
std::string get_description() const override { return "Alias/Wavefront"; }
|
||||
std::string get_extensions() const override { return "obj"; }
|
||||
|
||||
bool read(const std::string& _filename,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt);
|
||||
Options& _opt) override;
|
||||
|
||||
bool read(std::istream& _in,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt);
|
||||
Options& _opt) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -110,7 +105,7 @@ private:
|
||||
{
|
||||
public:
|
||||
|
||||
Material() { cleanup(); }
|
||||
Material():Tr_(0),index_Kd_(0) { cleanup(); }
|
||||
|
||||
void cleanup()
|
||||
{
|
||||
@@ -142,7 +137,7 @@ private:
|
||||
void set_Tr( float t )
|
||||
{ Tr_=t; Tr_is_set_=true; }
|
||||
|
||||
void set_map_Kd( std::string _name, int _index_Kd )
|
||||
void set_map_Kd( const std::string& _name, int _index_Kd )
|
||||
{ map_Kd_ = _name, index_Kd_ = _index_Kd; map_Kd_is_set_ = true; };
|
||||
|
||||
const Vec3f& Kd( void ) const { return Kd_; }
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#define LINE_LEN 4096
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -53,10 +48,7 @@
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
#ifndef __OFFREADER_HH__
|
||||
#define __OFFREADER_HH__
|
||||
|
||||
#pragma once
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
@@ -123,17 +115,17 @@ public:
|
||||
/// Destructor
|
||||
virtual ~_OFFReader_() {};
|
||||
|
||||
std::string get_description() const { return "Object File Format"; }
|
||||
std::string get_extensions() const { return "off"; }
|
||||
std::string get_magic() const { return "OFF"; }
|
||||
std::string get_description() const override { return "Object File Format"; }
|
||||
std::string get_extensions() const override { return "off"; }
|
||||
std::string get_magic() const override { return "OFF"; }
|
||||
|
||||
bool read(const std::string& _filename,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt);
|
||||
Options& _opt) override;
|
||||
|
||||
bool can_u_read(const std::string& _filename) const;
|
||||
bool can_u_read(const std::string& _filename) const override;
|
||||
|
||||
bool read(std::istream& _in, BaseImporter& _bi, Options& _opt );
|
||||
bool read(std::istream& _in, BaseImporter& _bi, Options& _opt ) override;
|
||||
|
||||
private:
|
||||
|
||||
@@ -167,5 +159,3 @@ OPENMESHDLLEXPORT _OFFReader_& OFFReader();
|
||||
} // namespace IO
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -61,6 +56,7 @@
|
||||
#include <OpenMesh/Core/Utils/Endian.hh>
|
||||
#include <OpenMesh/Core/IO/OMFormat.hh>
|
||||
#include <OpenMesh/Core/IO/reader/OMReader.hh>
|
||||
#include <OpenMesh/Core/IO/writer/OMWriter.hh>
|
||||
|
||||
|
||||
//=== NAMESPACES ==============================================================
|
||||
@@ -176,6 +172,15 @@ bool _OMReader_::read_binary(std::istream& _is, BaseImporter& _bi, Options& _opt
|
||||
bytes_ += restore(_is, header_, swap);
|
||||
|
||||
|
||||
if (header_.version_ > _OMWriter_::get_version())
|
||||
{
|
||||
omerr() << "File uses .om version " << OMFormat::as_string(header_.version_) << " but reader only "
|
||||
<< "supports up to version " << OMFormat::as_string(_OMWriter_::get_version()) << ".\n"
|
||||
<< "Please update your OpenMesh." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
while (!_is.eof()) {
|
||||
bytes_ += restore(_is, chunk_header_, swap);
|
||||
|
||||
@@ -292,30 +297,67 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi,
|
||||
assert( chunk_header_.entity_ == Chunk::Entity_Vertex);
|
||||
|
||||
OpenMesh::Vec3f v3f;
|
||||
OpenMesh::Vec3d v3d;
|
||||
OpenMesh::Vec2f v2f;
|
||||
OpenMesh::Vec3uc v3uc; // rgb
|
||||
OpenMesh::Attributes::StatusInfo status;
|
||||
|
||||
OMFormat::Chunk::PropertyName custom_prop;
|
||||
|
||||
size_t vidx = 0;
|
||||
switch (chunk_header_.type_) {
|
||||
case Chunk::Type_Pos:
|
||||
assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
|
||||
if (chunk_header_.bits_ == OMFormat::bits(0.0f)) // read floats
|
||||
{
|
||||
assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
|
||||
|
||||
for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
|
||||
bytes_ += vector_restore(_is, v3f, _swap);
|
||||
_bi.add_vertex(v3f);
|
||||
for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
|
||||
bytes_ += vector_restore(_is, v3f, _swap);
|
||||
_bi.add_vertex(v3f);
|
||||
}
|
||||
}
|
||||
else if (chunk_header_.bits_ == OMFormat::bits(0.0)) // read doubles
|
||||
{
|
||||
assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3d::dim()));
|
||||
|
||||
for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
|
||||
bytes_ += vector_restore(_is, v3d, _swap);
|
||||
_bi.add_vertex(v3d);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
omerr() << "unknown Vector size" << std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
case Chunk::Type_Normal:
|
||||
assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
|
||||
|
||||
fileOptions_ += Options::VertexNormal;
|
||||
for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
|
||||
bytes_ += vector_restore(_is, v3f, _swap);
|
||||
if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal())
|
||||
_bi.set_normal(VertexHandle(int(vidx)), v3f);
|
||||
if (chunk_header_.bits_ == OMFormat::bits(0.0f)) // read floats
|
||||
{
|
||||
assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
|
||||
|
||||
fileOptions_ += Options::VertexNormal;
|
||||
for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
|
||||
bytes_ += vector_restore(_is, v3f, _swap);
|
||||
if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal())
|
||||
_bi.set_normal(VertexHandle(int(vidx)), v3f);
|
||||
}
|
||||
}
|
||||
else if (chunk_header_.bits_ == OMFormat::bits(0.0)) // read doubles
|
||||
{
|
||||
assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3d::dim()));
|
||||
|
||||
fileOptions_ += Options::VertexNormal;
|
||||
for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
|
||||
bytes_ += vector_restore(_is, v3d, _swap);
|
||||
if (fileOptions_.vertex_has_normal() && _opt.vertex_has_normal())
|
||||
_bi.set_normal(VertexHandle(int(vidx)), v3d);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
omerr() << "Unknown vertex normal format" << std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -343,6 +385,20 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi,
|
||||
}
|
||||
break;
|
||||
|
||||
case Chunk::Type_Status:
|
||||
{
|
||||
assert( OMFormat::dimensions(chunk_header_) == 1);
|
||||
|
||||
fileOptions_ += Options::Status;
|
||||
|
||||
for (; vidx < header_.n_vertices_ && !_is.eof(); ++vidx) {
|
||||
bytes_ += restore(_is, status, _swap);
|
||||
if (fileOptions_.vertex_has_status() && _opt.vertex_has_status())
|
||||
_bi.set_status(VertexHandle(int(vidx)), status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Chunk::Type_Custom:
|
||||
|
||||
bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_vprop(property_name_), header_.n_vertices_, _swap);
|
||||
@@ -351,13 +407,28 @@ bool _OMReader_::read_binary_vertex_chunk(std::istream &_is, BaseImporter &_bi,
|
||||
|
||||
break;
|
||||
|
||||
case Chunk::Type_Topology:
|
||||
{
|
||||
for (; vidx < header_.n_vertices_; ++vidx)
|
||||
{
|
||||
int halfedge_id = 0;
|
||||
bytes_ += restore( _is, halfedge_id, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
|
||||
|
||||
_bi.set_halfedge(VertexHandle(static_cast<int>(vidx)), HalfedgeHandle(halfedge_id));
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
default: // skip unknown chunks
|
||||
{
|
||||
omerr() << "Unknown chunk type ignored!\n";
|
||||
size_t size_of = header_.n_vertices_ * OMFormat::vector_size(chunk_header_);
|
||||
_is.ignore(size_of);
|
||||
bytes_ += size_of;
|
||||
size_t chunk_size = header_.n_vertices_ * OMFormat::vector_size(chunk_header_);
|
||||
_is.ignore(chunk_size);
|
||||
bytes_ += chunk_size;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// all chunk data has been read..?!
|
||||
@@ -375,35 +446,53 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
|
||||
size_t fidx = 0;
|
||||
OpenMesh::Vec3f v3f; // normal
|
||||
OpenMesh::Vec3d v3d; // normal as double
|
||||
OpenMesh::Vec3uc v3uc; // rgb
|
||||
OpenMesh::Attributes::StatusInfo status;
|
||||
|
||||
switch (chunk_header_.type_) {
|
||||
case Chunk::Type_Topology: {
|
||||
BaseImporter::VHandles vhandles;
|
||||
size_t nV = 0;
|
||||
size_t vidx = 0;
|
||||
case Chunk::Type_Topology:
|
||||
{
|
||||
if (header_.version_ < OMFormat::mk_version(2,0))
|
||||
{
|
||||
// add faces based on vertex indices
|
||||
BaseImporter::VHandles vhandles;
|
||||
size_t nV = 0;
|
||||
size_t vidx = 0;
|
||||
|
||||
switch (header_.mesh_) {
|
||||
case 'T':
|
||||
nV = 3;
|
||||
break;
|
||||
case 'Q':
|
||||
nV = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
for (; fidx < header_.n_faces_; ++fidx) {
|
||||
if (header_.mesh_ == 'P')
|
||||
bytes_ += restore(_is, nV, Chunk::Integer_16, _swap);
|
||||
|
||||
vhandles.clear();
|
||||
for (size_t j = 0; j < nV; ++j) {
|
||||
bytes_ += restore(_is, vidx, Chunk::Integer_Size(chunk_header_.bits_), _swap);
|
||||
|
||||
vhandles.push_back(VertexHandle(int(vidx)));
|
||||
switch (header_.mesh_) {
|
||||
case 'T':
|
||||
nV = 3;
|
||||
break;
|
||||
case 'Q':
|
||||
nV = 4;
|
||||
break;
|
||||
}
|
||||
|
||||
_bi.add_face(vhandles);
|
||||
for (; fidx < header_.n_faces_; ++fidx) {
|
||||
if (header_.mesh_ == 'P')
|
||||
bytes_ += restore(_is, nV, Chunk::Integer_16, _swap);
|
||||
|
||||
vhandles.clear();
|
||||
for (size_t j = 0; j < nV; ++j) {
|
||||
bytes_ += restore(_is, vidx, Chunk::Integer_Size(chunk_header_.bits_), _swap);
|
||||
|
||||
vhandles.push_back(VertexHandle(int(vidx)));
|
||||
}
|
||||
|
||||
_bi.add_face(vhandles);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add faces by simply setting an incident halfedge
|
||||
for (; fidx < header_.n_faces_; ++fidx)
|
||||
{
|
||||
int halfedge_id = 0;
|
||||
bytes_ += restore( _is, halfedge_id, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
|
||||
|
||||
_bi.add_face(HalfedgeHandle(halfedge_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -412,10 +501,26 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
assert( OMFormat::dimensions(chunk_header_) == size_t(OpenMesh::Vec3f::dim()));
|
||||
|
||||
fileOptions_ += Options::FaceNormal;
|
||||
for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
|
||||
bytes_ += vector_restore(_is, v3f, _swap);
|
||||
if( fileOptions_.face_has_normal() && _opt.face_has_normal())
|
||||
_bi.set_normal(FaceHandle(int(fidx)), v3f);
|
||||
|
||||
if (chunk_header_.bits_ == OMFormat::bits(0.0f)) // read floats
|
||||
{
|
||||
for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
|
||||
bytes_ += vector_restore(_is, v3f, _swap);
|
||||
if( fileOptions_.face_has_normal() && _opt.face_has_normal())
|
||||
_bi.set_normal(FaceHandle(int(fidx)), v3f);
|
||||
}
|
||||
}
|
||||
else if (chunk_header_.bits_ == OMFormat::bits(0.0)) // read doubles
|
||||
{
|
||||
for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
|
||||
bytes_ += vector_restore(_is, v3d, _swap);
|
||||
if( fileOptions_.face_has_normal() && _opt.face_has_normal())
|
||||
_bi.set_normal(FaceHandle(int(fidx)), v3d);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
omerr() << "Unknown face normal format" << std::endl;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -430,6 +535,19 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
_bi.set_color(FaceHandle(int(fidx)), v3uc);
|
||||
}
|
||||
break;
|
||||
case Chunk::Type_Status:
|
||||
{
|
||||
assert( OMFormat::dimensions(chunk_header_) == 1);
|
||||
|
||||
fileOptions_ += Options::Status;
|
||||
|
||||
for (; fidx < header_.n_faces_ && !_is.eof(); ++fidx) {
|
||||
bytes_ += restore(_is, status, _swap);
|
||||
if (fileOptions_.face_has_status() && _opt.face_has_status())
|
||||
_bi.set_status(FaceHandle(int(fidx)), status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Chunk::Type_Custom:
|
||||
|
||||
@@ -442,9 +560,9 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
default: // skip unknown chunks
|
||||
{
|
||||
omerr() << "Unknown chunk type ignore!\n";
|
||||
size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
|
||||
_is.ignore(size_of);
|
||||
bytes_ += size_of;
|
||||
size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_);
|
||||
_is.ignore(chunk_size);
|
||||
bytes_ += chunk_size;
|
||||
}
|
||||
}
|
||||
return fidx == header_.n_faces_;
|
||||
@@ -453,7 +571,7 @@ bool _OMReader_::read_binary_face_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Options &/*_opt */, bool _swap) const
|
||||
bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Options &_opt, bool _swap) const
|
||||
{
|
||||
using OMFormat::Chunk;
|
||||
|
||||
@@ -461,6 +579,8 @@ bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
|
||||
size_t b = bytes_;
|
||||
|
||||
OpenMesh::Attributes::StatusInfo status;
|
||||
|
||||
switch (chunk_header_.type_) {
|
||||
case Chunk::Type_Custom:
|
||||
|
||||
@@ -468,11 +588,25 @@ bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
|
||||
break;
|
||||
|
||||
case Chunk::Type_Status:
|
||||
{
|
||||
assert( OMFormat::dimensions(chunk_header_) == 1);
|
||||
|
||||
fileOptions_ += Options::Status;
|
||||
|
||||
for (size_t eidx = 0; eidx < header_.n_edges_ && !_is.eof(); ++eidx) {
|
||||
bytes_ += restore(_is, status, _swap);
|
||||
if (fileOptions_.edge_has_status() && _opt.edge_has_status())
|
||||
_bi.set_status(EdgeHandle(int(eidx)), status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// skip unknown type
|
||||
size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
|
||||
_is.ignore(size_of);
|
||||
bytes_ += size_of;
|
||||
size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_);
|
||||
_is.ignore(chunk_size);
|
||||
bytes_ += chunk_size;
|
||||
}
|
||||
|
||||
return b < bytes_;
|
||||
@@ -481,13 +615,14 @@ bool _OMReader_::read_binary_edge_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi, Options &/* _opt */, bool _swap) const
|
||||
bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi, Options & _opt, bool _swap) const
|
||||
{
|
||||
using OMFormat::Chunk;
|
||||
|
||||
assert( chunk_header_.entity_ == Chunk::Entity_Halfedge);
|
||||
|
||||
size_t b = bytes_;
|
||||
OpenMesh::Attributes::StatusInfo status;
|
||||
|
||||
switch (chunk_header_.type_) {
|
||||
case Chunk::Type_Custom:
|
||||
@@ -495,12 +630,61 @@ bool _OMReader_::read_binary_halfedge_chunk(std::istream &_is, BaseImporter &_bi
|
||||
bytes_ += restore_binary_custom_data(_is, _bi.kernel()->_get_hprop(property_name_), 2 * header_.n_edges_, _swap);
|
||||
break;
|
||||
|
||||
case Chunk::Type_Topology:
|
||||
{
|
||||
std::vector<HalfedgeHandle> next_halfedges;
|
||||
for (size_t e_idx = 0; e_idx < header_.n_edges_; ++e_idx)
|
||||
{
|
||||
int next_id_0 = -1;
|
||||
int to_vertex_id_0 = -1;
|
||||
int face_id_0 = -1;
|
||||
bytes_ += restore( _is, next_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
|
||||
bytes_ += restore( _is, to_vertex_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
|
||||
bytes_ += restore( _is, face_id_0, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
|
||||
|
||||
int next_id_1 = -1;
|
||||
int to_vertex_id_1 = -1;
|
||||
int face_id_1 = -1;
|
||||
bytes_ += restore( _is, next_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
|
||||
bytes_ += restore( _is, to_vertex_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
|
||||
bytes_ += restore( _is, face_id_1, OMFormat::Chunk::Integer_Size(chunk_header_.bits_), _swap );
|
||||
|
||||
auto heh0 = _bi.add_edge(VertexHandle(to_vertex_id_1), VertexHandle(to_vertex_id_0));
|
||||
auto heh1 = HalfedgeHandle(heh0.idx() + 1);
|
||||
|
||||
next_halfedges.push_back(HalfedgeHandle(next_id_0));
|
||||
next_halfedges.push_back(HalfedgeHandle(next_id_1));
|
||||
|
||||
_bi.set_face(heh0, FaceHandle(face_id_0));
|
||||
_bi.set_face(heh1, FaceHandle(face_id_1));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < next_halfedges.size(); ++i)
|
||||
_bi.set_next(HalfedgeHandle(static_cast<int>(i)), next_halfedges[i]);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case Chunk::Type_Status:
|
||||
{
|
||||
assert( OMFormat::dimensions(chunk_header_) == 1);
|
||||
|
||||
fileOptions_ += Options::Status;
|
||||
|
||||
for (size_t hidx = 0; hidx < header_.n_edges_ * 2 && !_is.eof(); ++hidx) {
|
||||
bytes_ += restore(_is, status, _swap);
|
||||
if (fileOptions_.halfedge_has_status() && _opt.halfedge_has_status())
|
||||
_bi.set_status(HalfedgeHandle(int(hidx)), status);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// skip unknown chunk
|
||||
omerr() << "Unknown chunk type ignored!\n";
|
||||
size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
|
||||
_is.ignore(size_of);
|
||||
bytes_ += size_of;
|
||||
size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_);
|
||||
_is.ignore(chunk_size);
|
||||
bytes_ += chunk_size;
|
||||
}
|
||||
|
||||
return b < bytes_;
|
||||
@@ -526,9 +710,9 @@ bool _OMReader_::read_binary_mesh_chunk(std::istream &_is, BaseImporter &_bi, Op
|
||||
|
||||
default:
|
||||
// skip unknown chunk
|
||||
size_t size_of = OMFormat::chunk_data_size(header_, chunk_header_);
|
||||
_is.ignore(size_of);
|
||||
bytes_ += size_of;
|
||||
size_t chunk_size = OMFormat::chunk_data_size(header_, chunk_header_);
|
||||
_is.ignore(chunk_size);
|
||||
bytes_ += chunk_size;
|
||||
}
|
||||
|
||||
return b < bytes_;
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -94,20 +89,20 @@ public:
|
||||
_OMReader_();
|
||||
virtual ~_OMReader_() { }
|
||||
|
||||
std::string get_description() const { return "OpenMesh File Format"; }
|
||||
std::string get_extensions() const { return "om"; }
|
||||
std::string get_magic() const { return "OM"; }
|
||||
std::string get_description() const override { return "OpenMesh File Format"; }
|
||||
std::string get_extensions() const override { return "om"; }
|
||||
std::string get_magic() const override { return "OM"; }
|
||||
|
||||
bool read(const std::string& _filename,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt );
|
||||
Options& _opt ) override;
|
||||
|
||||
//! Stream Reader for std::istream input in binary format
|
||||
bool read(std::istream& _is,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt );
|
||||
Options& _opt ) override;
|
||||
|
||||
virtual bool can_u_read(const std::string& _filename) const;
|
||||
virtual bool can_u_read(const std::string& _filename) const override;
|
||||
virtual bool can_u_read(std::istream& _is) const;
|
||||
|
||||
|
||||
|
||||
@@ -39,13 +39,6 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#define LINE_LEN 4096
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -135,6 +128,14 @@ bool _PLYReader_::read(std::istream& _in, BaseImporter& _bi, Options& _opt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Reparse the header
|
||||
if (!can_u_read(_in)) {
|
||||
omerr() << "[PLYReader] : Unable to parse header\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// filter relevant options for reading
|
||||
bool swap = _opt.check(Options::Swap);
|
||||
|
||||
@@ -218,16 +219,13 @@ void _PLYReader_::readCreateCustomProperty(std::istream& _in, BaseImporter& _bi,
|
||||
}
|
||||
|
||||
//init vector
|
||||
int numberOfValues;
|
||||
read(_listType, _in, numberOfValues, OpenMesh::GenProg::Bool2Type<binary>());
|
||||
std::vector<T> vec;
|
||||
vec.reserve(numberOfValues);
|
||||
unsigned int numberOfValues;
|
||||
readInteger(_listType, _in, numberOfValues, OpenMesh::GenProg::Bool2Type<binary>());
|
||||
std::vector<T> vec(numberOfValues);
|
||||
//read and assign
|
||||
for (int i = 0; i < numberOfValues; ++i)
|
||||
for (unsigned int i = 0; i < numberOfValues; ++i)
|
||||
{
|
||||
T in;
|
||||
read(_valueType, _in, in, OpenMesh::GenProg::Bool2Type<binary>());
|
||||
vec.push_back(in);
|
||||
read(_valueType, _in, vec[i], OpenMesh::GenProg::Bool2Type<binary>());
|
||||
}
|
||||
_bi.kernel()->property(prop,_h) = vec;
|
||||
}
|
||||
@@ -281,12 +279,6 @@ void _PLYReader_::readCustomProperty(std::istream& _in, BaseImporter& _bi, Handl
|
||||
|
||||
bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options& _opt) const {
|
||||
|
||||
// Reparse the header
|
||||
if (!can_u_read(_in)) {
|
||||
omerr() << "[PLYReader] : Unable to parse header\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned int i, j, k, l, idx;
|
||||
unsigned int nV;
|
||||
OpenMesh::Vec3f v, n;
|
||||
@@ -311,6 +303,14 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
||||
|
||||
for (std::vector<ElementInfo>::iterator e_it = elements_.begin(); e_it != elements_.end(); ++e_it)
|
||||
{
|
||||
if (_in.eof()) {
|
||||
if (err_enabled)
|
||||
omerr().enable();
|
||||
|
||||
omerr() << "Unexpected end of file while reading." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (e_it->element_== VERTEX)
|
||||
{
|
||||
// read vertices:
|
||||
@@ -422,6 +422,12 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
||||
// faces
|
||||
for (i = 0; i < faceCount_ && !_in.eof(); ++i) {
|
||||
FaceHandle fh;
|
||||
|
||||
c[0] = 0;
|
||||
c[1] = 0;
|
||||
c[2] = 0;
|
||||
c[3] = 255;
|
||||
|
||||
for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex) {
|
||||
PropertyInfo prop = e_it->properties_[propertyIndex];
|
||||
switch (prop.property) {
|
||||
@@ -453,6 +459,38 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
||||
++complex_faces;
|
||||
break;
|
||||
|
||||
case COLORRED:
|
||||
if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) {
|
||||
_in >> tmp;
|
||||
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
} else
|
||||
_in >> c[0];
|
||||
break;
|
||||
|
||||
case COLORGREEN:
|
||||
if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) {
|
||||
_in >> tmp;
|
||||
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
} else
|
||||
_in >> c[1];
|
||||
break;
|
||||
|
||||
case COLORBLUE:
|
||||
if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) {
|
||||
_in >> tmp;
|
||||
c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
} else
|
||||
_in >> c[2];
|
||||
break;
|
||||
|
||||
case COLORALPHA:
|
||||
if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) {
|
||||
_in >> tmp;
|
||||
c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
} else
|
||||
_in >> c[3];
|
||||
break;
|
||||
|
||||
case CUSTOM_PROP:
|
||||
if (_opt.check(Options::Custom) && fh.is_valid())
|
||||
readCustomProperty<false>(_in, _bi, fh, prop.name, prop.value, prop.listIndexType);
|
||||
@@ -465,7 +503,8 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_opt.face_has_color())
|
||||
_bi.set_color(fh, Vec4uc(c));
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -480,14 +519,6 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
||||
}
|
||||
}
|
||||
|
||||
if (_in.eof()) {
|
||||
if (err_enabled)
|
||||
omerr().enable();
|
||||
|
||||
omerr() << "Unexpected end of file while reading." << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
if(e_it->element_== FACE)
|
||||
// stop reading after the faces since additional elements are not preserved anyway
|
||||
break;
|
||||
@@ -507,12 +538,6 @@ bool _PLYReader_::read_ascii(std::istream& _in, BaseImporter& _bi, const Options
|
||||
|
||||
bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap*/, const Options& _opt) const {
|
||||
|
||||
// Reparse the header
|
||||
if (!can_u_read(_in)) {
|
||||
omerr() << "[PLYReader] : Unable to parse header\n";
|
||||
return false;
|
||||
}
|
||||
|
||||
OpenMesh::Vec3f v, n; // Vertex
|
||||
OpenMesh::Vec2f t; // TexCoords
|
||||
BaseImporter::VHandles vhandles;
|
||||
@@ -579,29 +604,26 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
|
||||
readValue(prop.value, _in, t[1]);
|
||||
break;
|
||||
case COLORRED:
|
||||
if (prop.value == ValueTypeFLOAT32 ||
|
||||
prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
|
||||
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
}
|
||||
else
|
||||
readInteger(prop.value, _in, c[0]);
|
||||
readInteger(prop.value, _in, c[0]);
|
||||
|
||||
break;
|
||||
case COLORGREEN:
|
||||
if (prop.value == ValueTypeFLOAT32 ||
|
||||
prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
}
|
||||
else
|
||||
readInteger(prop.value, _in, c[1]);
|
||||
if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
}
|
||||
else
|
||||
readInteger(prop.value, _in, c[1]);
|
||||
|
||||
break;
|
||||
case COLORBLUE:
|
||||
if (prop.value == ValueTypeFLOAT32 ||
|
||||
prop.value == ValueTypeFLOAT) {
|
||||
if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
}
|
||||
@@ -610,8 +632,7 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
|
||||
|
||||
break;
|
||||
case COLORALPHA:
|
||||
if (prop.value == ValueTypeFLOAT32 ||
|
||||
prop.value == ValueTypeFLOAT) {
|
||||
if (prop.value == ValueTypeFLOAT32 || prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
}
|
||||
@@ -645,6 +666,12 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
|
||||
else if (e_it->element_ == FACE) {
|
||||
for (unsigned i = 0; i < e_it->count_ && !_in.eof(); ++i) {
|
||||
FaceHandle fh;
|
||||
|
||||
c[0] = 0;
|
||||
c[1] = 0;
|
||||
c[2] = 0;
|
||||
c[3] = 255;
|
||||
|
||||
for (size_t propertyIndex = 0; propertyIndex < e_it->properties_.size(); ++propertyIndex)
|
||||
{
|
||||
PropertyInfo prop = e_it->properties_[propertyIndex];
|
||||
@@ -679,7 +706,38 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
|
||||
if (!fh.is_valid())
|
||||
++complex_faces;
|
||||
break;
|
||||
|
||||
case COLORRED:
|
||||
if (prop.value == ValueTypeFLOAT32 ||
|
||||
prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
c[0] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
} else
|
||||
readInteger(prop.value, _in, c[0]);
|
||||
break;
|
||||
case COLORGREEN:
|
||||
if (prop.value == ValueTypeFLOAT32 ||
|
||||
prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
c[1] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
} else
|
||||
readInteger(prop.value, _in, c[1]);
|
||||
break;
|
||||
case COLORBLUE:
|
||||
if (prop.value == ValueTypeFLOAT32 ||
|
||||
prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
c[2] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
} else
|
||||
readInteger(prop.value, _in, c[2]);
|
||||
break;
|
||||
case COLORALPHA:
|
||||
if (prop.value == ValueTypeFLOAT32 ||
|
||||
prop.value == ValueTypeFLOAT) {
|
||||
readValue(prop.value, _in, tmp);
|
||||
c[3] = static_cast<OpenMesh::Vec4i::value_type> (tmp * 255.0f);
|
||||
} else
|
||||
readInteger(prop.value, _in, c[3]);
|
||||
break;
|
||||
case CUSTOM_PROP:
|
||||
if (_opt.check(Options::Custom) && fh.is_valid())
|
||||
readCustomProperty<true>(_in, _bi, fh, prop.name, prop.value, prop.listIndexType);
|
||||
@@ -692,6 +750,8 @@ bool _PLYReader_::read_binary(std::istream& _in, BaseImporter& _bi, bool /*_swap
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_opt.face_has_color())
|
||||
_bi.set_color(fh, Vec4uc(c));
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -741,6 +801,12 @@ void _PLYReader_::readValue(ValueType _type, std::istream& _in, float& _value) c
|
||||
restore(_in, tmp, options_.check(Options::MSB));
|
||||
_value = tmp;
|
||||
break;
|
||||
case ValueTypeDOUBLE:
|
||||
case ValueTypeFLOAT64:
|
||||
double dtmp;
|
||||
readValue(_type, _in, dtmp);
|
||||
_value = static_cast<float>(dtmp);
|
||||
break;
|
||||
default:
|
||||
_value = 0.0;
|
||||
std::cerr << "unsupported conversion type to float: " << _type << std::endl;
|
||||
@@ -905,9 +971,13 @@ void _PLYReader_::readValue(ValueType _type, std::istream& _in, int& _value) con
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<typename T>
|
||||
void _PLYReader_::readInteger(ValueType _type, std::istream& _in, T& _value) const {
|
||||
|
||||
void _PLYReader_::readInteger(ValueType _type, std::istream& _in, int& _value) const {
|
||||
static_assert(std::is_integral<T>::value, "Integral required.");
|
||||
|
||||
int16_t tmp_int16_t;
|
||||
uint16_t tmp_uint16_t;
|
||||
int32_t tmp_int32_t;
|
||||
uint32_t tmp_uint32_t;
|
||||
int8_t tmp_char;
|
||||
@@ -915,6 +985,22 @@ void _PLYReader_::readInteger(ValueType _type, std::istream& _in, int& _value) c
|
||||
|
||||
switch (_type) {
|
||||
|
||||
case ValueTypeINT16:
|
||||
|
||||
case ValueTypeSHORT:
|
||||
restore(_in, tmp_int16_t, options_.check(Options::MSB));
|
||||
_value = tmp_int16_t;
|
||||
|
||||
break;
|
||||
|
||||
case ValueTypeUINT16:
|
||||
|
||||
case ValueTypeUSHORT:
|
||||
restore(_in, tmp_uint16_t, options_.check(Options::MSB));
|
||||
_value = tmp_uint16_t;
|
||||
|
||||
break;
|
||||
|
||||
case ValueTypeINT:
|
||||
|
||||
case ValueTypeINT32:
|
||||
@@ -954,71 +1040,12 @@ void _PLYReader_::readInteger(ValueType _type, std::istream& _in, int& _value) c
|
||||
default:
|
||||
|
||||
_value = 0;
|
||||
std::cerr << "unsupported conversion type to int: " << _type << std::endl;
|
||||
std::cerr << "unsupported conversion type to integral: " << _type << std::endl;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
void _PLYReader_::readInteger(ValueType _type, std::istream& _in, unsigned int& _value) const {
|
||||
|
||||
int32_t tmp_int32_t;
|
||||
uint32_t tmp_uint32_t;
|
||||
int8_t tmp_char;
|
||||
uint8_t tmp_uchar;
|
||||
|
||||
switch (_type) {
|
||||
|
||||
case ValueTypeUINT:
|
||||
|
||||
case ValueTypeUINT32:
|
||||
|
||||
restore(_in, tmp_uint32_t, options_.check(Options::MSB));
|
||||
_value = tmp_uint32_t;
|
||||
|
||||
break;
|
||||
|
||||
case ValueTypeINT:
|
||||
|
||||
case ValueTypeINT32:
|
||||
|
||||
restore(_in, tmp_int32_t, options_.check(Options::MSB));
|
||||
_value = tmp_int32_t;
|
||||
|
||||
break;
|
||||
|
||||
case ValueTypeUCHAR:
|
||||
|
||||
case ValueTypeUINT8:
|
||||
|
||||
restore(_in, tmp_uchar, options_.check(Options::MSB));
|
||||
_value = tmp_uchar;
|
||||
|
||||
break;
|
||||
|
||||
case ValueTypeCHAR:
|
||||
|
||||
case ValueTypeINT8:
|
||||
|
||||
restore(_in, tmp_char, options_.check(Options::MSB));
|
||||
_value = tmp_char;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
_value = 0;
|
||||
std::cerr << "unsupported conversion type to unsigned int: " << _type << std::endl;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
|
||||
@@ -1062,7 +1089,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")
|
||||
|
||||
@@ -1201,183 +1228,211 @@ bool _PLYReader_::can_u_read(std::istream& _is) const {
|
||||
_is >> keyword;
|
||||
while (keyword != "end_header") {
|
||||
|
||||
if (keyword == "comment") {
|
||||
std::getline(_is, line);
|
||||
} else if (keyword == "element") {
|
||||
_is >> elementName;
|
||||
_is >> elementCount;
|
||||
if (keyword == "comment") {
|
||||
std::getline(_is, line);
|
||||
} else if (keyword == "element") {
|
||||
_is >> elementName;
|
||||
_is >> elementCount;
|
||||
|
||||
ElementInfo element;
|
||||
element.name_ = elementName;
|
||||
element.count_ = elementCount;
|
||||
ElementInfo element;
|
||||
element.name_ = elementName;
|
||||
element.count_ = elementCount;
|
||||
|
||||
if (elementName == "vertex") {
|
||||
vertexCount_ = elementCount;
|
||||
element.element_ = VERTEX;
|
||||
} else if (elementName == "face") {
|
||||
faceCount_ = elementCount;
|
||||
element.element_ = FACE;
|
||||
} else {
|
||||
omerr() << "PLY header unsupported element type: " << elementName << std::endl;
|
||||
element.element_ = UNKNOWN;
|
||||
}
|
||||
if (elementName == "vertex") {
|
||||
vertexCount_ = elementCount;
|
||||
element.element_ = VERTEX;
|
||||
} else if (elementName == "face") {
|
||||
faceCount_ = elementCount;
|
||||
element.element_ = FACE;
|
||||
} else {
|
||||
omerr() << "PLY header unsupported element type: " << elementName << std::endl;
|
||||
element.element_ = UNKNOWN;
|
||||
}
|
||||
|
||||
elements_.push_back(element);
|
||||
} else if (keyword == "property") {
|
||||
std::string tmp1;
|
||||
std::string tmp2;
|
||||
elements_.push_back(element);
|
||||
} else if (keyword == "property") {
|
||||
std::string tmp1;
|
||||
std::string tmp2;
|
||||
|
||||
// Read first keyword, as it might be a list
|
||||
_is >> tmp1;
|
||||
// Read first keyword, as it might be a list
|
||||
_is >> tmp1;
|
||||
|
||||
if (tmp1 == "list") {
|
||||
_is >> listIndexType;
|
||||
_is >> listEntryType;
|
||||
_is >> propertyName;
|
||||
if (tmp1 == "list") {
|
||||
_is >> listIndexType;
|
||||
_is >> listEntryType;
|
||||
_is >> propertyName;
|
||||
|
||||
ValueType indexType = Unsupported;
|
||||
ValueType entryType = Unsupported;
|
||||
ValueType indexType = Unsupported;
|
||||
ValueType entryType = Unsupported;
|
||||
|
||||
if (listIndexType == "uint8") {
|
||||
indexType = ValueTypeUINT8;
|
||||
} else if (listIndexType == "uchar") {
|
||||
indexType = ValueTypeUCHAR;
|
||||
} else if (listIndexType == "int") {
|
||||
indexType = ValueTypeINT;
|
||||
} else {
|
||||
omerr() << "Unsupported Index type for property list: " << listIndexType << std::endl;
|
||||
continue;
|
||||
}
|
||||
if (listIndexType == "uint8") {
|
||||
indexType = ValueTypeUINT8;
|
||||
} else if (listIndexType == "uint16") {
|
||||
indexType = ValueTypeUINT16;
|
||||
} else if (listIndexType == "uchar") {
|
||||
indexType = ValueTypeUCHAR;
|
||||
} else if (listIndexType == "int") {
|
||||
indexType = ValueTypeINT;
|
||||
} else {
|
||||
omerr() << "Unsupported Index type for property list: " << listIndexType << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
entryType = get_property_type(listEntryType, listEntryType);
|
||||
entryType = get_property_type(listEntryType, listEntryType);
|
||||
|
||||
if (entryType == Unsupported) {
|
||||
omerr() << "Unsupported Entry type for property list: " << listEntryType << std::endl;
|
||||
}
|
||||
if (entryType == Unsupported) {
|
||||
omerr() << "Unsupported Entry type for property list: " << listEntryType << std::endl;
|
||||
}
|
||||
|
||||
PropertyInfo property(CUSTOM_PROP, entryType, propertyName);
|
||||
property.listIndexType = indexType;
|
||||
PropertyInfo property(CUSTOM_PROP, entryType, propertyName);
|
||||
property.listIndexType = indexType;
|
||||
|
||||
if (elementName == "face")
|
||||
{
|
||||
// special case for vertex indices
|
||||
if (propertyName == "vertex_index" || propertyName == "vertex_indices")
|
||||
{
|
||||
property.property = VERTEX_INDICES;
|
||||
|
||||
if (!elements_.back().properties_.empty())
|
||||
{
|
||||
omerr() << "Custom face Properties defined, before 'vertex_indices' property was defined. They will be skipped" << std::endl;
|
||||
elements_.back().properties_.clear();
|
||||
}
|
||||
}
|
||||
if (elementName == "face")
|
||||
{
|
||||
// special case for vertex indices
|
||||
if (propertyName == "vertex_index" || propertyName == "vertex_indices")
|
||||
{
|
||||
property.property = VERTEX_INDICES;
|
||||
|
||||
}
|
||||
else
|
||||
omerr() << "property " << propertyName << " belongs to unsupported element " << elementName << std::endl;
|
||||
|
||||
elements_.back().properties_.push_back(property);
|
||||
|
||||
} else {
|
||||
// as this is not a list property, read second value of property
|
||||
_is >> tmp2;
|
||||
|
||||
|
||||
// Extract name and type of property
|
||||
// As the order seems to be different in some files, autodetect it.
|
||||
ValueType valueType = get_property_type(tmp1, tmp2);
|
||||
propertyName = get_property_name(tmp1, tmp2);
|
||||
|
||||
PropertyInfo entry;
|
||||
|
||||
//special treatment for some vertex properties.
|
||||
if (elementName == "vertex") {
|
||||
if (propertyName == "x") {
|
||||
entry = PropertyInfo(XCOORD, valueType);
|
||||
vertexDimension_++;
|
||||
} else if (propertyName == "y") {
|
||||
entry = PropertyInfo(YCOORD, valueType);
|
||||
vertexDimension_++;
|
||||
} else if (propertyName == "z") {
|
||||
entry = PropertyInfo(ZCOORD, valueType);
|
||||
vertexDimension_++;
|
||||
} else if (propertyName == "nx") {
|
||||
entry = PropertyInfo(XNORM, valueType);
|
||||
options_ += Options::VertexNormal;
|
||||
} else if (propertyName == "ny") {
|
||||
entry = PropertyInfo(YNORM, valueType);
|
||||
options_ += Options::VertexNormal;
|
||||
} else if (propertyName == "nz") {
|
||||
entry = PropertyInfo(ZNORM, valueType);
|
||||
options_ += Options::VertexNormal;
|
||||
} else if (propertyName == "u" || propertyName == "s") {
|
||||
entry = PropertyInfo(TEXX, valueType);
|
||||
options_ += Options::VertexTexCoord;
|
||||
} else if (propertyName == "v" || propertyName == "t") {
|
||||
entry = PropertyInfo(TEXY, valueType);
|
||||
options_ += Options::VertexTexCoord;
|
||||
} else if (propertyName == "red") {
|
||||
entry = PropertyInfo(COLORRED, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "green") {
|
||||
entry = PropertyInfo(COLORGREEN, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "blue") {
|
||||
entry = PropertyInfo(COLORBLUE, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "diffuse_red") {
|
||||
entry = PropertyInfo(COLORRED, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "diffuse_green") {
|
||||
entry = PropertyInfo(COLORGREEN, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "diffuse_blue") {
|
||||
entry = PropertyInfo(COLORBLUE, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "alpha") {
|
||||
entry = PropertyInfo(COLORALPHA, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
options_ += Options::ColorAlpha;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
}
|
||||
}
|
||||
|
||||
//not a special property, load as custom
|
||||
if (entry.value == Unsupported){
|
||||
Property prop = CUSTOM_PROP;
|
||||
options_ += Options::Custom;
|
||||
entry = PropertyInfo(prop, valueType, propertyName);
|
||||
}
|
||||
|
||||
if (entry.property != UNSUPPORTED)
|
||||
if (!elements_.back().properties_.empty())
|
||||
{
|
||||
elements_.back().properties_.push_back(entry);
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
omerr() << "property " << propertyName << " belongs to unsupported element " << elementName << std::endl;
|
||||
|
||||
elements_.back().properties_.push_back(property);
|
||||
|
||||
} else {
|
||||
omlog() << "Unsupported keyword : " << keyword << std::endl;
|
||||
// as this is not a list property, read second value of property
|
||||
_is >> tmp2;
|
||||
|
||||
|
||||
// Extract name and type of property
|
||||
// As the order seems to be different in some files, autodetect it.
|
||||
ValueType valueType = get_property_type(tmp1, tmp2);
|
||||
propertyName = get_property_name(tmp1, tmp2);
|
||||
|
||||
PropertyInfo entry;
|
||||
|
||||
//special treatment for some vertex properties.
|
||||
if (elementName == "vertex") {
|
||||
if (propertyName == "x") {
|
||||
entry = PropertyInfo(XCOORD, valueType);
|
||||
vertexDimension_++;
|
||||
} else if (propertyName == "y") {
|
||||
entry = PropertyInfo(YCOORD, valueType);
|
||||
vertexDimension_++;
|
||||
} else if (propertyName == "z") {
|
||||
entry = PropertyInfo(ZCOORD, valueType);
|
||||
vertexDimension_++;
|
||||
} else if (propertyName == "nx") {
|
||||
entry = PropertyInfo(XNORM, valueType);
|
||||
options_ += Options::VertexNormal;
|
||||
} else if (propertyName == "ny") {
|
||||
entry = PropertyInfo(YNORM, valueType);
|
||||
options_ += Options::VertexNormal;
|
||||
} else if (propertyName == "nz") {
|
||||
entry = PropertyInfo(ZNORM, valueType);
|
||||
options_ += Options::VertexNormal;
|
||||
} else if (propertyName == "u" || propertyName == "s") {
|
||||
entry = PropertyInfo(TEXX, valueType);
|
||||
options_ += Options::VertexTexCoord;
|
||||
} else if (propertyName == "v" || propertyName == "t") {
|
||||
entry = PropertyInfo(TEXY, valueType);
|
||||
options_ += Options::VertexTexCoord;
|
||||
} else if (propertyName == "red") {
|
||||
entry = PropertyInfo(COLORRED, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "green") {
|
||||
entry = PropertyInfo(COLORGREEN, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "blue") {
|
||||
entry = PropertyInfo(COLORBLUE, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "diffuse_red") {
|
||||
entry = PropertyInfo(COLORRED, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "diffuse_green") {
|
||||
entry = PropertyInfo(COLORGREEN, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "diffuse_blue") {
|
||||
entry = PropertyInfo(COLORBLUE, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "alpha") {
|
||||
entry = PropertyInfo(COLORALPHA, valueType);
|
||||
options_ += Options::VertexColor;
|
||||
options_ += Options::ColorAlpha;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
}
|
||||
}
|
||||
else if (elementName == "face") {
|
||||
if (propertyName == "red") {
|
||||
entry = PropertyInfo(COLORRED, valueType);
|
||||
options_ += Options::FaceColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "green") {
|
||||
entry = PropertyInfo(COLORGREEN, valueType);
|
||||
options_ += Options::FaceColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "blue") {
|
||||
entry = PropertyInfo(COLORBLUE, valueType);
|
||||
options_ += Options::FaceColor;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
} else if (propertyName == "alpha") {
|
||||
entry = PropertyInfo(COLORALPHA, valueType);
|
||||
options_ += Options::FaceColor;
|
||||
options_ += Options::ColorAlpha;
|
||||
if (valueType == ValueTypeFLOAT || valueType == ValueTypeFLOAT32)
|
||||
options_ += Options::ColorFloat;
|
||||
}
|
||||
}
|
||||
|
||||
//not a special property, load as custom
|
||||
if (entry.value == Unsupported){
|
||||
Property prop = CUSTOM_PROP;
|
||||
options_ += Options::Custom;
|
||||
entry = PropertyInfo(prop, valueType, propertyName);
|
||||
}
|
||||
|
||||
if (entry.property != UNSUPPORTED)
|
||||
{
|
||||
elements_.back().properties_.push_back(entry);
|
||||
}
|
||||
}
|
||||
|
||||
streamPos = _is.tellg();
|
||||
_is >> keyword;
|
||||
if (_is.bad()) {
|
||||
omerr() << "Error while reading PLY file header" << std::endl;
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
omlog() << "Unsupported keyword : " << keyword << std::endl;
|
||||
}
|
||||
|
||||
streamPos = _is.tellg();
|
||||
_is >> keyword;
|
||||
if (_is.bad()) {
|
||||
omerr() << "Error while reading PLY file header" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// As the binary data is directy after the end_header keyword
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -102,19 +97,19 @@ public:
|
||||
|
||||
_PLYReader_();
|
||||
|
||||
std::string get_description() const { return "PLY polygon file format"; }
|
||||
std::string get_extensions() const { return "ply"; }
|
||||
std::string get_magic() const { return "PLY"; }
|
||||
std::string get_description() const override { return "PLY polygon file format"; }
|
||||
std::string get_extensions() const override { return "ply"; }
|
||||
std::string get_magic() const override { return "PLY"; }
|
||||
|
||||
bool read(const std::string& _filename,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt);
|
||||
Options& _opt) override;
|
||||
|
||||
bool read(std::istream& _is,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt);
|
||||
Options& _opt) override;
|
||||
|
||||
bool can_u_read(const std::string& _filename) const;
|
||||
bool can_u_read(const std::string& _filename) const override;
|
||||
|
||||
enum ValueType {
|
||||
Unsupported,
|
||||
@@ -135,8 +130,6 @@ private:
|
||||
bool read_ascii(std::istream& _in, BaseImporter& _bi, const Options& _opt) const;
|
||||
bool read_binary(std::istream& _in, BaseImporter& _bi, bool swap, const Options& _opt) const;
|
||||
|
||||
float readToFloatValue(ValueType _type , std::fstream& _in) const;
|
||||
|
||||
void readValue(ValueType _type , std::istream& _in, float& _value) const;
|
||||
void readValue(ValueType _type , std::istream& _in, double& _value) const;
|
||||
void readValue(ValueType _type , std::istream& _in, unsigned int& _value) const;
|
||||
@@ -146,8 +139,8 @@ private:
|
||||
void readValue(ValueType _type , std::istream& _in, short& _value) const;
|
||||
void readValue(ValueType _type , std::istream& _in, signed char& _value) const;
|
||||
|
||||
void readInteger(ValueType _type, std::istream& _in, int& _value) const;
|
||||
void readInteger(ValueType _type, std::istream& _in, unsigned int& _value) const;
|
||||
template<typename T>
|
||||
void readInteger(ValueType _type, std::istream& _in, T& _value) const;
|
||||
|
||||
/// Read unsupported properties in PLY file
|
||||
void consume_input(std::istream& _in, int _count) const {
|
||||
@@ -219,6 +212,18 @@ private:
|
||||
_in >> _value;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void readInteger(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::TrueType /*_binary*/) const
|
||||
{
|
||||
readInteger(_type, _in, _value);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void readInteger(_PLYReader_::ValueType _type, std::istream& _in, T& _value, OpenMesh::GenProg::FalseType /*_binary*/) const
|
||||
{
|
||||
_in >> _value;
|
||||
}
|
||||
|
||||
//read and assign custom properties with the given type. Also creates property, if not exist
|
||||
template<bool binary, typename T, typename Handle>
|
||||
void readCreateCustomProperty(std::istream& _in, BaseImporter& _bi, Handle _h, const std::string& _propName, const ValueType _valueType, const ValueType _listType) const;
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -176,7 +171,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
|
||||
{
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -97,17 +92,17 @@ public:
|
||||
virtual ~_STLReader_() {};
|
||||
|
||||
|
||||
std::string get_description() const
|
||||
std::string get_description() const override
|
||||
{ return "Stereolithography Interface Format"; }
|
||||
std::string get_extensions() const { return "stl stla stlb"; }
|
||||
std::string get_extensions() const override { return "stl stla stlb"; }
|
||||
|
||||
bool read(const std::string& _filename,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt);
|
||||
Options& _opt) override;
|
||||
|
||||
bool read(std::istream& _in,
|
||||
BaseImporter& _bi,
|
||||
Options& _opt);
|
||||
Options& _opt) override;
|
||||
|
||||
/** Set the threshold to be used for considering two point to be equal.
|
||||
Can be used to merge small gaps */
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=== INCLUDES ================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -138,11 +133,13 @@ protected:
|
||||
|
||||
bool check(BaseExporter& _be, Options _opt) const
|
||||
{
|
||||
return (_opt.check(Options::VertexNormal ) <= _be.has_vertex_normals())
|
||||
&& (_opt.check(Options::VertexTexCoord)<= _be.has_vertex_texcoords())
|
||||
&& (_opt.check(Options::VertexColor) <= _be.has_vertex_colors())
|
||||
&& (_opt.check(Options::FaceNormal) <= _be.has_face_normals())
|
||||
&& (_opt.check(Options::FaceColor) <= _be.has_face_colors());
|
||||
// Check for all Options. When we want to write them (_opt.check() ) , they have to be available ( has_ )
|
||||
// Converts to not A (write them) or B (available)
|
||||
return ( !_opt.check(Options::VertexNormal ) || _be.has_vertex_normals())
|
||||
&& ( !_opt.check(Options::VertexTexCoord)|| _be.has_vertex_texcoords())
|
||||
&& ( !_opt.check(Options::VertexColor) || _be.has_vertex_colors())
|
||||
&& ( !_opt.check(Options::FaceNormal) || _be.has_face_normals())
|
||||
&& ( !_opt.check(Options::FaceColor) || _be.has_face_colors());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -97,28 +92,32 @@ write(const std::string& _filename, BaseExporter& _be, Options _opt, std::stream
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set precision on output stream. The default is set via IOManager and passed through to all writers.
|
||||
out.precision(_precision);
|
||||
|
||||
// Set fixed output to avoid problems with programs not reading scientific notation correctly
|
||||
out << std::fixed;
|
||||
|
||||
{
|
||||
#if defined(WIN32)
|
||||
std::string::size_type dot = _filename.find_last_of("\\/");
|
||||
std::string::size_type dotposition = _filename.find_last_of("\\/");
|
||||
#else
|
||||
std::string::size_type dot = _filename.rfind("/");
|
||||
std::string::size_type dotposition = _filename.rfind("/");
|
||||
#endif
|
||||
|
||||
if (dot == std::string::npos){
|
||||
if (dotposition == std::string::npos){
|
||||
path_ = "./";
|
||||
objName_ = _filename;
|
||||
}else{
|
||||
path_ = _filename.substr(0,dot+1);
|
||||
objName_ = _filename.substr(dot+1);
|
||||
path_ = _filename.substr(0,dotposition+1);
|
||||
objName_ = _filename.substr(dotposition+1);
|
||||
}
|
||||
|
||||
//remove the file extension
|
||||
dot = objName_.find_last_of(".");
|
||||
dotposition = objName_.find_last_of(".");
|
||||
|
||||
if(dot != std::string::npos)
|
||||
objName_ = objName_.substr(0,dot);
|
||||
if(dotposition != std::string::npos)
|
||||
objName_ = objName_.substr(0,dotposition);
|
||||
}
|
||||
|
||||
bool result = write(out, _be, _opt, _precision);
|
||||
@@ -207,7 +206,6 @@ _OBJWriter_::
|
||||
write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _precision) const
|
||||
{
|
||||
unsigned int idx;
|
||||
size_t i, j,nV, nF;
|
||||
Vec3f v, n;
|
||||
Vec2f t;
|
||||
VertexHandle vh;
|
||||
@@ -274,9 +272,9 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
std::vector<Vec2f> texCoords;
|
||||
//add all texCoords to map
|
||||
unsigned int num = _be.get_face_texcoords(texCoords);
|
||||
for(unsigned int i = 0; i < num ; ++i)
|
||||
for(size_t i = 0; i < num ; ++i)
|
||||
{
|
||||
texMap[texCoords[i]] = i;
|
||||
texMap[texCoords[i]] = static_cast<int>(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -304,7 +302,7 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
}
|
||||
|
||||
// vertex data (point, normals, texcoords)
|
||||
for (i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
for (size_t i=0, nV=_be.n_vertices(); i<nV; ++i)
|
||||
{
|
||||
vh = VertexHandle(int(i));
|
||||
v = _be.point(vh);
|
||||
@@ -325,7 +323,7 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
&& !_opt.check(Options::FaceTexCoord);
|
||||
|
||||
// faces (indices starting at 1 not 0)
|
||||
for (i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
for (size_t i=0, nF=_be.n_faces(); i<nF; ++i)
|
||||
{
|
||||
|
||||
if (useMatrial && _opt.check(Options::FaceColor) ){
|
||||
@@ -352,7 +350,7 @@ write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _prec
|
||||
|
||||
_be.get_vhandles(FaceHandle(int(i)), vhandles);
|
||||
|
||||
for (j=0; j< vhandles.size(); ++j)
|
||||
for (size_t j=0; j< vhandles.size(); ++j)
|
||||
{
|
||||
|
||||
// Write vertex index
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -93,14 +88,14 @@ public:
|
||||
/// Destructor
|
||||
virtual ~_OBJWriter_() {};
|
||||
|
||||
std::string get_description() const { return "Alias/Wavefront"; }
|
||||
std::string get_extensions() const { return "obj"; }
|
||||
std::string get_description() const override { return "Alias/Wavefront"; }
|
||||
std::string get_extensions() const override { return "obj"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
size_t binary_size(BaseExporter&, Options) const { return 0; }
|
||||
size_t binary_size(BaseExporter&, Options) const override { return 0; }
|
||||
|
||||
private:
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -102,14 +97,14 @@ public:
|
||||
|
||||
virtual ~_OFFWriter_() {};
|
||||
|
||||
std::string get_description() const { return "no description"; }
|
||||
std::string get_extensions() const { return "off"; }
|
||||
std::string get_description() const override { return "no description"; }
|
||||
std::string get_extensions() const override { return "off"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const;
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const override;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -86,7 +81,7 @@ _OMWriter_& OMWriter() { return __OMWriterInstance; }
|
||||
|
||||
|
||||
const OMFormat::uchar _OMWriter_::magic_[3] = "OM";
|
||||
const OMFormat::uint8 _OMWriter_::version_ = OMFormat::mk_version(1,2);
|
||||
const OMFormat::uint8 _OMWriter_::version_ = OMFormat::mk_version(2,1);
|
||||
|
||||
|
||||
_OMWriter_::
|
||||
@@ -163,7 +158,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(); }
|
||||
@@ -182,13 +177,13 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
|
||||
size_t bytes = 0;
|
||||
|
||||
bool swap = _opt.check(Options::Swap) || (Endian::local() == Endian::MSB);
|
||||
const bool swap =
|
||||
_opt.check(Options::Swap) || (Endian::local() == Endian::MSB);
|
||||
|
||||
unsigned int i, nV, nF;
|
||||
Vec3f v;
|
||||
Vec3d vd;
|
||||
Vec2f t;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
|
||||
// -------------------- write header
|
||||
OMFormat::Header header;
|
||||
@@ -218,14 +213,28 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Pos;
|
||||
chunk_header.signed_ = OMFormat::is_signed(v[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(v[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(v);
|
||||
chunk_header.bits_ = OMFormat::bits(v[0]);
|
||||
if (_be.is_point_double())
|
||||
{
|
||||
chunk_header.signed_ = OMFormat::is_signed(vd[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(vd[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(vd);
|
||||
chunk_header.bits_ = OMFormat::bits(vd[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk_header.signed_ = OMFormat::is_signed(v[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(v[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(v);
|
||||
chunk_header.bits_ = OMFormat::bits(v[0]);
|
||||
}
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
for (i=0, nV=header.n_vertices_; i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.point(VertexHandle(i)), swap );
|
||||
if (_be.is_point_double())
|
||||
for (i=0, nV=header.n_vertices_; i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.pointd(VertexHandle(i)), swap );
|
||||
else
|
||||
for (i=0, nV=header.n_vertices_; i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.point(VertexHandle(i)), swap );
|
||||
}
|
||||
|
||||
|
||||
@@ -233,18 +242,34 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
if (_be.n_vertices() && _opt.check( Options::VertexNormal ))
|
||||
{
|
||||
Vec3f n = _be.normal(VertexHandle(0));
|
||||
Vec3d nd = _be.normald(VertexHandle(0));
|
||||
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Normal;
|
||||
chunk_header.signed_ = OMFormat::is_signed(n[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(n[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(n);
|
||||
chunk_header.bits_ = OMFormat::bits(n[0]);
|
||||
if (_be.is_normal_double())
|
||||
{
|
||||
chunk_header.signed_ = OMFormat::is_signed(nd[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(nd[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(nd);
|
||||
chunk_header.bits_ = OMFormat::bits(nd[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk_header.signed_ = OMFormat::is_signed(n[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(n[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(n);
|
||||
chunk_header.bits_ = OMFormat::bits(n[0]);
|
||||
}
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
for (i=0, nV=header.n_vertices_; i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.normal(VertexHandle(i)), swap );
|
||||
if (_be.is_normal_double())
|
||||
for (i=0, nV=header.n_vertices_; i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.normald(VertexHandle(i)), swap );
|
||||
else
|
||||
for (i=0, nV=header.n_vertices_; i<nV; ++i)
|
||||
bytes += vector_store( _os, _be.normal(VertexHandle(i)), swap );
|
||||
|
||||
}
|
||||
|
||||
// ---------- write vertex color
|
||||
@@ -286,6 +311,50 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
|
||||
}
|
||||
|
||||
// ---------- wirte halfedge data
|
||||
if (_be.n_edges())
|
||||
{
|
||||
chunk_header.reserved_ = 0;
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Halfedge;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Topology;
|
||||
chunk_header.signed_ = true;
|
||||
chunk_header.float_ = true; // TODO: is this correct? This causes a scalar size of 1 in OMFormat.hh scalar_size which we need I think?
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_3D;
|
||||
chunk_header.bits_ = OMFormat::needed_bits(_be.n_edges()*4); // *2 due to halfedge ids being stored, *2 due to signedness
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
auto nE=header.n_edges_*2;
|
||||
for (i=0; i<nE; ++i)
|
||||
{
|
||||
auto next_id = _be.get_next_halfedge_id(HalfedgeHandle(static_cast<int>(i)));
|
||||
auto to_vertex_id = _be.get_to_vertex_id(HalfedgeHandle(static_cast<int>(i)));
|
||||
auto face_id = _be.get_face_id(HalfedgeHandle(static_cast<int>(i)));
|
||||
|
||||
bytes += store( _os, next_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap );
|
||||
bytes += store( _os, to_vertex_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap );
|
||||
bytes += store( _os, face_id, OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap );
|
||||
}
|
||||
}
|
||||
|
||||
// ---------- write vertex topology (outgoing halfedge)
|
||||
if (_be.n_vertices())
|
||||
{
|
||||
chunk_header.reserved_ = 0;
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Topology;
|
||||
chunk_header.signed_ = true;
|
||||
chunk_header.float_ = true; // TODO: is this correct? This causes a scalar size of 1 in OMFormat.hh scalar_size which we need I think?
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
|
||||
chunk_header.bits_ = OMFormat::needed_bits(_be.n_edges()*4); // *2 due to halfedge ids being stored, *2 due to signedness
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
for (i=0, nV=header.n_vertices_; i<nV; ++i)
|
||||
bytes += store( _os, _be.get_halfedge_id(VertexHandle(i)), OMFormat::Chunk::Integer_Size(chunk_header.bits_), swap );
|
||||
}
|
||||
|
||||
|
||||
// -------------------- write face data
|
||||
|
||||
// ---------- write topology
|
||||
@@ -293,26 +362,17 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Topology;
|
||||
chunk_header.signed_ = 0;
|
||||
chunk_header.float_ = 0;
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_1D; // ignored
|
||||
chunk_header.bits_ = OMFormat::needed_bits(_be.n_vertices());
|
||||
chunk_header.signed_ = true;
|
||||
chunk_header.float_ = true; // TODO: is this correct? This causes a scalar size of 1 in OMFormat.hh scalar_size which we need I think?
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
|
||||
chunk_header.bits_ = OMFormat::needed_bits(_be.n_edges()*4); // *2 due to halfedge ids being stored, *2 due to signedness
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
|
||||
for (i=0, nF=header.n_faces_; i<nF; ++i)
|
||||
{
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
if ( header.mesh_ == 'P' )
|
||||
bytes += store( _os, vhandles.size(), OMFormat::Chunk::Integer_16, swap );
|
||||
|
||||
for (size_t j=0; j < vhandles.size(); ++j)
|
||||
{
|
||||
using namespace OMFormat;
|
||||
using namespace GenProg;
|
||||
|
||||
bytes += store( _os, vhandles[j].idx(), Chunk::Integer_Size(chunk_header.bits_), swap );
|
||||
}
|
||||
auto size = OMFormat::Chunk::Integer_Size(chunk_header.bits_);
|
||||
bytes += store( _os, _be.get_halfedge_id(FaceHandle(i)), size, swap);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -328,19 +388,36 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
{
|
||||
#endif
|
||||
Vec3f n = _be.normal(FaceHandle(0));
|
||||
Vec3d nd = _be.normald(FaceHandle(0));
|
||||
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Normal;
|
||||
chunk_header.signed_ = OMFormat::is_signed(n[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(n[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(n);
|
||||
chunk_header.bits_ = OMFormat::bits(n[0]);
|
||||
|
||||
if (_be.is_normal_double())
|
||||
{
|
||||
chunk_header.signed_ = OMFormat::is_signed(nd[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(nd[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(nd);
|
||||
chunk_header.bits_ = OMFormat::bits(nd[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
chunk_header.signed_ = OMFormat::is_signed(n[0]);
|
||||
chunk_header.float_ = OMFormat::is_float(n[0]);
|
||||
chunk_header.dim_ = OMFormat::dim(n);
|
||||
chunk_header.bits_ = OMFormat::bits(n[0]);
|
||||
}
|
||||
|
||||
bytes += store( _os, chunk_header, swap );
|
||||
#if !NEW_STYLE
|
||||
for (i=0, nF=header.n_faces_; i<nF; ++i)
|
||||
bytes += vector_store( _os, _be.normal(FaceHandle(i)), swap );
|
||||
if (_be.is_normal_double())
|
||||
for (i=0, nF=header.n_faces_; i<nF; ++i)
|
||||
bytes += vector_store( _os, _be.normald(FaceHandle(i)), swap );
|
||||
else
|
||||
for (i=0, nF=header.n_faces_; i<nF; ++i)
|
||||
bytes += vector_store( _os, _be.normal(FaceHandle(i)), swap );
|
||||
|
||||
#else
|
||||
bytes += bp->store(_os, swap );
|
||||
}
|
||||
@@ -384,51 +461,112 @@ bool _OMWriter_::write_binary(std::ostream& _os, BaseExporter& _be,
|
||||
#endif
|
||||
}
|
||||
|
||||
// ---------- write vertex status
|
||||
if (_be.n_vertices() && _be.has_vertex_status() && _opt.check(Options::Status))
|
||||
{
|
||||
auto s = _be.status(VertexHandle(0));
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Vertex;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Status;
|
||||
chunk_header.signed_ = false;
|
||||
chunk_header.float_ = false;
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
|
||||
chunk_header.bits_ = OMFormat::bits(s);
|
||||
|
||||
// std::clog << chunk_header << std::endl;
|
||||
bytes += store(_os, chunk_header, swap);
|
||||
|
||||
for (i = 0, nV = header.n_vertices_; i < nV; ++i)
|
||||
bytes += store(_os, _be.status(VertexHandle(i)), swap);
|
||||
}
|
||||
|
||||
// ---------- write edge status
|
||||
if (_be.n_edges() && _be.has_edge_status() && _opt.check(Options::Status))
|
||||
{
|
||||
auto s = _be.status(EdgeHandle(0));
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Edge;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Status;
|
||||
chunk_header.signed_ = false;
|
||||
chunk_header.float_ = false;
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
|
||||
chunk_header.bits_ = OMFormat::bits(s);
|
||||
|
||||
// std::clog << chunk_header << std::endl;
|
||||
bytes += store(_os, chunk_header, swap);
|
||||
|
||||
for (i = 0, nV = header.n_edges_; i < nV; ++i)
|
||||
bytes += store(_os, _be.status(EdgeHandle(i)), swap);
|
||||
}
|
||||
|
||||
// ---------- write halfedge status
|
||||
if (_be.n_edges() && _be.has_halfedge_status() && _opt.check(Options::Status))
|
||||
{
|
||||
auto s = _be.status(HalfedgeHandle(0));
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Halfedge;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Status;
|
||||
chunk_header.signed_ = false;
|
||||
chunk_header.float_ = false;
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
|
||||
chunk_header.bits_ = OMFormat::bits(s);
|
||||
|
||||
// std::clog << chunk_header << std::endl;
|
||||
bytes += store(_os, chunk_header, swap);
|
||||
|
||||
for (i = 0, nV = header.n_edges_ * 2; i < nV; ++i)
|
||||
bytes += store(_os, _be.status(HalfedgeHandle(i)), swap);
|
||||
}
|
||||
|
||||
// ---------- write face status
|
||||
if (_be.n_faces() && _be.has_face_status() && _opt.check(Options::Status))
|
||||
{
|
||||
auto s = _be.status(FaceHandle(0));
|
||||
chunk_header.name_ = false;
|
||||
chunk_header.entity_ = OMFormat::Chunk::Entity_Face;
|
||||
chunk_header.type_ = OMFormat::Chunk::Type_Status;
|
||||
chunk_header.signed_ = false;
|
||||
chunk_header.float_ = false;
|
||||
chunk_header.dim_ = OMFormat::Chunk::Dim_1D;
|
||||
chunk_header.bits_ = OMFormat::bits(s);
|
||||
|
||||
// std::clog << chunk_header << std::endl;
|
||||
bytes += store(_os, chunk_header, swap);
|
||||
|
||||
for (i = 0, nV = header.n_faces_; i < nV; ++i)
|
||||
bytes += store(_os, _be.status(FaceHandle(i)), swap);
|
||||
}
|
||||
|
||||
// -------------------- write custom properties
|
||||
|
||||
|
||||
BaseKernel::const_prop_iterator prop;
|
||||
|
||||
for (prop = _be.kernel()->vprops_begin();
|
||||
prop != _be.kernel()->vprops_end(); ++prop)
|
||||
const auto store_property = [this, &_os, swap, &bytes](
|
||||
const BaseKernel::const_prop_iterator _it_begin,
|
||||
const BaseKernel::const_prop_iterator _it_end,
|
||||
const OMFormat::Chunk::Entity _ent)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Vertex, swap );
|
||||
}
|
||||
for (prop = _be.kernel()->fprops_begin();
|
||||
prop != _be.kernel()->fprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Face, swap );
|
||||
}
|
||||
for (prop = _be.kernel()->eprops_begin();
|
||||
prop != _be.kernel()->eprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Edge, swap );
|
||||
}
|
||||
for (prop = _be.kernel()->hprops_begin();
|
||||
prop != _be.kernel()->hprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Halfedge, swap );
|
||||
}
|
||||
for (prop = _be.kernel()->mprops_begin();
|
||||
prop != _be.kernel()->mprops_end(); ++prop)
|
||||
{
|
||||
if ( !*prop ) continue;
|
||||
if ( (*prop)->name()[1]==':') continue;
|
||||
bytes += store_binary_custom_chunk(_os, **prop,
|
||||
OMFormat::Chunk::Entity_Mesh, swap );
|
||||
}
|
||||
for (auto prop = _it_begin; prop != _it_end; ++prop)
|
||||
{
|
||||
if (!*prop || (*prop)->name().empty() ||
|
||||
((*prop)->name().size() > 1 && (*prop)->name()[1] == ':'))
|
||||
{ // skip dead and "private" properties (no name or name matches "?:*")
|
||||
continue;
|
||||
}
|
||||
bytes += store_binary_custom_chunk(_os, **prop, _ent, swap);
|
||||
}
|
||||
};
|
||||
|
||||
store_property(_be.kernel()->vprops_begin(), _be.kernel()->vprops_end(),
|
||||
OMFormat::Chunk::Entity_Vertex);
|
||||
store_property(_be.kernel()->fprops_begin(), _be.kernel()->fprops_end(),
|
||||
OMFormat::Chunk::Entity_Face);
|
||||
store_property(_be.kernel()->eprops_begin(), _be.kernel()->eprops_end(),
|
||||
OMFormat::Chunk::Entity_Edge);
|
||||
store_property(_be.kernel()->hprops_begin(), _be.kernel()->hprops_end(),
|
||||
OMFormat::Chunk::Entity_Halfedge);
|
||||
store_property(_be.kernel()->mprops_begin(), _be.kernel()->mprops_end(),
|
||||
OMFormat::Chunk::Entity_Mesh);
|
||||
|
||||
memset(&chunk_header, 0, sizeof(chunk_header));
|
||||
chunk_header.name_ = false;
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -103,17 +98,17 @@ public:
|
||||
/// Destructor
|
||||
virtual ~_OMWriter_() {};
|
||||
|
||||
std::string get_description() const
|
||||
std::string get_description() const override
|
||||
{ return "OpenMesh Format"; }
|
||||
|
||||
std::string get_extensions() const
|
||||
std::string get_extensions() const override
|
||||
{ return "om"; }
|
||||
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const override;
|
||||
|
||||
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const;
|
||||
static OMFormat::uint8 get_version() { return version_; }
|
||||
|
||||
|
||||
protected:
|
||||
@@ -121,7 +116,7 @@ protected:
|
||||
static const OMFormat::uchar magic_[3];
|
||||
static const OMFormat::uint8 version_;
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
bool write_binary(std::ostream&, BaseExporter&, Options) const;
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -127,14 +122,6 @@ write(std::ostream& _os, BaseExporter& _be, Options _opt, std::streamsize _preci
|
||||
omerr() << "[PLYWriter] : Warning: Face normals are not supported and thus not exported! " << std::endl;
|
||||
}
|
||||
|
||||
if ( _opt.check(Options::FaceColor) ) {
|
||||
// Face normals are not supported
|
||||
// Uncheck these options and output message that
|
||||
// they are not written out even though they were requested
|
||||
_opt.unset(Options::FaceColor);
|
||||
omerr() << "[PLYWriter] : Warning: Face colors are not supported and thus not exported! " << std::endl;
|
||||
}
|
||||
|
||||
options_ = _opt;
|
||||
|
||||
|
||||
@@ -318,6 +305,24 @@ void _PLYWriter_::write_header(std::ostream& _out, BaseExporter& _be, Options& _
|
||||
_out << "element face " << _be.n_faces() << '\n';
|
||||
_out << "property list uchar int vertex_indices" << '\n';
|
||||
|
||||
if ( _opt.face_has_color() ){
|
||||
if ( _opt.color_is_float() ) {
|
||||
_out << "property float red" << '\n';
|
||||
_out << "property float green" << '\n';
|
||||
_out << "property float blue" << '\n';
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
_out << "property float alpha" << '\n';
|
||||
} else {
|
||||
_out << "property uchar red" << '\n';
|
||||
_out << "property uchar green" << '\n';
|
||||
_out << "property uchar blue" << '\n';
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
_out << "property uchar alpha" << '\n';
|
||||
}
|
||||
}
|
||||
|
||||
_ofProps = writeCustomTypeHeader(_out, _be.kernel()->fprops_begin(), _be.kernel()->fprops_end());
|
||||
|
||||
_out << "end_header" << '\n';
|
||||
@@ -340,6 +345,7 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
|
||||
OpenMesh::Vec4f cAf;
|
||||
OpenMesh::Vec2f t;
|
||||
VertexHandle vh;
|
||||
FaceHandle fh;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
std::vector<CustomProperty> vProps;
|
||||
@@ -405,12 +411,37 @@ write_ascii(std::ostream& _out, BaseExporter& _be, Options _opt) const
|
||||
// faces (indices starting at 0)
|
||||
for (i=0, nF=int(_be.n_faces()); i<nF; ++i)
|
||||
{
|
||||
fh = FaceHandle(i);
|
||||
|
||||
// write vertex indices per face
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
nV = _be.get_vhandles(fh, vhandles);
|
||||
_out << nV;
|
||||
for (size_t j=0; j<vhandles.size(); ++j)
|
||||
_out << " " << vhandles[j].idx();
|
||||
|
||||
// FaceColor
|
||||
if ( _opt.face_has_color() ) {
|
||||
//with alpha
|
||||
if ( _opt.color_has_alpha() ){
|
||||
if (_opt.color_is_float()) {
|
||||
cAf = _be.colorAf(fh);
|
||||
_out << " " << cAf;
|
||||
} else {
|
||||
cA = _be.colorAi(fh);
|
||||
_out << " " << cA;
|
||||
}
|
||||
}else{
|
||||
//without alpha
|
||||
if (_opt.color_is_float()) {
|
||||
cf = _be.colorf(fh);
|
||||
_out << " " << cf;
|
||||
} else {
|
||||
c = _be.colori(fh);
|
||||
_out << " " << c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write custom props
|
||||
for (std::vector<CustomProperty>::iterator iter = fProps.begin(); iter < fProps.end(); ++iter)
|
||||
write_customProp<false>(_out,*iter,i);
|
||||
@@ -567,6 +598,7 @@ write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const
|
||||
OpenMesh::Vec4uc c;
|
||||
OpenMesh::Vec4f cf;
|
||||
VertexHandle vh;
|
||||
FaceHandle fh;
|
||||
std::vector<VertexHandle> vhandles;
|
||||
|
||||
// vProps and fProps will be empty, until custom properties are supported by the binary writer
|
||||
@@ -629,12 +661,35 @@ write_binary(std::ostream& _out, BaseExporter& _be, Options _opt) const
|
||||
|
||||
for (i=0, nF=int(_be.n_faces()); i<nF; ++i)
|
||||
{
|
||||
fh = FaceHandle(i);
|
||||
|
||||
//face
|
||||
nV = _be.get_vhandles(FaceHandle(i), vhandles);
|
||||
nV = _be.get_vhandles(fh, vhandles);
|
||||
writeValue(ValueTypeUINT8, _out, nV);
|
||||
for (size_t j=0; j<vhandles.size(); ++j)
|
||||
writeValue(ValueTypeINT32, _out, vhandles[j].idx() );
|
||||
|
||||
// face color
|
||||
if ( _opt.face_has_color() ) {
|
||||
if ( _opt.color_is_float() ) {
|
||||
cf = _be.colorAf(fh);
|
||||
writeValue(ValueTypeFLOAT, _out, cf[0]);
|
||||
writeValue(ValueTypeFLOAT, _out, cf[1]);
|
||||
writeValue(ValueTypeFLOAT, _out, cf[2]);
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
writeValue(ValueTypeFLOAT, _out, cf[3]);
|
||||
} else {
|
||||
c = _be.colorA(fh);
|
||||
writeValue(ValueTypeUCHAR, _out, (int)c[0]);
|
||||
writeValue(ValueTypeUCHAR, _out, (int)c[1]);
|
||||
writeValue(ValueTypeUCHAR, _out, (int)c[2]);
|
||||
|
||||
if ( _opt.color_has_alpha() )
|
||||
writeValue(ValueTypeUCHAR, _out, (int)c[3]);
|
||||
}
|
||||
}
|
||||
|
||||
for (std::vector<CustomProperty>::iterator iter = fProps.begin(); iter < fProps.end(); ++iter)
|
||||
write_customProp<true>(_out,*iter,i);
|
||||
}
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -87,6 +82,7 @@ namespace IO {
|
||||
|
||||
currently supported options:
|
||||
- VertexColors
|
||||
- FaceColors
|
||||
- Binary
|
||||
- Binary -> MSB
|
||||
*/
|
||||
@@ -99,14 +95,14 @@ public:
|
||||
/// Destructor
|
||||
virtual ~_PLYWriter_() {};
|
||||
|
||||
std::string get_description() const { return "PLY polygon file format"; }
|
||||
std::string get_extensions() const { return "ply"; }
|
||||
std::string get_description() const override { return "PLY polygon file format"; }
|
||||
std::string get_extensions() const override { return "ply"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const;
|
||||
size_t binary_size(BaseExporter& _be, Options _opt) const override;
|
||||
|
||||
enum ValueType {
|
||||
Unsupported = 0,
|
||||
@@ -124,7 +120,7 @@ private:
|
||||
{
|
||||
ValueType type;
|
||||
const BaseProperty* property;
|
||||
CustomProperty(const BaseProperty* const _p):type(Unsupported),property(_p){}
|
||||
explicit CustomProperty(const BaseProperty* const _p):type(Unsupported),property(_p){}
|
||||
};
|
||||
|
||||
const char* nameOfType_[12];
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -158,7 +153,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 +167,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 +206,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 +221,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 +268,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 +289,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 +339,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 +361,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)
|
||||
{
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -93,14 +88,14 @@ public:
|
||||
/// Destructor
|
||||
virtual ~_STLWriter_() {};
|
||||
|
||||
std::string get_description() const { return "Stereolithography Format"; }
|
||||
std::string get_extensions() const { return "stl stla stlb"; }
|
||||
std::string get_description() const override { return "Stereolithography Format"; }
|
||||
std::string get_extensions() const override { return "stl stla stlb"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
size_t binary_size(BaseExporter&, Options) const;
|
||||
size_t binary_size(BaseExporter&, Options) const override;
|
||||
|
||||
private:
|
||||
bool write_stla(const std::string&, BaseExporter&, Options) const;
|
||||
|
||||
@@ -40,11 +40,7 @@ bool _VTKWriter_::write(const std::string& _filename, BaseExporter& _be, Options
|
||||
|
||||
bool _VTKWriter_::write(std::ostream& _out, BaseExporter& _be, Options _opt, std::streamsize _precision) const
|
||||
{
|
||||
Vec3f v, n;
|
||||
Vec2f t;
|
||||
VertexHandle vh;
|
||||
OpenMesh::Vec3f c;
|
||||
OpenMesh::Vec4f cA;
|
||||
|
||||
// check exporter features
|
||||
if (!check(_be, _opt)) {
|
||||
@@ -78,7 +74,7 @@ bool _VTKWriter_::write(std::ostream& _out, BaseExporter& _be, Options _opt, std
|
||||
_out << "POINTS " << _be.n_vertices() << " float\n";
|
||||
size_t nv = _be.n_vertices();
|
||||
for (size_t i = 0; i < nv; ++i) {
|
||||
Vec3f v = _be.point(VertexHandle(int(i)));
|
||||
const Vec3f v = _be.point(VertexHandle(int(i)));
|
||||
_out << v[0] << ' ' << v[1] << ' ' << v[2] << '\n';
|
||||
}
|
||||
|
||||
|
||||
@@ -29,13 +29,13 @@ class OPENMESHDLLEXPORT _VTKWriter_ : public BaseWriter
|
||||
public:
|
||||
_VTKWriter_();
|
||||
|
||||
std::string get_description() const { return "VTK"; }
|
||||
std::string get_extensions() const { return "vtk"; }
|
||||
std::string get_description() const override { return "VTK"; }
|
||||
std::string get_extensions() const override { return "vtk"; }
|
||||
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const;
|
||||
bool write(const std::string&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
bool write(std::ostream&, BaseExporter&, Options, std::streamsize _precision = 6) const override;
|
||||
|
||||
size_t binary_size(BaseExporter&, Options) const { return 0; }
|
||||
size_t binary_size(BaseExporter&, Options) const override { return 0; }
|
||||
};
|
||||
|
||||
//== TYPE DEFINITION ==========================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef OPENMESH_ARRAY_ITEMS_HH
|
||||
#define OPENMESH_ARRAY_ITEMS_HH
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#include <OpenMesh/Core/Mesh/ArrayKernel.hh>
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -345,10 +340,10 @@ public:
|
||||
void clean_keep_reservation();
|
||||
|
||||
// --- number of items ---
|
||||
size_t n_vertices() const { return vertices_.size(); }
|
||||
size_t n_halfedges() const { return 2*edges_.size(); }
|
||||
size_t n_edges() const { return edges_.size(); }
|
||||
size_t n_faces() const { return faces_.size(); }
|
||||
size_t n_vertices() const override { return vertices_.size(); }
|
||||
size_t n_halfedges() const override { return 2*edges_.size(); }
|
||||
size_t n_edges() const override { return edges_.size(); }
|
||||
size_t n_faces() const override { return faces_.size(); }
|
||||
|
||||
bool vertices_empty() const { return vertices_.empty(); }
|
||||
bool halfedges_empty() const { return edges_.empty(); }
|
||||
@@ -702,7 +697,7 @@ public:
|
||||
typedef StatusSetT<Handle> Base;
|
||||
|
||||
public:
|
||||
AutoStatusSetT(ArrayKernel& _kernel)
|
||||
explicit AutoStatusSetT(ArrayKernel& _kernel)
|
||||
: StatusSetT<Handle>(_kernel, _kernel.pop_bit_mask(Handle()))
|
||||
{ /*assert(size() == 0);*/ } //the set should be empty on creation
|
||||
|
||||
@@ -746,12 +741,12 @@ public:
|
||||
{ handles_.reserve(_capacity_hint); }
|
||||
|
||||
~ExtStatusSetT()
|
||||
{ clear(); }
|
||||
{ Base::clear(); }
|
||||
|
||||
// Complexity: O(1)
|
||||
inline void insert(Handle _hnd)
|
||||
{
|
||||
if (!is_in(_hnd))
|
||||
if (!Base::is_in(_hnd))
|
||||
{
|
||||
Base::insert(_hnd);
|
||||
handles_.push_back(_hnd);
|
||||
@@ -771,7 +766,8 @@ public:
|
||||
//! Complexity: O(1)
|
||||
inline void erase(iterator _it)
|
||||
{
|
||||
assert(_it != end() && is_in(*_it));
|
||||
assert(_it != const_cast<const ExtStatusSetT*>(this)->end() &&
|
||||
Base::is_in(*_it));
|
||||
Base::erase(*_it);
|
||||
*_it = handles_.back();
|
||||
_it.pop_back();
|
||||
@@ -781,7 +777,7 @@ public:
|
||||
{
|
||||
for (iterator it = begin(); it != end(); ++it)
|
||||
{
|
||||
assert(is_in(*it));
|
||||
assert(Base::is_in(*it));
|
||||
Base::erase(*it);
|
||||
}
|
||||
handles_.clear();
|
||||
@@ -908,7 +904,7 @@ private:
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_ARRAY_KERNEL_C)
|
||||
# define OPENMESH_ARRAY_KERNEL_TEMPLATES
|
||||
# include "ArrayKernelT.cc"
|
||||
# include "ArrayKernelT_impl.hh"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_ARRAY_KERNEL_HH defined
|
||||
|
||||
@@ -39,13 +39,6 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision: 362 $ *
|
||||
* $Date: 2011-01-26 10:21:12 +0100 (Mi, 26 Jan 2011) $ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#define OPENMESH_ARRAY_KERNEL_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef OPENMESH_ATTRIBKERNEL_HH
|
||||
#define OPENMESH_ATTRIBKERNEL_HH
|
||||
@@ -110,10 +105,26 @@ public:
|
||||
FAttribs = MeshItems::FAttribs
|
||||
};
|
||||
|
||||
typedef VPropHandleT<VertexData> DataVPropHandle;
|
||||
typedef HPropHandleT<HalfedgeData> DataHPropHandle;
|
||||
typedef EPropHandleT<EdgeData> DataEPropHandle;
|
||||
typedef FPropHandleT<FaceData> DataFPropHandle;
|
||||
typedef VPropHandleT<VertexData> DataVPropHandle;
|
||||
typedef HPropHandleT<HalfedgeData> DataHPropHandle;
|
||||
typedef EPropHandleT<EdgeData> DataEPropHandle;
|
||||
typedef FPropHandleT<FaceData> DataFPropHandle;
|
||||
|
||||
typedef VPropHandleT<Point> PointsPropertyHandle;
|
||||
typedef VPropHandleT<Normal> VertexNormalsPropertyHandle;
|
||||
typedef VPropHandleT<Color> VertexColorsPropertyHandle;
|
||||
typedef VPropHandleT<TexCoord1D> VertexTexCoords1DPropertyHandle;
|
||||
typedef VPropHandleT<TexCoord2D> VertexTexCoords2DPropertyHandle;
|
||||
typedef VPropHandleT<TexCoord3D> VertexTexCoords3DPropertyHandle;
|
||||
typedef HPropHandleT<TexCoord1D> HalfedgeTexCoords1DPropertyHandle;
|
||||
typedef HPropHandleT<TexCoord2D> HalfedgeTexCoords2DPropertyHandle;
|
||||
typedef HPropHandleT<TexCoord3D> HalfedgeTexCoords3DPropertyHandle;
|
||||
typedef EPropHandleT<Color> EdgeColorsPropertyHandle;
|
||||
typedef HPropHandleT<Normal> HalfedgeNormalsPropertyHandle;
|
||||
typedef HPropHandleT<Color> HalfedgeColorsPropertyHandle;
|
||||
typedef FPropHandleT<Normal> FaceNormalsPropertyHandle;
|
||||
typedef FPropHandleT<Color> FaceColorsPropertyHandle;
|
||||
typedef FPropHandleT<TextureIndex> FaceTextureIndexPropertyHandle;
|
||||
|
||||
public:
|
||||
|
||||
@@ -245,6 +256,9 @@ public:
|
||||
void set_point(VertexHandle _vh, const Point& _p)
|
||||
{ this->property(points_, _vh) = _p; }
|
||||
|
||||
const PointsPropertyHandle& points_property_handle() const
|
||||
{ return points_; }
|
||||
|
||||
|
||||
//------------------------------------------------------------ vertex normals
|
||||
|
||||
@@ -597,24 +611,6 @@ public:
|
||||
bool has_face_colors() const { return face_colors_.is_valid(); }
|
||||
bool has_face_texture_index() const { return face_texture_index_.is_valid(); }
|
||||
|
||||
public:
|
||||
|
||||
typedef VPropHandleT<Point> PointsPropertyHandle;
|
||||
typedef VPropHandleT<Normal> VertexNormalsPropertyHandle;
|
||||
typedef VPropHandleT<Color> VertexColorsPropertyHandle;
|
||||
typedef VPropHandleT<TexCoord1D> VertexTexCoords1DPropertyHandle;
|
||||
typedef VPropHandleT<TexCoord2D> VertexTexCoords2DPropertyHandle;
|
||||
typedef VPropHandleT<TexCoord3D> VertexTexCoords3DPropertyHandle;
|
||||
typedef HPropHandleT<TexCoord1D> HalfedgeTexCoords1DPropertyHandle;
|
||||
typedef HPropHandleT<TexCoord2D> HalfedgeTexCoords2DPropertyHandle;
|
||||
typedef HPropHandleT<TexCoord3D> HalfedgeTexCoords3DPropertyHandle;
|
||||
typedef EPropHandleT<Color> EdgeColorsPropertyHandle;
|
||||
typedef HPropHandleT<Normal> HalfedgeNormalsPropertyHandle;
|
||||
typedef HPropHandleT<Color> HalfedgeColorsPropertyHandle;
|
||||
typedef FPropHandleT<Normal> FaceNormalsPropertyHandle;
|
||||
typedef FPropHandleT<Color> FaceColorsPropertyHandle;
|
||||
typedef FPropHandleT<TextureIndex> FaceTextureIndexPropertyHandle;
|
||||
|
||||
public:
|
||||
//standard vertex properties
|
||||
PointsPropertyHandle points_pph() const
|
||||
@@ -744,48 +740,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 ;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#include <OpenMesh/Core/Mesh/BaseKernel.hh>
|
||||
#include <iostream>
|
||||
@@ -69,27 +64,27 @@ void BaseKernel::property_stats(std::ostream& _ostr) const
|
||||
_ostr << vprops_.size() << " vprops:\n";
|
||||
for (it=vps.begin(); it!=vps.end(); ++it)
|
||||
{
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
}
|
||||
_ostr << hprops_.size() << " hprops:\n";
|
||||
for (it=hps.begin(); it!=hps.end(); ++it)
|
||||
{
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
}
|
||||
_ostr << eprops_.size() << " eprops:\n";
|
||||
for (it=eps.begin(); it!=eps.end(); ++it)
|
||||
{
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
}
|
||||
_ostr << fprops_.size() << " fprops:\n";
|
||||
for (it=fps.begin(); it!=fps.end(); ++it)
|
||||
{
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
}
|
||||
_ostr << mprops_.size() << " mprops:\n";
|
||||
for (it=mps.begin(); it!=mps.end(); ++it)
|
||||
{
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +97,7 @@ void BaseKernel::vprop_stats( std::string& _string ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& vps = vprops_.properties();
|
||||
for (it=vps.begin(); it!=vps.end(); ++it)
|
||||
if ( *it == NULL )
|
||||
if ( *it == nullptr )
|
||||
_string += "[deleted] \n";
|
||||
else {
|
||||
_string += (*it)->name();
|
||||
@@ -118,7 +113,7 @@ void BaseKernel::hprop_stats( std::string& _string ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& hps = hprops_.properties();
|
||||
for (it=hps.begin(); it!=hps.end(); ++it)
|
||||
if ( *it == NULL )
|
||||
if ( *it == nullptr )
|
||||
_string += "[deleted] \n";
|
||||
else {
|
||||
_string += (*it)->name();
|
||||
@@ -134,7 +129,7 @@ void BaseKernel::eprop_stats( std::string& _string ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& eps = eprops_.properties();
|
||||
for (it=eps.begin(); it!=eps.end(); ++it)
|
||||
if ( *it == NULL )
|
||||
if ( *it == nullptr )
|
||||
_string += "[deleted] \n";
|
||||
else {
|
||||
_string += (*it)->name();
|
||||
@@ -149,7 +144,7 @@ void BaseKernel::fprop_stats( std::string& _string ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& fps = fprops_.properties();
|
||||
for (it=fps.begin(); it!=fps.end(); ++it)
|
||||
if ( *it == NULL )
|
||||
if ( *it == nullptr )
|
||||
_string += "[deleted] \n";
|
||||
else {
|
||||
_string += (*it)->name();
|
||||
@@ -165,7 +160,7 @@ void BaseKernel::mprop_stats( std::string& _string ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& mps = mprops_.properties();
|
||||
for (it=mps.begin(); it!=mps.end(); ++it)
|
||||
if ( *it == NULL )
|
||||
if ( *it == nullptr )
|
||||
_string += "[deleted] \n";
|
||||
else {
|
||||
_string += (*it)->name();
|
||||
@@ -183,7 +178,7 @@ void BaseKernel::vprop_stats(std::ostream& _ostr ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& vps = vprops_.properties();
|
||||
for (it=vps.begin(); it!=vps.end(); ++it)
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
|
||||
}
|
||||
void BaseKernel::hprop_stats() const
|
||||
@@ -195,7 +190,7 @@ void BaseKernel::hprop_stats(std::ostream& _ostr ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& hps = hprops_.properties();
|
||||
for (it=hps.begin(); it!=hps.end(); ++it)
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
|
||||
}
|
||||
void BaseKernel::eprop_stats() const
|
||||
@@ -207,7 +202,7 @@ void BaseKernel::eprop_stats(std::ostream& _ostr ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& eps = eprops_.properties();
|
||||
for (it=eps.begin(); it!=eps.end(); ++it)
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
|
||||
}
|
||||
void BaseKernel::fprop_stats() const
|
||||
@@ -219,7 +214,7 @@ void BaseKernel::fprop_stats(std::ostream& _ostr ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& fps = fprops_.properties();
|
||||
for (it=fps.begin(); it!=fps.end(); ++it)
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
|
||||
}
|
||||
void BaseKernel::mprop_stats() const
|
||||
@@ -231,7 +226,7 @@ void BaseKernel::mprop_stats(std::ostream& _ostr ) const
|
||||
PropertyContainer::Properties::const_iterator it;
|
||||
const PropertyContainer::Properties& mps = mprops_.properties();
|
||||
for (it=mps.begin(); it!=mps.end(); ++it)
|
||||
*it == NULL ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
*it == nullptr ? (void)(_ostr << "[deleted]" << "\n") : (*it)->stats(_ostr);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -521,7 +516,7 @@ public:
|
||||
// Copy all properties, if build in is true
|
||||
// Otherwise, copy only properties without build in specifier
|
||||
if ( *p_it && ( _copyBuildIn || (*p_it)->name().substr(0,2) != "v:" ) )
|
||||
(*p_it)->copy(_vh_from.idx(), _vh_to.idx());
|
||||
(*p_it)->copy(static_cast<size_t>(_vh_from.idx()), static_cast<size_t>(_vh_to.idx()));
|
||||
|
||||
}
|
||||
}
|
||||
@@ -695,6 +690,9 @@ public: //----------------------------------------------------- element numbers
|
||||
virtual size_t n_edges() const { return 0; }
|
||||
virtual size_t n_faces() const { return 0; }
|
||||
|
||||
template <typename HandleT>
|
||||
size_t n_elements() const;
|
||||
|
||||
|
||||
protected: //------------------------------------------- synchronize properties
|
||||
|
||||
@@ -819,6 +817,16 @@ private:
|
||||
};
|
||||
|
||||
|
||||
template <>
|
||||
inline size_t BaseKernel::n_elements<VertexHandle>() const { return n_vertices(); }
|
||||
template <>
|
||||
inline size_t BaseKernel::n_elements<HalfedgeHandle>() const { return n_halfedges(); }
|
||||
template <>
|
||||
inline size_t BaseKernel::n_elements<EdgeHandle>() const { return n_edges(); }
|
||||
template <>
|
||||
inline size_t BaseKernel::n_elements<FaceHandle>() const { return n_faces(); }
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef OPENMESH_CASTS_HH
|
||||
#define OPENMESH_CASTS_HH
|
||||
|
||||
@@ -39,15 +39,9 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#ifndef OPENMESH_CIRCULATORS_HH
|
||||
#define OPENMESH_CIRCULATORS_HH
|
||||
#pragma once
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// Vertex and Face circulators for PolyMesh/TriMesh
|
||||
@@ -201,7 +195,7 @@ class GenericCirculatorBaseT {
|
||||
public:
|
||||
GenericCirculatorBaseT() : mesh_(0), lap_counter_(0) {}
|
||||
|
||||
GenericCirculatorBaseT(mesh_ref mesh, HalfedgeHandle heh, bool end = false) :
|
||||
GenericCirculatorBaseT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
|
||||
mesh_(&mesh), start_(heh), heh_(heh), lap_counter_(static_cast<int>(end && heh.is_valid())) {}
|
||||
|
||||
GenericCirculatorBaseT(const GenericCirculatorBaseT &rhs) :
|
||||
@@ -253,19 +247,25 @@ class GenericCirculatorBaseT {
|
||||
int lap_counter_;
|
||||
};
|
||||
|
||||
template<class Mesh, class CenterEntityHandle, class ValueHandle,
|
||||
ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const, bool CW = true >
|
||||
class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
|
||||
//template<class Mesh, class CenterEntityHandle, class ValueHandle,
|
||||
// ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const, bool CW = true >
|
||||
template <typename GenericCirculatorT_TraitsT, bool CW = true>
|
||||
class GenericCirculatorT : protected GenericCirculatorBaseT<typename GenericCirculatorT_TraitsT::Mesh> {
|
||||
public:
|
||||
using Mesh = typename GenericCirculatorT_TraitsT::Mesh;
|
||||
using value_type = typename GenericCirculatorT_TraitsT::ValueHandle;
|
||||
using CenterEntityHandle = typename GenericCirculatorT_TraitsT::CenterEntityHandle;
|
||||
|
||||
using smart_value_type = decltype(make_smart(std::declval<value_type>(), std::declval<Mesh>()));
|
||||
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef ValueHandle value_type;
|
||||
typedef const value_type& reference;
|
||||
typedef const value_type* pointer;
|
||||
typedef const smart_value_type* pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
|
||||
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
|
||||
typedef GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, ValueHandle, CW> GenericCirculator_ValueHandleFns;
|
||||
typedef GenericCirculator_ValueHandleFnsT<Mesh, CenterEntityHandle, value_type, CW> GenericCirculator_ValueHandleFns;
|
||||
|
||||
public:
|
||||
GenericCirculatorT() {}
|
||||
@@ -274,15 +274,15 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
|
||||
|
||||
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
|
||||
}
|
||||
GenericCirculatorT(mesh_ref mesh, HalfedgeHandle heh, bool end = false) :
|
||||
GenericCirculatorT(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
|
||||
GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
|
||||
|
||||
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
|
||||
}
|
||||
GenericCirculatorT(const GenericCirculatorT &rhs) : GenericCirculatorBaseT<Mesh>(rhs) {}
|
||||
|
||||
friend class GenericCirculatorT<Mesh,CenterEntityHandle,ValueHandle,Handle2Value,!CW>;
|
||||
explicit GenericCirculatorT( const GenericCirculatorT<Mesh,CenterEntityHandle,ValueHandle,Handle2Value,!CW>& rhs )
|
||||
friend class GenericCirculatorT<GenericCirculatorT_TraitsT,!CW>;
|
||||
explicit GenericCirculatorT( const GenericCirculatorT<GenericCirculatorT_TraitsT,!CW>& rhs )
|
||||
:GenericCirculatorBaseT<Mesh>(rhs){}
|
||||
|
||||
GenericCirculatorT& operator++() {
|
||||
@@ -313,16 +313,14 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
|
||||
}
|
||||
|
||||
/// Standard dereferencing operator.
|
||||
value_type operator*() const {
|
||||
// We can't use this due to a GCC6 compiler bug
|
||||
const GenericCirculatorBaseT<Mesh>* self = this;
|
||||
smart_value_type operator*() const {
|
||||
#ifndef NDEBUG
|
||||
assert(this->heh_.is_valid());
|
||||
value_type res = (self->*Handle2Value)();
|
||||
value_type res = GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_);
|
||||
assert(res.is_valid());
|
||||
return res;
|
||||
return make_smart(res, this->mesh_);
|
||||
#else
|
||||
return (self->*Handle2Value)();
|
||||
return make_smart(GenericCirculatorT_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -362,7 +360,7 @@ class GenericCirculatorT : protected GenericCirculatorBaseT<Mesh> {
|
||||
}
|
||||
|
||||
private:
|
||||
mutable value_type pointer_deref_value;
|
||||
mutable smart_value_type pointer_deref_value;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -425,19 +423,22 @@ class GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, typ
|
||||
}
|
||||
};
|
||||
|
||||
template<class Mesh, class CenterEntityHandle, class ValueHandle,
|
||||
ValueHandle (GenericCirculatorBaseT<Mesh>::*Handle2Value)() const>
|
||||
class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
template <typename GenericCirculatorT_DEPRECATED_TraitsT>
|
||||
class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh> {
|
||||
public:
|
||||
using Mesh = typename GenericCirculatorT_DEPRECATED_TraitsT::Mesh;
|
||||
using CenterEntityHandle = typename GenericCirculatorT_DEPRECATED_TraitsT::CenterEntityHandle;
|
||||
using value_type = typename GenericCirculatorT_DEPRECATED_TraitsT::ValueHandle;
|
||||
using smart_value_type = decltype (make_smart(std::declval<value_type>(), std::declval<Mesh>()));
|
||||
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef ValueHandle value_type;
|
||||
typedef const value_type& reference;
|
||||
typedef const value_type* pointer;
|
||||
typedef const smart_value_type* pointer;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
|
||||
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ptr mesh_ptr;
|
||||
typedef typename GenericCirculatorBaseT<Mesh>::mesh_ref mesh_ref;
|
||||
typedef GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, ValueHandle> GenericCirculator_ValueHandleFns;
|
||||
typedef GenericCirculator_ValueHandleFnsT_DEPRECATED<Mesh, CenterEntityHandle, value_type> GenericCirculator_ValueHandleFns;
|
||||
|
||||
public:
|
||||
GenericCirculatorT_DEPRECATED() {}
|
||||
@@ -446,7 +447,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
|
||||
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
|
||||
}
|
||||
GenericCirculatorT_DEPRECATED(mesh_ref mesh, HalfedgeHandle heh, bool end = false) :
|
||||
GenericCirculatorT_DEPRECATED(mesh_ref mesh, typename Mesh::HalfedgeHandle heh, bool end = false) :
|
||||
GenericCirculatorBaseT<Mesh>(mesh, heh, end) {
|
||||
|
||||
GenericCirculator_ValueHandleFns::init(this->mesh_, this->heh_, this->start_, this->lap_counter_);
|
||||
@@ -470,7 +471,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
To be save, you can use the CW/CCW circulator definitions, which behave\
|
||||
the same as the original ones, without the previously mentioned issues."
|
||||
|
||||
DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
|
||||
OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
|
||||
#endif // NO_DECREMENT_DEPRECATED_WARNINGS
|
||||
GenericCirculatorT_DEPRECATED& operator--() {
|
||||
assert(this->mesh_);
|
||||
@@ -488,7 +489,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
|
||||
/// Post-decrement
|
||||
#ifndef NO_DECREMENT_DEPRECATED_WARNINGS
|
||||
DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
|
||||
OM_DEPRECATED( DECREMENT_DEPRECATED_WARNINGS_TEXT )
|
||||
#undef DECREMENT_DEPRECATED_WARNINGS_TEXT
|
||||
#endif //NO_DECREMENT_DEPRECATED_WARNINGS
|
||||
GenericCirculatorT_DEPRECATED operator--(int) {
|
||||
@@ -499,16 +500,14 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
}
|
||||
|
||||
/// Standard dereferencing operator.
|
||||
value_type operator*() const {
|
||||
// We can't use this due to a GCC6 compiler bug
|
||||
const GenericCirculatorBaseT<Mesh>* self = this;
|
||||
smart_value_type operator*() const {
|
||||
#ifndef NDEBUG
|
||||
assert(this->heh_.is_valid());
|
||||
value_type res = (self->*Handle2Value)();
|
||||
value_type res = (GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_));
|
||||
assert(res.is_valid());
|
||||
return res;
|
||||
return make_smart(res, this->mesh_);
|
||||
#else
|
||||
return (self->*Handle2Value)();
|
||||
return make_smart(GenericCirculatorT_DEPRECATED_TraitsT::toHandle(this->mesh_, this->heh_), this->mesh_);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -542,17 +541,17 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
return GenericCirculator_ValueHandleFns::is_valid(this->heh_,this->start_, this->lap_counter_);
|
||||
}
|
||||
|
||||
DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
|
||||
OM_DEPRECATED("current_halfedge_handle() is an implementation detail and should not be accessed from outside the iterator class.")
|
||||
/**
|
||||
* \deprecated
|
||||
* current_halfedge_handle() is an implementation detail and should not
|
||||
* be accessed from outside the iterator class.
|
||||
*/
|
||||
const HalfedgeHandle ¤t_halfedge_handle() const {
|
||||
const typename Mesh::HalfedgeHandle ¤t_halfedge_handle() const {
|
||||
return this->heh_;
|
||||
}
|
||||
|
||||
DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
|
||||
OM_DEPRECATED("Do not use this error prone implicit cast. Compare to end-iterator or use is_valid(), instead.")
|
||||
/**
|
||||
* \deprecated
|
||||
* Do not use this error prone implicit cast. Compare to the
|
||||
@@ -567,8 +566,8 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
* \deprecated
|
||||
* This function clutters your code. Use dereferencing operators -> and * instead.
|
||||
*/
|
||||
DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
|
||||
value_type handle() const {
|
||||
OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
|
||||
smart_value_type handle() const {
|
||||
return **this;
|
||||
}
|
||||
|
||||
@@ -578,7 +577,7 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
* Implicit casts of iterators are unsafe. Use dereferencing operators
|
||||
* -> and * instead.
|
||||
*/
|
||||
DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
|
||||
OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
|
||||
operator value_type() const {
|
||||
return **this;
|
||||
}
|
||||
@@ -589,10 +588,9 @@ class GenericCirculatorT_DEPRECATED : protected GenericCirculatorBaseT<Mesh> {
|
||||
}
|
||||
|
||||
private:
|
||||
mutable value_type pointer_deref_value;
|
||||
mutable smart_value_type pointer_deref_value;
|
||||
};
|
||||
|
||||
} // namespace Iterators
|
||||
} // namespace OpenMesh
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
||||
* Copyright (c) 2001-2019, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
@@ -39,39 +39,28 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
// CLASS newClass - IMPLEMENTATION
|
||||
//
|
||||
//=============================================================================
|
||||
#ifndef OPENMESH_DEFAULTPOLYMESH_HH
|
||||
#define OPENMESH_DEFAULTPOLYMESH_HH
|
||||
|
||||
#define OPENMESH_NEWCLASS_C
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/.../newClass.hh>
|
||||
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
#include <OpenMesh/Core/Mesh/PolyMesh_ArrayKernelT.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
//== TYPEDEFS =================================================================
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
typedef PolyMesh_ArrayKernelT<DefaultTraitsDouble> PolyMesh;
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_DEFAULTPOLYMESH_HH defined
|
||||
//=============================================================================
|
||||
66
src/OpenMesh/Core/Mesh/DefaultTriMesh.hh
Normal file
66
src/OpenMesh/Core/Mesh/DefaultTriMesh.hh
Normal file
@@ -0,0 +1,66 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2019, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. Redistributions in binary form must reproduce the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer in the *
|
||||
* documentation and/or other materials provided with the distribution. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder nor the names of its *
|
||||
* contributors may be used to endorse or promote products derived from *
|
||||
* this software without specific prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
#ifndef OPENMESH_DEFAULTTRIMESH_HH
|
||||
#define OPENMESH_DEFAULTTRIMESH_HH
|
||||
|
||||
|
||||
//== INCLUDES =================================================================
|
||||
|
||||
#include <OpenMesh/Core/Mesh/Traits.hh>
|
||||
#include <OpenMesh/Core/Mesh/TriMesh_ArrayKernelT.hh>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
//== TYPEDEFS =================================================================
|
||||
|
||||
typedef TriMesh_ArrayKernelT<DefaultTraitsDouble> TriMesh;
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_DEFAULTTRIMESH_HH defined
|
||||
//=============================================================================
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef OPENMESH_MESH_ITEMS_HH
|
||||
#define OPENMESH_MESH_ITEMS_HH
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef OPENMESH_HANDLES_HH
|
||||
#define OPENMESH_HANDLES_HH
|
||||
@@ -64,7 +59,7 @@ namespace OpenMesh {
|
||||
|
||||
|
||||
/// Base class for all handle types
|
||||
class BaseHandle
|
||||
class OPENMESHDLLEXPORT BaseHandle
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -122,33 +117,42 @@ inline std::ostream& operator<<(std::ostream& _os, const BaseHandle& _hnd)
|
||||
|
||||
|
||||
/// Handle for a vertex entity
|
||||
struct VertexHandle : public BaseHandle
|
||||
struct OPENMESHDLLEXPORT VertexHandle : public BaseHandle
|
||||
{
|
||||
explicit VertexHandle(int _idx=-1) : BaseHandle(_idx) {}
|
||||
};
|
||||
|
||||
|
||||
/// Handle for a halfedge entity
|
||||
struct HalfedgeHandle : public BaseHandle
|
||||
struct OPENMESHDLLEXPORT HalfedgeHandle : public BaseHandle
|
||||
{
|
||||
explicit HalfedgeHandle(int _idx=-1) : BaseHandle(_idx) {}
|
||||
};
|
||||
|
||||
|
||||
/// Handle for a edge entity
|
||||
struct EdgeHandle : public BaseHandle
|
||||
struct OPENMESHDLLEXPORT EdgeHandle : public BaseHandle
|
||||
{
|
||||
explicit EdgeHandle(int _idx=-1) : BaseHandle(_idx) {}
|
||||
};
|
||||
|
||||
|
||||
/// Handle for a face entity
|
||||
struct FaceHandle : public BaseHandle
|
||||
struct OPENMESHDLLEXPORT FaceHandle : public BaseHandle
|
||||
{
|
||||
explicit FaceHandle(int _idx=-1) : BaseHandle(_idx) {}
|
||||
};
|
||||
|
||||
|
||||
/// Handle type for meshes to simplify some template programming
|
||||
struct OPENMESHDLLEXPORT MeshHandle : public BaseHandle
|
||||
{
|
||||
explicit MeshHandle(int _idx=-1) : BaseHandle(_idx) {}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
@@ -165,8 +169,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 +181,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 +193,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 +206,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 +219,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();
|
||||
|
||||
@@ -39,15 +39,8 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
#ifndef OPENMESH_ITERATORS_HH
|
||||
#define OPENMESH_ITERATORS_HH
|
||||
#pragma once
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
@@ -94,24 +87,22 @@ class GenericIteratorT {
|
||||
typedef value_handle value_type;
|
||||
typedef std::bidirectional_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef const value_type& reference;
|
||||
typedef const value_type* pointer;
|
||||
typedef const Mesh* mesh_ptr;
|
||||
typedef const Mesh& mesh_ref;
|
||||
typedef decltype(make_smart(std::declval<ValueHandle>(), std::declval<Mesh>())) SmartHandle;
|
||||
typedef const SmartHandle& reference;
|
||||
typedef const SmartHandle* pointer;
|
||||
|
||||
/// Default constructor.
|
||||
GenericIteratorT()
|
||||
: mesh_(0), skip_bits_(0)
|
||||
: hnd_(make_smart(ValueHandle(),nullptr)), skip_bits_(0)
|
||||
{}
|
||||
|
||||
/// Construct with mesh and a target handle.
|
||||
GenericIteratorT(mesh_ref _mesh, value_handle _hnd, bool _skip=false)
|
||||
: mesh_(&_mesh), hnd_(_hnd), skip_bits_(0)
|
||||
: hnd_(make_smart(_hnd, _mesh)), 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.
|
||||
@@ -129,7 +120,7 @@ class GenericIteratorT {
|
||||
* \deprecated
|
||||
* This function clutters your code. Use dereferencing operators -> and * instead.
|
||||
*/
|
||||
DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
|
||||
OM_DEPRECATED("This function clutters your code. Use dereferencing operators -> and * instead.")
|
||||
value_handle handle() const {
|
||||
return hnd_;
|
||||
}
|
||||
@@ -140,14 +131,14 @@ class GenericIteratorT {
|
||||
* Implicit casts of iterators are unsafe. Use dereferencing operators
|
||||
* -> and * instead.
|
||||
*/
|
||||
DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
|
||||
OM_DEPRECATED("Implicit casts of iterators are unsafe. Use dereferencing operators -> and * instead.")
|
||||
operator value_handle() const {
|
||||
return hnd_;
|
||||
}
|
||||
|
||||
/// Are two iterators equal? Only valid if they refer to the same mesh!
|
||||
bool operator==(const GenericIteratorT& _rhs) const {
|
||||
return ((mesh_ == _rhs.mesh_) && (hnd_ == _rhs.hnd_));
|
||||
return ((hnd_.mesh() == _rhs.hnd_.mesh()) && (hnd_ == _rhs.hnd_));
|
||||
}
|
||||
|
||||
/// Not equal?
|
||||
@@ -218,7 +209,7 @@ class GenericIteratorT {
|
||||
|
||||
/// Turn on skipping: automatically skip deleted/hidden elements
|
||||
void enable_skipping() {
|
||||
if (mesh_ && (mesh_->*PrimitiveStatusMember)()) {
|
||||
if (hnd_.mesh() && (hnd_.mesh()->*PrimitiveStatusMember)()) {
|
||||
Attributes::StatusInfo status;
|
||||
status.set_deleted(true);
|
||||
status.set_hidden(true);
|
||||
@@ -236,21 +227,20 @@ class GenericIteratorT {
|
||||
private:
|
||||
|
||||
void skip_fwd() {
|
||||
assert(mesh_ && skip_bits_);
|
||||
while ((hnd_.idx() < (signed) (mesh_->*PrimitiveCountMember)())
|
||||
&& (mesh_->status(hnd_).bits() & skip_bits_))
|
||||
assert(hnd_.mesh() && skip_bits_);
|
||||
while ((hnd_.idx() < (signed) (hnd_.mesh()->*PrimitiveCountMember)())
|
||||
&& (hnd_.mesh()->status(hnd_).bits() & skip_bits_))
|
||||
hnd_.__increment();
|
||||
}
|
||||
|
||||
void skip_bwd() {
|
||||
assert(mesh_ && skip_bits_);
|
||||
while ((hnd_.idx() >= 0) && (mesh_->status(hnd_).bits() & skip_bits_))
|
||||
assert(hnd_.mesh() && skip_bits_);
|
||||
while ((hnd_.idx() >= 0) && (hnd_.mesh()->status(hnd_).bits() & skip_bits_))
|
||||
hnd_.__decrement();
|
||||
}
|
||||
|
||||
protected:
|
||||
mesh_ptr mesh_;
|
||||
value_handle hnd_;
|
||||
SmartHandle hnd_;
|
||||
unsigned int skip_bits_;
|
||||
};
|
||||
|
||||
@@ -258,5 +248,3 @@ class GenericIteratorT {
|
||||
} // namespace Iterators
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
#endif
|
||||
//=============================================================================
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//== IMPLEMENTATION ==========================================================
|
||||
#include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
|
||||
@@ -59,8 +54,7 @@ const PolyConnectivity::FaceHandle PolyConnectivity::InvalidFaceHandle;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
PolyConnectivity::HalfedgeHandle
|
||||
PolyConnectivity::find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh ) const
|
||||
SmartHalfedgeHandle PolyConnectivity::find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh ) const
|
||||
{
|
||||
assert(_start_vh.is_valid() && _end_vh.is_valid());
|
||||
|
||||
@@ -68,7 +62,7 @@ PolyConnectivity::find_halfedge(VertexHandle _start_vh, VertexHandle _end_vh ) c
|
||||
if (to_vertex_handle(*voh_it) == _end_vh)
|
||||
return *voh_it;
|
||||
|
||||
return InvalidHalfedgeHandle;
|
||||
return make_smart(InvalidHalfedgeHandle, this);
|
||||
}
|
||||
|
||||
|
||||
@@ -104,6 +98,7 @@ bool PolyConnectivity::is_manifold(VertexHandle _vh) const
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void PolyConnectivity::adjust_outgoing_halfedge(VertexHandle _vh)
|
||||
{
|
||||
for (ConstVertexOHalfedgeIter vh_it=cvoh_iter(_vh); vh_it.is_valid(); ++vh_it)
|
||||
@@ -118,7 +113,7 @@ void PolyConnectivity::adjust_outgoing_halfedge(VertexHandle _vh)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
PolyConnectivity::FaceHandle
|
||||
SmartFaceHandle
|
||||
PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size)
|
||||
{
|
||||
VertexHandle vh;
|
||||
@@ -147,7 +142,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size
|
||||
if ( !is_boundary(_vertex_handles[i]) )
|
||||
{
|
||||
omerr() << "PolyMeshT::add_face: complex vertex\n";
|
||||
return InvalidFaceHandle;
|
||||
return make_smart(InvalidFaceHandle, this);
|
||||
}
|
||||
|
||||
// Initialise edge attributes
|
||||
@@ -159,7 +154,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size
|
||||
if (!edgeData_[i].is_new && !is_boundary(edgeData_[i].halfedge_handle))
|
||||
{
|
||||
omerr() << "PolyMeshT::add_face: complex edge\n";
|
||||
return InvalidFaceHandle;
|
||||
return make_smart(InvalidFaceHandle, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,7 +186,7 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size
|
||||
if (boundary_prev == inner_prev)
|
||||
{
|
||||
omerr() << "PolyMeshT::add_face: patch re-linking failed\n";
|
||||
return InvalidFaceHandle;
|
||||
return make_smart(InvalidFaceHandle, this);
|
||||
}
|
||||
|
||||
assert(is_boundary(boundary_prev));
|
||||
@@ -302,12 +297,12 @@ PolyConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size
|
||||
if (edgeData_[i].needs_adjust)
|
||||
adjust_outgoing_halfedge(_vertex_handles[i]);
|
||||
|
||||
return fh;
|
||||
return make_smart(fh, this);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3)
|
||||
SmartFaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3)
|
||||
{
|
||||
VertexHandle vhs[4] = { _vh0, _vh1, _vh2, _vh3 };
|
||||
return add_face(vhs, 4);
|
||||
@@ -315,7 +310,7 @@ FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, Vert
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2)
|
||||
SmartFaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2)
|
||||
{
|
||||
VertexHandle vhs[3] = { _vh0, _vh1, _vh2 };
|
||||
return add_face(vhs, 3);
|
||||
@@ -323,9 +318,17 @@ FaceHandle PolyConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, Vert
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FaceHandle PolyConnectivity::add_face(const std::vector<VertexHandle>& _vhandles)
|
||||
SmartFaceHandle PolyConnectivity::add_face(const std::vector<VertexHandle>& _vhandles)
|
||||
{ return add_face(&_vhandles.front(), _vhandles.size()); }
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SmartFaceHandle PolyConnectivity::add_face(const std::vector<SmartVertexHandle>& _vhandles)
|
||||
{
|
||||
std::vector<VertexHandle> vhandles(_vhandles.begin(), _vhandles.end());
|
||||
return add_face(&vhandles.front(), vhandles.size());
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
bool PolyConnectivity::is_collapse_ok(HalfedgeHandle v0v1)
|
||||
@@ -364,14 +367,16 @@ bool PolyConnectivity::is_collapse_ok(HalfedgeHandle v0v1)
|
||||
|
||||
//the edges v1-vl and vl-v0 must not be both boundary edges
|
||||
//this test makes only sense in a polymesh if the side face is a triangle
|
||||
VertexHandle vl;
|
||||
if (!is_boundary(v0v1))
|
||||
{
|
||||
if (v0v1_triangle)
|
||||
{
|
||||
//VertexHandle vl = to_vertex_handle(next_halfedge_handle(v0v1));
|
||||
|
||||
HalfedgeHandle h1 = next_halfedge_handle(v0v1);
|
||||
HalfedgeHandle h2 = next_halfedge_handle(h1);
|
||||
|
||||
vl = to_vertex_handle(h1);
|
||||
|
||||
if (is_boundary(opposite_halfedge_handle(h1)) && is_boundary(opposite_halfedge_handle(h2)))
|
||||
return false;
|
||||
}
|
||||
@@ -379,19 +384,24 @@ bool PolyConnectivity::is_collapse_ok(HalfedgeHandle v0v1)
|
||||
|
||||
//the edges v0-vr and vr-v1 must not be both boundary edges
|
||||
//this test makes only sense in a polymesh if the side face is a triangle
|
||||
VertexHandle vr;
|
||||
if (!is_boundary(v1v0))
|
||||
{
|
||||
if (v1v0_triangle)
|
||||
{
|
||||
//VertexHandle vr = to_vertex_handle(next_halfedge_handle(v1v0));
|
||||
|
||||
HalfedgeHandle h1 = next_halfedge_handle(v1v0);
|
||||
HalfedgeHandle h2 = next_halfedge_handle(h1);
|
||||
|
||||
vr = to_vertex_handle(h1);
|
||||
|
||||
if (is_boundary(opposite_halfedge_handle(h1)) && is_boundary(opposite_halfedge_handle(h2)))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if vl and vr are equal and valid (e.g. triangle case) -> fail
|
||||
if ( vl.is_valid() && (vl == vr)) return false;
|
||||
|
||||
// edge between two boundary vertices should be a boundary edge
|
||||
if ( is_boundary(v0) && is_boundary(v1) && !is_boundary(v0v1) && !is_boundary(v1v0))
|
||||
return false;
|
||||
@@ -621,101 +631,6 @@ void PolyConnectivity::delete_face(FaceHandle _fh, bool _delete_isolated_vertice
|
||||
adjust_outgoing_halfedge(*v_it);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::VertexIter PolyConnectivity::vertices_begin()
|
||||
{
|
||||
return VertexIter(*this, VertexHandle(0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_begin() const
|
||||
{
|
||||
return ConstVertexIter(*this, VertexHandle(0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::VertexIter PolyConnectivity::vertices_end()
|
||||
{
|
||||
return VertexIter(*this, VertexHandle( int(n_vertices() ) ));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_end() const
|
||||
{
|
||||
return ConstVertexIter(*this, VertexHandle( int(n_vertices()) ));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_begin()
|
||||
{
|
||||
return HalfedgeIter(*this, HalfedgeHandle(0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_begin() const
|
||||
{
|
||||
return ConstHalfedgeIter(*this, HalfedgeHandle(0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_end()
|
||||
{
|
||||
return HalfedgeIter(*this, HalfedgeHandle(int(n_halfedges())));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_end() const
|
||||
{
|
||||
return ConstHalfedgeIter(*this, HalfedgeHandle(int(n_halfedges())));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::EdgeIter PolyConnectivity::edges_begin()
|
||||
{
|
||||
return EdgeIter(*this, EdgeHandle(0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_begin() const
|
||||
{
|
||||
return ConstEdgeIter(*this, EdgeHandle(0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::EdgeIter PolyConnectivity::edges_end()
|
||||
{
|
||||
return EdgeIter(*this, EdgeHandle(int(n_edges())));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_end() const
|
||||
{
|
||||
return ConstEdgeIter(*this, EdgeHandle(int(n_edges())));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::FaceIter PolyConnectivity::faces_begin()
|
||||
{
|
||||
return FaceIter(*this, FaceHandle(0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::ConstFaceIter PolyConnectivity::faces_begin() const
|
||||
{
|
||||
return ConstFaceIter(*this, FaceHandle(0));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::FaceIter PolyConnectivity::faces_end()
|
||||
{
|
||||
return FaceIter(*this, FaceHandle(int(n_faces())));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const
|
||||
{
|
||||
return ConstFaceIter(*this, FaceHandle(int(n_faces())));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void PolyConnectivity::collapse(HalfedgeHandle _hh)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
832
src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh
Normal file
832
src/OpenMesh/Core/Mesh/PolyConnectivity_inline_impl.hh
Normal file
@@ -0,0 +1,832 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. Redistributions in binary form must reproduce the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer in the *
|
||||
* documentation and/or other materials provided with the distribution. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder nor the names of its *
|
||||
* contributors may be used to endorse or promote products derived from *
|
||||
* this software without specific prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
#ifndef OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE
|
||||
#error Do not include this directly, include instead PolyConnectivity.hh
|
||||
#endif // OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE
|
||||
|
||||
#include <OpenMesh/Core/Mesh/IteratorsT.hh>
|
||||
#include <OpenMesh/Core/Mesh/CirculatorsT.hh>
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
|
||||
inline SmartVertexHandle PolyConnectivity::add_vertex() { return make_smart(new_vertex(), *this); }
|
||||
|
||||
inline SmartHalfedgeHandle PolyConnectivity::next_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(next_halfedge_handle(HalfedgeHandle(_heh)), *this); }
|
||||
inline SmartHalfedgeHandle PolyConnectivity::prev_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(prev_halfedge_handle(HalfedgeHandle(_heh)), *this); }
|
||||
inline SmartHalfedgeHandle PolyConnectivity::opposite_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(opposite_halfedge_handle(HalfedgeHandle(_heh)), *this); }
|
||||
inline SmartHalfedgeHandle PolyConnectivity::ccw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(ccw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); }
|
||||
inline SmartHalfedgeHandle PolyConnectivity::cw_rotated_halfedge_handle(SmartHalfedgeHandle _heh) const { return make_smart(cw_rotated_halfedge_handle(HalfedgeHandle(_heh)), *this); }
|
||||
|
||||
inline SmartHalfedgeHandle PolyConnectivity::s_halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) { return make_smart(ArrayKernel::s_halfedge_handle(EdgeHandle(_eh), _i), _eh.mesh()); }
|
||||
inline SmartEdgeHandle PolyConnectivity::s_edge_handle(SmartHalfedgeHandle _heh) { return make_smart(ArrayKernel::s_edge_handle(HalfedgeHandle(_heh)), _heh.mesh()); }
|
||||
|
||||
inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartEdgeHandle _eh, unsigned int _i) const { return make_smart(halfedge_handle(EdgeHandle(_eh), _i), *this); }
|
||||
inline SmartEdgeHandle PolyConnectivity::edge_handle(SmartHalfedgeHandle _heh) const { return make_smart(edge_handle(HalfedgeHandle(_heh)), *this); }
|
||||
inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartFaceHandle _fh) const { return make_smart(halfedge_handle(FaceHandle(_fh)), *this); }
|
||||
inline SmartHalfedgeHandle PolyConnectivity::halfedge_handle(SmartVertexHandle _vh) const { return make_smart(halfedge_handle(VertexHandle(_vh)), *this); }
|
||||
|
||||
inline SmartFaceHandle PolyConnectivity::face_handle(SmartHalfedgeHandle _heh) const { return make_smart(face_handle(HalfedgeHandle(_heh)), *this); }
|
||||
|
||||
inline SmartFaceHandle PolyConnectivity::opposite_face_handle(HalfedgeHandle _heh) const { return make_smart(face_handle(opposite_halfedge_handle(_heh)), *this); }
|
||||
|
||||
|
||||
/// Generic class for vertex/halfedge/edge/face ranges.
|
||||
template <typename RangeTraitT>
|
||||
class EntityRange : public SmartRangeT<EntityRange<RangeTraitT>, typename RangeTraitT::ITER_TYPE::SmartHandle> {
|
||||
public:
|
||||
typedef typename RangeTraitT::ITER_TYPE iterator;
|
||||
typedef typename RangeTraitT::ITER_TYPE const_iterator;
|
||||
|
||||
explicit EntityRange(typename RangeTraitT::CONTAINER_TYPE &container) : container_(container) {}
|
||||
typename RangeTraitT::ITER_TYPE begin() const { return RangeTraitT::begin(container_); }
|
||||
typename RangeTraitT::ITER_TYPE end() const { return RangeTraitT::end(container_); }
|
||||
|
||||
private:
|
||||
typename RangeTraitT::CONTAINER_TYPE &container_;
|
||||
};
|
||||
|
||||
/// Generic class for iterator ranges.
|
||||
template <typename CirculatorRangeTraitT>
|
||||
//class CirculatorRange : public SmartRangeT<CirculatorRange<CirculatorRangeTraitT>, decltype (make_smart(std::declval<typename CirculatorRangeTraitT::TO_ENTITYE_TYPE>(), std::declval<PolyConnectivity>()))>{
|
||||
class CirculatorRange : public SmartRangeT<CirculatorRange<CirculatorRangeTraitT>, typename SmartHandle<typename CirculatorRangeTraitT::TO_ENTITYE_TYPE>::type>{
|
||||
public:
|
||||
typedef typename CirculatorRangeTraitT::ITER_TYPE ITER_TYPE;
|
||||
typedef typename CirculatorRangeTraitT::CENTER_ENTITY_TYPE CENTER_ENTITY_TYPE;
|
||||
typedef typename CirculatorRangeTraitT::CONTAINER_TYPE CONTAINER_TYPE;
|
||||
typedef ITER_TYPE iterator;
|
||||
typedef ITER_TYPE const_iterator;
|
||||
|
||||
CirculatorRange(
|
||||
const CONTAINER_TYPE &container,
|
||||
CENTER_ENTITY_TYPE center) :
|
||||
container_(container), center_(center) {}
|
||||
ITER_TYPE begin() const { return CirculatorRangeTraitT::begin(container_, center_); }
|
||||
ITER_TYPE end() const { return CirculatorRangeTraitT::end(container_, center_); }
|
||||
|
||||
private:
|
||||
const CONTAINER_TYPE &container_;
|
||||
CENTER_ENTITY_TYPE center_;
|
||||
};
|
||||
|
||||
|
||||
inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::vertices() const { return ConstVertexRangeSkipping(*this); }
|
||||
inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_vertices() const { return ConstVertexRange(*this); }
|
||||
inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::halfedges() const { return ConstHalfedgeRangeSkipping(*this); }
|
||||
inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_halfedges() const { return ConstHalfedgeRange(*this); }
|
||||
inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::edges() const { return ConstEdgeRangeSkipping(*this); }
|
||||
inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_edges() const { return ConstEdgeRange(*this); }
|
||||
inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::faces() const { return ConstFaceRangeSkipping(*this); }
|
||||
inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_faces() const { return ConstFaceRange(*this); }
|
||||
|
||||
template <> inline PolyConnectivity::ConstVertexRangeSkipping PolyConnectivity::elements<VertexHandle>() const { return vertices(); }
|
||||
template <> inline PolyConnectivity::ConstVertexRange PolyConnectivity::all_elements<VertexHandle>() const { return all_vertices(); }
|
||||
template <> inline PolyConnectivity::ConstHalfedgeRangeSkipping PolyConnectivity::elements<HalfedgeHandle>() const { return halfedges(); }
|
||||
template <> inline PolyConnectivity::ConstHalfedgeRange PolyConnectivity::all_elements<HalfedgeHandle>() const { return all_halfedges(); }
|
||||
template <> inline PolyConnectivity::ConstEdgeRangeSkipping PolyConnectivity::elements<EdgeHandle>() const { return edges(); }
|
||||
template <> inline PolyConnectivity::ConstEdgeRange PolyConnectivity::all_elements<EdgeHandle>() const { return all_edges(); }
|
||||
template <> inline PolyConnectivity::ConstFaceRangeSkipping PolyConnectivity::elements<FaceHandle>() const { return faces(); }
|
||||
template <> inline PolyConnectivity::ConstFaceRange PolyConnectivity::all_elements<FaceHandle>() const { return all_faces(); }
|
||||
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexRange PolyConnectivity::vv_range(VertexHandle _vh) const {
|
||||
return ConstVertexVertexRange(*this, _vh);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeRange PolyConnectivity::vih_range(VertexHandle _vh) const {
|
||||
return ConstVertexIHalfedgeRange(*this, _vh);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeRange PolyConnectivity::voh_range(VertexHandle _vh) const {
|
||||
return ConstVertexOHalfedgeRange(*this, _vh);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeRange PolyConnectivity::ve_range(VertexHandle _vh) const {
|
||||
return ConstVertexEdgeRange(*this, _vh);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceRange PolyConnectivity::vf_range(VertexHandle _vh) const {
|
||||
return ConstVertexFaceRange(*this, _vh);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexRange PolyConnectivity::fv_range(FaceHandle _fh) const {
|
||||
return ConstFaceVertexRange(*this, _fh);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeRange PolyConnectivity::fh_range(FaceHandle _fh) const {
|
||||
return ConstFaceHalfedgeRange(*this, _fh);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeRange PolyConnectivity::fe_range(FaceHandle _fh) const {
|
||||
return ConstFaceEdgeRange(*this, _fh);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceRange PolyConnectivity::ff_range(FaceHandle _fh) const {
|
||||
return ConstFaceFaceRange(*this, _fh);
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline PolyConnectivity::VertexIter PolyConnectivity::vertices_begin()
|
||||
{ return VertexIter(*this, VertexHandle(0)); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_begin() const
|
||||
{ return ConstVertexIter(*this, VertexHandle(0)); }
|
||||
|
||||
inline PolyConnectivity::VertexIter PolyConnectivity::vertices_end()
|
||||
{ return VertexIter(*this, VertexHandle( int(n_vertices() ) )); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_end() const
|
||||
{ return ConstVertexIter(*this, VertexHandle( int(n_vertices()) )); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_begin()
|
||||
{ return HalfedgeIter(*this, HalfedgeHandle(0)); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_begin() const
|
||||
{ return ConstHalfedgeIter(*this, HalfedgeHandle(0)); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_end()
|
||||
{ return HalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_end() const
|
||||
{ return ConstHalfedgeIter(*this, HalfedgeHandle(int(n_halfedges()))); }
|
||||
|
||||
inline PolyConnectivity::EdgeIter PolyConnectivity::edges_begin()
|
||||
{ return EdgeIter(*this, EdgeHandle(0)); }
|
||||
|
||||
inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_begin() const
|
||||
{ return ConstEdgeIter(*this, EdgeHandle(0)); }
|
||||
|
||||
inline PolyConnectivity::EdgeIter PolyConnectivity::edges_end()
|
||||
{ return EdgeIter(*this, EdgeHandle(int(n_edges()))); }
|
||||
|
||||
inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_end() const
|
||||
{ return ConstEdgeIter(*this, EdgeHandle(int(n_edges()))); }
|
||||
|
||||
inline PolyConnectivity::FaceIter PolyConnectivity::faces_begin()
|
||||
{ return FaceIter(*this, FaceHandle(0)); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_begin() const
|
||||
{ return ConstFaceIter(*this, FaceHandle(0)); }
|
||||
|
||||
inline PolyConnectivity::FaceIter PolyConnectivity::faces_end()
|
||||
{ return FaceIter(*this, FaceHandle(int(n_faces()))); }
|
||||
|
||||
|
||||
inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_end() const
|
||||
{ return ConstFaceIter(*this, FaceHandle(int(n_faces()))); }
|
||||
|
||||
inline PolyConnectivity::VertexIter PolyConnectivity::vertices_sbegin()
|
||||
{ return VertexIter(*this, VertexHandle(0), true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIter PolyConnectivity::vertices_sbegin() const
|
||||
{ return ConstVertexIter(*this, VertexHandle(0), true); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeIter PolyConnectivity::halfedges_sbegin()
|
||||
{ return HalfedgeIter(*this, HalfedgeHandle(0), true); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeIter PolyConnectivity::halfedges_sbegin() const
|
||||
{ return ConstHalfedgeIter(*this, HalfedgeHandle(0), true); }
|
||||
|
||||
inline PolyConnectivity::EdgeIter PolyConnectivity::edges_sbegin()
|
||||
{ return EdgeIter(*this, EdgeHandle(0), true); }
|
||||
|
||||
inline PolyConnectivity::ConstEdgeIter PolyConnectivity::edges_sbegin() const
|
||||
{ return ConstEdgeIter(*this, EdgeHandle(0), true); }
|
||||
|
||||
inline PolyConnectivity::FaceIter PolyConnectivity::faces_sbegin()
|
||||
{ return FaceIter(*this, FaceHandle(0), true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceIter PolyConnectivity::faces_sbegin() const
|
||||
{ return ConstFaceIter(*this, FaceHandle(0), true); }
|
||||
|
||||
inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_iter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexVertexIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexVertexCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexVertexCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_iter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexIHalfedgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexIHalfedgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexIHalfedgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_iter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexOHalfedgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexOHalfedgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexOHalfedgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_iter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexEdgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexEdgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexEdgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_iter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexFaceIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexFaceCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwiter(ArrayKernel::VertexHandle _vh)
|
||||
{ return VertexFaceCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_iter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexVertexIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexVertexCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexVertexCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_iter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_iter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_iter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_iter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexFaceIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexFaceCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwiter(ArrayKernel::VertexHandle _vh) const
|
||||
{ return ConstVertexFaceCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_iter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceVertexIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwiter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceVertexCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwiter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceVertexCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_iter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceHalfedgeIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwiter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceHalfedgeCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwiter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceHalfedgeCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_iter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceEdgeIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwiter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceEdgeCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwiter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceEdgeCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_iter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceFaceIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwiter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceFaceCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwiter(ArrayKernel::FaceHandle _fh)
|
||||
{ return FaceFaceCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_iter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceVertexIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwiter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceVertexCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwiter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceVertexCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_iter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwiter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwiter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_iter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwiter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwiter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_iter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceFaceIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwiter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceFaceCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwiter(ArrayKernel::FaceHandle _fh) const
|
||||
{ return ConstFaceFaceCCWIter(*this, _fh); }
|
||||
|
||||
|
||||
inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_begin(VertexHandle _vh)
|
||||
{ return VertexVertexIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwbegin(VertexHandle _vh)
|
||||
{ return VertexVertexCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwbegin(VertexHandle _vh)
|
||||
{ return VertexVertexCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_begin(VertexHandle _vh)
|
||||
{ return VertexIHalfedgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwbegin(VertexHandle _vh)
|
||||
{ return VertexIHalfedgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwbegin(VertexHandle _vh)
|
||||
{ return VertexIHalfedgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_begin(VertexHandle _vh)
|
||||
{ return VertexOHalfedgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwbegin(VertexHandle _vh)
|
||||
{ return VertexOHalfedgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwbegin(VertexHandle _vh)
|
||||
{ return VertexOHalfedgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_begin(VertexHandle _vh)
|
||||
{ return VertexEdgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwbegin(VertexHandle _vh)
|
||||
{ return VertexEdgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwbegin(VertexHandle _vh)
|
||||
{ return VertexEdgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_begin(VertexHandle _vh)
|
||||
{ return VertexFaceIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwbegin(VertexHandle _vh)
|
||||
{ return VertexFaceCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwbegin(VertexHandle _vh)
|
||||
{ return VertexFaceCCWIter(*this, _vh); }
|
||||
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_begin(VertexHandle _vh) const
|
||||
{ return ConstVertexVertexIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexVertexCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexVertexCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_begin(VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_begin(VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_begin(VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeCCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_begin(VertexHandle _vh) const
|
||||
{ return ConstVertexFaceIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexFaceCWIter(*this, _vh); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwbegin(VertexHandle _vh) const
|
||||
{ return ConstVertexFaceCCWIter(*this, _vh); }
|
||||
|
||||
|
||||
inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_begin(FaceHandle _fh)
|
||||
{ return FaceVertexIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwbegin(FaceHandle _fh)
|
||||
{ return FaceVertexCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwbegin(FaceHandle _fh)
|
||||
{ return FaceVertexCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_begin(FaceHandle _fh)
|
||||
{ return FaceHalfedgeIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwbegin(FaceHandle _fh)
|
||||
{ return FaceHalfedgeCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwbegin(FaceHandle _fh)
|
||||
{ return FaceHalfedgeCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_begin(FaceHandle _fh)
|
||||
{ return FaceEdgeIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwbegin(FaceHandle _fh)
|
||||
{ return FaceEdgeCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwbegin(FaceHandle _fh)
|
||||
{ return FaceEdgeCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_begin(FaceHandle _fh)
|
||||
{ return FaceFaceIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwbegin(FaceHandle _fh)
|
||||
{ return FaceFaceCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwbegin(FaceHandle _fh)
|
||||
{ return FaceFaceCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_begin(HalfedgeHandle _heh)
|
||||
{ return HalfedgeLoopIter(*this, _heh); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwbegin(HalfedgeHandle _heh)
|
||||
{ return HalfedgeLoopCWIter(*this, _heh); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwbegin(HalfedgeHandle _heh)
|
||||
{ return HalfedgeLoopCCWIter(*this, _heh); }
|
||||
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_begin(FaceHandle _fh) const
|
||||
{ return ConstFaceVertexIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwbegin(FaceHandle _fh) const
|
||||
{ return ConstFaceVertexCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwbegin(FaceHandle _fh) const
|
||||
{ return ConstFaceVertexCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_begin(FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwbegin(FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwbegin(FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_begin(FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwbegin(FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwbegin(FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_begin(FaceHandle _fh) const
|
||||
{ return ConstFaceFaceIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwbegin(FaceHandle _fh) const
|
||||
{ return ConstFaceFaceCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwbegin(FaceHandle _fh) const
|
||||
{ return ConstFaceFaceCCWIter(*this, _fh); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_begin(HalfedgeHandle _heh) const
|
||||
{ return ConstHalfedgeLoopIter(*this, _heh); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwbegin(HalfedgeHandle _heh) const
|
||||
{ return ConstHalfedgeLoopCWIter(*this, _heh); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwbegin(HalfedgeHandle _heh) const
|
||||
{ return ConstHalfedgeLoopCCWIter(*this, _heh); }
|
||||
|
||||
// 'end' circulators
|
||||
|
||||
inline PolyConnectivity::VertexVertexIter PolyConnectivity::vv_end(VertexHandle _vh)
|
||||
{ return VertexVertexIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexVertexCWIter PolyConnectivity::vv_cwend(VertexHandle _vh)
|
||||
{ return VertexVertexCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexVertexCCWIter PolyConnectivity::vv_ccwend(VertexHandle _vh)
|
||||
{ return VertexVertexCCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeIter PolyConnectivity::vih_end(VertexHandle _vh)
|
||||
{ return VertexIHalfedgeIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeCWIter PolyConnectivity::vih_cwend(VertexHandle _vh)
|
||||
{ return VertexIHalfedgeCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexIHalfedgeCCWIter PolyConnectivity::vih_ccwend(VertexHandle _vh)
|
||||
{ return VertexIHalfedgeCCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeIter PolyConnectivity::voh_end(VertexHandle _vh)
|
||||
{ return VertexOHalfedgeIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeCWIter PolyConnectivity::voh_cwend(VertexHandle _vh)
|
||||
{ return VertexOHalfedgeCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexOHalfedgeCCWIter PolyConnectivity::voh_ccwend(VertexHandle _vh)
|
||||
{ return VertexOHalfedgeCCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeIter PolyConnectivity::ve_end(VertexHandle _vh)
|
||||
{ return VertexEdgeIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeCWIter PolyConnectivity::ve_cwend(VertexHandle _vh)
|
||||
{ return VertexEdgeCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexEdgeCCWIter PolyConnectivity::ve_ccwend(VertexHandle _vh)
|
||||
{ return VertexEdgeCCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceIter PolyConnectivity::vf_end(VertexHandle _vh)
|
||||
{ return VertexFaceIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceCWIter PolyConnectivity::vf_cwend(VertexHandle _vh)
|
||||
{ return VertexFaceCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::VertexFaceCCWIter PolyConnectivity::vf_ccwend(VertexHandle _vh)
|
||||
{ return VertexFaceCCWIter(*this, _vh, true); }
|
||||
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexIter PolyConnectivity::cvv_end(VertexHandle _vh) const
|
||||
{ return ConstVertexVertexIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexCWIter PolyConnectivity::cvv_cwend(VertexHandle _vh) const
|
||||
{ return ConstVertexVertexCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexCCWIter PolyConnectivity::cvv_ccwend(VertexHandle _vh) const
|
||||
{ return ConstVertexVertexCCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeIter PolyConnectivity::cvih_end(VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeCWIter PolyConnectivity::cvih_cwend(VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeCCWIter PolyConnectivity::cvih_ccwend(VertexHandle _vh) const
|
||||
{ return ConstVertexIHalfedgeCCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeIter PolyConnectivity::cvoh_end(VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeCWIter PolyConnectivity::cvoh_cwend(VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeCCWIter PolyConnectivity::cvoh_ccwend(VertexHandle _vh) const
|
||||
{ return ConstVertexOHalfedgeCCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeIter PolyConnectivity::cve_end(VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeCWIter PolyConnectivity::cve_cwend(VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeCCWIter PolyConnectivity::cve_ccwend(VertexHandle _vh) const
|
||||
{ return ConstVertexEdgeCCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceIter PolyConnectivity::cvf_end(VertexHandle _vh) const
|
||||
{ return ConstVertexFaceIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceCWIter PolyConnectivity::cvf_cwend(VertexHandle _vh) const
|
||||
{ return ConstVertexFaceCWIter(*this, _vh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceCCWIter PolyConnectivity::cvf_ccwend(VertexHandle _vh) const
|
||||
{ return ConstVertexFaceCCWIter(*this, _vh, true); }
|
||||
|
||||
|
||||
inline PolyConnectivity::FaceVertexIter PolyConnectivity::fv_end(FaceHandle _fh)
|
||||
{ return FaceVertexIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceVertexCWIter PolyConnectivity::fv_cwend(FaceHandle _fh)
|
||||
{ return FaceVertexCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceVertexCCWIter PolyConnectivity::fv_ccwend(FaceHandle _fh)
|
||||
{ return FaceVertexCCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeIter PolyConnectivity::fh_end(FaceHandle _fh)
|
||||
{ return FaceHalfedgeIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeCWIter PolyConnectivity::fh_cwend(FaceHandle _fh)
|
||||
{ return FaceHalfedgeCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceHalfedgeCCWIter PolyConnectivity::fh_ccwend(FaceHandle _fh)
|
||||
{ return FaceHalfedgeCCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeIter PolyConnectivity::fe_end(FaceHandle _fh)
|
||||
{ return FaceEdgeIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeCWIter PolyConnectivity::fe_cwend(FaceHandle _fh)
|
||||
{ return FaceEdgeCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceEdgeCCWIter PolyConnectivity::fe_ccwend(FaceHandle _fh)
|
||||
{ return FaceEdgeCCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceIter PolyConnectivity::ff_end(FaceHandle _fh)
|
||||
{ return FaceFaceIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceCWIter PolyConnectivity::ff_cwend(FaceHandle _fh)
|
||||
{ return FaceFaceCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::FaceFaceCCWIter PolyConnectivity::ff_ccwend(FaceHandle _fh)
|
||||
{ return FaceFaceCCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeLoopIter PolyConnectivity::hl_end(HalfedgeHandle _heh)
|
||||
{ return HalfedgeLoopIter(*this, _heh, true); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeLoopCWIter PolyConnectivity::hl_cwend(HalfedgeHandle _heh)
|
||||
{ return HalfedgeLoopCWIter(*this, _heh, true); }
|
||||
|
||||
inline PolyConnectivity::HalfedgeLoopCCWIter PolyConnectivity::hl_ccwend(HalfedgeHandle _heh)
|
||||
{ return HalfedgeLoopCCWIter(*this, _heh, true); }
|
||||
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexIter PolyConnectivity::cfv_end(FaceHandle _fh) const
|
||||
{ return ConstFaceVertexIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexCWIter PolyConnectivity::cfv_cwend(FaceHandle _fh) const
|
||||
{ return ConstFaceVertexCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexCCWIter PolyConnectivity::cfv_ccwend(FaceHandle _fh) const
|
||||
{ return ConstFaceVertexCCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeIter PolyConnectivity::cfh_end(FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeCWIter PolyConnectivity::cfh_cwend(FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeCCWIter PolyConnectivity::cfh_ccwend(FaceHandle _fh) const
|
||||
{ return ConstFaceHalfedgeCCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeIter PolyConnectivity::cfe_end(FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeCWIter PolyConnectivity::cfe_cwend(FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeCCWIter PolyConnectivity::cfe_ccwend(FaceHandle _fh) const
|
||||
{ return ConstFaceEdgeCCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceIter PolyConnectivity::cff_end(FaceHandle _fh) const
|
||||
{ return ConstFaceFaceIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceCWIter PolyConnectivity::cff_cwend(FaceHandle _fh) const
|
||||
{ return ConstFaceFaceCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceCCWIter PolyConnectivity::cff_ccwend(FaceHandle _fh) const
|
||||
{ return ConstFaceFaceCCWIter(*this, _fh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeLoopIter PolyConnectivity::chl_end(HalfedgeHandle _heh) const
|
||||
{ return ConstHalfedgeLoopIter(*this, _heh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeLoopCWIter PolyConnectivity::chl_cwend(HalfedgeHandle _heh) const
|
||||
{ return ConstHalfedgeLoopCWIter(*this, _heh, true); }
|
||||
|
||||
inline PolyConnectivity::ConstHalfedgeLoopCCWIter PolyConnectivity::chl_ccwend(HalfedgeHandle _heh) const
|
||||
{ return ConstHalfedgeLoopCCWIter(*this, _heh, true); }
|
||||
|
||||
|
||||
inline PolyConnectivity::ConstVertexFaceRange SmartVertexHandle::faces() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->vf_range(*this);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstVertexEdgeRange SmartVertexHandle::edges() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->ve_range(*this);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstVertexVertexRange
|
||||
SmartVertexHandle::vertices() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->vv_range(*this);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstVertexIHalfedgeRange
|
||||
SmartVertexHandle::incoming_halfedges() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->vih_range(*this);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstVertexOHalfedgeRange
|
||||
SmartVertexHandle::outgoing_halfedges() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->voh_range(*this);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstFaceVertexRange SmartFaceHandle::vertices() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->fv_range(*this);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstFaceHalfedgeRange
|
||||
SmartFaceHandle::halfedges() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->fh_range(*this);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstFaceEdgeRange SmartFaceHandle::edges() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->fe_range(*this);
|
||||
}
|
||||
|
||||
inline PolyConnectivity::ConstFaceFaceRange SmartFaceHandle::faces() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->ff_range(*this);
|
||||
}
|
||||
|
||||
}//namespace OpenMesh
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -65,6 +60,7 @@
|
||||
#include <OpenMesh/Core/Geometry/MathDefs.hh>
|
||||
#include <OpenMesh/Core/Mesh/PolyConnectivity.hh>
|
||||
#include <OpenMesh/Core/Mesh/FinalMeshItemsT.hh>
|
||||
#include <OpenMesh/Core/Mesh/Tags.hh>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -100,11 +96,12 @@ public:
|
||||
//--- item types ---
|
||||
|
||||
//@{
|
||||
/// Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT )
|
||||
/// Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT)
|
||||
static constexpr bool is_polymesh() { return true; }
|
||||
static constexpr bool is_trimesh() { return false; }
|
||||
using ConnectivityTag = PolyConnectivityTag;
|
||||
enum { IsPolyMesh = 1 };
|
||||
enum { IsTriMesh = 0 };
|
||||
static bool is_polymesh() { return true; }
|
||||
static bool is_trimesh() { return false; }
|
||||
//@}
|
||||
|
||||
/// \name Mesh Items
|
||||
@@ -201,19 +198,19 @@ public:
|
||||
*
|
||||
* \sa new_vertex(const Point&), new_vertex_dirty()
|
||||
*/
|
||||
inline VertexHandle new_vertex()
|
||||
{ return Kernel::new_vertex(); }
|
||||
inline SmartVertexHandle new_vertex()
|
||||
{ return make_smart(Kernel::new_vertex(), this); }
|
||||
|
||||
/**
|
||||
* \brief Adds a new vertex initialized to a custom position.
|
||||
*
|
||||
* \sa new_vertex(), new_vertex_dirty()
|
||||
*/
|
||||
inline VertexHandle new_vertex(const Point& _p)
|
||||
inline SmartVertexHandle new_vertex(const Point& _p)
|
||||
{
|
||||
VertexHandle vh(Kernel::new_vertex());
|
||||
this->set_point(vh, _p);
|
||||
return vh;
|
||||
return make_smart(vh, this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -227,20 +224,20 @@ public:
|
||||
*
|
||||
* \sa new_vertex(const Point &)
|
||||
*/
|
||||
inline VertexHandle new_vertex_dirty(const Point& _p)
|
||||
inline SmartVertexHandle new_vertex_dirty(const Point& _p)
|
||||
{
|
||||
VertexHandle vh(Kernel::new_vertex_dirty());
|
||||
this->set_point(vh, _p);
|
||||
return vh;
|
||||
return make_smart(vh, this);
|
||||
}
|
||||
|
||||
/// Alias for new_vertex(const Point&).
|
||||
inline VertexHandle add_vertex(const Point& _p)
|
||||
inline SmartVertexHandle add_vertex(const Point& _p)
|
||||
{ return new_vertex(_p); }
|
||||
|
||||
/// Alias for new_vertex_dirty().
|
||||
inline VertexHandle add_vertex_dirty(const Point& _p)
|
||||
{ return new_vertex_dirty(_p); }
|
||||
inline SmartVertexHandle add_vertex_dirty(const Point& _p)
|
||||
{ return make_smart(new_vertex_dirty(_p), this); }
|
||||
|
||||
// --- normal vectors ---
|
||||
|
||||
@@ -274,14 +271,33 @@ public:
|
||||
/** Calculate normal vector for face (_p0, _p1, _p2). */
|
||||
Normal calc_face_normal(const Point& _p0, const Point& _p1,
|
||||
const Point& _p2) const;
|
||||
|
||||
/// same as calc_face_normal
|
||||
Normal calc_normal(FaceHandle _fh) const;
|
||||
|
||||
/// calculates the average of the vertices defining _fh
|
||||
void calc_face_centroid(FaceHandle _fh, Point& _pt) const {
|
||||
_pt = calc_face_centroid(_fh);
|
||||
}
|
||||
|
||||
/// Computes and returns the average of the vertices defining _gh
|
||||
/// Computes and returns the average of the vertices defining _fh
|
||||
Point calc_face_centroid(FaceHandle _fh) const;
|
||||
|
||||
/// Computes and returns the average of the vertices defining _fh (same as calc_face_centroid)
|
||||
Point calc_centroid(FaceHandle _fh) const;
|
||||
|
||||
/// Computes and returns the average of the vertices defining _eh (same as calc_edge_midpoint)
|
||||
Point calc_centroid(EdgeHandle _eh) const;
|
||||
|
||||
/// Computes and returns the average of the vertices defining _heh (same as calc_edge_midpoint for edge of halfedge)
|
||||
Point calc_centroid(HalfedgeHandle _heh) const;
|
||||
|
||||
/// Returns the point of _vh
|
||||
Point calc_centroid(VertexHandle _vh) const;
|
||||
|
||||
/// Computes and returns the average of the vertices defining the mesh
|
||||
Point calc_centroid(MeshHandle _mh) const;
|
||||
|
||||
/// Update normal for halfedge _heh
|
||||
void update_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8)
|
||||
{ this->set_normal(_heh, calc_halfedge_normal(_heh,_feature_angle)); }
|
||||
@@ -311,6 +327,8 @@ public:
|
||||
*/
|
||||
virtual Normal calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle = 0.8) const;
|
||||
|
||||
/// same as calc_halfedge_normal
|
||||
Normal calc_normal(HalfedgeHandle, const double _feature_angle = 0.8) const;
|
||||
|
||||
/** identifies feature edges w.r.t. the minimal dihedral angle for feature edges (in radians) */
|
||||
/** and the status feature tag */
|
||||
@@ -356,6 +374,8 @@ public:
|
||||
void calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const;
|
||||
void calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const;
|
||||
|
||||
/// same as calc_vertex_normal_correct
|
||||
Normal calc_normal(VertexHandle _vh) const;
|
||||
|
||||
//@}
|
||||
|
||||
@@ -406,7 +426,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
|
||||
@@ -425,6 +445,15 @@ public:
|
||||
return calc_edge_midpoint(this->halfedge_handle(_eh, 0));
|
||||
}
|
||||
|
||||
/// calculated and returns the average of the two vertex normals
|
||||
Normal calc_normal(EdgeHandle _eh) const
|
||||
{
|
||||
HalfedgeHandle _heh = this->halfedge_handle(_eh, 0);
|
||||
VertexHandle vh0 = this->from_vertex_handle(_heh);
|
||||
VertexHandle vh1 = this->to_vertex_handle(_heh);
|
||||
return 0.5 * (this->calc_normal(vh0) + this->calc_normal(vh1));
|
||||
}
|
||||
|
||||
/** defines a consistent representation of a sector geometry:
|
||||
the halfedge _in_heh defines the sector orientation
|
||||
the vertex pointed by _in_heh defines the sector center
|
||||
@@ -444,7 +473,7 @@ public:
|
||||
{
|
||||
Normal v0, v1;
|
||||
calc_sector_vectors(_in_heh, v0, v1);
|
||||
Scalar denom = v0.norm()*v1.norm();
|
||||
Scalar denom = norm(v0)*norm(v1);
|
||||
if ( denom == Scalar(0))
|
||||
{
|
||||
return 0;
|
||||
@@ -470,7 +499,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;
|
||||
@@ -479,7 +508,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;
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -499,7 +528,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
|
||||
@@ -539,7 +568,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;
|
||||
@@ -631,7 +660,7 @@ const LHS mesh_cast(const PolyMeshT<KERNEL> *rhs) {
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_POLYMESH_C)
|
||||
# define OPENMESH_POLYMESH_TEMPLATES
|
||||
# include "PolyMeshT.cc"
|
||||
# include "PolyMeshT_impl.hh"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_POLYMESHT_HH defined
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -139,18 +134,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);
|
||||
}
|
||||
|
||||
@@ -159,7 +154,15 @@ typename PolyMeshT<Kernel>::Normal
|
||||
PolyMeshT<Kernel>::calc_face_normal_impl(FaceHandle, PointIsNot3DTag) const
|
||||
{
|
||||
// Dummy fallback implementation
|
||||
return Normal(typename Normal::value_type(0));
|
||||
// Returns just an initialized all 0 normal
|
||||
// This function is only used if we don't have a matching implementation
|
||||
// for normal computation with the current vector type defined in the mesh traits
|
||||
|
||||
assert(false);
|
||||
|
||||
Normal normal;
|
||||
vectorize(normal,Scalar(0));
|
||||
return normal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -178,6 +181,14 @@ calc_face_normal(const Point& _p0,
|
||||
>::Result());
|
||||
}
|
||||
|
||||
template<class Kernel>
|
||||
typename PolyMeshT<Kernel>::Normal
|
||||
PolyMeshT<Kernel>::
|
||||
calc_normal(FaceHandle _fh) const
|
||||
{
|
||||
return calc_face_normal(_fh);
|
||||
}
|
||||
|
||||
template <class Kernel>
|
||||
typename PolyMeshT<Kernel>::Normal
|
||||
PolyMeshT<Kernel>::
|
||||
@@ -194,20 +205,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
|
||||
}
|
||||
|
||||
@@ -215,7 +228,17 @@ template <class Kernel>
|
||||
typename PolyMeshT<Kernel>::Normal
|
||||
PolyMeshT<Kernel>::calc_face_normal_impl(const Point&, const Point&, const Point&, PointIsNot3DTag) const
|
||||
{
|
||||
return Normal(typename Normal::value_type(0));
|
||||
|
||||
// Dummy fallback implementation
|
||||
// Returns just an initialized all 0 normal
|
||||
// This function is only used if we don't have a matching implementation
|
||||
// for normal computation with the current vector type defined in the mesh traits
|
||||
|
||||
assert(false);
|
||||
|
||||
Normal normal;
|
||||
vectorize(normal,Scalar(0));
|
||||
return normal;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -226,7 +249,7 @@ PolyMeshT<Kernel>::
|
||||
calc_face_centroid(FaceHandle _fh) const
|
||||
{
|
||||
Point _pt;
|
||||
_pt.vectorize(0);
|
||||
vectorize(_pt, Scalar(0));
|
||||
Scalar valence = 0.0;
|
||||
for (ConstFaceVertexIter cfv_it = this->cfv_iter(_fh); cfv_it.is_valid(); ++cfv_it, valence += 1.0)
|
||||
{
|
||||
@@ -235,8 +258,58 @@ calc_face_centroid(FaceHandle _fh) const
|
||||
_pt /= valence;
|
||||
return _pt;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Kernel>
|
||||
typename PolyMeshT<Kernel>::Point
|
||||
PolyMeshT<Kernel>::
|
||||
calc_centroid(FaceHandle _fh) const
|
||||
{
|
||||
return calc_face_centroid(_fh);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Kernel>
|
||||
typename PolyMeshT<Kernel>::Point
|
||||
PolyMeshT<Kernel>::
|
||||
calc_centroid(EdgeHandle _eh) const
|
||||
{
|
||||
return this->calc_edge_midpoint(_eh);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Kernel>
|
||||
typename PolyMeshT<Kernel>::Point
|
||||
PolyMeshT<Kernel>::
|
||||
calc_centroid(HalfedgeHandle _heh) const
|
||||
{
|
||||
return this->calc_edge_midpoint(this->edge_handle(_heh));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Kernel>
|
||||
typename PolyMeshT<Kernel>::Point
|
||||
PolyMeshT<Kernel>::
|
||||
calc_centroid(VertexHandle _vh) const
|
||||
{
|
||||
return this->point(_vh);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Kernel>
|
||||
typename PolyMeshT<Kernel>::Point
|
||||
PolyMeshT<Kernel>::
|
||||
calc_centroid(MeshHandle /*_mh*/) const
|
||||
{
|
||||
return this->vertices().avg(getPointsProperty(*this));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class Kernel>
|
||||
void
|
||||
@@ -331,7 +404,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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -339,6 +412,18 @@ calc_halfedge_normal(HalfedgeHandle _heh, const double _feature_angle) const
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Kernel>
|
||||
typename PolyMeshT<Kernel>::Normal
|
||||
PolyMeshT<Kernel>::
|
||||
calc_normal(HalfedgeHandle _heh, const double _feature_angle) const
|
||||
{
|
||||
return calc_halfedge_normal(_heh, _feature_angle);
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
template <class Kernel>
|
||||
bool
|
||||
PolyMeshT<Kernel>::
|
||||
@@ -378,8 +463,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 +474,7 @@ template <class Kernel>
|
||||
void PolyMeshT<Kernel>::
|
||||
calc_vertex_normal_fast(VertexHandle _vh, Normal& _n) const
|
||||
{
|
||||
_n.vectorize(0.0);
|
||||
vectorize(_n, Scalar(0));
|
||||
for (ConstVertexFaceIter vf_it = this->cvf_iter(_vh); vf_it.is_valid(); ++vf_it)
|
||||
_n += this->normal(*vf_it);
|
||||
}
|
||||
@@ -399,7 +484,7 @@ template <class Kernel>
|
||||
void PolyMeshT<Kernel>::
|
||||
calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const
|
||||
{
|
||||
_n.vectorize(0.0);
|
||||
vectorize(_n, Scalar(0));
|
||||
ConstVertexIHalfedgeIter cvih_it = this->cvih_iter(_vh);
|
||||
if (! cvih_it.is_valid() )
|
||||
{//don't crash on isolated vertices
|
||||
@@ -420,6 +505,9 @@ calc_vertex_normal_correct(VertexHandle _vh, Normal& _n) const
|
||||
in_he_vec = out_he_vec;
|
||||
in_he_vec *= -1;//change the orientation
|
||||
}
|
||||
Scalar length = norm(_n);
|
||||
if (length != 0.0)
|
||||
_n *= (Scalar(1.0)/length);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -444,6 +532,17 @@ calc_vertex_normal_loop(VertexHandle _vh, Normal& _n) const
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template<class Kernel>
|
||||
typename PolyMeshT<Kernel>::Normal
|
||||
PolyMeshT<Kernel>::
|
||||
calc_normal(VertexHandle _vh) const
|
||||
{
|
||||
Normal n;
|
||||
calc_vertex_normal_correct(_vh, n);
|
||||
return n;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
template <class Kernel>
|
||||
void
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -102,7 +97,7 @@ class PolyMesh_ArrayKernelT
|
||||
public:
|
||||
PolyMesh_ArrayKernelT() {}
|
||||
template<class OtherTraits>
|
||||
PolyMesh_ArrayKernelT( const TriMesh_ArrayKernelT<OtherTraits> & t)
|
||||
explicit PolyMesh_ArrayKernelT( const TriMesh_ArrayKernelT<OtherTraits> & t)
|
||||
{
|
||||
//assign the connectivity and standard properties
|
||||
this->assign(t, true);
|
||||
|
||||
357
src/OpenMesh/Core/Mesh/SmartHandles.hh
Normal file
357
src/OpenMesh/Core/Mesh/SmartHandles.hh
Normal file
@@ -0,0 +1,357 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2019, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. Redistributions in binary form must reproduce the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer in the *
|
||||
* documentation and/or other materials provided with the distribution. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder nor the names of its *
|
||||
* contributors may be used to endorse or promote products derived from *
|
||||
* this software without specific prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
#ifndef OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE
|
||||
#error Do not include this directly, include instead PolyConnectivity.hh
|
||||
#endif//OPENMESH_POLYCONNECTIVITY_INTERFACE_INCLUDE
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
//== FORWARD DECLARATION ======================================================
|
||||
|
||||
struct SmartVertexHandle;
|
||||
struct SmartHalfedgeHandle;
|
||||
struct SmartEdgeHandle;
|
||||
struct SmartFaceHandle;
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
/// Base class for all smart handle types
|
||||
class OPENMESHDLLEXPORT SmartBaseHandle
|
||||
{
|
||||
public:
|
||||
explicit SmartBaseHandle(const PolyConnectivity* _mesh = nullptr) : mesh_(_mesh) {}
|
||||
|
||||
/// Get the underlying mesh of this handle
|
||||
const PolyConnectivity* mesh() const { return mesh_; }
|
||||
|
||||
// TODO: should operators ==, !=, < look at mesh_?
|
||||
|
||||
private:
|
||||
const PolyConnectivity* mesh_;
|
||||
|
||||
};
|
||||
|
||||
/// Smart version of VertexHandle contains a pointer to the corresponding mesh and allows easier access to navigation methods
|
||||
struct OPENMESHDLLEXPORT SmartVertexHandle : public SmartBaseHandle, VertexHandle
|
||||
{
|
||||
explicit SmartVertexHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), VertexHandle(_idx) {}
|
||||
|
||||
/// Returns an outgoing halfedge
|
||||
SmartHalfedgeHandle out() const;
|
||||
/// Returns an outgoing halfedge
|
||||
SmartHalfedgeHandle halfedge() const; // alias for out
|
||||
/// Returns an incoming halfedge
|
||||
SmartHalfedgeHandle in() const;
|
||||
|
||||
/// Returns a range of faces incident to the vertex (PolyConnectivity::vf_range())
|
||||
PolyConnectivity::ConstVertexFaceRange faces() const;
|
||||
/// Returns a range of edges incident to the vertex (PolyConnectivity::ve_range())
|
||||
PolyConnectivity::ConstVertexEdgeRange edges() const;
|
||||
/// Returns a range of vertices adjacent to the vertex (PolyConnectivity::vv_range())
|
||||
PolyConnectivity::ConstVertexVertexRange vertices() const;
|
||||
/// Returns a range of outgoing halfedges incident to the vertex (PolyConnectivity::voh_range())
|
||||
PolyConnectivity::ConstVertexIHalfedgeRange incoming_halfedges() const;
|
||||
/// Returns a range of incoming halfedges incident to the vertex (PolyConnectivity::vih_range())
|
||||
PolyConnectivity::ConstVertexOHalfedgeRange outgoing_halfedges() const;
|
||||
|
||||
/// Returns valence of the vertex
|
||||
uint valence() const;
|
||||
/// Returns true iff the vertex is incident to a boundary halfedge
|
||||
bool is_boundary() const;
|
||||
/// Returns true iff (the mesh at) the vertex is two-manifold ?
|
||||
bool is_manifold() const;
|
||||
};
|
||||
|
||||
struct OPENMESHDLLEXPORT SmartHalfedgeHandle : public SmartBaseHandle, HalfedgeHandle
|
||||
{
|
||||
explicit SmartHalfedgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), HalfedgeHandle(_idx) {}
|
||||
|
||||
/// Returns next halfedge handle
|
||||
SmartHalfedgeHandle next() const;
|
||||
/// Returns previous halfedge handle
|
||||
SmartHalfedgeHandle prev() const;
|
||||
/// Returns opposite halfedge handle
|
||||
SmartHalfedgeHandle opp() const;
|
||||
/// Returns vertex pointed to by halfedge
|
||||
SmartVertexHandle to() const;
|
||||
/// Returns vertex at start of halfedge
|
||||
SmartVertexHandle from() const;
|
||||
/// Returns incident edge of halfedge
|
||||
SmartEdgeHandle edge() const;
|
||||
/// Returns incident face of halfedge
|
||||
SmartFaceHandle face() const;
|
||||
|
||||
/// Returns true iff the halfedge is on the boundary (i.e. it has no corresponding face)
|
||||
bool is_boundary() const;
|
||||
};
|
||||
|
||||
struct OPENMESHDLLEXPORT SmartEdgeHandle : public SmartBaseHandle, EdgeHandle
|
||||
{
|
||||
explicit SmartEdgeHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), EdgeHandle(_idx) {}
|
||||
|
||||
/// Returns one of the two halfedges of the edge
|
||||
SmartHalfedgeHandle halfedge(unsigned int _i) const;
|
||||
/// Shorthand for halfedge()
|
||||
SmartHalfedgeHandle h(unsigned int _i) const;
|
||||
/// Shorthand for halfedge(0)
|
||||
SmartHalfedgeHandle h0() const;
|
||||
/// Shorthand for halfedge(1)
|
||||
SmartHalfedgeHandle h1() const;
|
||||
/// Returns one of the two incident vertices of the edge
|
||||
SmartVertexHandle vertex(unsigned int _i) const;
|
||||
/// Shorthand for vertex()
|
||||
SmartVertexHandle v(unsigned int _i) const;
|
||||
/// Shorthand for vertex(0)
|
||||
SmartVertexHandle v0() const;
|
||||
/// Shorthand for vertex(1)
|
||||
SmartVertexHandle v1() const;
|
||||
|
||||
/// Returns true iff the edge lies on the boundary (i.e. one of the halfedges is boundary)
|
||||
bool is_boundary() const;
|
||||
};
|
||||
|
||||
struct OPENMESHDLLEXPORT SmartFaceHandle : public SmartBaseHandle, FaceHandle
|
||||
{
|
||||
explicit SmartFaceHandle(int _idx=-1, const PolyConnectivity* _mesh = nullptr) : SmartBaseHandle(_mesh), FaceHandle(_idx) {}
|
||||
|
||||
/// Returns one of the halfedges of the face
|
||||
SmartHalfedgeHandle halfedge() const;
|
||||
|
||||
/// Returns a range of vertices incident to the face (PolyConnectivity::fv_range())
|
||||
PolyConnectivity::ConstFaceVertexRange vertices() const;
|
||||
/// Returns a range of halfedges of the face (PolyConnectivity::fh_range())
|
||||
PolyConnectivity::ConstFaceHalfedgeRange halfedges() const;
|
||||
/// Returns a range of edges of the face (PolyConnectivity::fv_range())
|
||||
PolyConnectivity::ConstFaceEdgeRange edges() const;
|
||||
/// Returns a range adjacent faces of the face (PolyConnectivity::ff_range())
|
||||
PolyConnectivity::ConstFaceFaceRange faces() const;
|
||||
|
||||
/// Returns the valence of the face
|
||||
uint valence() const;
|
||||
/// Returns true iff the face lies at the boundary (i.e. one of the edges is boundary)
|
||||
bool is_boundary() const;
|
||||
};
|
||||
|
||||
|
||||
/// Creats a SmartVertexHandle from a VertexHandle and a Mesh
|
||||
inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity* _mesh) { return SmartVertexHandle (_vh.idx(), _mesh); }
|
||||
/// Creats a SmartHalfedgeHandle from a HalfedgeHandle and a Mesh
|
||||
inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity* _mesh) { return SmartHalfedgeHandle(_hh.idx(), _mesh); }
|
||||
/// Creats a SmartEdgeHandle from an EdgeHandle and a Mesh
|
||||
inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity* _mesh) { return SmartEdgeHandle (_eh.idx(), _mesh); }
|
||||
/// Creats a SmartFaceHandle from a FaceHandle and a Mesh
|
||||
inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity* _mesh) { return SmartFaceHandle (_fh.idx(), _mesh); }
|
||||
|
||||
/// Creats a SmartVertexHandle from a VertexHandle and a Mesh
|
||||
inline SmartVertexHandle make_smart(VertexHandle _vh, const PolyConnectivity& _mesh) { return SmartVertexHandle (_vh.idx(), &_mesh); }
|
||||
/// Creats a SmartHalfedgeHandle from a HalfedgeHandle and a Mesh
|
||||
inline SmartHalfedgeHandle make_smart(HalfedgeHandle _hh, const PolyConnectivity& _mesh) { return SmartHalfedgeHandle(_hh.idx(), &_mesh); }
|
||||
/// Creats a SmartEdgeHandle from an EdgeHandle and a Mesh
|
||||
inline SmartEdgeHandle make_smart(EdgeHandle _eh, const PolyConnectivity& _mesh) { return SmartEdgeHandle (_eh.idx(), &_mesh); }
|
||||
/// Creats a SmartFaceHandle from a FaceHandle and a Mesh
|
||||
inline SmartFaceHandle make_smart(FaceHandle _fh, const PolyConnectivity& _mesh) { return SmartFaceHandle (_fh.idx(), &_mesh); }
|
||||
|
||||
|
||||
// helper to convert Handle Types to Smarthandle Types
|
||||
template <typename HandleT>
|
||||
struct SmartHandle;
|
||||
|
||||
template <> struct SmartHandle<VertexHandle> { using type = SmartVertexHandle; };
|
||||
template <> struct SmartHandle<HalfedgeHandle> { using type = SmartHalfedgeHandle; };
|
||||
template <> struct SmartHandle<EdgeHandle> { using type = SmartEdgeHandle; };
|
||||
template <> struct SmartHandle<FaceHandle> { using type = SmartFaceHandle; };
|
||||
|
||||
|
||||
inline SmartHalfedgeHandle SmartVertexHandle::out() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->halfedge_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartVertexHandle::halfedge() const
|
||||
{
|
||||
return out();
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartVertexHandle::in() const
|
||||
{
|
||||
return out().opp();
|
||||
}
|
||||
|
||||
inline uint SmartVertexHandle::valence() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->valence(*this);
|
||||
}
|
||||
|
||||
inline bool SmartVertexHandle::is_boundary() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->is_boundary(*this);
|
||||
}
|
||||
|
||||
inline bool SmartVertexHandle::is_manifold() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->is_manifold(*this);
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartHalfedgeHandle::next() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->next_halfedge_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartHalfedgeHandle::prev() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->prev_halfedge_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartHalfedgeHandle::opp() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->opposite_halfedge_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline SmartVertexHandle SmartHalfedgeHandle::to() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->to_vertex_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline SmartVertexHandle SmartHalfedgeHandle::from() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->from_vertex_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline SmartEdgeHandle SmartHalfedgeHandle::edge() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->edge_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline SmartFaceHandle SmartHalfedgeHandle::face() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->face_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline bool SmartHalfedgeHandle::is_boundary() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->is_boundary(*this);
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartEdgeHandle::halfedge(unsigned int _i) const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->halfedge_handle(*this, _i), mesh());
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartEdgeHandle::h(unsigned int _i) const
|
||||
{
|
||||
return halfedge(_i);
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartEdgeHandle::h0() const
|
||||
{
|
||||
return h(0);
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartEdgeHandle::h1() const
|
||||
{
|
||||
return h(1);
|
||||
}
|
||||
|
||||
inline SmartVertexHandle SmartEdgeHandle::vertex(unsigned int _i) const
|
||||
{
|
||||
return halfedge(_i).from();
|
||||
}
|
||||
|
||||
inline SmartVertexHandle SmartEdgeHandle::v(unsigned int _i) const
|
||||
{
|
||||
return vertex(_i);
|
||||
}
|
||||
|
||||
inline SmartVertexHandle SmartEdgeHandle::v0() const
|
||||
{
|
||||
return v(0);
|
||||
}
|
||||
|
||||
inline SmartVertexHandle SmartEdgeHandle::v1() const
|
||||
{
|
||||
return v(1);
|
||||
}
|
||||
|
||||
inline bool SmartEdgeHandle::is_boundary() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->is_boundary(*this);
|
||||
}
|
||||
|
||||
inline SmartHalfedgeHandle SmartFaceHandle::halfedge() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return make_smart(mesh()->halfedge_handle(*this), mesh());
|
||||
}
|
||||
|
||||
inline uint SmartFaceHandle::valence() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->valence(*this);
|
||||
}
|
||||
|
||||
inline bool SmartFaceHandle::is_boundary() const
|
||||
{
|
||||
assert(mesh() != nullptr);
|
||||
return mesh()->is_boundary(*this);
|
||||
}
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
475
src/OpenMesh/Core/Mesh/SmartRange.hh
Normal file
475
src/OpenMesh/Core/Mesh/SmartRange.hh
Normal file
@@ -0,0 +1,475 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2019, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. Redistributions in binary form must reproduce the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer in the *
|
||||
* documentation and/or other materials provided with the distribution. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder nor the names of its *
|
||||
* contributors may be used to endorse or promote products derived from *
|
||||
* this software without specific prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <utility>
|
||||
#include <array>
|
||||
#include <vector>
|
||||
#include <set>
|
||||
|
||||
//== NAMESPACES ===============================================================
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
//== FORWARD DECLARATION ======================================================
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
namespace {
|
||||
|
||||
struct Identity
|
||||
{
|
||||
template <typename T>
|
||||
T operator()(const T& _t) const { return _t; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <typename RangeT, typename HandleT, typename Functor>
|
||||
struct FilteredSmartRangeT;
|
||||
|
||||
/// Base class for all smart range types
|
||||
template <typename RangeT, typename HandleT>
|
||||
struct SmartRangeT
|
||||
{
|
||||
using Handle = HandleT;
|
||||
using SmartRange = SmartRangeT<RangeT, HandleT>;
|
||||
using Range = RangeT;
|
||||
|
||||
// TODO: Someone with better c++ knowledge may improve the code below.
|
||||
|
||||
/** @brief Computes the sum of elements.
|
||||
*
|
||||
* Computes the sum of all elements in the range after applying the functor \p f.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before computing the sum
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto sum(Functor&& f) -> typename std::decay<decltype (f(std::declval<HandleT>()))>::type
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
auto begin = range->begin();
|
||||
auto end = range->end();
|
||||
assert(begin != end);
|
||||
typename std::decay<decltype (f(*begin))>::type result = f(*begin);
|
||||
auto it = begin;
|
||||
++it;
|
||||
for (; it != end; ++it)
|
||||
result += f(*it);
|
||||
return result;
|
||||
}
|
||||
|
||||
/** @brief Computes the average of elements.
|
||||
*
|
||||
* Computes the average of all elements in the range after applying the functor \p f.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before computing the average.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto avg(Functor&& f) -> typename std::decay<decltype (f(std::declval<HandleT>()))>::type
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
auto begin = range->begin();
|
||||
auto end = range->end();
|
||||
assert(begin != end);
|
||||
typename std::decay<decltype (f(*begin))>::type result = f(*begin);
|
||||
auto it = begin;
|
||||
++it;
|
||||
int n_elements = 1;
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
result += f(*it);
|
||||
++n_elements;
|
||||
}
|
||||
return (1.0 / n_elements) * result;
|
||||
}
|
||||
|
||||
/** @brief Check if any element fulfils condition.
|
||||
*
|
||||
* Checks if functor \p f returns true for any of the elements in the range.
|
||||
* Returns true if that is the case, false otherwise.
|
||||
*
|
||||
* @param f Functor that is evaluated for all elements.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto any_of(Functor&& f) -> bool
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
for (auto e : *range)
|
||||
if (f(e))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @brief Check if all elements fulfil condition.
|
||||
*
|
||||
* Checks if functor \p f returns true for all of the elements in the range.
|
||||
* Returns true if that is the case, false otherwise.
|
||||
*
|
||||
* @param f Functor that is evaluated for all elements.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto all_of(Functor&& f) -> bool
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
for (auto e : *range)
|
||||
if (!f(e))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @brief Convert range to array.
|
||||
*
|
||||
* Converts the range of elements into an array of objects returned by functor \p f.
|
||||
* The size of the array needs to be provided by the user. If the size is larger than the number of
|
||||
* elements in the range, the remaining entries of the array will be uninitialized.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before putting them into the array. If no functor is provided
|
||||
* the array will contain the handles.
|
||||
*/
|
||||
template <int n, typename Functor = Identity>
|
||||
auto to_array(Functor&& f = {}) -> std::array<typename std::decay<decltype (f(std::declval<HandleT>()))>::type, n>
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
std::array<typename std::decay<decltype (f(std::declval<HandleT>()))>::type, n> res;
|
||||
auto it = range->begin();
|
||||
auto end = range->end();
|
||||
int i = 0;
|
||||
while (i < n && it != end)
|
||||
res[i++] = f(*(it++));
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Convert range to vector.
|
||||
*
|
||||
* Converts the range of elements into a vector of objects returned by functor \p f.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before putting them into the vector. If no functor is provided
|
||||
* the vector will contain the handles.
|
||||
*/
|
||||
template <typename Functor = Identity>
|
||||
auto to_vector(Functor&& f = {}) -> std::vector<typename std::decay<decltype (f(std::declval<HandleT>()))>::type>
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
std::vector<typename std::decay<decltype (f(std::declval<HandleT>()))>::type> res;
|
||||
for (const auto& e : *range)
|
||||
res.push_back(f(e));
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Convert range to set.
|
||||
*
|
||||
* Converts the range of elements into a set of objects returned by functor \p f.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before putting them into the set. If no functor is provided
|
||||
* the set will contain the handles.
|
||||
*/
|
||||
template <typename Functor = Identity>
|
||||
auto to_set(Functor&& f = {}) -> std::set<typename std::decay<decltype (f(std::declval<HandleT>()))>::type>
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
std::set<typename std::decay<decltype (f(std::declval<HandleT>()))>::type> res;
|
||||
for (const auto& e : *range)
|
||||
res.insert(f(e));
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Get the first element that fulfills a condition.
|
||||
*
|
||||
* Finds the first element of the range for which the functor \p f evaluates to true.
|
||||
* Returns an invalid handle if none evaluates to true
|
||||
*
|
||||
* @param f Functor that is applied to all elements before putting them into the set. If no functor is provided
|
||||
* the set will contain the handles.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto first(Functor&& f = {}) -> HandleT
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
for (const auto& e : *range)
|
||||
if (f(e))
|
||||
return e;
|
||||
return HandleT();
|
||||
}
|
||||
|
||||
/** @brief Compute minimum.
|
||||
*
|
||||
* Computes the minimum of all objects returned by functor \p f.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before computing minimum.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto min(Functor&& f) -> typename std::decay<decltype (f(std::declval<HandleT>()))>::type
|
||||
{
|
||||
using std::min;
|
||||
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
auto it = range->begin();
|
||||
auto end = range->end();
|
||||
assert(it != end);
|
||||
|
||||
typename std::decay<decltype (f(std::declval<HandleT>()))>::type res = f(*it);
|
||||
++it;
|
||||
|
||||
for (; it != end; ++it)
|
||||
res = min(res, f(*it));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/** @brief Compute minimal element.
|
||||
*
|
||||
* Computes the element that minimizes \p f.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before comparing.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto argmin(Functor&& f) -> HandleT
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
auto it = range->begin();
|
||||
auto min_it = it;
|
||||
auto end = range->end();
|
||||
assert(it != end);
|
||||
|
||||
typename std::decay<decltype (f(std::declval<HandleT>()))>::type curr_min = f(*it);
|
||||
++it;
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
auto val = f(*it);
|
||||
if (val < curr_min)
|
||||
{
|
||||
curr_min = val;
|
||||
min_it = it;
|
||||
}
|
||||
}
|
||||
|
||||
return *min_it;
|
||||
}
|
||||
|
||||
/** @brief Compute maximum.
|
||||
*
|
||||
* Computes the maximum of all objects returned by functor \p f.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before computing maximum.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto max(Functor&& f) -> typename std::decay<decltype (f(std::declval<HandleT>()))>::type
|
||||
{
|
||||
using std::max;
|
||||
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
auto it = range->begin();
|
||||
auto end = range->end();
|
||||
assert(it != end);
|
||||
|
||||
typename std::decay<decltype (f(std::declval<HandleT>()))>::type res = f(*it);
|
||||
++it;
|
||||
|
||||
for (; it != end; ++it)
|
||||
res = max(res, f(*it));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Compute maximal element.
|
||||
*
|
||||
* Computes the element that maximizes \p f.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before comparing.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto argmax(Functor&& f) -> HandleT
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
auto it = range->begin();
|
||||
auto max_it = it;
|
||||
auto end = range->end();
|
||||
assert(it != end);
|
||||
|
||||
typename std::decay<decltype (f(std::declval<HandleT>()))>::type curr_max = f(*it);
|
||||
++it;
|
||||
|
||||
for (; it != end; ++it)
|
||||
{
|
||||
auto val = f(*it);
|
||||
if (val > curr_max)
|
||||
{
|
||||
curr_max = val;
|
||||
max_it = it;
|
||||
}
|
||||
}
|
||||
|
||||
return *max_it;
|
||||
}
|
||||
|
||||
/** @brief Computes minimum and maximum.
|
||||
*
|
||||
* Computes the minimum and maximum of all objects returned by functor \p f. Result is returned as std::pair
|
||||
* containing minimum as first and maximum as second element.
|
||||
*
|
||||
* @param f Functor that is applied to all elements before computing maximum.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto minmax(Functor&& f) -> std::pair<typename std::decay<decltype (f(std::declval<HandleT>()))>::type,
|
||||
typename std::decay<decltype (f(std::declval<HandleT>()))>::type>
|
||||
{
|
||||
return std::make_pair(this->min(f), this->max(f));
|
||||
}
|
||||
|
||||
|
||||
/** @brief Compute number of elements that satisfy a given predicate.
|
||||
*
|
||||
* Computes the numer of elements which satisfy functor \p f.
|
||||
*
|
||||
* @param f Predicate that elements have to satisfy in order to be counted.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto count_if(Functor&& f) -> int
|
||||
{
|
||||
int count = 0;
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
for (const auto& e : *range)
|
||||
if (f(e))
|
||||
++count;
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
/** @brief Apply a functor to each element.
|
||||
*
|
||||
* Calls functor \p f with each element as parameter
|
||||
*
|
||||
* @param f Functor that is called for each element.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto for_each(Functor&& f) -> void
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
for (const auto& e : *range)
|
||||
f(e);
|
||||
}
|
||||
|
||||
|
||||
/** @brief Only iterate over a subset of elements
|
||||
*
|
||||
* Returns a smart range which skips all elements that do not satisfy functor \p f
|
||||
*
|
||||
* @param f Functor that needs to be evaluated to true if the element should not be skipped.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto filtered(Functor&& f) -> FilteredSmartRangeT<SmartRange, Handle, typename std::decay<Functor>::type>
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
auto b = (*range).begin();
|
||||
auto e = (*range).end();
|
||||
return FilteredSmartRangeT<SmartRange, Handle, typename std::decay<Functor>::type>(f, b, e);
|
||||
}
|
||||
|
||||
/** @brief Only iterate over a subset of elements
|
||||
*
|
||||
* Returns a smart range which skips all elements that do not satisfy functor \p f
|
||||
*
|
||||
* @param f Functor that needs to be evaluated to true if the element should not be skipped.
|
||||
*/
|
||||
template <typename Functor>
|
||||
auto filtered(Functor& f) -> FilteredSmartRangeT<SmartRange, Handle, const typename std::decay<Functor>::type&>
|
||||
{
|
||||
auto range = static_cast<const RangeT*>(this);
|
||||
auto b = (*range).begin();
|
||||
auto e = (*range).end();
|
||||
return FilteredSmartRangeT<SmartRange, Handle, const typename std::decay<Functor>::type&>(f, b, e);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/// Class which applies a filter when iterating over elements
|
||||
template <typename RangeT, typename HandleT, typename Functor>
|
||||
struct FilteredSmartRangeT : public SmartRangeT<FilteredSmartRangeT<RangeT, HandleT, Functor>, HandleT>
|
||||
{
|
||||
using BaseRange = SmartRangeT<FilteredSmartRangeT<RangeT, HandleT, Functor>, HandleT>;
|
||||
using BaseIterator = decltype((std::declval<typename RangeT::Range>().begin()));
|
||||
|
||||
struct FilteredIterator : public BaseIterator
|
||||
{
|
||||
|
||||
FilteredIterator(Functor f, BaseIterator it, BaseIterator end): BaseIterator(it), f_(f), end_(end)
|
||||
{
|
||||
if (!BaseIterator::operator==(end_) && !f_(*(*this))) // if start is not valid go to first valid one
|
||||
operator++();
|
||||
}
|
||||
|
||||
FilteredIterator& operator++()
|
||||
{
|
||||
if (BaseIterator::operator==(end_)) // don't go past end
|
||||
return *this;
|
||||
|
||||
// go to next valid one
|
||||
do
|
||||
BaseIterator::operator++();
|
||||
while (BaseIterator::operator!=(end_) && !f_(*(*this)));
|
||||
return *this;
|
||||
}
|
||||
|
||||
Functor f_;
|
||||
BaseIterator end_;
|
||||
};
|
||||
|
||||
FilteredSmartRangeT(Functor f, BaseIterator begin, BaseIterator end) : f_(f), begin_(begin), end_(end){}
|
||||
FilteredIterator begin() const { return FilteredIterator(f_, begin_, end_); }
|
||||
FilteredIterator end() const { return FilteredIterator(f_, end_, end_); }
|
||||
|
||||
Functor f_;
|
||||
BaseIterator begin_;
|
||||
BaseIterator end_;
|
||||
};
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
} // namespace OpenMesh
|
||||
//=============================================================================
|
||||
|
||||
//=============================================================================
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
|
||||
52
src/OpenMesh/Core/Mesh/Tags.hh
Normal file
52
src/OpenMesh/Core/Mesh/Tags.hh
Normal file
@@ -0,0 +1,52 @@
|
||||
/* ========================================================================= *
|
||||
* *
|
||||
* OpenMesh *
|
||||
* Copyright (c) 2001-2015, RWTH-Aachen University *
|
||||
* Department of Computer Graphics and Multimedia *
|
||||
* All rights reserved. *
|
||||
* www.openmesh.org *
|
||||
* *
|
||||
*---------------------------------------------------------------------------*
|
||||
* This file is part of OpenMesh. *
|
||||
*---------------------------------------------------------------------------*
|
||||
* *
|
||||
* Redistribution and use in source and binary forms, with or without *
|
||||
* modification, are permitted provided that the following conditions *
|
||||
* are met: *
|
||||
* *
|
||||
* 1. Redistributions of source code must retain the above copyright notice, *
|
||||
* this list of conditions and the following disclaimer. *
|
||||
* *
|
||||
* 2. Redistributions in binary form must reproduce the above copyright *
|
||||
* notice, this list of conditions and the following disclaimer in the *
|
||||
* documentation and/or other materials provided with the distribution. *
|
||||
* *
|
||||
* 3. Neither the name of the copyright holder nor the names of its *
|
||||
* contributors may be used to endorse or promote products derived from *
|
||||
* this software without specific prior written permission. *
|
||||
* *
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
|
||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
|
||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
|
||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace OpenMesh {
|
||||
|
||||
/// Connectivity tag indicating that the tagged mesh has polygon connectivity.
|
||||
struct PolyConnectivityTag {};
|
||||
/// Connectivity tag indicating that the tagged mesh has triangle connectivity.
|
||||
struct TriConnectivityTag {};
|
||||
|
||||
} // namespace OpenMesh
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
/** \file Core/Mesh/Traits.hh
|
||||
@@ -157,6 +152,24 @@ struct DefaultTraits
|
||||
FaceAttributes(0);
|
||||
};
|
||||
|
||||
/** \class DefaultTraitsDouble Traits.hh <OpenMesh/Mesh/Traits.hh>
|
||||
|
||||
Version of Default Traits that uses double precision for points and
|
||||
normals as well as floating point vectors for colors
|
||||
|
||||
\see The Mesh docu section on \ref mesh_type.
|
||||
\see Traits.hh for a list of macros for traits classes.
|
||||
*/
|
||||
struct DefaultTraitsDouble : public DefaultTraits
|
||||
{
|
||||
/// Use double precision points
|
||||
typedef OpenMesh::Vec3d Point;
|
||||
/// Use double precision Normals
|
||||
typedef OpenMesh::Vec3d Normal;
|
||||
/// Use RGBA Color
|
||||
typedef OpenMesh::Vec4f Color;
|
||||
};
|
||||
|
||||
|
||||
//== CLASS DEFINITION =========================================================
|
||||
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
// CLASS TriMeshT - IMPLEMENTATION
|
||||
@@ -54,11 +49,11 @@
|
||||
namespace OpenMesh
|
||||
{
|
||||
|
||||
TriConnectivity::FaceHandle
|
||||
SmartFaceHandle
|
||||
TriConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size)
|
||||
{
|
||||
// need at least 3 vertices
|
||||
if (_vhs_size < 3) return InvalidFaceHandle;
|
||||
if (_vhs_size < 3) return make_smart(InvalidFaceHandle, this);
|
||||
|
||||
/// face is triangle -> ok
|
||||
if (_vhs_size == 3)
|
||||
@@ -83,21 +78,29 @@ TriConnectivity::add_face(const VertexHandle* _vertex_handles, size_t _vhs_size)
|
||||
fh = PolyConnectivity::add_face(vhandles, 3);
|
||||
}
|
||||
|
||||
return fh;
|
||||
return make_smart(fh, this);
|
||||
}
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
FaceHandle TriConnectivity::add_face(const std::vector<VertexHandle>& _vhandles)
|
||||
SmartFaceHandle TriConnectivity::add_face(const std::vector<VertexHandle>& _vhandles)
|
||||
{
|
||||
return add_face(&_vhandles.front(), _vhandles.size());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
SmartFaceHandle TriConnectivity::add_face(const std::vector<SmartVertexHandle>& _vhandles)
|
||||
{
|
||||
std::vector<VertexHandle> vhandles(_vhandles.begin(), _vhandles.end());
|
||||
return add_face(&vhandles.front(), vhandles.size());
|
||||
}
|
||||
|
||||
FaceHandle TriConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2)
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
|
||||
SmartFaceHandle TriConnectivity::add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2)
|
||||
{
|
||||
VertexHandle vhs[3] = { _vh0, _vh1, _vh2 };
|
||||
return PolyConnectivity::add_face(vhs, 3);
|
||||
@@ -488,6 +491,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 size_t nf = n_faces();
|
||||
|
||||
// Split the halfedge ( handle will be preserved)
|
||||
split(_eh, _vh);
|
||||
|
||||
@@ -495,6 +503,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 (static_cast<size_t>(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
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef OPENMESH_TRICONNECTIVITY_HH
|
||||
#define OPENMESH_TRICONNECTIVITY_HH
|
||||
@@ -90,8 +85,8 @@ public:
|
||||
*
|
||||
*
|
||||
* */
|
||||
FaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size);
|
||||
|
||||
SmartFaceHandle add_face(const VertexHandle* _vhandles, size_t _vhs_size);
|
||||
|
||||
/** \brief Add a face with arbitrary valence to the triangle mesh
|
||||
*
|
||||
* Override OpenMesh::Mesh::PolyMeshT::add_face(). Faces that aren't
|
||||
@@ -100,7 +95,17 @@ public:
|
||||
*
|
||||
*
|
||||
* */
|
||||
FaceHandle add_face(const std::vector<VertexHandle>& _vhandles);
|
||||
SmartFaceHandle add_face(const std::vector<VertexHandle>& _vhandles);
|
||||
|
||||
/** \brief Add a face with arbitrary valence to the triangle mesh
|
||||
*
|
||||
* Override OpenMesh::Mesh::PolyMeshT::add_face(). Faces that aren't
|
||||
* triangles will be triangulated and added. In this case an
|
||||
* invalid face handle will be returned.
|
||||
*
|
||||
*
|
||||
* */
|
||||
SmartFaceHandle add_face(const std::vector<SmartVertexHandle>& _vhandles);
|
||||
|
||||
/** \brief Add a face to the mesh (triangle)
|
||||
*
|
||||
@@ -112,7 +117,7 @@ public:
|
||||
* @param _vh2 VertexHandle 3
|
||||
* @return FaceHandle of the added face (invalid, if the operation failed)
|
||||
*/
|
||||
FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2);
|
||||
SmartFaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2);
|
||||
|
||||
//@}
|
||||
|
||||
@@ -162,27 +167,63 @@ public:
|
||||
*
|
||||
* \note The properties of the new edges, halfedges, and faces will be undefined!
|
||||
*
|
||||
* @param _eh Edge handle that should be splitted
|
||||
* @param _eh Edge handle that should be split
|
||||
* @param _vh Vertex handle that will be inserted at the edge
|
||||
*/
|
||||
void split(EdgeHandle _eh, VertexHandle _vh);
|
||||
|
||||
/** \brief Edge split (= 2-to-4 split)
|
||||
*
|
||||
*
|
||||
* The function will introduce two new faces ( non-boundary case) or
|
||||
* one additional face (if edge is boundary)
|
||||
*
|
||||
* \note The properties of the new edges, halfedges, and faces will be undefined!
|
||||
*
|
||||
* \note This is an override to prevent a direct call to PolyConnectivity split_edge,
|
||||
* which would introduce a singular vertex with valence 2 which is not allowed
|
||||
* on TriMeshes
|
||||
*
|
||||
* @param _eh Edge handle that should be split
|
||||
* @param _vh Vertex handle that will be inserted at the edge
|
||||
*/
|
||||
inline void split_edge(EdgeHandle _eh, VertexHandle _vh) { TriConnectivity::split(_eh, _vh); }
|
||||
|
||||
/** \brief Edge split (= 2-to-4 split)
|
||||
*
|
||||
* The function will introduce two new faces ( non-boundary case) or
|
||||
* one additional face (if edge is boundary)
|
||||
*
|
||||
* \note The properties of the new edges will be adjusted to the properties of the original edge
|
||||
* \note The properties of the new faces and halfedges will be undefined
|
||||
* \note The properties of the new edges and faces will be adjusted to the
|
||||
* properties of the original edge and face
|
||||
* \note The properties of the new halfedges will be undefined
|
||||
*
|
||||
* @param _eh Edge handle that should be splitted
|
||||
* @param _eh Edge handle that should be split
|
||||
* @param _vh Vertex handle that will be inserted at the edge
|
||||
*/
|
||||
void split_copy(EdgeHandle _eh, VertexHandle _vh);
|
||||
|
||||
/** \brief Edge split (= 2-to-4 split)
|
||||
*
|
||||
* The function will introduce two new faces ( non-boundary case) or
|
||||
* one additional face (if edge is boundary)
|
||||
*
|
||||
* \note The properties of the new edges and faces will be adjusted to the
|
||||
* properties of the original edge and face
|
||||
* \note The properties of the new halfedges will be undefined
|
||||
*
|
||||
* \note This is an override to prevent a direct call to PolyConnectivity split_edge_copy,
|
||||
* which would introduce a singular vertex with valence 2 which is not allowed
|
||||
* on TriMeshes
|
||||
*
|
||||
* @param _eh Edge handle that should be split
|
||||
* @param _vh Vertex handle that will be inserted at the edge
|
||||
*/
|
||||
inline void split_edge_copy(EdgeHandle _eh, VertexHandle _vh) { TriConnectivity::split_copy(_eh, _vh); }
|
||||
|
||||
/** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function).
|
||||
*
|
||||
* @param _fh Face handle that should be splitted
|
||||
* @param _fh Face handle that should be split
|
||||
* @param _vh Vertex handle that will be inserted at the face
|
||||
*/
|
||||
inline void split(FaceHandle _fh, VertexHandle _vh)
|
||||
@@ -190,7 +231,7 @@ public:
|
||||
|
||||
/** \brief Face split (= 1-to-3) split, calls corresponding PolyMeshT function).
|
||||
*
|
||||
* @param _fh Face handle that should be splitted
|
||||
* @param _fh Face handle that should be split
|
||||
* @param _vh Vertex handle that will be inserted at the face
|
||||
*/
|
||||
inline void split_copy(FaceHandle _fh, VertexHandle _vh)
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -63,6 +58,7 @@
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
#include <OpenMesh/Core/Mesh/PolyMeshT.hh>
|
||||
#include <OpenMesh/Core/Mesh/Tags.hh>
|
||||
#include <vector>
|
||||
|
||||
|
||||
@@ -103,11 +99,12 @@ public:
|
||||
typedef PolyMeshT<Kernel> PolyMesh;
|
||||
|
||||
//@{
|
||||
/// Determine whether this is a PolyMeshT or TriMeshT ( This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT )
|
||||
/// Determine whether this is a PolyMeshT or TriMeshT (This function does not check the per face vertex count! It only checks if the datatype is PolyMeshT or TriMeshT)
|
||||
static constexpr bool is_polymesh() { return false; }
|
||||
static constexpr bool is_trimesh() { return true; }
|
||||
using ConnectivityTag = TriConnectivityTag;
|
||||
enum { IsPolyMesh = 0 };
|
||||
enum { IsTriMesh = 1 };
|
||||
static bool is_polymesh() { return false; }
|
||||
static bool is_trimesh() { return true; }
|
||||
//@}
|
||||
|
||||
//--- items ---
|
||||
@@ -181,9 +178,11 @@ public:
|
||||
/** \brief Vertex Split: inverse operation to collapse().
|
||||
*
|
||||
* Insert the new vertex at position v0. The vertex will be added
|
||||
* as the inverse of the vertex split. The faces above the split
|
||||
* as the inverse of the edge collapse. The faces above the split
|
||||
* will be correctly attached to the two new edges
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* Before:
|
||||
* v_l v0 v_r
|
||||
* x x x
|
||||
@@ -208,6 +207,8 @@ public:
|
||||
* x
|
||||
* v1
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @param _v0_point Point position for the new point
|
||||
* @param _v1 Vertex that will be split
|
||||
* @param _vl Left vertex handle
|
||||
@@ -221,9 +222,11 @@ public:
|
||||
/** \brief Vertex Split: inverse operation to collapse().
|
||||
*
|
||||
* Insert the new vertex at position v0. The vertex will be added
|
||||
* as the inverse of the vertex split. The faces above the split
|
||||
* as the inverse of the edge collapse. The faces above the split
|
||||
* will be correctly attached to the two new edges
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* Before:
|
||||
* v_l v0 v_r
|
||||
* x x x
|
||||
@@ -248,6 +251,8 @@ public:
|
||||
* x
|
||||
* v1
|
||||
*
|
||||
* </pre>
|
||||
*
|
||||
* @param _v0 Vertex handle for the newly inserted point (Input has to be unconnected!)
|
||||
* @param _v1 Vertex that will be split
|
||||
* @param _vl Left vertex handle
|
||||
@@ -267,10 +272,10 @@ public:
|
||||
* @param _p New point position that will be inserted at the edge
|
||||
* @return Vertex handle of the newly added vertex
|
||||
*/
|
||||
inline VertexHandle split(EdgeHandle _eh, const Point& _p)
|
||||
inline SmartVertexHandle split(EdgeHandle _eh, const Point& _p)
|
||||
{
|
||||
//Do not call PolyMeshT function below as this does the wrong operation
|
||||
const VertexHandle vh = this->add_vertex(_p); Kernel::split(_eh, vh); return vh;
|
||||
const SmartVertexHandle vh = this->add_vertex(_p); Kernel::split(_eh, vh); return vh;
|
||||
}
|
||||
|
||||
/** \brief Edge split (= 2-to-4 split)
|
||||
@@ -281,10 +286,10 @@ public:
|
||||
* @param _p New point position that will be inserted at the edge
|
||||
* @return Vertex handle of the newly added vertex
|
||||
*/
|
||||
inline VertexHandle split_copy(EdgeHandle _eh, const Point& _p)
|
||||
inline SmartVertexHandle split_copy(EdgeHandle _eh, const Point& _p)
|
||||
{
|
||||
//Do not call PolyMeshT function below as this does the wrong operation
|
||||
const VertexHandle vh = this->add_vertex(_p); Kernel::split_copy(_eh, vh); return vh;
|
||||
const SmartVertexHandle vh = this->add_vertex(_p); Kernel::split_copy(_eh, vh); return vh;
|
||||
}
|
||||
|
||||
/** \brief Edge split (= 2-to-4 split)
|
||||
@@ -322,8 +327,8 @@ public:
|
||||
*
|
||||
* @return Vertex handle of the new vertex
|
||||
*/
|
||||
inline VertexHandle split(FaceHandle _fh, const Point& _p)
|
||||
{ const VertexHandle vh = this->add_vertex(_p); PolyMesh::split(_fh, vh); return vh; }
|
||||
inline SmartVertexHandle split(FaceHandle _fh, const Point& _p)
|
||||
{ const SmartVertexHandle vh = this->add_vertex(_p); PolyMesh::split(_fh, vh); return vh; }
|
||||
|
||||
/** \brief Face split (= 1-to-3 split, calls corresponding PolyMeshT function).
|
||||
*
|
||||
@@ -334,8 +339,8 @@ public:
|
||||
*
|
||||
* @return Vertex handle of the new vertex
|
||||
*/
|
||||
inline VertexHandle split_copy(FaceHandle _fh, const Point& _p)
|
||||
{ const VertexHandle vh = this->add_vertex(_p); PolyMesh::split_copy(_fh, vh); return vh; }
|
||||
inline SmartVertexHandle split_copy(FaceHandle _fh, const Point& _p)
|
||||
{ const SmartVertexHandle vh = this->add_vertex(_p); PolyMesh::split_copy(_fh, vh); return vh; }
|
||||
|
||||
|
||||
/** \brief Face split (= 1-to-4) split, splits edges at midpoints and adds 4 new faces in the interior).
|
||||
@@ -359,9 +364,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);
|
||||
@@ -414,6 +419,16 @@ public:
|
||||
*/
|
||||
inline void split_copy(FaceHandle _fh, VertexHandle _vh)
|
||||
{ PolyMesh::split_copy(_fh, _vh); }
|
||||
|
||||
/** \brief Calculates the area of a face
|
||||
*
|
||||
* @param _fh Handle of the face to calculate the area of
|
||||
*/
|
||||
Scalar calc_face_area(FaceHandle _fh) const
|
||||
{
|
||||
const HalfedgeHandle heh = this->halfedge_handle(_fh);
|
||||
return this->calc_sector_area(heh);
|
||||
}
|
||||
|
||||
/** \name Normal vector computation
|
||||
*/
|
||||
@@ -431,7 +446,7 @@ public:
|
||||
//=============================================================================
|
||||
#if defined(OM_INCLUDE_TEMPLATES) && !defined(OPENMESH_TRIMESH_C)
|
||||
#define OPENMESH_TRIMESH_TEMPLATES
|
||||
#include "TriMeshT.cc"
|
||||
#include "TriMeshT_impl.hh"
|
||||
#endif
|
||||
//=============================================================================
|
||||
#endif // OPENMESH_TRIMESH_HH defined
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
//=============================================================================
|
||||
@@ -102,7 +97,7 @@ class TriMesh_ArrayKernelT
|
||||
public:
|
||||
TriMesh_ArrayKernelT() {}
|
||||
template<class OtherTraits>
|
||||
TriMesh_ArrayKernelT( const PolyMesh_ArrayKernelT<OtherTraits> & t)
|
||||
explicit TriMesh_ArrayKernelT( const PolyMesh_ArrayKernelT<OtherTraits> & t)
|
||||
{
|
||||
//assign the connectivity and standard properties
|
||||
this->assign(t,true);
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef OPENMESH_CIRCULATORS_HH
|
||||
#define OPENMESH_CIRCULATORS_HH
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#ifndef OPENMESH_ITERATORS_HH
|
||||
#define OPENMESH_ITERATORS_HH
|
||||
|
||||
@@ -39,13 +39,6 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision: 566 $ *
|
||||
* $Date: 2012-03-23 18:00:57 +0100 (Fr, 23 Mär 2012) $ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
// Disable the warnings about needs to have DLL interface as we have tons of vector templates
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( disable: 4251 )
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
|
||||
#ifndef OPENMESH_COMPILER_H
|
||||
|
||||
@@ -65,11 +65,8 @@
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
|
||||
#define OM_VERSION 0x70000
|
||||
//#define OM_VERSION 0x60300
|
||||
|
||||
// only defined, if it is a beta version
|
||||
//#define OM_VERSION_BETA 4
|
||||
#define OM_VERSION 0x90000
|
||||
//#define OM_VERSION 0x70200
|
||||
|
||||
#define OM_GET_VER ((OM_VERSION & 0xf0000) >> 16)
|
||||
#define OM_GET_MAJ ((OM_VERSION & 0x0ff00) >> 8)
|
||||
@@ -86,18 +83,23 @@
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
# define DEPRECATED(msg) __declspec(deprecated(msg))
|
||||
//! define OM_SUPPRESS_DEPRECATED to suppress deprecated code warnings
|
||||
#if defined(OM_SUPPRESS_DEPRECATED)
|
||||
#pragma message( \
|
||||
"OpenMesh deprecated code warnings suppressed, please fix your code soon")
|
||||
# define OM_DEPRECATED(msg)
|
||||
#elif defined(_MSC_VER)
|
||||
# define OM_DEPRECATED(msg) __declspec(deprecated(msg))
|
||||
#elif defined(__GNUC__)
|
||||
# if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) >= 40500 /* Test for GCC >= 4.5.0 */
|
||||
# define DEPRECATED(msg) __attribute__ ((deprecated(msg)))
|
||||
# define OM_DEPRECATED(msg) __attribute__ ((deprecated(msg)))
|
||||
# else
|
||||
# define DEPRECATED(msg) __attribute__ ((deprecated))
|
||||
# define OM_DEPRECATED(msg) __attribute__ ((deprecated))
|
||||
# endif
|
||||
#elif defined(__clang__)
|
||||
# define DEPRECATED(msg) __attribute__ ((deprecated(msg)))
|
||||
# define OM_DEPRECATED(msg) __attribute__ ((deprecated(msg)))
|
||||
#else
|
||||
# define DEPRECATED(msg)
|
||||
# define OM_DEPRECATED(msg)
|
||||
#endif
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
@@ -39,11 +39,6 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
#include <OpenMesh/Core/System/config.h>
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
@@ -97,7 +92,7 @@ class multiplex_target : public basic_multiplex_target
|
||||
{
|
||||
public:
|
||||
explicit multiplex_target(T& _t) : target_(_t) {}
|
||||
virtual void operator<<(const std::string& _s) { target_ << _s; }
|
||||
virtual void operator<<(const std::string& _s) override { target_ << _s; }
|
||||
private:
|
||||
T& target_;
|
||||
};
|
||||
@@ -290,7 +285,7 @@ class mostream : public std::ostream
|
||||
public:
|
||||
|
||||
/// Explicit constructor
|
||||
explicit mostream() : std::ostream(NULL) { init(&streambuffer_); }
|
||||
explicit mostream() : std::ostream(nullptr) { init(&streambuffer_); }
|
||||
|
||||
|
||||
/// Connect target to multiplexer
|
||||
|
||||
@@ -39,12 +39,7 @@
|
||||
* *
|
||||
* ========================================================================= */
|
||||
|
||||
/*===========================================================================*\
|
||||
* *
|
||||
* $Revision$ *
|
||||
* $Date$ *
|
||||
* *
|
||||
\*===========================================================================*/
|
||||
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user