You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1659 lines
83 KiB
1659 lines
83 KiB
/**************************************************************************** |
|
* NanoPLY * |
|
* NanoPLY is a C++11 header-only library to read and write PLY file * |
|
* * |
|
* Copyright(C) 2014-2015 * |
|
* Visual Computing Lab * |
|
* ISTI - Italian National Research Council * |
|
* * |
|
* This Source Code Form is subject to the terms of the Mozilla Public * |
|
* License, v. 2.0. If a copy of the MPL was not distributed with this * |
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. * |
|
* * |
|
****************************************************************************/ |
|
|
|
#ifndef NANOPLY_WRAPPER_VCG_H |
|
#define NANOPLY_WRAPPER_VCG_H |
|
|
|
#include <wrap/nanoply/include/nanoply.hpp> |
|
#include <vcg/complex/complex.h> |
|
#include <vcg/space/point.h> |
|
#include <map> |
|
|
|
#include <typeinfo> |
|
#include <type_traits> |
|
|
|
namespace nanoply |
|
{ |
|
|
|
template <class MeshType> |
|
class NanoPlyWrapper{ |
|
|
|
|
|
private: |
|
|
|
typedef typename MeshType::PointerToAttribute PointerToAttribute; |
|
typedef typename MeshType::ScalarType ScalarType; |
|
|
|
typedef typename MeshType::VertexType VertexType; |
|
typedef typename MeshType::VertexType::ScalarType VertexCoordScalar; |
|
typedef typename MeshType::VertexType::NormalType VertexNormalType; |
|
typedef typename MeshType::VertexType::NormalType::ScalarType VertexNormScalar; |
|
typedef typename MeshType::VertexType::ColorType VertexColorType; |
|
typedef typename MeshType::VertexType::ColorType::ScalarType VertexColorScalar; |
|
typedef typename MeshType::VertexType::QualityType VertexQuality; |
|
typedef typename MeshType::VertexType::RadiusType VertexRadius; |
|
typedef typename MeshType::VertexType::FlagType VertexFlag; |
|
typedef typename MeshType::VertexType::TexCoordType VertexTexCoordType; |
|
typedef typename MeshType::VertexType::TexCoordType::ScalarType VertexTexScalar; |
|
typedef typename MeshType::VertexType::CurvatureType VertexCurType; |
|
typedef typename MeshType::VertexType::CurvatureType::ScalarType VertexCurScalar; |
|
typedef typename MeshType::VertexType::CurvatureDirType VertexCurDirType; |
|
typedef typename MeshType::VertexType::CurScalarType VertexDirCurScalar; |
|
typedef typename MeshType::VertexType::CurVecType::ScalarType VertexDirCurVecScalar; |
|
|
|
typedef typename MeshType::EdgeType EdgeType; |
|
typedef typename MeshType::EdgeType::ColorType::ScalarType EdgeColorScalar; |
|
typedef typename MeshType::EdgeType::QualityType EdgeQuality; |
|
typedef typename MeshType::EdgeType::FlagType EdgeFlag; |
|
|
|
typedef typename MeshType::FaceType FaceType; |
|
typedef typename MeshType::FaceType::NormalType FaceNormalType; |
|
typedef typename MeshType::FaceType::NormalType::ScalarType FaceNormScalar; |
|
typedef typename MeshType::FaceType::ColorType FaceColorType; |
|
typedef typename MeshType::FaceType::ColorType::ScalarType FaceColorScalar; |
|
typedef typename MeshType::FaceType::QualityType FaceQuality; |
|
typedef typename MeshType::FaceType::FlagType FaceFlag; |
|
typedef typename vcg::face::vector_ocf<FaceType>::WedgeTexTypePack FaceTexCoordType; |
|
typedef typename MeshType::FaceType::TexCoordType::ScalarType FaceTexScalar; |
|
typedef typename MeshType::FaceType::CurvatureDirType FaceCurDirType; |
|
typedef typename MeshType::FaceType::CurScalarType FaceDirCurScalar; |
|
typedef typename MeshType::FaceType::CurVecType::ScalarType FaceDirCurVecScalar; |
|
typedef typename vcg::face::vector_ocf<FaceType>::WedgeColorTypePack WedgeColorType; |
|
typedef typename MeshType::FaceType::WedgeColorType::ScalarType WedgeColorScalar; |
|
typedef typename vcg::face::vector_ocf<FaceType>::WedgeNormalTypePack WedgeNormalType; |
|
typedef typename MeshType::FaceType::WedgeNormalType::ScalarType WedgeNormalScalar; |
|
|
|
typedef typename MeshType::FaceIterator FaceIterator; |
|
|
|
template<class T> |
|
static PlyType getEntity() |
|
{ |
|
if constexpr (std::is_same<T, unsigned char>::value) { return NNP_UINT8; } |
|
if constexpr (std::is_same<T, char>::value) { return NNP_INT8; } |
|
if constexpr (std::is_same<T, unsigned short>::value) { return NNP_UINT16; } |
|
if constexpr (std::is_same<T, short>::value) { return NNP_INT16; } |
|
if constexpr (std::is_same<T, unsigned int>::value) { return NNP_UINT32; } |
|
if constexpr (std::is_same<T, int>::value) { return NNP_INT32; } |
|
if constexpr (std::is_same<T, float>::value) { return NNP_FLOAT32; } |
|
if constexpr (std::is_same<T, double>::value) { return NNP_FLOAT64; } |
|
return NNP_UNKNOWN_TYPE; |
|
}; |
|
|
|
template<class T> |
|
static PlyType getEntityList() |
|
{ |
|
if constexpr (std::is_same<T, unsigned char>::value) { return NNP_LIST_UINT8_UINT8; }; |
|
if constexpr (std::is_same<T, char>::value) { return NNP_LIST_UINT8_INT8; }; |
|
if constexpr (std::is_same<T, unsigned short>::value) { return NNP_LIST_UINT8_UINT16; }; |
|
if constexpr (std::is_same<T, short>::value) { return NNP_LIST_UINT8_INT16; }; |
|
if constexpr (std::is_same<T, unsigned int>::value) { return NNP_LIST_UINT8_UINT32; }; |
|
if constexpr (std::is_same<T, int>::value) { return NNP_LIST_UINT8_INT32; }; |
|
if constexpr (std::is_same<T, float>::value) { return NNP_LIST_UINT8_FLOAT32; }; |
|
if constexpr (std::is_same<T, double>::value) { return NNP_LIST_UINT8_FLOAT64; }; |
|
return NNP_UNKNOWN_TYPE; |
|
} |
|
|
|
|
|
template<class Container, class Type, int n> |
|
inline static void PushDescriport(std::vector<PlyProperty>& prop, ElementDescriptor& elem, PlyEntity entity, void* ptr) |
|
{ |
|
prop.push_back(PlyProperty(getEntity<Type>(), entity)); |
|
DescriptorInterface* di = new DataDescriptor<Container, n, Type>(entity, ptr); |
|
elem.dataDescriptor.push_back(di); |
|
} |
|
|
|
|
|
template<class Container, class Type, int n> |
|
inline static void PushDescriportList(std::vector<PlyProperty>& prop, ElementDescriptor& elem, PlyEntity entity, void* ptr) |
|
{ |
|
prop.push_back(PlyProperty(getEntityList<Type>(), entity)); |
|
DescriptorInterface* di = new DataDescriptor<Container, n, Type>(entity, ptr); |
|
elem.dataDescriptor.push_back(di); |
|
} |
|
|
|
|
|
template<class Container, class Type, int n> |
|
inline static void PushDescriport(std::vector<PlyProperty>& prop, ElementDescriptor& elem, const std::string& name, void* ptr) |
|
{ |
|
prop.push_back(PlyProperty(getEntity<Type>(), name)); |
|
DescriptorInterface* di = new DataDescriptor<Container, n, Type>(name, ptr); |
|
elem.dataDescriptor.push_back(di); |
|
} |
|
|
|
|
|
template<class Container, class Type, int n> |
|
inline static void PushDescriportList(std::vector<PlyProperty>& prop, ElementDescriptor& elem, const std::string& name, void* ptr) |
|
{ |
|
prop.push_back(PlyProperty(getEntityList<Type>(), name)); |
|
DescriptorInterface* di = new DataDescriptor<Container, n, Type>(name, ptr); |
|
elem.dataDescriptor.push_back(di); |
|
} |
|
|
|
public: |
|
|
|
|
|
typedef enum { |
|
IO_NONE = 0x00000000, |
|
|
|
IO_VERTCOORD = 0x00000001, |
|
IO_VERTFLAGS = 0x00000002, |
|
IO_VERTCOLOR = 0x00000004, |
|
IO_VERTQUALITY = 0x00000008, |
|
IO_VERTNORMAL = 0x00000010, |
|
IO_VERTTEXCOORD = 0x00000020, |
|
IO_VERTRADIUS = 0x00000040, |
|
IO_VERTCURV = 0x00000080, |
|
IO_VERTCURVDIR = 0x00000100, |
|
IO_VERTATTRIB = 0x00000200, |
|
|
|
IO_FACEINDEX = 0x00000400, |
|
IO_FACEFLAGS = 0x00000800, |
|
IO_FACECOLOR = 0x00001000, |
|
IO_FACEQUALITY = 0x00002000, |
|
IO_FACENORMAL = 0x00004000, |
|
IO_FACECURVDIR = 0x00008000, |
|
IO_FACEATTRIB = 0x00010000, |
|
|
|
IO_EDGEINDEX = 0x00020000, |
|
IO_EDGEQUALITY = 0x00040000, |
|
IO_EDGECOLOR = 0x00080000, |
|
IO_EDGEFLAGS = 0x00100000, |
|
IO_EDGEATTRIB = 0x00200000, |
|
|
|
IO_WEDGCOLOR = 0x00400000, |
|
IO_WEDGTEXCOORD = 0x00800000, |
|
IO_WEDGTEXMULTI = 0x01000000, // when texture index is explicit |
|
IO_WEDGNORMAL = 0x02000000, |
|
|
|
IO_ALL_ATTRIB = 0x03FFFFFF, |
|
|
|
IO_BITPOLYGONAL = 0x04000000, // loads explicit polygonal mesh |
|
|
|
IO_CAMERA = 0x08000000, |
|
IO_MESHATTRIB = 0x10000000, |
|
|
|
IO_FLAGS = IO_VERTFLAGS | IO_FACEFLAGS, |
|
|
|
IO_ALL = 0xFFFFFFFF |
|
}BitMask; |
|
|
|
|
|
|
|
class CustomAttributeDescriptor |
|
{ |
|
public: |
|
|
|
typedef std::map<std::string, ElementDescriptor::PropertyDescriptor> MapMeshAttrib; |
|
typedef std::map<std::string, ElementDescriptor::PropertyDescriptor>::iterator MapMeshAttribIter; |
|
typedef std::map<std::string, std::vector<PlyProperty>> MapMeshAttribProp; |
|
typedef std::map<std::string, std::vector<PlyProperty>>::iterator MapMeshAttribPropIter; |
|
|
|
ElementDescriptor::PropertyDescriptor vertexAttrib; |
|
ElementDescriptor::PropertyDescriptor faceAttrib; |
|
ElementDescriptor::PropertyDescriptor edgeAttrib; |
|
std::vector<PlyProperty> vertexAttribProp; |
|
std::vector<PlyProperty> faceAttribProp; |
|
std::vector<PlyProperty> edgeAttribProp; |
|
|
|
MapMeshAttrib meshAttrib; |
|
MapMeshAttribProp meshAttribProp; |
|
std::map<std::string, int> meshAttribCnt; |
|
|
|
|
|
~CustomAttributeDescriptor() |
|
{ |
|
for (size_t i = 0; i < vertexAttrib.size(); i++) |
|
delete vertexAttrib[i]; |
|
for (size_t i = 0; i < edgeAttrib.size(); i++) |
|
delete edgeAttrib[i]; |
|
for (size_t i = 0; i < faceAttrib.size(); i++) |
|
delete faceAttrib[i]; |
|
CustomAttributeDescriptor::MapMeshAttribIter iter = meshAttrib.begin(); |
|
for (; iter != meshAttrib.end(); iter++) |
|
for (size_t i = 0; i < (*iter).second.size(); i++) |
|
delete (*iter).second[i]; |
|
} |
|
|
|
|
|
template<class Container, class Type, int n> |
|
void AddVertexAttribDescriptor(const std::string& name, PlyType type, void* ptr) |
|
{ |
|
AddAttribDescriptor<Container, Type, n>(name, type, ptr, vertexAttrib, vertexAttribProp); |
|
} |
|
|
|
template<class Container, class Type, int n> |
|
void AddEdgeAttribDescriptor(const std::string& name, PlyType type, void* ptr) |
|
{ |
|
AddAttribDescriptor<Container, Type, n>(name, type, ptr, edgeAttrib, edgeAttribProp); |
|
} |
|
|
|
template<class Container, class Type, int n> |
|
void AddFaceAttribDescriptor(const std::string& name, PlyType type, void* ptr) |
|
{ |
|
AddAttribDescriptor<Container, Type, n>(name, type, ptr, faceAttrib, faceAttribProp); |
|
} |
|
|
|
template<class Container, class Type, int n> |
|
void AddMeshAttribDescriptor(const std::string& nameAttrib, const std::string& nameProp, PlyType type, void* ptr) |
|
{ |
|
meshAttrib[nameAttrib].push_back(new DataDescriptor<Container, n, Type>(nameProp, ptr)); |
|
meshAttribProp[nameAttrib].push_back(PlyProperty(type, nameProp)); |
|
} |
|
|
|
void AddMeshAttrib(const std::string& name, int cnt) |
|
{ |
|
meshAttribCnt[name] = cnt; |
|
} |
|
|
|
void GetMeshAttrib(std::string filename) |
|
{ |
|
nanoply::Info info(filename); |
|
if (info.errInfo == nanoply::NNP_OK) |
|
{ |
|
for (size_t i = 0; i < info.elemVec.size(); i++) |
|
{ |
|
if (info.elemVec[i].plyElem == NNP_UNKNOWN_ELEM && info.elemVec[i].name != "camera") |
|
meshAttribCnt[info.elemVec[i].name] = info.elemVec[i].cnt; |
|
} |
|
} |
|
} |
|
|
|
bool CreateVertexAttribDescriptor(const PointerToAttribute* ptr) |
|
{ |
|
return CreateAttribDescriptor(ptr, vertexAttrib, vertexAttribProp); |
|
} |
|
|
|
bool CreateEdgeAttribDescriptor(const PointerToAttribute* ptr) |
|
{ |
|
return CreateAttribDescriptor(ptr, edgeAttrib, edgeAttribProp); |
|
} |
|
|
|
bool CreateFaceAttribDescriptor(const PointerToAttribute* ptr) |
|
{ |
|
return CreateAttribDescriptor(ptr, faceAttrib, faceAttribProp); |
|
} |
|
|
|
bool AddVertexAttrib(MeshType& m, std::set<PointerToAttribute>& ptrAttrib, PlyElement* elem) |
|
{ |
|
return AddCustomAttrib<0>(m, ptrAttrib, elem, vertexAttrib); |
|
} |
|
|
|
bool AddEdgeAttrib(MeshType& m, std::set<PointerToAttribute>& ptrAttrib, PlyElement* elem) |
|
{ |
|
return AddCustomAttrib<1>(m, ptrAttrib, elem, edgeAttrib); |
|
} |
|
|
|
bool AddFaceAttrib(MeshType& m, std::set<PointerToAttribute>& ptrAttrib, PlyElement* elem) |
|
{ |
|
return AddCustomAttrib<2>(m, ptrAttrib, elem, faceAttrib); |
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
const std::vector<std::string> pointSuffix = { "x", "y", "z", "w" }; |
|
const std::vector<std::string> colorSuffix = { "r", "g", "b", "a" }; |
|
const std::map<std::string, int> pointSuffixMap = { { "x", 0 },{ "y", 1 },{ "z", 2 },{ "w", 3 } }; |
|
const std::map<std::string, int> colorSuffixMap = { {"r", 0},{ "g", 1 },{ "b", 2 },{ "a", 3 } }; |
|
const std::string separator = std::string("@_.#$>"); |
|
|
|
template<class Container, class Type, int n> |
|
void AddAttribDescriptor(const std::string& name, PlyType type, void* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector<PlyProperty>& attribProp) |
|
{ |
|
attrib.push_back(new DataDescriptor<Container, n, Type>(name, ptr)); |
|
attribProp.push_back(PlyProperty(type, name)); |
|
} |
|
|
|
template<class Container> |
|
void AddScalarAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector<PlyProperty>& attribProp) |
|
{ |
|
AddAttribDescriptor<Container, Container, 1>(ptr->_name, getEntity<Container>(), ptr->_handle->DataBegin(), attrib, attribProp); |
|
} |
|
|
|
template<class Container> |
|
void AddPointAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector<PlyProperty>& attribProp) |
|
{ |
|
int size = int(Container::Dimension); |
|
std::string name(ptr->_name); |
|
Container* tmpPtr = (Container*)ptr->_handle->DataBegin(); |
|
for (int i = 0 ; i < size; i++) |
|
AddAttribDescriptor<Container, typename Container::ScalarType, 1>((name + "." + pointSuffix[i]), getEntity<typename Container::ScalarType>(), &(*tmpPtr)[i], attrib, attribProp); |
|
} |
|
|
|
template<class Container> |
|
void AddColorAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector<PlyProperty>& attribProp) |
|
{ |
|
int size = int(Container::Dimension); |
|
std::string name(ptr->_name); |
|
Container* tmpPtr = (Container*)ptr->_handle->DataBegin(); |
|
for (int i = 0; i < size; i++) |
|
AddAttribDescriptor<Container, typename Container::ScalarType, 1>((name + "." + colorSuffix[i]), getEntity<typename Container::ScalarType>(), &(*tmpPtr)[i], attrib, attribProp); |
|
} |
|
|
|
template<class Container, class Type> |
|
void AddListAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector<PlyProperty>& attribProp) |
|
{ |
|
AddAttribDescriptor<Container, Type, 0>(ptr->_name, getEntityList<Type>(), ptr->_handle->DataBegin(), attrib, attribProp); |
|
} |
|
|
|
bool CreateAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector<PlyProperty>& attribProp) |
|
{ |
|
if (ptr->_type == std::type_index(typeid(unsigned char))) |
|
AddScalarAttribDescriptor<unsigned char >(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(char))) |
|
AddScalarAttribDescriptor<char>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(unsigned short))) |
|
AddScalarAttribDescriptor<unsigned short>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(short))) |
|
AddScalarAttribDescriptor<short>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(unsigned int))) |
|
AddScalarAttribDescriptor<unsigned int>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(int))) |
|
AddScalarAttribDescriptor<int>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(float))) |
|
AddScalarAttribDescriptor<float>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(double))) |
|
AddScalarAttribDescriptor<double>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point2s))) |
|
AddPointAttribDescriptor<vcg::Point2s>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point2i))) |
|
AddPointAttribDescriptor<vcg::Point2i>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point2f))) |
|
AddPointAttribDescriptor<vcg::Point2f>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point2d))) |
|
AddPointAttribDescriptor<vcg::Point2d>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point3s))) |
|
AddPointAttribDescriptor<vcg::Point3s>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point3i))) |
|
AddPointAttribDescriptor<vcg::Point3i>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point3f))) |
|
AddPointAttribDescriptor<vcg::Point3f>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point3d))) |
|
AddPointAttribDescriptor<vcg::Point3d>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point4s))) |
|
AddPointAttribDescriptor<vcg::Point4s>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point4i))) |
|
AddPointAttribDescriptor<vcg::Point4i>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point4f))) |
|
AddPointAttribDescriptor<vcg::Point4f>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Point4d))) |
|
AddPointAttribDescriptor<vcg::Point4d>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Color4b))) |
|
AddColorAttribDescriptor<vcg::Color4b>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Color4f))) |
|
AddColorAttribDescriptor<vcg::Color4f>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Color4d))) |
|
AddColorAttribDescriptor<vcg::Color4d>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(vcg::Color4d))) |
|
AddColorAttribDescriptor<vcg::Color4d>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(std::vector<unsigned char>))) |
|
AddListAttribDescriptor<std::vector<unsigned char>, unsigned char>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(std::vector<char>))) |
|
AddListAttribDescriptor<std::vector<char>,char>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(std::vector<unsigned short>))) |
|
AddListAttribDescriptor<std::vector<unsigned short>, unsigned short>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(std::vector<short>))) |
|
AddListAttribDescriptor<std::vector<short>, short>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(std::vector<unsigned int>))) |
|
AddListAttribDescriptor<std::vector<unsigned int>, unsigned int>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(std::vector<int>))) |
|
AddListAttribDescriptor<std::vector<int>, int>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(std::vector<float>))) |
|
AddListAttribDescriptor<std::vector<float>, float>(ptr, attrib, attribProp); |
|
else if (ptr->_type == std::type_index(typeid(std::vector<double>))) |
|
AddListAttribDescriptor<std::vector<double>, double>(ptr, attrib, attribProp); |
|
else |
|
return false; |
|
return true; |
|
} |
|
|
|
|
|
template <size_t ActionType, class Container> |
|
void AddScalarAttrib(MeshType& m, const std::string& name, PlyType& type) |
|
{ |
|
if (ActionType == 0) //vertex |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<Container>(m, name); |
|
AddVertexAttribDescriptor<Container, Container, 1>(name, type, h._handle->DataBegin()); |
|
} |
|
else if (ActionType == 1) //Edge |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerEdgeAttribute<Container>(m, name); |
|
AddEdgeAttribDescriptor<Container, Container, 1>(name, type, h._handle->DataBegin()); |
|
} |
|
else if (ActionType == 2) //Face |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerFaceAttribute<Container>(m, name); |
|
AddFaceAttribDescriptor<Container, Container, 1>(name, type, h._handle->DataBegin()); |
|
} |
|
} |
|
|
|
template <size_t ActionType, class Container> |
|
void AddPointAttrib(MeshType& m, const std::string& name, std::vector<PlyProperty>& prop) |
|
{ |
|
if (ActionType == 0) //vertex |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<Container>(m, name); |
|
for (size_t i = 0; i < prop.size(); i++) |
|
AddVertexAttribDescriptor<Container, typename Container::ScalarType, 1>(prop[i].name, prop[i].type, &h[0][i]); |
|
} |
|
else if (ActionType == 1) //Edge |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerEdgeAttribute<Container>(m, name); |
|
for (size_t i = 0; i < prop.size(); i++) |
|
AddEdgeAttribDescriptor<Container, typename Container::ScalarType, 1>(prop[i].name, prop[i].type, &h[0][i]); |
|
} |
|
else if (ActionType == 2) //Face |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerFaceAttribute<Container>(m, name); |
|
for (size_t i = 0; i < prop.size(); i++) |
|
AddFaceAttribDescriptor<Container, typename Container::ScalarType, 1>(prop[i].name, prop[i].type, &h[0][i]); |
|
} |
|
} |
|
|
|
|
|
template <size_t ActionType, class Container, class Type> |
|
void AddListAttrib(MeshType& m, const std::string& name, PlyType& type) |
|
{ |
|
if (ActionType == 0) //vertex |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerVertexAttribute<Container>(m, name); |
|
AddVertexAttribDescriptor<Container, Type, 0>(name, type, h._handle->DataBegin()); |
|
} |
|
else if (ActionType == 1) //Edge |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerEdgeAttribute<Container>(m, name); |
|
AddEdgeAttribDescriptor<Container, Type, 0>(name, type, h._handle->DataBegin()); |
|
} |
|
else if (ActionType == 2) //Face |
|
{ |
|
auto h = vcg::tri::Allocator<MeshType>::template GetPerFaceAttribute<Container>(m, name); |
|
AddFaceAttribDescriptor<Container, Type, 0>(name, type, h._handle->DataBegin()); |
|
} |
|
} |
|
|
|
|
|
template <size_t ActionType> |
|
bool AddCustomAttrib(MeshType& m, std::set<PointerToAttribute>& ptrAttrib, PlyElement* elem, ElementDescriptor::PropertyDescriptor& attrib) |
|
{ |
|
//Custom attribute with already a data descriptor |
|
std::set<std::string> validCustomAttrib; |
|
for (size_t i = 0; i < attrib.size(); i++) |
|
{ |
|
if (attrib[i]->base == NULL) |
|
{ |
|
typename std::set<PointerToAttribute>::iterator ai; |
|
for (ai = ptrAttrib.begin(); ai != ptrAttrib.end(); ++ai) |
|
{ |
|
if (attrib[i]->name == (*ai)._name) |
|
{ |
|
attrib[i]->base = ai->_handle->DataBegin(); |
|
validCustomAttrib.insert(attrib[i]->name); |
|
break; |
|
} |
|
} |
|
} |
|
else |
|
validCustomAttrib.insert(attrib[i]->name); |
|
} |
|
//Get custom properties without a data descriptor |
|
std::map<std::string, std::pair<std::vector<PlyProperty>, int>> customAttribName; |
|
std::vector<std::string> attribName((*elem).propVec.size()); |
|
for (size_t i = 0; i < (*elem).propVec.size(); i++) |
|
{ |
|
if ((*elem).propVec[i].elem == NNP_UNKNOWN_ENTITY) |
|
{ |
|
if (validCustomAttrib.find((*elem).propVec[i].name) == validCustomAttrib.end()) |
|
{ |
|
std::size_t found = (*elem).propVec[i].name.find_first_of(separator); |
|
if (found != std::string::npos) |
|
{ |
|
attribName[i] = (*elem).propVec[i].name.substr(0, found); |
|
std::string suffix = (*elem).propVec[i].name.substr(found+1); |
|
std::map<std::string, int>::const_iterator it1, it2; |
|
it1 = pointSuffixMap.find(suffix); |
|
it2 = colorSuffixMap.find(suffix); |
|
if (it1 != pointSuffixMap.cend()) |
|
customAttribName[attribName[i]].second |= (1 << (*it1).second); |
|
else if (it2 != colorSuffixMap.cend()) |
|
customAttribName[attribName[i]].second |= (1 << ((*it2).second + 4)); |
|
} |
|
else |
|
attribName[i] = (*elem).propVec[i].name; |
|
customAttribName[attribName[i]].first.push_back((*elem).propVec[i]); |
|
|
|
} |
|
} |
|
} |
|
//Create the attribute and the data descriptor |
|
std::map<std::string, std::pair<std::vector<PlyProperty>, int>>::iterator mapIter; |
|
for (mapIter = customAttribName.begin(); mapIter != customAttribName.end(); mapIter++) |
|
{ |
|
unsigned int bitType = 0; |
|
std::vector<PlyProperty> tempProp((*mapIter).second.first.size()); |
|
int checkMask = (1 << (*mapIter).second.first.size()) - 1; |
|
for (size_t i = 0; i < (*mapIter).second.first.size(); i++) |
|
{ |
|
PlyProperty& p = (*mapIter).second.first[i]; |
|
bitType |= p.type; |
|
std::size_t found = p.name.find_first_of(separator); |
|
if (found != std::string::npos) |
|
{ |
|
std::string suffix = p.name.substr(found + 1); |
|
if ((*mapIter).second.second == checkMask) |
|
tempProp[(*pointSuffixMap.find(suffix)).second] = p; |
|
else if ((*mapIter).second.second == (checkMask << 4)) |
|
tempProp[(*colorSuffixMap.find(suffix)).second] = p; |
|
else |
|
tempProp[i] = p; |
|
} |
|
else |
|
tempProp[i] = p; |
|
} |
|
unsigned int r = (bitType & (~tempProp[0].type)); (void)r; |
|
if (tempProp.size() > 1 && ((bitType & (~tempProp[0].type)) == 0)) |
|
{ |
|
if (tempProp.size() == 2) |
|
{ |
|
switch (tempProp[0].type) |
|
{ |
|
case NNP_FLOAT32: AddPointAttrib<ActionType, vcg::Point2f>(m, (*mapIter).first, tempProp); break; |
|
case NNP_FLOAT64: AddPointAttrib<ActionType, vcg::Point2d>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT8: AddPointAttrib<ActionType, vcg::Point2<char>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT16: AddPointAttrib<ActionType, vcg::Point2s>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT32: AddPointAttrib<ActionType, vcg::Point2i>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT8: AddPointAttrib<ActionType, vcg::Point2<unsigned char>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT16: AddPointAttrib<ActionType, vcg::Point2<unsigned short>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT32: AddPointAttrib<ActionType, vcg::Point2<unsigned int>>(m, (*mapIter).first, tempProp); break; |
|
default: assert(0); |
|
} |
|
} |
|
else if (tempProp.size() == 3) |
|
{ |
|
switch (tempProp[0].type) |
|
{ |
|
case NNP_FLOAT32: AddPointAttrib<ActionType, vcg::Point3f>(m, (*mapIter).first, tempProp); break; |
|
case NNP_FLOAT64: AddPointAttrib<ActionType, vcg::Point3d>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT8: AddPointAttrib<ActionType, vcg::Point3<char>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT16: AddPointAttrib<ActionType, vcg::Point3s>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT32: AddPointAttrib<ActionType, vcg::Point3i>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT8: AddPointAttrib<ActionType, vcg::Point3<unsigned char>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT16: AddPointAttrib<ActionType, vcg::Point3<unsigned short>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT32: AddPointAttrib<ActionType, vcg::Point3<unsigned int>>(m, (*mapIter).first, tempProp); break; |
|
default: assert(0); |
|
} |
|
} |
|
else if (tempProp.size() == 4 && (*mapIter).second.second != (checkMask << 4)) |
|
{ |
|
switch (tempProp[0].type) |
|
{ |
|
case NNP_FLOAT32: AddPointAttrib<ActionType, vcg::Point4d>(m, (*mapIter).first, tempProp); break; |
|
case NNP_FLOAT64: AddPointAttrib<ActionType, vcg::Point4d>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT8: AddPointAttrib<ActionType, vcg::Point4<char>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT16: AddPointAttrib<ActionType, vcg::Point4s>(m, (*mapIter).first, tempProp); break; |
|
case NNP_INT32: AddPointAttrib<ActionType, vcg::Point4i>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT8: AddPointAttrib<ActionType, vcg::Point4<unsigned char>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT16: AddPointAttrib<ActionType, vcg::Point4<unsigned short>>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT32: AddPointAttrib<ActionType, vcg::Point4<unsigned int>>(m, (*mapIter).first, tempProp); break; |
|
default: assert(0); |
|
} |
|
} |
|
else if (tempProp.size() == 4) |
|
{ |
|
switch (tempProp[0].type) |
|
{ |
|
case NNP_INT8: |
|
case NNP_INT16: |
|
case NNP_INT32: |
|
case NNP_UINT16: |
|
case NNP_UINT32: |
|
case NNP_FLOAT32: AddPointAttrib<ActionType, vcg::Color4f>(m, (*mapIter).first, tempProp); break; |
|
case NNP_FLOAT64: AddPointAttrib<ActionType, vcg::Color4d>(m, (*mapIter).first, tempProp); break; |
|
case NNP_UINT8: AddPointAttrib<ActionType, vcg::Color4b>(m, (*mapIter).first, tempProp); break; |
|
default: assert(0); |
|
} |
|
} |
|
} |
|
else |
|
{ |
|
for (size_t i = 0; i < tempProp.size(); i++) |
|
{ |
|
switch (tempProp[i].type) |
|
{ |
|
case NNP_FLOAT32: AddScalarAttrib<ActionType, float>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_FLOAT64: AddScalarAttrib<ActionType, double>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_INT8: AddScalarAttrib<ActionType, char>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_INT16: AddScalarAttrib<ActionType, short>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_INT32: AddScalarAttrib<ActionType, int>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_UINT8: AddScalarAttrib<ActionType, unsigned char>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_UINT16: AddScalarAttrib<ActionType, unsigned short>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_UINT32: AddScalarAttrib<ActionType, unsigned int>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_LIST_UINT8_UINT32: |
|
case NNP_LIST_INT8_UINT32: AddListAttrib<ActionType, std::vector<unsigned int>, unsigned int>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_LIST_UINT8_INT32: |
|
case NNP_LIST_INT8_INT32: AddListAttrib<ActionType, std::vector<int>, int>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_LIST_UINT8_FLOAT32: |
|
case NNP_LIST_INT8_FLOAT32: AddListAttrib<ActionType, std::vector<float>, float>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_LIST_UINT8_FLOAT64: |
|
case NNP_LIST_INT8_FLOAT64: AddListAttrib<ActionType, std::vector<double>, double>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_LIST_UINT8_UINT8: |
|
case NNP_LIST_INT8_UINT8: AddListAttrib<ActionType, std::vector<unsigned char>, unsigned char>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_LIST_UINT8_INT8: |
|
case NNP_LIST_INT8_INT8: AddListAttrib<ActionType, std::vector<char>, char>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_LIST_UINT8_UINT16: |
|
case NNP_LIST_INT8_UINT16: AddListAttrib<ActionType, std::vector<unsigned short>, unsigned short>(m, tempProp[i].name, tempProp[i].type); break; |
|
case NNP_LIST_UINT8_INT16: |
|
case NNP_LIST_INT8_INT16: AddListAttrib<ActionType, std::vector<short>, short>(m, tempProp[i].name, tempProp[i].type); break; |
|
default: assert(0); |
|
} |
|
} |
|
} |
|
} |
|
return true; |
|
} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
template <class T> |
|
struct OcfManager |
|
{ |
|
typedef typename T::VertexType VType; |
|
typedef typename T::FaceType FType; |
|
typedef typename T::EdgeType EType; |
|
|
|
|
|
template <bool f = std::is_same<typename T::VertContainer, vcg::vertex::vector_ocf<VType>>::value> |
|
static unsigned int EnableVertexOcf(typename T::VertContainer& cont, unsigned int mask) |
|
{ |
|
unsigned int enabledMask = 0; |
|
if constexpr (f) |
|
{ |
|
if ((mask & BitMask::IO_VERTNORMAL) && VType::HasNormalOcf() && !cont.IsNormalEnabled()) |
|
{ |
|
cont.EnableNormal(); |
|
enabledMask |= BitMask::IO_VERTNORMAL; |
|
} |
|
if ((mask & BitMask::IO_VERTCOLOR) && VType::HasColorOcf() && !cont.IsColorEnabled()) |
|
{ |
|
cont.EnableColor(); |
|
enabledMask |= BitMask::IO_VERTCOLOR; |
|
} |
|
if ((mask & BitMask::IO_VERTQUALITY) && VType::HasQualityOcf() && !cont.IsQualityEnabled()) |
|
{ |
|
cont.EnableQuality(); |
|
enabledMask |= BitMask::IO_VERTQUALITY; |
|
} |
|
if ((mask & BitMask::IO_VERTCURV) && VType::HasCurvatureOcf() && !cont.IsCurvatureEnabled()) |
|
{ |
|
cont.EnableCurvature(); |
|
enabledMask |= BitMask::IO_VERTCURV; |
|
} |
|
if ((mask & BitMask::IO_VERTCURVDIR) && VType::HasCurvatureDirOcf() && !cont.IsCurvatureDirEnabled()) |
|
{ |
|
cont.EnableCurvatureDir(); |
|
enabledMask |= BitMask::IO_VERTCURVDIR; |
|
} |
|
if ((mask & BitMask::IO_VERTRADIUS) && VType::HasRadiusOcf() && !cont.IsRadiusEnabled()) |
|
{ |
|
cont.EnableRadius(); |
|
enabledMask |= BitMask::IO_VERTRADIUS; |
|
} |
|
if ((mask & BitMask::IO_VERTTEXCOORD) && VType::HasTexCoordOcf() && !cont.IsTexCoordEnabled()) |
|
{ |
|
cont.EnableTexCoord(); |
|
enabledMask |= BitMask::IO_VERTTEXCOORD; |
|
} |
|
} |
|
return enabledMask; |
|
} |
|
|
|
template <bool f = std::is_same<typename T::FaceContainer, vcg::face::vector_ocf<FType>>::value> |
|
static unsigned int EnableFaceOcf(typename T::FaceContainer& cont, unsigned int mask) |
|
{ |
|
unsigned int enabledMask = 0; |
|
if constexpr (f) |
|
{ |
|
if ((mask & BitMask::IO_FACENORMAL) && FType::HasNormalOcf() && !cont.IsNormalEnabled()) |
|
{ |
|
cont.EnableNormal(); |
|
enabledMask |= BitMask::IO_FACENORMAL; |
|
} |
|
if ((mask & BitMask::IO_FACECOLOR) && FType::HasColorOcf() && !cont.IsColorEnabled()) |
|
{ |
|
cont.EnableColor(); |
|
enabledMask |= BitMask::IO_FACECOLOR; |
|
} |
|
if ((mask & BitMask::IO_FACEQUALITY) && FType::HasQualityOcf() && !cont.IsQualityEnabled()) |
|
{ |
|
cont.EnableQuality(); |
|
enabledMask |= BitMask::IO_FACEQUALITY; |
|
} |
|
if ((mask & BitMask::IO_FACECURVDIR) && FType::HasCurvatureDirOcf() && !cont.IsCurvatureDirEnabled()) |
|
{ |
|
cont.EnableCurvatureDir(); |
|
enabledMask |= BitMask::IO_FACECURVDIR; |
|
} |
|
if ((mask & BitMask::IO_WEDGCOLOR) && FType::HasWedgeColorOcf() && !cont.IsWedgeColorEnabled()) |
|
{ |
|
cont.EnableWedgeColor(); |
|
enabledMask |= BitMask::IO_WEDGCOLOR; |
|
} |
|
if ((mask & BitMask::IO_WEDGNORMAL) && FType::HasWedgeNormalOcf() && !cont.IsWedgeNormalEnabled()) |
|
{ |
|
cont.EnableWedgeNormal(); |
|
enabledMask |= BitMask::IO_WEDGNORMAL; |
|
} |
|
if ((mask & BitMask::IO_WEDGTEXCOORD) && FType::HasWedgeTexCoordOcf() && !cont.IsWedgeTexCoordEnabled()) |
|
{ |
|
cont.EnableWedgeTexCoord(); |
|
enabledMask |= BitMask::IO_WEDGTEXCOORD; |
|
} |
|
if ((mask & BitMask::IO_WEDGTEXMULTI) && FType::HasWedgeTexCoordOcf()) |
|
{ |
|
if (!cont.IsWedgeTexCoordEnabled()) |
|
cont.EnableWedgeTexCoord(); |
|
enabledMask |= BitMask::IO_WEDGTEXMULTI; |
|
} |
|
} |
|
return enabledMask; |
|
} |
|
|
|
|
|
template <bool f = std::is_same<typename T::VertContainer, vcg::vertex::vector_ocf<VType>>::value> |
|
static unsigned int VertexOcfMask(typename T::VertContainer& cont) |
|
{ |
|
unsigned int enabledMask = 0; |
|
if constexpr(f) |
|
{ |
|
if (VType::HasNormalOcf() && cont.IsNormalEnabled()) |
|
enabledMask |= BitMask::IO_VERTNORMAL; |
|
if (VType::HasColorOcf() && cont.IsColorEnabled()) |
|
enabledMask |= BitMask::IO_VERTCOLOR; |
|
if (VType::HasQualityOcf() && cont.IsQualityEnabled()) |
|
enabledMask |= BitMask::IO_VERTQUALITY; |
|
if (VType::HasCurvatureOcf() && cont.IsCurvatureEnabled()) |
|
enabledMask |= BitMask::IO_VERTCURV; |
|
if (VType::HasCurvatureDirOcf() && cont.IsCurvatureDirEnabled()) |
|
enabledMask |= BitMask::IO_VERTCURVDIR; |
|
if (VType::HasRadiusOcf() && cont.IsRadiusEnabled()) |
|
enabledMask |= BitMask::IO_VERTRADIUS; |
|
if (VType::HasTexCoordOcf() && cont.IsTexCoordEnabled()) |
|
enabledMask |= BitMask::IO_VERTTEXCOORD; |
|
} |
|
return enabledMask; |
|
} |
|
|
|
template <bool f = std::is_same<typename T::FaceContainer, vcg::face::vector_ocf<FType>>::value> |
|
static unsigned int FaceOcfMask(typename T::FaceContainer& cont) |
|
{ |
|
unsigned int enabledMask = 0; |
|
if constexpr (f) |
|
{ |
|
if (FType::HasNormalOcf() && cont.IsNormalEnabled()) |
|
enabledMask |= BitMask::IO_FACENORMAL; |
|
if (FType::HasColorOcf() && cont.IsColorEnabled()) |
|
enabledMask |= BitMask::IO_FACECOLOR; |
|
if (FType::HasQualityOcf() && cont.IsQualityEnabled()) |
|
enabledMask |= BitMask::IO_FACEQUALITY; |
|
if (FType::HasCurvatureDirOcf() && cont.IsCurvatureDirEnabled()) |
|
enabledMask |= BitMask::IO_FACECURVDIR; |
|
if (FType::HasWedgeColorOcf() && cont.IsWedgeColorEnabled()) |
|
enabledMask |= BitMask::IO_WEDGCOLOR; |
|
if (FType::HasWedgeNormalOcf() && cont.IsWedgeNormalEnabled()) |
|
enabledMask |= BitMask::IO_WEDGNORMAL; |
|
if (FType::HasWedgeTexCoordOcf() && cont.IsWedgeTexCoordEnabled()) |
|
{ |
|
enabledMask |= BitMask::IO_WEDGTEXCOORD; |
|
enabledMask |= BitMask::IO_WEDGTEXMULTI; |
|
} |
|
} |
|
return enabledMask; |
|
} |
|
}; |
|
|
|
|
|
static unsigned int GetFileBitMask(nanoply::Info& info) |
|
{ |
|
unsigned int mask = 0; |
|
for (size_t j = 0; j < info.elemVec.size(); j++) |
|
{ |
|
PlyElement& elem = info.elemVec[j]; |
|
if (elem.plyElem == PlyElemEntity::NNP_VERTEX_ELEM) |
|
{ |
|
for (size_t i = 0; i < elem.propVec.size(); i++) |
|
{ |
|
switch (elem.propVec[i].elem) |
|
{ |
|
case NNP_PXYZ: mask |= BitMask::IO_VERTCOORD; break; |
|
case NNP_NXYZ: mask |= BitMask::IO_VERTNORMAL; break; |
|
case NNP_CRGB: |
|
case NNP_CRGBA: mask |= BitMask::IO_VERTCOLOR; break; |
|
case NNP_BITFLAG: mask |= BitMask::IO_VERTFLAGS; break; |
|
case NNP_QUALITY: mask |= BitMask::IO_VERTQUALITY; break; |
|
case NNP_DENSITY: mask |= BitMask::IO_VERTRADIUS; break; |
|
case NNP_TEXTURE2D: |
|
case NNP_TEXTURE3D: mask |= BitMask::IO_VERTTEXCOORD; break; |
|
// case NNP_KH: |
|
// case NNP_KG: mask |= BitMask::IO_VERTCURV; break; |
|
case NNP_K1: |
|
case NNP_K2: |
|
case NNP_K1DIR: |
|
case NNP_K2DIR: mask |= BitMask::IO_VERTCURVDIR; break; |
|
case NNP_UNKNOWN_ENTITY: mask |= BitMask::IO_VERTATTRIB; break; |
|
default: assert(0); |
|
} |
|
} |
|
} |
|
else if (elem.plyElem == PlyElemEntity::NNP_EDGE_ELEM) |
|
{ |
|
for (size_t i = 0; i < elem.propVec.size(); i++) |
|
{ |
|
switch (elem.propVec[i].elem) |
|
{ |
|
case NNP_EDGE_V1: |
|
case NNP_EDGE_V2: mask |= BitMask::IO_EDGEINDEX; break; |
|
case NNP_CRGB: |
|
case NNP_CRGBA: mask |= BitMask::IO_EDGECOLOR; break; |
|
case NNP_BITFLAG: mask |= BitMask::IO_EDGEFLAGS; break; |
|
case NNP_QUALITY: mask |= BitMask::IO_EDGEQUALITY; break; |
|
case NNP_UNKNOWN_ENTITY: mask |= BitMask::IO_EDGEATTRIB; break; |
|
default: assert(0); |
|
} |
|
} |
|
} |
|
else if (elem.plyElem == PlyElemEntity::NNP_FACE_ELEM) |
|
{ |
|
for (size_t i = 0; i < elem.propVec.size(); i++) |
|
{ |
|
switch (elem.propVec[i].elem) |
|
{ |
|
case NNP_FACE_VERTEX_LIST: mask |= BitMask::IO_FACEINDEX; break; |
|
case NNP_NXYZ: mask |= BitMask::IO_FACENORMAL; break; |
|
case NNP_CRGB: |
|
case NNP_CRGBA: mask |= BitMask::IO_FACECOLOR; break; |
|
case NNP_BITFLAG: mask |= BitMask::IO_FACEFLAGS; break; |
|
case NNP_QUALITY: mask |= BitMask::IO_FACEQUALITY; break; |
|
case NNP_K1: |
|
case NNP_K2: |
|
case NNP_K1DIR: |
|
case NNP_K2DIR: mask |= BitMask::IO_FACECURVDIR; break; |
|
case NNP_FACE_WEDGE_COLOR: mask |= BitMask::IO_WEDGCOLOR; break; |
|
case NNP_FACE_WEDGE_NORMAL: mask |= BitMask::IO_WEDGNORMAL; break; |
|
case NNP_FACE_WEDGE_TEX: mask |= BitMask::IO_WEDGTEXCOORD; break; |
|
case NNP_TEXTUREINDEX: mask |= BitMask::IO_WEDGTEXMULTI; break; |
|
case NNP_UNKNOWN_ENTITY: mask |= BitMask::IO_FACEATTRIB; break; |
|
default: assert(0); |
|
} |
|
} |
|
} |
|
else if (elem.plyElem == PlyElemEntity::NNP_UNKNOWN_ELEM) |
|
{ |
|
if (elem.name == "camera") |
|
mask |= BitMask::IO_CAMERA; |
|
else |
|
mask |= BitMask::IO_MESHATTRIB; |
|
} |
|
} |
|
return mask; |
|
} |
|
|
|
|
|
|
|
static int LoadModel(const char* filename, MeshType& mesh, unsigned int bitMask, CustomAttributeDescriptor& custom) |
|
{ |
|
nanoply::Info info(filename); |
|
if (info.errInfo != nanoply::NNP_OK) |
|
return info.errInfo; |
|
|
|
unsigned int headerMask = GetFileBitMask(info); |
|
bitMask &= headerMask; |
|
unsigned int ocfVertexMask = OcfManager<MeshType>::EnableVertexOcf(mesh.vert, bitMask); |
|
unsigned int ocfFaceMask = OcfManager<MeshType>::EnableFaceOcf(mesh.face, bitMask); |
|
|
|
//Camera |
|
ElementDescriptor cameraDescr(std::string("camera")); |
|
vcg::Point3<ScalarType> tra; |
|
vcg::Matrix44<ScalarType> rot; |
|
size_t count = info.GetElementCount(std::string("camera")); |
|
if (count > 0 && (bitMask & BitMask::IO_CAMERA)) |
|
{ |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("view_px"), &tra[0])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("view_py"), &tra[1])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("view_pz"), &tra[2])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("x_axisx"), &rot[0][0])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("x_axisy"), &rot[0][1])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("x_axisz"), &rot[0][2])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("y_axisx"), &rot[1][0])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("y_axisy"), &rot[1][1])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("y_axisz"), &rot[1][2])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("z_axisx"), &rot[2][0])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("z_axisy"), &rot[2][1])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("z_axisz"), &rot[2][2])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("focal"), &mesh.shot.Intrinsics.FocalMm)); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("scalex"), &mesh.shot.Intrinsics.PixelSizeMm[0])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("scaley"), &mesh.shot.Intrinsics.PixelSizeMm[1])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("centerx"), &mesh.shot.Intrinsics.CenterPx[0])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("centery"), &mesh.shot.Intrinsics.CenterPx[1])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<int, 1, int>(std::string("viewportx"), &mesh.shot.Intrinsics.ViewportPx[0])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<int, 1, int>(std::string("viewporty"), &mesh.shot.Intrinsics.ViewportPx[1])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("k1"), &mesh.shot.Intrinsics.k[0])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("k2"), &mesh.shot.Intrinsics.k[1])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("k3"), &mesh.shot.Intrinsics.k[2])); |
|
cameraDescr.dataDescriptor.push_back(new DataDescriptor<ScalarType, 1, ScalarType>(std::string("k4"), &mesh.shot.Intrinsics.k[3])); |
|
} |
|
|
|
//Vertex |
|
std::vector<std::string> nameList; |
|
VertexType::Name(nameList); |
|
ElementDescriptor vertexDescr(NNP_VERTEX_ELEM); |
|
count = info.GetVertexCount(); |
|
if (nameList.size() > 0 && count > 0) |
|
{ |
|
vcg::tri::Allocator<MeshType>::AddVertices(mesh, count); |
|
if ((bitMask & BitMask::IO_VERTCOORD) && VertexType::HasCoord()) |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 3, VertexCoordScalar>(NNP_PXYZ, (*mesh.vert.begin()).P().V())); |
|
if ((bitMask & BitMask::IO_VERTNORMAL) && vcg::tri::HasPerVertexNormal(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTNORMAL) |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexNormalType, 3, VertexNormScalar>(NNP_NXYZ, (*mesh.vert.begin()).N().V())); |
|
else |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 3, VertexNormScalar>(NNP_NXYZ, (*mesh.vert.begin()).N().V())); |
|
} |
|
if ((bitMask & BitMask::IO_VERTCOLOR) && vcg::tri::HasPerVertexColor(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTCOLOR) |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexColorType, 4, VertexColorScalar>(NNP_CRGBA, (*mesh.vert.begin()).C().V())); |
|
else |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 4, VertexColorScalar>(NNP_CRGBA, (*mesh.vert.begin()).C().V())); |
|
} |
|
if ((bitMask & BitMask::IO_VERTQUALITY) && vcg::tri::HasPerVertexQuality(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTQUALITY) |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexQuality, 1, VertexQuality>(NNP_QUALITY, &(*mesh.vert.begin()).Q())); |
|
else |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 1, VertexQuality>(NNP_QUALITY, &(*mesh.vert.begin()).Q())); |
|
} |
|
if ((bitMask & BitMask::IO_VERTFLAGS) && vcg::tri::HasPerVertexFlags(mesh)) |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 1, VertexFlag>(NNP_BITFLAG, &(*mesh.vert.begin()).Flags())); |
|
if ((bitMask & BitMask::IO_VERTRADIUS) && vcg::tri::HasPerVertexRadius(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTRADIUS) |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexRadius, 1, VertexRadius>(NNP_DENSITY, &(*mesh.vert.begin()).R())); |
|
else |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 1, VertexRadius>(NNP_DENSITY, &(*mesh.vert.begin()).R())); |
|
} |
|
if ((bitMask & BitMask::IO_VERTTEXCOORD) && vcg::tri::HasPerVertexTexCoord(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexTexCoordType, 2, VertexTexScalar>(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); |
|
else |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 2, VertexTexScalar>(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); |
|
} |
|
// if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) |
|
// { |
|
// if (ocfVertexMask & BitMask::IO_VERTCURV) |
|
// { |
|
// vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexCurType, 1, VertexCurScalar>(NNP_KG, &(*mesh.vert.begin()).Kg())); |
|
// vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexCurType, 1, VertexCurScalar>(NNP_KH, &(*mesh.vert.begin()).Kh())); |
|
// } |
|
// else |
|
// { |
|
// vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 1, VertexCurScalar>(NNP_KG, &(*mesh.vert.begin()).Kg())); |
|
// vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 1, VertexCurScalar>(NNP_KH, &(*mesh.vert.begin()).Kh())); |
|
// } |
|
// } |
|
if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTCURVDIR) |
|
{ |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexCurDirType, 1, VertexDirCurScalar>(NNP_K1, &(*mesh.vert.begin()).K1())); |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexCurDirType, 1, VertexDirCurScalar>(NNP_K2, &(*mesh.vert.begin()).K2())); |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexCurDirType, 3, VertexDirCurVecScalar>(NNP_K1DIR, (*mesh.vert.begin()).PD1().V())); |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexCurDirType, 3, VertexDirCurVecScalar>(NNP_K2DIR, (*mesh.vert.begin()).PD2().V())); |
|
} |
|
else |
|
{ |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 1, VertexDirCurScalar>(NNP_K1, &(*mesh.vert.begin()).K1())); |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 1, VertexDirCurScalar>(NNP_K2, &(*mesh.vert.begin()).K2())); |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 3, VertexDirCurVecScalar>(NNP_K1DIR, (*mesh.vert.begin()).PD1().V())); |
|
vertexDescr.dataDescriptor.push_back(new DataDescriptor<VertexType, 3, VertexDirCurVecScalar>(NNP_K2DIR, (*mesh.vert.begin()).PD2().V())); |
|
} |
|
} |
|
if (bitMask & BitMask::IO_VERTATTRIB) |
|
{ |
|
custom.AddVertexAttrib(mesh, mesh.vert_attr, info.GetVertexElement()); |
|
for (size_t i = 0; i < custom.vertexAttrib.size(); i++) |
|
{ |
|
if ((*custom.vertexAttrib[i]).base != NULL) |
|
vertexDescr.dataDescriptor.push_back(custom.vertexAttrib[i]); |
|
} |
|
} |
|
} |
|
|
|
//Edge |
|
nameList.clear(); |
|
EdgeType::Name(nameList); |
|
ElementDescriptor edgeDescr(NNP_EDGE_ELEM); |
|
count = info.GetEdgeCount(); |
|
std::vector<vcg::Point2i> edgeIndex; |
|
if (nameList.size() > 0 && count > 0) |
|
{ |
|
vcg::tri::Allocator<MeshType>::AddEdges(mesh, count); |
|
if ((bitMask & BitMask::IO_EDGEINDEX) && MeshType::EdgeType::HasVertexRef()) |
|
{ |
|
edgeIndex.resize(count); |
|
edgeDescr.dataDescriptor.push_back(new DataDescriptor<vcg::Point2i, 1, int>(NNP_EDGE_V1, &(*edgeIndex.begin()).V()[0])); |
|
edgeDescr.dataDescriptor.push_back(new DataDescriptor<vcg::Point2i, 1, int>(NNP_EDGE_V2, &(*edgeIndex.begin()).V()[1])); |
|
} |
|
if ((bitMask & BitMask::IO_EDGEQUALITY) && vcg::tri::HasPerEdgeQuality(mesh)) |
|
edgeDescr.dataDescriptor.push_back(new DataDescriptor<EdgeType, 1, EdgeQuality>(NNP_QUALITY, &(*mesh.edge.begin()).Q())); |
|
if ((bitMask & BitMask::IO_EDGECOLOR) && vcg::tri::HasPerEdgeColor(mesh)) |
|
edgeDescr.dataDescriptor.push_back(new DataDescriptor<EdgeType, 4, EdgeColorScalar>(NNP_CRGBA, (*mesh.edge.begin()).C().V())); |
|
if ((bitMask & BitMask::IO_EDGEFLAGS) && vcg::tri::HasPerEdgeFlags(mesh)) |
|
edgeDescr.dataDescriptor.push_back(new DataDescriptor<EdgeType, 1, EdgeFlag>(NNP_BITFLAG, &(*mesh.edge.begin()).Flags())); |
|
if (bitMask & BitMask::IO_EDGEATTRIB) |
|
{ |
|
custom.AddEdgeAttrib(mesh, mesh.edge_attr, info.GetEdgeElement()); |
|
for (size_t i = 0; i < custom.edgeAttrib.size(); i++) |
|
{ |
|
if ((*custom.edgeAttrib[i]).base != NULL) |
|
edgeDescr.dataDescriptor.push_back(custom.edgeAttrib[i]); |
|
} |
|
} |
|
} |
|
|
|
//Face |
|
nameList.clear(); |
|
FaceType::Name(nameList); |
|
ElementDescriptor faceDescr(NNP_FACE_ELEM); |
|
count = info.GetFaceCount(); |
|
std::vector<std::vector<unsigned int>> faceIndex; |
|
std::vector<vcg::ndim::Point<6, FaceTexScalar>> wedgeTexCoord; |
|
if (nameList.size() > 0 && count > 0) |
|
{ |
|
vcg::tri::Allocator<MeshType>::AddFaces(mesh, count); |
|
if ((bitMask & BitMask::IO_FACEINDEX) && FaceType::HasVertexRef()) |
|
{ |
|
faceIndex.resize(count); |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<std::vector<unsigned int>,0, unsigned int>(NNP_FACE_VERTEX_LIST, &faceIndex[0])); |
|
} |
|
if ((bitMask & BitMask::IO_FACEFLAGS) && vcg::tri::HasPerFaceFlags(mesh)) |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 1, FaceFlag>(NNP_BITFLAG, &(*mesh.face.begin()).Flags())); |
|
if ((bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_FACECOLOR) |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceColorType, 4, FaceColorScalar>(NNP_CRGBA, (*mesh.face.begin()).C().V())); |
|
else |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 4, FaceColorScalar>(NNP_CRGBA, (*mesh.face.begin()).C().V())); |
|
} |
|
if ((bitMask & BitMask::IO_FACEQUALITY) && vcg::tri::HasPerFaceQuality(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_FACEQUALITY) |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceQuality, 1, FaceQuality>(NNP_QUALITY, &(*mesh.face.begin()).Q())); |
|
else |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 1, FaceQuality>(NNP_QUALITY, &(*mesh.face.begin()).Q())); |
|
} |
|
if ((bitMask & BitMask::IO_FACENORMAL) && vcg::tri::HasPerFaceNormal(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_FACENORMAL) |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceNormalType, 3, FaceNormScalar>(NNP_NXYZ, (*mesh.face.begin()).N().V())); |
|
else |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 3, FaceNormScalar>(NNP_NXYZ, (*mesh.face.begin()).N().V())); |
|
} |
|
if ((bitMask & BitMask::IO_FACECURVDIR) && vcg::tri::HasPerFaceCurvatureDir(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_FACECURVDIR) |
|
{ |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceCurDirType, 1, FaceDirCurScalar>(NNP_K1, &(*mesh.face.begin()).K1())); |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceCurDirType, 1, FaceDirCurScalar>(NNP_K2, &(*mesh.face.begin()).K2())); |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceCurDirType, 3, FaceDirCurVecScalar>(NNP_K1DIR, (*mesh.face.begin()).PD1().V())); |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceCurDirType, 3, FaceDirCurVecScalar>(NNP_K2DIR, (*mesh.face.begin()).PD2().V())); |
|
} |
|
else |
|
{ |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 1, FaceDirCurScalar>(NNP_K1, &(*mesh.face.begin()).K1())); |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 1, FaceDirCurScalar>(NNP_K2, &(*mesh.face.begin()).K2())); |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 3, FaceDirCurVecScalar>(NNP_K1DIR, (*mesh.face.begin()).PD1().V())); |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 3, FaceDirCurVecScalar>(NNP_K2DIR, (*mesh.face.begin()).PD2().V())); |
|
} |
|
} |
|
if (((bitMask & BitMask::IO_WEDGTEXCOORD) || (bitMask & BitMask::IO_WEDGTEXMULTI)) && vcg::tri::HasPerWedgeTexCoord(mesh)) |
|
{ |
|
wedgeTexCoord.resize(count); |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<vcg::ndim::Point<6, FaceTexScalar>, 6, FaceTexScalar>(NNP_FACE_WEDGE_TEX, (*wedgeTexCoord.begin()).V())); |
|
} |
|
if ((bitMask & BitMask::IO_WEDGTEXMULTI) && vcg::tri::HasPerWedgeTexCoord(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_WEDGTEXMULTI) |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceTexCoordType, 1, short>(NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N())); |
|
else |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 1, short>(NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N())); |
|
} |
|
if ((bitMask & BitMask::IO_WEDGCOLOR) && vcg::tri::HasPerWedgeColor(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_WEDGCOLOR) |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<WedgeColorType, 12, WedgeColorScalar>(NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V())); |
|
else |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 12, WedgeColorScalar>(NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V())); |
|
} |
|
if ((bitMask & BitMask::IO_WEDGNORMAL) && vcg::tri::HasPerWedgeNormal(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_WEDGNORMAL) |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<WedgeNormalType, 9, WedgeNormalScalar>(NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V())); |
|
else |
|
faceDescr.dataDescriptor.push_back(new DataDescriptor<FaceType, 9, WedgeNormalScalar>(NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V())); |
|
} |
|
if (bitMask & BitMask::IO_FACEATTRIB) |
|
{ |
|
custom.AddFaceAttrib(mesh, mesh.face_attr, info.GetFaceElement()); |
|
for (size_t i = 0; i < custom.faceAttrib.size(); i++) |
|
{ |
|
if ((*custom.faceAttrib[i]).base != NULL) |
|
faceDescr.dataDescriptor.push_back(custom.faceAttrib[i]); |
|
} |
|
} |
|
} |
|
|
|
std::vector<ElementDescriptor*> meshDescr; |
|
meshDescr.push_back(&cameraDescr); |
|
meshDescr.push_back(&vertexDescr); |
|
meshDescr.push_back(&edgeDescr); |
|
meshDescr.push_back(&faceDescr); |
|
|
|
//Mesh attribute |
|
if ((bitMask & BitMask::IO_MESHATTRIB)) |
|
{ |
|
typename CustomAttributeDescriptor::MapMeshAttribIter iter = custom.meshAttrib.begin(); |
|
for (; iter != custom.meshAttrib.end(); iter++) |
|
{ |
|
std::string name((*iter).first); |
|
meshDescr.push_back(new ElementDescriptor(name)); |
|
count = info.GetElementCount(name); |
|
if (count > 0) |
|
{ |
|
meshDescr.back()->dataDescriptor = (*iter).second; |
|
} |
|
} |
|
|
|
} |
|
if (!OpenModel(info, meshDescr)) |
|
return info.errInfo; |
|
|
|
mesh.shot.SetViewPoint(tra); |
|
mesh.shot.Extrinsics.SetRot(rot); |
|
bool triangleMesh = true; |
|
for (size_t i = 0; i < faceIndex.size(); i++) |
|
if (faceIndex[i].size() > 3) |
|
triangleMesh = false; |
|
|
|
if (!triangleMesh && !vcg::tri::HasPolyInfo(mesh)) |
|
{ |
|
bool hasFaceFlags = (bitMask & BitMask::IO_FACEFLAGS) && vcg::tri::HasPerFaceFlags(mesh); |
|
bool hasFaceColor = (bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh); |
|
bool hasFaceQuality = (bitMask & BitMask::IO_FACEQUALITY) && vcg::tri::HasPerFaceQuality(mesh); |
|
bool hasFaceNormal = (bitMask & BitMask::IO_FACENORMAL) && vcg::tri::HasPerFaceNormal(mesh); |
|
for (size_t i = 0; i < faceIndex.size(); i++) |
|
{ |
|
if (faceIndex[i].size() >= 3) |
|
{ |
|
for (int j = 0; j < 3; j++) |
|
mesh.face[i].V(j) = &mesh.vert[faceIndex[i][j]]; |
|
if (hasFaceFlags) |
|
mesh.face[i].SetF(2); |
|
FaceIterator fi = vcg::tri::Allocator<MeshType>::AddFaces(mesh, faceIndex[i].size() - 3); |
|
for (size_t j = 3; j < faceIndex[i].size(); j++) |
|
{ |
|
(*fi).V(0) = &mesh.vert[faceIndex[i][0]]; |
|
(*fi).V(1) = &mesh.vert[faceIndex[i][j - 1]]; |
|
(*fi).V(2) = &mesh.vert[faceIndex[i][j]]; |
|
if (hasFaceFlags) |
|
{ |
|
(*fi).SetFlags(mesh.face[i].Flags()); |
|
(*fi).SetF(0); |
|
if (j == faceIndex[i].size() - 1) |
|
(*fi).ClearF(2); |
|
} |
|
if (hasFaceColor) |
|
(*fi).C() = mesh.face[i].C(); |
|
if (hasFaceQuality) |
|
(*fi).Q() = mesh.face[i].Q(); |
|
if (hasFaceNormal) |
|
(*fi).N() = mesh.face[i].N(); |
|
fi++; |
|
} |
|
} |
|
else |
|
mesh.face[i].V(0) = mesh.face[i].V(1) = mesh.face[i].V(2) = &mesh.vert[0]; |
|
} |
|
} |
|
else |
|
{ |
|
for (size_t i = 0; i < faceIndex.size(); i++) |
|
{ |
|
mesh.face[i].Alloc(faceIndex[i].size()); |
|
for (size_t j = 0; j < faceIndex[i].size(); j++) |
|
mesh.face[i].V(j) = &mesh.vert[faceIndex[i][j]]; |
|
} |
|
for (size_t i = 0; i < wedgeTexCoord.size(); i++) |
|
{ |
|
for (int j = 0; j < 3; j++) |
|
{ |
|
mesh.face[i].WT(j).U() = wedgeTexCoord[i][j * 2]; |
|
mesh.face[i].WT(j).V() = wedgeTexCoord[i][j * 2 + 1]; |
|
mesh.face[i].WT(j).N() = mesh.face[i].WT(0).N(); |
|
} |
|
} |
|
} |
|
|
|
for (size_t i = 0; i < edgeIndex.size(); i++) |
|
{ |
|
mesh.edge[i].V(0) = &mesh.vert[edgeIndex[i].X()]; |
|
mesh.edge[i].V(1) = &mesh.vert[edgeIndex[i].Y()]; |
|
} |
|
|
|
for (size_t i = 0; i < cameraDescr.dataDescriptor.size(); i++) |
|
delete cameraDescr.dataDescriptor[i]; |
|
for (size_t i = 0; i < vertexDescr.dataDescriptor.size(); i++) |
|
if (vertexDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) |
|
delete vertexDescr.dataDescriptor[i]; |
|
for (size_t i = 0; i < edgeDescr.dataDescriptor.size(); i++) |
|
if (edgeDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) |
|
delete edgeDescr.dataDescriptor[i]; |
|
for (size_t i = 0; i < faceDescr.dataDescriptor.size(); i++) |
|
if (faceDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) |
|
delete faceDescr.dataDescriptor[i]; |
|
mesh.textures = info.textureFile; |
|
return info.errInfo; |
|
} |
|
|
|
|
|
static int LoadModel(const char* filename, MeshType& mesh, unsigned int bitMask) |
|
{ |
|
CustomAttributeDescriptor custom; |
|
return LoadModel(filename, mesh, bitMask, custom); |
|
} |
|
|
|
|
|
static bool SaveModel(const char* filename, MeshType& mesh, unsigned int bitMask, CustomAttributeDescriptor& custom, bool binary) |
|
{ |
|
unsigned int ocfVertexMask = OcfManager<MeshType>::VertexOcfMask(mesh.vert); |
|
unsigned int ocfFaceMask = OcfManager<MeshType>::FaceOcfMask(mesh.face); |
|
|
|
//Camera |
|
std::vector<PlyProperty> cameraProp; |
|
ElementDescriptor cameraDescr(std::string("camera")); |
|
vcg::Point3<ScalarType> tra = mesh.shot.Extrinsics.Tra(); |
|
vcg::Matrix44<ScalarType> rot = mesh.shot.Extrinsics.Rot(); |
|
if (bitMask & BitMask::IO_CAMERA) |
|
{ |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("view_px"), &tra[0]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("view_py"), &tra[1]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("view_pz"), &tra[2]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("x_axisx"), &rot[0][0]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("x_axisy"), &rot[0][1]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("x_axisz"), &rot[0][2]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("y_axisx"), &rot[1][0]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("y_axisy"), &rot[1][1]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("y_axisz"), &rot[1][2]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("z_axisx"), &rot[2][0]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("z_axisy"), &rot[2][1]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("z_axisz"), &rot[2][2]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("focal"), &mesh.shot.Intrinsics.FocalMm); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("scalex"), &mesh.shot.Intrinsics.PixelSizeMm[0]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("scaley"), &mesh.shot.Intrinsics.PixelSizeMm[1]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("centerx"), &mesh.shot.Intrinsics.CenterPx[0]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("centery"), &mesh.shot.Intrinsics.CenterPx[1]); |
|
PushDescriport<int, int, 1>(cameraProp, cameraDescr, std::string("viewportx"), &mesh.shot.Intrinsics.ViewportPx[0]); |
|
PushDescriport<int, int, 1>(cameraProp, cameraDescr, std::string("viewporty"), &mesh.shot.Intrinsics.ViewportPx[1]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("k1"), &mesh.shot.Intrinsics.k[0]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("k2"), &mesh.shot.Intrinsics.k[1]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("k3"), &mesh.shot.Intrinsics.k[2]); |
|
PushDescriport<ScalarType, ScalarType, 1>(cameraProp, cameraDescr, std::string("k4"), &mesh.shot.Intrinsics.k[3]); |
|
} |
|
|
|
//Vertex |
|
std::vector<std::string> nameList; |
|
VertexType::Name(nameList); |
|
std::vector<PlyProperty> vertexProp; |
|
ElementDescriptor vertexDescr(NNP_VERTEX_ELEM); |
|
if (nameList.size() > 0 && mesh.vert.size() > 0) |
|
{ |
|
if ((bitMask & BitMask::IO_VERTCOORD) && VertexType::HasCoord()) |
|
PushDescriport<VertexType, VertexCoordScalar, 3>(vertexProp, vertexDescr, NNP_PXYZ, (*mesh.vert.begin()).P().V()); |
|
if ((bitMask & BitMask::IO_VERTNORMAL) && vcg::tri::HasPerVertexNormal(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTNORMAL) |
|
PushDescriport<VertexNormalType, VertexNormScalar, 3>(vertexProp, vertexDescr, NNP_NXYZ, (*mesh.vert.begin()).N().V()); |
|
else |
|
PushDescriport<VertexType, VertexNormScalar, 3>(vertexProp, vertexDescr, NNP_NXYZ, (*mesh.vert.begin()).N().V()); |
|
} |
|
if ((bitMask & BitMask::IO_VERTCOLOR) && vcg::tri::HasPerVertexColor(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTCOLOR) |
|
PushDescriport<VertexColorType, VertexColorScalar, 4>(vertexProp, vertexDescr, NNP_CRGBA, (*mesh.vert.begin()).C().V()); |
|
else |
|
PushDescriport<VertexType, VertexColorScalar, 4>(vertexProp, vertexDescr, NNP_CRGBA, (*mesh.vert.begin()).C().V()); |
|
} |
|
if ((bitMask & BitMask::IO_VERTQUALITY) && vcg::tri::HasPerVertexQuality(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTQUALITY) |
|
PushDescriport<VertexQuality, VertexQuality, 1>(vertexProp, vertexDescr, NNP_QUALITY, &(*mesh.vert.begin()).Q()); |
|
else |
|
PushDescriport<VertexType, VertexQuality, 1>(vertexProp, vertexDescr, NNP_QUALITY, &(*mesh.vert.begin()).Q()); |
|
} |
|
if ((bitMask & BitMask::IO_VERTFLAGS) && vcg::tri::HasPerVertexFlags(mesh)) |
|
PushDescriport<VertexType, VertexFlag, 1>(vertexProp, vertexDescr, NNP_BITFLAG, &(*mesh.vert.begin()).Flags()); |
|
if ((bitMask & BitMask::IO_VERTRADIUS) && vcg::tri::HasPerVertexRadius(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTRADIUS) |
|
PushDescriport<VertexRadius, VertexRadius, 1>(vertexProp, vertexDescr, NNP_DENSITY, &(*mesh.vert.begin()).R()); |
|
else |
|
PushDescriport<VertexType, VertexRadius, 1>(vertexProp, vertexDescr, NNP_DENSITY, &(*mesh.vert.begin()).R()); |
|
} |
|
if ((bitMask & BitMask::IO_VERTTEXCOORD) && vcg::tri::HasPerVertexTexCoord(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) |
|
PushDescriport<VertexTexCoordType, VertexTexScalar, 2>(vertexProp, vertexDescr, NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V()); |
|
else |
|
PushDescriport<VertexType, VertexTexScalar, 2>(vertexProp, vertexDescr, NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V()); |
|
} |
|
// if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) |
|
// { |
|
// if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) |
|
// { |
|
// PushDescriport<VertexCurType, VertexCurScalar, 1>(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); |
|
// PushDescriport<VertexCurType, VertexCurScalar, 1>(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); |
|
// } |
|
// else |
|
// { |
|
// PushDescriport<VertexType, VertexCurScalar, 1>(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); |
|
// PushDescriport<VertexType, VertexCurScalar, 1>(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); |
|
// } |
|
// } |
|
if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) |
|
{ |
|
if (ocfVertexMask & BitMask::IO_VERTCURVDIR) |
|
{ |
|
PushDescriport<VertexCurDirType, VertexDirCurScalar, 1>(vertexProp, vertexDescr, NNP_K1, &(*mesh.vert.begin()).K1()); |
|
PushDescriport<VertexCurDirType, VertexDirCurScalar, 1>(vertexProp, vertexDescr, NNP_K2, &(*mesh.vert.begin()).K2()); |
|
PushDescriportList<VertexCurDirType, VertexDirCurVecScalar, 3>(vertexProp, vertexDescr, NNP_K1DIR, (*mesh.vert.begin()).PD1().V()); |
|
PushDescriportList<VertexCurDirType, VertexDirCurVecScalar, 3>(vertexProp, vertexDescr, NNP_K2DIR, (*mesh.vert.begin()).PD2().V()); |
|
} |
|
else |
|
{ |
|
PushDescriport<VertexType, VertexDirCurScalar, 1>(vertexProp, vertexDescr, NNP_K1, &(*mesh.vert.begin()).K1()); |
|
PushDescriport<VertexType, VertexDirCurScalar, 1>(vertexProp, vertexDescr, NNP_K2, &(*mesh.vert.begin()).K2()); |
|
PushDescriportList<VertexType, VertexDirCurVecScalar, 3>(vertexProp, vertexDescr, NNP_K1DIR, (*mesh.vert.begin()).PD1().V()); |
|
PushDescriportList<VertexType, VertexDirCurVecScalar, 3>(vertexProp, vertexDescr, NNP_K2DIR, (*mesh.vert.begin()).PD2().V()); |
|
} |
|
} |
|
if ((bitMask & BitMask::IO_VERTATTRIB)) |
|
{ |
|
typename std::set<PointerToAttribute>::iterator ai; |
|
int userSize = custom.vertexAttrib.size(); |
|
for (ai = mesh.vert_attr.begin(); ai != mesh.vert_attr.end(); ++ai) |
|
{ |
|
bool userDescr = false; |
|
for (int i = 0; i < userSize; i++) |
|
{ |
|
if ((*custom.vertexAttrib[i]).name == (*ai)._name) |
|
{ |
|
userDescr = true; |
|
break; |
|
} |
|
} |
|
if (!userDescr) |
|
custom.CreateVertexAttribDescriptor(&(*ai)); |
|
} |
|
for (size_t i = 0; i < custom.vertexAttrib.size(); i++) |
|
{ |
|
vertexProp.push_back(custom.vertexAttribProp[i]); |
|
vertexDescr.dataDescriptor.push_back(custom.vertexAttrib[i]); |
|
} |
|
} |
|
} |
|
|
|
//Edge |
|
nameList.clear(); |
|
EdgeType::Name(nameList); |
|
std::vector<PlyProperty> edgeProp; |
|
ElementDescriptor edgeDescr(NNP_EDGE_ELEM); |
|
std::vector<vcg::Point2i> edgeIndex; |
|
for (size_t i = 0; i < mesh.edge.size(); i++) |
|
edgeIndex.push_back(vcg::Point2i(vcg::tri::Index(mesh, mesh.edge[i].V(0)), vcg::tri::Index(mesh, mesh.edge[i].V(1)))); |
|
if (nameList.size() > 0 && mesh.edge.size() > 0) |
|
{ |
|
if ((bitMask & BitMask::IO_EDGEINDEX) && EdgeType::HasVertexRef()) |
|
{ |
|
PushDescriport<vcg::Point2i, int, 1>(edgeProp, edgeDescr, NNP_EDGE_V1, &(*edgeIndex.begin()).V()[0]); |
|
PushDescriport<vcg::Point2i, int, 1>(edgeProp, edgeDescr, NNP_EDGE_V2, &(*edgeIndex.begin()).V()[1]); |
|
} |
|
if ((bitMask & BitMask::IO_EDGEQUALITY) && vcg::tri::HasPerEdgeQuality(mesh)) |
|
PushDescriport<EdgeType, EdgeQuality, 1>(edgeProp, edgeDescr, NNP_QUALITY, &(*mesh.edge.begin()).Q()); |
|
if ((bitMask & BitMask::IO_EDGECOLOR) && vcg::tri::HasPerEdgeColor(mesh)) |
|
PushDescriport<EdgeType, EdgeColorScalar, 4>(edgeProp, edgeDescr, NNP_CRGBA, (*mesh.edge.begin()).C().V()); |
|
if ((bitMask & BitMask::IO_EDGEFLAGS) && vcg::tri::HasPerEdgeFlags(mesh)) |
|
PushDescriport<EdgeType, EdgeFlag, 1>(edgeProp, edgeDescr, NNP_BITFLAG, &(*mesh.edge.begin()).Flags()); |
|
|
|
if ((bitMask & BitMask::IO_EDGEATTRIB)) |
|
{ |
|
typename std::set<PointerToAttribute>::iterator ai; |
|
int userSize = custom.edgeAttrib.size(); |
|
for (ai = mesh.edge_attr.begin(); ai != mesh.edge_attr.end(); ++ai) |
|
{ |
|
bool userDescr = false; |
|
for (int i = 0; i < userSize; i++) |
|
{ |
|
if ((*custom.edgeAttrib[i]).name == (*ai)._name) |
|
{ |
|
userDescr = true; |
|
break; |
|
} |
|
} |
|
if (!userDescr) |
|
custom.CreateEdgeAttribDescriptor(&(*ai)); |
|
} |
|
for (size_t i = 0; i < custom.edgeAttrib.size(); i++) |
|
{ |
|
edgeProp.push_back(custom.edgeAttribProp[i]); |
|
edgeDescr.dataDescriptor.push_back(custom.edgeAttrib[i]); |
|
} |
|
} |
|
} |
|
|
|
//Face |
|
nameList.clear(); |
|
FaceType::Name(nameList); |
|
std::vector<PlyProperty> faceProp; |
|
ElementDescriptor faceDescr(NNP_FACE_ELEM); |
|
std::vector<std::vector<unsigned int>> faceIndex; |
|
std::vector<vcg::ndim::Point<6, FaceTexScalar>> wedgeTexCoord; |
|
for (size_t i = 0; i < mesh.face.size(); i++) |
|
{ |
|
faceIndex.push_back(std::vector<unsigned int>()); |
|
for (int j = 0; j < mesh.face[i].VN(); j++) |
|
faceIndex.back().push_back(vcg::tri::Index(mesh, mesh.face[i].V(j))); |
|
} |
|
if (((bitMask & BitMask::IO_WEDGTEXCOORD) || (bitMask & BitMask::IO_WEDGTEXMULTI)) && vcg::tri::HasPerWedgeTexCoord(mesh)) |
|
{ |
|
for (size_t i = 0; i < mesh.face.size(); i++) |
|
{ |
|
wedgeTexCoord.push_back(vcg::ndim::Point<6, FaceTexScalar>()); |
|
for (int j = 0; j < 3; j++) |
|
{ |
|
wedgeTexCoord.back()[j * 2] = mesh.face[i].WT(j).U(); |
|
wedgeTexCoord.back()[j * 2 + 1] = mesh.face[i].WT(j).V(); |
|
} |
|
} |
|
} |
|
if (nameList.size() > 0 && mesh.face.size() > 0) |
|
{ |
|
if ((bitMask & BitMask::IO_FACEINDEX) && FaceType::HasVertexRef()) |
|
PushDescriportList<std::vector<unsigned int>, unsigned int, 0>(faceProp, faceDescr, NNP_FACE_VERTEX_LIST, &faceIndex[0]); |
|
if ((bitMask & BitMask::IO_FACEFLAGS) && vcg::tri::HasPerFaceFlags(mesh)) |
|
PushDescriport<FaceType, FaceFlag, 1>(faceProp, faceDescr, NNP_BITFLAG, &(*mesh.face.begin()).Flags()); |
|
if ((bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_FACECOLOR) |
|
PushDescriport<FaceColorType, FaceColorScalar, 4>(faceProp, faceDescr, NNP_CRGBA, (*mesh.face.begin()).C().V()); |
|
else |
|
PushDescriport<FaceType, FaceColorScalar, 4>(faceProp, faceDescr, NNP_CRGBA, (*mesh.face.begin()).C().V()); |
|
} |
|
if ((bitMask & BitMask::IO_FACEQUALITY) && vcg::tri::HasPerFaceQuality(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_FACEQUALITY) |
|
PushDescriport<FaceQuality, FaceQuality, 1>(faceProp, faceDescr, NNP_QUALITY, &(*mesh.face.begin()).Q()); |
|
else |
|
PushDescriport<FaceType, FaceQuality, 1>(faceProp, faceDescr, NNP_QUALITY, &(*mesh.face.begin()).Q()); |
|
} |
|
if ((bitMask & BitMask::IO_FACENORMAL) && vcg::tri::HasPerFaceNormal(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_FACENORMAL) |
|
PushDescriport<FaceNormalType, FaceNormScalar, 3>(faceProp, faceDescr, NNP_NXYZ, (*mesh.face.begin()).N().V()); |
|
else |
|
PushDescriport<FaceType, FaceNormScalar, 3>(faceProp, faceDescr, NNP_NXYZ, (*mesh.face.begin()).N().V()); |
|
} |
|
if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerFaceCurvatureDir(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_VERTCURVDIR) |
|
{ |
|
PushDescriport<FaceCurDirType, FaceDirCurScalar, 1>(faceProp, faceDescr, NNP_K1, &(*mesh.face.begin()).K1()); |
|
PushDescriport<FaceCurDirType, FaceDirCurScalar, 1>(faceProp, faceDescr, NNP_K2, &(*mesh.face.begin()).K2()); |
|
PushDescriportList<FaceCurDirType, FaceDirCurVecScalar, 3>(faceProp, faceDescr, NNP_K1DIR, (*mesh.face.begin()).PD1().V()); |
|
PushDescriportList<FaceCurDirType, FaceDirCurVecScalar, 3>(faceProp, faceDescr, NNP_K2DIR, (*mesh.face.begin()).PD2().V()); |
|
} |
|
else |
|
{ |
|
PushDescriport<FaceType, FaceDirCurScalar, 1>(faceProp, faceDescr, NNP_K1, &(*mesh.face.begin()).K1()); |
|
PushDescriport<FaceType, FaceDirCurScalar, 1>(faceProp, faceDescr, NNP_K2, &(*mesh.face.begin()).K2()); |
|
PushDescriportList<FaceType, FaceDirCurVecScalar, 3>(faceProp, faceDescr, NNP_K1DIR, (*mesh.face.begin()).PD1().V()); |
|
PushDescriportList<FaceType, FaceDirCurVecScalar, 3>(faceProp, faceDescr, NNP_K2DIR, (*mesh.face.begin()).PD2().V()); |
|
} |
|
} |
|
if (((bitMask & BitMask::IO_WEDGTEXCOORD) || (bitMask & BitMask::IO_WEDGTEXMULTI)) && vcg::tri::HasPerWedgeTexCoord(mesh)) |
|
PushDescriportList<vcg::ndim::Point<6, FaceTexScalar>, FaceTexScalar, 6>(faceProp, faceDescr, NNP_FACE_WEDGE_TEX, (*wedgeTexCoord.begin()).V()); |
|
if ((bitMask & BitMask::IO_WEDGTEXMULTI) && vcg::tri::HasPerWedgeTexCoord(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_VERTCURVDIR) |
|
PushDescriport<FaceTexCoordType, short, 1>(faceProp, faceDescr, NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N()); |
|
else |
|
PushDescriport<FaceType, short, 1>(faceProp, faceDescr, NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N()); |
|
} |
|
if ((bitMask & BitMask::IO_WEDGCOLOR) && vcg::tri::HasPerWedgeColor(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_WEDGCOLOR) |
|
PushDescriportList<WedgeColorType, WedgeColorScalar, 12>(faceProp, faceDescr, NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V()); |
|
else |
|
PushDescriportList<FaceType, WedgeColorScalar, 12>(faceProp, faceDescr, NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V()); |
|
} |
|
if ((bitMask & BitMask::IO_WEDGNORMAL) && vcg::tri::HasPerWedgeNormal(mesh)) |
|
{ |
|
if (ocfFaceMask & BitMask::IO_WEDGNORMAL) |
|
PushDescriportList<WedgeNormalType, WedgeNormalScalar, 9>(faceProp, faceDescr, NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V()); |
|
else |
|
PushDescriportList<FaceType, WedgeNormalScalar, 9>(faceProp, faceDescr, NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V()); |
|
} |
|
if ((bitMask & BitMask::IO_FACEATTRIB)) |
|
{ |
|
typename std::set<PointerToAttribute>::iterator ai; |
|
int userSize = custom.faceAttrib.size(); |
|
for (ai = mesh.face_attr.begin(); ai != mesh.face_attr.end(); ++ai) |
|
{ |
|
bool userDescr = false; |
|
for (int i = 0; i < userSize; i++) |
|
{ |
|
if ((*custom.faceAttrib[i]).name == (*ai)._name) |
|
{ |
|
userDescr = true; |
|
break; |
|
} |
|
} |
|
if (!userDescr) |
|
custom.CreateFaceAttribDescriptor(&(*ai)); |
|
} |
|
for (size_t i = 0; i < custom.faceAttrib.size(); i++) |
|
{ |
|
faceProp.push_back(custom.faceAttribProp[i]); |
|
faceDescr.dataDescriptor.push_back(custom.faceAttrib[i]); |
|
} |
|
} |
|
} |
|
|
|
Info infoSave; |
|
infoSave.filename = filename; |
|
infoSave.binary = binary; |
|
PlyElement cameraElem(std::string("camera"), cameraProp, 1); |
|
PlyElement vertexElem(NNP_VERTEX_ELEM, vertexProp, mesh.vert.size()); |
|
PlyElement edgeElem(NNP_EDGE_ELEM, edgeProp, mesh.edge.size()); |
|
PlyElement faceElem(NNP_FACE_ELEM, faceProp, mesh.face.size()); |
|
infoSave.AddPlyElement(cameraElem); |
|
infoSave.AddPlyElement(vertexElem); |
|
infoSave.AddPlyElement(edgeElem); |
|
infoSave.AddPlyElement(faceElem); |
|
infoSave.textureFile = mesh.textures; |
|
std::vector<ElementDescriptor*> meshDescr; |
|
meshDescr.push_back(&cameraDescr); |
|
meshDescr.push_back(&vertexDescr); |
|
meshDescr.push_back(&edgeDescr); |
|
meshDescr.push_back(&faceDescr); |
|
|
|
//Mesh attribute |
|
if ((bitMask & BitMask::IO_MESHATTRIB)) |
|
{ |
|
typename CustomAttributeDescriptor::MapMeshAttribIter iter = custom.meshAttrib.begin(); |
|
typename CustomAttributeDescriptor::MapMeshAttribPropIter iterProp = custom.meshAttribProp.begin(); |
|
for (; iter != custom.meshAttrib.end(); iter++, iterProp++) |
|
{ |
|
std::string name((*iter).first); |
|
PlyElement customElem(name, (*iterProp).second, custom.meshAttribCnt[(*iter).first]); |
|
infoSave.AddPlyElement(customElem); |
|
meshDescr.push_back(new ElementDescriptor(name)); |
|
meshDescr.back()->dataDescriptor = (*iter).second; |
|
} |
|
} |
|
|
|
bool flag = nanoply::SaveModel(infoSave.filename, meshDescr, infoSave); |
|
|
|
for (size_t i = 0; i < cameraDescr.dataDescriptor.size(); i++) |
|
delete cameraDescr.dataDescriptor[i]; |
|
for (size_t i = 0; i < vertexDescr.dataDescriptor.size(); i++) |
|
if (vertexDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) |
|
delete vertexDescr.dataDescriptor[i]; |
|
for (size_t i = 0; i < edgeDescr.dataDescriptor.size(); i++) |
|
if (edgeDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) |
|
delete edgeDescr.dataDescriptor[i]; |
|
for (size_t i = 0; i < faceDescr.dataDescriptor.size(); i++) |
|
if (faceDescr.dataDescriptor[i]->elem != NNP_UNKNOWN_ENTITY) |
|
delete faceDescr.dataDescriptor[i]; |
|
|
|
return flag; |
|
} |
|
|
|
|
|
static bool SaveModel(const char* filename, MeshType& mesh, unsigned int bitMask, bool binary) |
|
{ |
|
CustomAttributeDescriptor custom; |
|
return SaveModel(filename, mesh, bitMask, custom, binary); |
|
} |
|
|
|
|
|
}; |
|
|
|
} |
|
|
|
#endif
|
|
|