diff --git a/vcg/complex/algorithms/curve_on_manifold.h b/vcg/complex/algorithms/curve_on_manifold.h index 713e5498..61de82ac 100644 --- a/vcg/complex/algorithms/curve_on_manifold.h +++ b/vcg/complex/algorithms/curve_on_manifold.h @@ -201,7 +201,7 @@ public: { VertexPointer v0 = FindVertexSnap(f0,ip0); VertexPointer v1 = FindVertexSnap(f1,ip1); - assert(v1 != NULL && v1 != NULL && v0 != v1); + assert(v0 != NULL && v1 != NULL && v0 != v1); FacePointer ff0,ff1; int e0,e1; ret &= face::FindSharedFaces(v0,v1,ff0,ff1,e0,e1); diff --git a/vcg/complex/allocate.h b/vcg/complex/allocate.h index 25486233..25cf2424 100644 --- a/vcg/complex/allocate.h +++ b/vcg/complex/allocate.h @@ -1070,6 +1070,7 @@ public: h._sizeof = sizeof(ATTR_TYPE); h._padding = 0; h._handle = new SimpleTempData(m.vert); + h._type = typeid(ATTR_TYPE); m.attrn++; h.n_attr = m.attrn; std::pair < AttrIterator , bool> res = m.vert_attr.insert(h); @@ -1211,6 +1212,7 @@ public: h._padding = 0; // h._typename = typeid(ATTR_TYPE).name(); h._handle = new SimpleTempData(m.edge); + h._type = typeid(ATTR_TYPE); m.attrn++; h.n_attr = m.attrn; std::pair < AttrIterator , bool> res = m.edge_attr.insert(h); @@ -1334,6 +1336,7 @@ public: h._sizeof = sizeof(ATTR_TYPE); h._padding = 0; h._handle = new SimpleTempData(m.face); + h._type = typeid(ATTR_TYPE); m.attrn++; h.n_attr = m.attrn; std::pair < AttrIterator , bool> res = m.face_attr.insert(h); @@ -1452,6 +1455,7 @@ public: h._sizeof = sizeof(ATTR_TYPE); h._padding = 0; h._handle = new Attribute(); + h._type = typeid(ATTR_TYPE); m.attrn++; h.n_attr = m.attrn; std::pair < AttrIterator , bool> res = m.mesh_attr.insert(h); diff --git a/vcg/complex/base.h b/vcg/complex/base.h index fc178f79..65cfb4a9 100644 --- a/vcg/complex/base.h +++ b/vcg/complex/base.h @@ -37,10 +37,12 @@ public: int _padding; // padding (used only with VMI loading) int n_attr; // unique ID of the attribute - + std::type_index _type; void Resize(size_t sz){((SimpleTempDataBase *)_handle)->Resize(sz);} void Reorder(std::vector & newVertIndex){((SimpleTempDataBase *)_handle)->Reorder(newVertIndex);} bool operator<(const PointerToAttribute b) const { return(_name.empty()&&b._name.empty())?(_handle < b._handle):( _name < b._name);} + + PointerToAttribute(): _type(typeid(void)) { }; }; diff --git a/vcg/complex/complex.h b/vcg/complex/complex.h index 0121700e..ebc3dc1e 100644 --- a/vcg/complex/complex.h +++ b/vcg/complex/complex.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include diff --git a/vcg/simplex/face/component_ocf.h b/vcg/simplex/face/component_ocf.h index 1389547f..77165733 100644 --- a/vcg/simplex/face/component_ocf.h +++ b/vcg/simplex/face/component_ocf.h @@ -96,7 +96,7 @@ public: } } - typename VALUE_TYPE::ColorType wc[3]; + typename VALUE_TYPE::WedgeColorType wc[3]; }; class WedgeNormalTypePack { @@ -111,7 +111,7 @@ public: } } - typename VALUE_TYPE::NormalType wn[3]; + typename VALUE_TYPE::WedgeNormalType wn[3]; }; diff --git a/vcg/simplex/face/component_polygon.h b/vcg/simplex/face/component_polygon.h index e63bd653..dde27016 100644 --- a/vcg/simplex/face/component_polygon.h +++ b/vcg/simplex/face/component_polygon.h @@ -108,6 +108,7 @@ public: T::Dealloc(); } + static bool HasVertexRef() { return true; } static bool HasFVAdjacency() { return true; } static void Name(std::vector & name){name.push_back(std::string("PFVAdj"));T::Name(name);} diff --git a/wrap/nanoply/include/nanoply.hpp b/wrap/nanoply/include/nanoply.hpp index 761e7f82..3f867c41 100644 --- a/wrap/nanoply/include/nanoply.hpp +++ b/wrap/nanoply/include/nanoply.hpp @@ -246,7 +246,7 @@ namespace nanoply { PlyEntity::NNP_K2DIR, NameVector({ "k2dir" }) }, { PlyEntity::NNP_EDGE_V1, NameVector({ "vertex1", "v1" }) }, { PlyEntity::NNP_EDGE_V2, NameVector({ "vertex2", "v2" }) }, - { PlyEntity::NNP_FACE_VERTEX_LIST, NameVector({ "vertex_index", "vertex_indices" }) }, + { PlyEntity::NNP_FACE_VERTEX_LIST, NameVector({ "vertex_indices", "vertex_index" }) }, { PlyEntity::NNP_FACE_WEDGE_COLOR, NameVector({ "color" }) }, { PlyEntity::NNP_FACE_WEDGE_NORMAL, NameVector({ "normal" }) }, { PlyEntity::NNP_FACE_WEDGE_TEX, NameVector({ "texcoord" }) } @@ -463,7 +463,7 @@ namespace nanoply if (fileStream.fail()) return false; bufferOffset = 0; - //fileStream.setf(std::ios::fixed, std::ios::floatfield); + fileStream.setf(std::ios::fixed, std::ios::floatfield); //fileStream.precision(7); return true; } @@ -583,6 +583,10 @@ namespace nanoply PlyEntity elem; /**< Property entity. */ bool validToWrite; /**< Property validity (necessary to write the header). */ + + inline PlyProperty() {} + + /** * Constructor that sets the type and the entity of a standard PLY property. * @@ -1732,7 +1736,7 @@ namespace nanoply * @param _s Name of the PlyProperty. * @param _b Pointer to the memory location that contains the data of the property. */ - inline DescriptorInterface(std::string& _s, void *_b) :curPos(0), elem(PlyEntity::NNP_UNKNOWN_ENTITY), name(_s), base(_b){}; + inline DescriptorInterface(const std::string& _s, void *_b) :curPos(0), elem(PlyEntity::NNP_UNKNOWN_ENTITY), name(_s), base(_b){}; /** * Restart the descriptor. @@ -1990,18 +1994,336 @@ namespace nanoply + template + class DescriptorHelper + { + + public: + + template + static void ReadBinary(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop, bool fixEndian) + { + char * buffer = nullptr; + int size; + int count = prop.CountValue(); + int typeSize = prop.TypeSize(); + if (prop.type >= NNP_LIST_UINT8_UINT32) + { + file.ReadBinaryData(buffer, sizeof(char)); + const int cntList = int(*(reinterpret_cast(buffer))); + size = typeSize * cntList; + count = cntList; + } + else + size = typeSize * count; + file.ReadBinaryData(buffer, size); + + if (typeSize > 1 && fixEndian) + adjustEndianess(reinterpret_cast(buffer), typeSize, count); + + unsigned char* baseProp = (unsigned char*)descr.base + descr.curPos * sizeof(ContainerType); + C* temp = (C*)buffer; + if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA)) + { + float norm = 1.0f; + if (std::is_same::value && std::is_same::value) + norm = 1.0f / 255.0f; + else if (std::is_same::value && std::is_same::value) + norm = 255.0f; + for (int i = 0; i < std::min(VectorSize, count); i++) + *((ScalarType *)(baseProp + i * sizeof(ScalarType))) = ScalarType(temp[i] * norm); + } + else + { + for (int i = 0; i < std::min(VectorSize, count); i++) + *((ScalarType *)(baseProp + i * sizeof(ScalarType))) = ScalarType(temp[i]); + } + ++(descr.curPos); + } + + template + static void ReadAscii(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop) + { + int count = prop.CountValue(); + if (prop.type >= NNP_LIST_UINT8_UINT32) + file.ReadAsciiData(count); + + C* temp = new C[count]; + for (int i = 0; i < count; i++) + file.ReadAsciiData(temp[i]); + + unsigned char* baseProp = (unsigned char*)descr.base + descr.curPos * sizeof(ContainerType); + if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA)) + { + float norm = 1.0f; + if (std::is_same::value && prop.type == NNP_UINT8) + norm = 1.0f / 255.0f; + else if (std::is_same::value && prop.type == NNP_FLOAT32) + norm = 255.0f; + for (int i = 0; i < std::min(VectorSize, count); i++) + *((ScalarType *)(baseProp + i * sizeof(ScalarType))) = ScalarType(temp[i] * norm); + } + else + { + for (int i = 0; i < std::min(VectorSize, count); i++) + *((ScalarType *)(baseProp + i * sizeof(ScalarType))) = ScalarType(temp[i]); + } + delete[] temp; + ++(descr.curPos); + } + + template + static void WriteBinary(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop, bool fixEndian) + { + (void)fixEndian; + int count = prop.CountValue(); + C data[VectorSize]; + if (prop.type >= NNP_LIST_UINT8_UINT32) + { + if (prop.IsSigned()) + { + char listSize = (char)VectorSize; + file.WriteBinaryData(&listSize, 1); + count = VectorSize; + } + else + { + unsigned char listSize = (unsigned char)VectorSize; + file.WriteBinaryData(&listSize, 1); + count = VectorSize; + } + } + + C temp = 0; + unsigned char* baseProp = (unsigned char*)descr.base + descr.curPos * sizeof(ContainerType); + if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA)) + { + float norm = 1.0f; + if (std::is_same::value && std::is_same::value) + norm = 255.0f; + else if (std::is_same::value && std::is_same::value) + norm = 1.0f / 255.0f; + for (int i = 0; i < std::min(VectorSize, count); i++) + data[i] = (C)((*(ScalarType*)(baseProp + i * sizeof(ScalarType))) * norm); + } + else + { + for (int i = 0; i < std::min(VectorSize, count); i++) + data[i] = (C)((*(ScalarType*)(baseProp + i * sizeof(ScalarType)))); + } + + if (sizeof(C) > 1 && fixEndian) + adjustEndianess((unsigned char*)data, sizeof(C), std::min(VectorSize, count)); + + file.WriteBinaryData(data, sizeof(C)*std::min(VectorSize, count)); + for (int i = 0; i < (count - VectorSize); i++) + file.WriteBinaryData(&temp, sizeof(C)); + ++(descr.curPos); + } + + template + static void WriteAscii(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop) + { + int count = prop.CountValue(); + if (prop.type >= NNP_LIST_UINT8_UINT32) + { + if (prop.IsSigned()) + { + int listSize = (int)VectorSize; + file.WriteAsciiData(listSize); + count = VectorSize; + } + else + { + unsigned int listSize = (unsigned int)VectorSize; + file.WriteAsciiData(listSize); + count = VectorSize; + } + file.WriteAsciiData(std::string(" ")); + } + + C data[VectorSize]; + unsigned char* baseProp = (unsigned char*)descr.base + descr.curPos * sizeof(ContainerType); + if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA)) + { + float norm = 1.0; + if (std::is_same::value && prop.type == NNP_UINT8) + norm = 255.0f; + else if (std::is_same::value && prop.type == NNP_FLOAT32) + norm = 1.0f / 255.0f; + for (int i = 0; i < std::min(VectorSize, count); i++) + data[i] = (C)((*(ScalarType*)(baseProp + i * sizeof(ScalarType))) * norm); + } + else + { + for (int i = 0; i < std::min(VectorSize, count); i++) + data[i] = (C)((*(ScalarType*)(baseProp + i * sizeof(ScalarType)))); + } + + + for (int i = 0; i < (count - VectorSize); i++) + data[i] = 0; + + for (int i = 0; i < count; i++) + { + file.WriteAsciiData(data[i]); + if (i < count - 1) + file.WriteAsciiData(std::string(" ")); + } + ++(descr.curPos); + } + }; + + + + + template + class DescriptorHelper + { + + public: + + template + static void ReadBinary(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop, bool fixEndian) + { + char * buffer = nullptr; + int size; + int count = prop.CountValue(); + int typeSize = prop.TypeSize(); + if (prop.type >= NNP_LIST_UINT8_UINT32) + { + file.ReadBinaryData(buffer, sizeof(char)); + const int cntList = int(*(reinterpret_cast(buffer))); + size = typeSize * cntList; + count = cntList; + } + else + size = typeSize * count; + file.ReadBinaryData(buffer, size); + + if (typeSize > 1 && fixEndian) + adjustEndianess(reinterpret_cast(buffer), typeSize, count); + + C* temp = (C*)buffer; + + ContainerType* container = (ContainerType*)((unsigned char*)descr.base + descr.curPos * sizeof(ContainerType)); + (*container).resize(count); + for (int i = 0; i < count; i++) + (*container)[i] = (ScalarType)(temp[i]); + ++(descr.curPos); + } + + template + static void ReadAscii(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop) + { + int count = prop.CountValue(); + if (prop.type >= NNP_LIST_UINT8_UINT32) + file.ReadAsciiData(count); + + C* temp = new C[count]; + for (int i = 0; i < count; i++) + file.ReadAsciiData(temp[i]); + + ContainerType* container = (ContainerType*)((unsigned char*)descr.base + descr.curPos * sizeof(ContainerType)); + (*container).resize(count); + for (int i = 0; i < count; i++) + (*container)[i] = (ScalarType)(temp[i]); + delete[] temp; + ++(descr.curPos); + } + + template + static void WriteBinary(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop, bool fixEndian) + { + size_t count = prop.CountValue(); + ContainerType* list = (ContainerType*)((unsigned char*)descr.base + descr.curPos * sizeof(ContainerType)); + if (prop.type >= NNP_LIST_UINT8_UINT32) + { + if (prop.IsSigned()) + { + char listSize = (char)list->size(); + file.WriteBinaryData(&listSize, 1); + count = list->size(); + } + else + { + unsigned char listSize = (unsigned char)list->size(); + file.WriteBinaryData(&listSize, 1); + count = list->size(); + } + } + + std::vector data(count); + + for (int i = 0; i < std::min(count, list->size()); i++) + data[i] = (C)((*list)[i]); + + if (sizeof(C) > 1 && fixEndian) + adjustEndianess((unsigned char*)data.data(), sizeof(C), std::min(count, list->size())); + + file.WriteBinaryData(data.data(), sizeof(C)*std::min(count, list->size())); + C temp = 0; + for (int i = 0; i < (count - list->size()); i++) + file.WriteBinaryData(&temp, sizeof(C)); + ++(descr.curPos); + } + + template + static void WriteAscii(DescriptorInterface& descr, PlyFile &file, PlyProperty &prop) + { + size_t count = prop.CountValue(); + ContainerType* list = (ContainerType*)((unsigned char*)descr.base + descr.curPos * sizeof(ContainerType)); + if (prop.type >= NNP_LIST_UINT8_UINT32) + { + if (prop.IsSigned()) + { + int listSize = (int)list->size(); + file.WriteAsciiData(listSize); + count = list->size(); + } + else + { + unsigned int listSize = (unsigned int)list->size(); + file.WriteAsciiData(listSize); + count = list->size(); + } + file.WriteAsciiData(std::string(" ")); + } + + std::vector data(count); + for (int i = 0; i < std::min(count, list->size()); i++) + data[i] = (C)((*list)[i]); + + for (int i = 0; i < (count - list->size()); i++) + data[i] = 0; + + for (int i = 0; i < count; i++) + { + file.WriteAsciiData(data[i]); + if (i < count - 1) + file.WriteAsciiData(std::string(" ")); + } + ++(descr.curPos); + } + }; + + + + /** Memory descriptor of a vector of properties. * The class defines how a vector of PlyProperty is saved in memory. * - * @tparam CointainerType Type of the container of the property + * @tparam ContainerType Type of the container of the property * @tparam VectorSize Number of values stored in the property. * @tparam ScalarType Type of the values stored in the property. */ - template + template class DataDescriptor : public DescriptorInterface { public: + DescriptorHelper helper; + inline DataDescriptor(); /** @@ -2018,7 +2340,7 @@ namespace nanoply * @param _s Name of the PlyProperty. * @param _b Pointer to the memory location that contains the data of the property. */ - inline DataDescriptor(std::string& _s, void *_b) :DescriptorInterface(_s, _b){}; + inline DataDescriptor(const std::string& _s, void *_b) :DescriptorInterface(_s, _b){}; inline void Restart(); @@ -2029,75 +2351,18 @@ namespace nanoply inline bool WriteElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian); inline bool WriteElemAscii(PlyFile &file, PlyProperty &prop); - - private: - - template - inline void ReadBinary(PlyFile &file, PlyProperty &prop, bool fixEndian); - - template - inline void ReadAscii(PlyFile &file, PlyProperty &prop); - - template - inline void WriteBinary(PlyFile &file, PlyProperty &prop, bool fixEndian); - - template - inline void WriteAscii(PlyFile &file, PlyProperty &prop); - }; + - - template - inline void DataDescriptor::Restart() + template + void DataDescriptor::Restart() { this->curPos = 0; } + template - template - inline void DataDescriptor::ReadBinary(PlyFile &file, PlyProperty &prop, bool fixEndian) - { - char * buffer = nullptr; - int size; - int count = prop.CountValue(); - int typeSize = prop.TypeSize(); - if (prop.type >= NNP_LIST_UINT8_UINT32) - { - file.ReadBinaryData(buffer, sizeof(char)); - const int cntList = int(*(reinterpret_cast(buffer))); - size = typeSize * cntList; - count = cntList; - } - else - size = typeSize * count; - file.ReadBinaryData(buffer, size); - - if (typeSize > 1 && fixEndian) - adjustEndianess(reinterpret_cast(buffer), typeSize, count); - - unsigned char* baseProp = (unsigned char*)base + this->curPos*sizeof(ContainerType); - C* temp = (C*)buffer; - if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA)) - { - float norm = 1.0f; - if (std::is_same::value && std::is_same::value) - norm = 1.0f / 255.0f; - else if (std::is_same::value && std::is_same::value) - norm = 255.0f; - for (int i = 0; i < std::min(VectorSize, count); i++) - *((ScalarType *)(baseProp + i*sizeof(ScalarType))) = ScalarType(temp[i] * norm); - } - else - { - for (int i = 0; i < std::min(VectorSize, count); i++) - *((ScalarType *)(baseProp + i*sizeof(ScalarType))) = ScalarType(temp[i]); - } - ++(this->curPos); - } - - - template - inline bool DataDescriptor::ReadElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian) + bool DataDescriptor::ReadElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian) { if (prop.elem != elem) return false; @@ -2105,70 +2370,35 @@ namespace nanoply { case NNP_LIST_INT8_INT8: case NNP_LIST_UINT8_INT8: - case NNP_INT8: this->ReadBinary(file, prop, fixEndian); break; + case NNP_INT8: helper.ReadBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_UINT8: case NNP_LIST_UINT8_UINT8: - case NNP_UINT8: this->ReadBinary(file, prop, fixEndian); break; + case NNP_UINT8: helper.ReadBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_INT16: case NNP_LIST_UINT8_INT16: - case NNP_INT16: this->ReadBinary(file, prop, fixEndian); break; + case NNP_INT16: helper.ReadBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_UINT16: case NNP_LIST_UINT8_UINT16: - case NNP_UINT16: this->ReadBinary(file, prop, fixEndian); break; + case NNP_UINT16: helper.ReadBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_FLOAT32: case NNP_LIST_UINT8_FLOAT32: - case NNP_FLOAT32: this->ReadBinary(file, prop, fixEndian); break; + case NNP_FLOAT32: helper.ReadBinary(*this, file, prop, fixEndian); break; case NNP_LIST_UINT8_INT32: case NNP_LIST_INT8_INT32: - case NNP_INT32: this->ReadBinary(file, prop, fixEndian); break; + case NNP_INT32: helper.ReadBinary(*this, file, prop, fixEndian); break; case NNP_LIST_UINT8_UINT32: case NNP_LIST_INT8_UINT32: - case NNP_UINT32: this->ReadBinary(file, prop, fixEndian); break; + case NNP_UINT32: helper.ReadBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_FLOAT64: case NNP_LIST_UINT8_FLOAT64: - case NNP_FLOAT64: this->ReadBinary(file, prop, fixEndian); break; + case NNP_FLOAT64: helper.ReadBinary(*this, file, prop, fixEndian); break; } return true; } - template - template - inline void DataDescriptor::ReadAscii(PlyFile &file, PlyProperty &prop) - { - int count = prop.CountValue(); - if (prop.type >= NNP_LIST_UINT8_UINT32) - file.ReadAsciiData(count); - - C* temp = new C[count]; - for (int i = 0; i < count; i++) - file.ReadAsciiData(temp[i]); - - unsigned char* baseProp = (unsigned char*)base + this->curPos*sizeof(ContainerType); - if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA)) - { - float norm = 1.0f; - if (std::is_same::value && prop.type == NNP_UINT8) - norm = 1.0f / 255.0f; - else if (std::is_same::value && prop.type == NNP_FLOAT32) - norm = 255.0f; - for (int i = 0; i < std::min(VectorSize, count); i++) - *((ScalarType *)(baseProp + i*sizeof(ScalarType))) = ScalarType(temp[i] * norm); - } - else - { - for (int i = 0; i < std::min(VectorSize, count); i++) - *((ScalarType *)(baseProp + i*sizeof(ScalarType))) = ScalarType(temp[i]); - } - delete[] temp; - ++(this->curPos); - } - - - - template - inline bool DataDescriptor::ReadElemAscii(PlyFile &file, PlyProperty &prop) + bool DataDescriptor::ReadElemAscii(PlyFile &file, PlyProperty &prop) { if (prop.elem != elem) return false; @@ -2176,87 +2406,35 @@ namespace nanoply { case NNP_LIST_UINT8_INT8: case NNP_LIST_INT8_INT8: - case NNP_INT8: this->ReadAscii(file, prop); break; + case NNP_INT8: helper.ReadAscii(*this, file, prop); break; case NNP_LIST_UINT8_UINT8: case NNP_LIST_INT8_UINT8: - case NNP_UINT8: this->ReadAscii(file, prop); break; + case NNP_UINT8: helper.ReadAscii(*this, file, prop); break; case NNP_LIST_UINT8_INT16: case NNP_LIST_INT8_INT16: - case NNP_INT16: this->ReadAscii(file, prop); break; + case NNP_INT16: helper.ReadAscii(*this, file, prop); break; case NNP_LIST_UINT8_UINT16: case NNP_LIST_INT8_UINT16: - case NNP_UINT16: this->ReadAscii(file, prop); break; + case NNP_UINT16: helper.ReadAscii(*this, file, prop); break; case NNP_LIST_UINT8_FLOAT32: case NNP_LIST_INT8_FLOAT32: - case NNP_FLOAT32: this->ReadAscii(file, prop); break; + case NNP_FLOAT32: helper.ReadAscii(*this, file, prop); break; case NNP_LIST_UINT8_INT32: case NNP_LIST_INT8_INT32: - case NNP_INT32: this->ReadAscii(file, prop); break; + case NNP_INT32: helper.ReadAscii(*this, file, prop); break; case NNP_LIST_UINT8_UINT32: case NNP_LIST_INT8_UINT32: - case NNP_UINT32: this->ReadAscii(file, prop); break; + case NNP_UINT32: helper.ReadAscii(*this, file, prop); break; case NNP_LIST_UINT8_FLOAT64: case NNP_LIST_INT8_FLOAT64: - case NNP_FLOAT64: this->ReadAscii(file, prop); break; + case NNP_FLOAT64: helper.ReadAscii(*this, file, prop); break; } return true; } - template - template - inline void DataDescriptor::WriteBinary(PlyFile &file, PlyProperty &prop, bool fixEndian) - { - (void)fixEndian; - int count = prop.CountValue(); - C data[VectorSize]; - if (prop.type >= NNP_LIST_UINT8_UINT32) - { - if (prop.IsSigned()) - { - char listSize = (char)VectorSize; - file.WriteBinaryData(&listSize, 1); - count = VectorSize; - } - else - { - unsigned char listSize = (unsigned char)VectorSize; - file.WriteBinaryData(&listSize, 1); - count = VectorSize; - } - } - - C temp = 0; - unsigned char* baseProp = (unsigned char*)base + this->curPos*sizeof(ContainerType); - if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA)) - { - float norm = 1.0f; - if (std::is_same::value && std::is_same::value) - norm = 255.0f; - else if (std::is_same::value && std::is_same::value) - norm = 1.0f / 255.0f; - for (int i = 0; i < std::min(VectorSize, count); i++) - data[i] = (C)((*(ScalarType*)(baseProp + i*sizeof(ScalarType))) * norm); - } - else - { - for (int i = 0; i < std::min(VectorSize, count); i++) - data[i] = (C)((*(ScalarType*)(baseProp + i*sizeof(ScalarType)))); - } - - if (sizeof(C) > 1 && fixEndian) - adjustEndianess((unsigned char*)data, sizeof(C), std::min(VectorSize, count)); - - file.WriteBinaryData(data, sizeof(C)*std::min(VectorSize, count)); - for (int i = 0; i < (count - VectorSize); i++) - file.WriteBinaryData(&temp, sizeof(C)); - ++(this->curPos); - } - - - template - inline bool DataDescriptor::WriteElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian) + bool DataDescriptor::WriteElemBinary(PlyFile &file, PlyProperty &prop, bool fixEndian) { if (prop.elem != elem) return false; @@ -2264,89 +2442,35 @@ namespace nanoply { case NNP_LIST_INT8_INT8: case NNP_LIST_UINT8_INT8: - case NNP_INT8: this->WriteBinary(file, prop, fixEndian); break; + case NNP_INT8: helper.WriteBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_UINT8: case NNP_LIST_UINT8_UINT8: - case NNP_UINT8: this->WriteBinary(file, prop, fixEndian); break; + case NNP_UINT8: helper.WriteBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_INT16: case NNP_LIST_UINT8_INT16: - case NNP_INT16: this->WriteBinary(file, prop, fixEndian); break; + case NNP_INT16: helper.WriteBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_UINT16: case NNP_LIST_UINT8_UINT16: - case NNP_UINT16: this->WriteBinary(file, prop, fixEndian); break; + case NNP_UINT16: helper.WriteBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_FLOAT32: case NNP_LIST_UINT8_FLOAT32: - case NNP_FLOAT32: this->WriteBinary(file, prop, fixEndian); break; + case NNP_FLOAT32: helper.WriteBinary(*this, file, prop, fixEndian); break; case NNP_LIST_UINT8_INT32: case NNP_LIST_INT8_INT32: - case NNP_INT32: this->WriteBinary(file, prop, fixEndian); break; + case NNP_INT32: helper.WriteBinary(*this, file, prop, fixEndian); break; case NNP_LIST_UINT8_UINT32: case NNP_LIST_INT8_UINT32: - case NNP_UINT32: this->WriteBinary(file, prop, fixEndian); break; + case NNP_UINT32: helper.WriteBinary(*this, file, prop, fixEndian); break; case NNP_LIST_INT8_FLOAT64: case NNP_LIST_UINT8_FLOAT64: - case NNP_FLOAT64: this->WriteBinary(file, prop, fixEndian); break; + case NNP_FLOAT64: helper.WriteBinary(*this, file, prop, fixEndian); break; } return true; } template - template - inline void DataDescriptor::WriteAscii(PlyFile &file, PlyProperty &prop) - { - int count = prop.CountValue(); - if (prop.type >= NNP_LIST_UINT8_UINT32) - { - if (prop.IsSigned()) - { - int listSize = (int)VectorSize; - file.WriteAsciiData(listSize); - count = VectorSize; - } - else - { - unsigned int listSize = (unsigned int)VectorSize; - file.WriteAsciiData(listSize); - count = VectorSize; - } - file.WriteAsciiData(std::string(" ")); - } - - C data[VectorSize]; - unsigned char* baseProp = (unsigned char*)base + this->curPos*sizeof(ContainerType); - if ((prop.elem == NNP_CRGB || prop.elem == NNP_CRGBA)) - { - float norm = 1.0; - if (std::is_same::value && prop.type == NNP_UINT8) - norm = 255.0f; - else if (std::is_same::value && prop.type == NNP_FLOAT32) - norm = 1.0f / 255.0f; - for (int i = 0; i < std::min(VectorSize, count); i++) - data[i] = (C)((*(ScalarType*)(baseProp + i*sizeof(ScalarType))) * norm); - } - else - { - for (int i = 0; i < std::min(VectorSize, count); i++) - data[i] = (C)((*(ScalarType*)(baseProp + i*sizeof(ScalarType)))); - } - - - for (int i = 0; i < (count - VectorSize); i++) - data[i] = 0; - - for (int i = 0; i < count; i++) - { - file.WriteAsciiData(data[i]); - if (i < count - 1) - file.WriteAsciiData(std::string(" ")); - } - ++(this->curPos); - } - - - template - inline bool DataDescriptor::WriteElemAscii(PlyFile &file, PlyProperty& prop) + bool DataDescriptor::WriteElemAscii(PlyFile &file, PlyProperty& prop) { if (prop.elem != elem) return false; @@ -2356,28 +2480,28 @@ namespace nanoply { case NNP_LIST_UINT8_INT8: case NNP_LIST_INT8_INT8: - case NNP_INT8: this->WriteAscii(file, prop); break; + case NNP_INT8: helper.WriteAscii(*this, file, prop); break; case NNP_LIST_UINT8_UINT8: case NNP_LIST_INT8_UINT8: - case NNP_UINT8: this->WriteAscii(file, prop); break; + case NNP_UINT8: helper.WriteAscii(*this, file, prop); break; case NNP_LIST_UINT8_INT16: case NNP_LIST_INT8_INT16: - case NNP_INT16: this->WriteAscii(file, prop); break; + case NNP_INT16: helper.WriteAscii(*this, file, prop); break; case NNP_LIST_UINT8_UINT16: case NNP_LIST_INT8_UINT16: - case NNP_UINT16: this->WriteAscii(file, prop); break; + case NNP_UINT16: helper.WriteAscii(*this, file, prop); break; case NNP_LIST_UINT8_FLOAT32: case NNP_LIST_INT8_FLOAT32: - case NNP_FLOAT32: this->WriteAscii(file, prop); break; + case NNP_FLOAT32: helper.WriteAscii(*this, file, prop); break; case NNP_LIST_UINT8_INT32: case NNP_LIST_INT8_INT32: - case NNP_INT32: this->WriteAscii(file, prop); break; + case NNP_INT32: helper.WriteAscii(*this, file, prop); break; case NNP_LIST_UINT8_UINT32: case NNP_LIST_INT8_UINT32: - case NNP_UINT32: this->WriteAscii(file, prop); break; + case NNP_UINT32: helper.WriteAscii(*this, file, prop); break; case NNP_LIST_UINT8_FLOAT64: case NNP_LIST_INT8_FLOAT64: - case NNP_FLOAT64: this->WriteAscii(file, prop); break; + case NNP_FLOAT64: helper.WriteAscii(*this, file, prop); break; } return true; } diff --git a/wrap/nanoply/include/nanoplyWrapper.hpp b/wrap/nanoply/include/nanoplyWrapper.hpp index 6fd77eab..c5f3a87c 100644 --- a/wrap/nanoply/include/nanoplyWrapper.hpp +++ b/wrap/nanoply/include/nanoplyWrapper.hpp @@ -19,6 +19,8 @@ #include #include +#include + namespace nanoply { @@ -28,38 +30,49 @@ namespace nanoply private: - typedef typename MeshType::PointerToAttribute PointerToAttribute; - typedef typename MeshType::ScalarType ScalarType; + 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::ScalarType VertexNormScalar; - 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::ScalarType VertexTexScalar; - typedef typename MeshType::VertexType::CurvatureType::ScalarType VertexCurScalar; - typedef typename MeshType::VertexType::CurScalarType VertexDirCurScalar; - typedef typename MeshType::VertexType::CurVecType::ScalarType VertexDirCurVecScalar; + 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::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::ScalarType FaceNormScalar; - typedef typename MeshType::FaceType::ColorType::ScalarType FaceColorScalar; - typedef typename MeshType::FaceType::QualityType FaceQuality; - typedef typename MeshType::FaceType::FlagType FaceFlag; - typedef typename MeshType::FaceType::TexCoordType::ScalarType FaceTexScalar; - typedef typename MeshType::FaceType::CurScalarType FaceDirCurScalar; - typedef typename MeshType::FaceType::CurVecType::ScalarType FaceDirCurVecScalar; - typedef typename MeshType::FaceType::WedgeColorType::ScalarType WedgeColorScalar; - typedef typename MeshType::FaceType::WedgeNormalType::ScalarType WedgeNormalScalar; + 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::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::WedgeColorTypePack WedgeColorType; + typedef typename MeshType::FaceType::WedgeColorType::ScalarType WedgeColorScalar; + typedef typename vcg::face::vector_ocf::WedgeNormalTypePack WedgeNormalType; + typedef typename MeshType::FaceType::WedgeNormalType::ScalarType WedgeNormalScalar; - + typedef typename MeshType::FaceIterator FaceIterator; template static PlyType getEntity() { return NNP_UNKNOWN_TYPE }; template<> static PlyType getEntity(){ return NNP_UINT8; }; @@ -120,38 +133,40 @@ namespace nanoply public: - typedef enum { - IO_NONE = 0x00000000, + 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_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_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_EDGEINDEX = 0x00020000, + IO_EDGEQUALITY = 0x00040000, + IO_EDGECOLOR = 0x00080000, + IO_EDGEFLAGS = 0x00100000, + IO_EDGEATTRIB = 0x00200000, - IO_WEDGCOLOR = 0x00400000, - IO_WEDGTEXCOORD = 0x00800000, - IO_WEDGTEXMULTI = 0x01000000, // when textrue index is explicit - IO_WEDGNORMAL = 0x02000000, + 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 @@ -202,28 +217,25 @@ namespace nanoply template - void AddVertexAttribDescriptor(std::string& name, PlyType type, void* ptr) + void AddVertexAttribDescriptor(const std::string& name, PlyType type, void* ptr) { - vertexAttrib.push_back(new DataDescriptor(name, ptr)); - vertexAttribProp.push_back(PlyProperty(type, name)); + AddAttribDescriptor(name, type, ptr, vertexAttrib, vertexAttribProp); + } + + template + void AddEdgeAttribDescriptor(const std::string& name, PlyType type, void* ptr) + { + AddAttribDescriptor(name, type, ptr, edgeAttrib, edgeAttribProp); } template - void AddEdgeAttribDescriptor(std::string& name, PlyType type, void* ptr) + void AddFaceAttribDescriptor(const std::string& name, PlyType type, void* ptr) { - edgeAttrib.push_back(new DataDescriptor(name, ptr)); - edgeAttribProp.push_back(PlyProperty(type, name)); + AddAttribDescriptor(name, type, ptr, faceAttrib, faceAttribProp); } template - void AddFaceAttribDescriptor(std::string& name, PlyType type, void* ptr) - { - faceAttrib.push_back(new DataDescriptor(name, ptr)); - faceAttribProp.push_back(PlyProperty(type, name)); - } - - template - void AddMeshAttribDescriptor(std::string& nameAttrib, std::string& nameProp, PlyType type, void* ptr) + void AddMeshAttribDescriptor(const std::string& nameAttrib, std::string& nameProp, PlyType type, void* ptr) { meshAttrib[nameAttrib].push_back(new DataDescriptor(nameProp, ptr)); meshAttribProp[nameAttrib].push_back(PlyProperty(type, nameProp)); @@ -246,18 +258,669 @@ namespace nanoply } } } + + 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& ptrAttrib, PlyElement* elem) + { + return AddCustomAttrib<0>(m, ptrAttrib, elem, vertexAttrib); + } + + bool AddEdgeAttrib(MeshType& m, std::set& ptrAttrib, PlyElement* elem) + { + return AddCustomAttrib<1>(m, ptrAttrib, elem, vertexAttrib); + } + + bool AddFaceAttrib(MeshType& m, std::set& ptrAttrib, PlyElement* elem) + { + return AddCustomAttrib<2>(m, ptrAttrib, elem, vertexAttrib); + } + + + + private: + + const std::vector pointSuffix = { "x", "y", "z", "w" }; + const std::vector colorSuffix = { "r", "g", "b", "a" }; + const std::map pointSuffixMap = { { "x", 0 },{ "y", 1 },{ "z", 2 },{ "w", 3 } }; + const std::map colorSuffixMap = { {"r", 0},{ "g", 1 },{ "b", 2 },{ "a", 3 } }; + const std::string separator = std::string("@_.#$>"); + + template + void AddAttribDescriptor(const std::string& name, PlyType type, void* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector& attribProp) + { + attrib.push_back(new DataDescriptor(name, ptr)); + attribProp.push_back(PlyProperty(type, name)); + } + + template + void AddScalarAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector& attribProp) + { + AddAttribDescriptor(ptr->_name, getEntity(), ptr->_handle->DataBegin(), attrib, attribProp); + } + + template + void AddPointAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector& attribProp) + { + int size = typename Container::Dimension; + std::string name(ptr->_name); + Container* tmpPtr = (Container*)ptr->_handle->DataBegin(); + for (int i = 0 ; i < size; i++) + AddAttribDescriptor((name + "." + pointSuffix[i]), getEntity(), &(*tmpPtr)[i], attrib, attribProp); + } + + template + void AddColorAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector& attribProp) + { + int size = typename Container::Dimension; + std::string name(ptr->_name); + Container* tmpPtr = (Container*)ptr->_handle->DataBegin(); + for (int i = 0; i < size; i++) + AddAttribDescriptor((name + "." + colorSuffix[i]), getEntity(), &(*tmpPtr)[i], attrib, attribProp); + } + + template + void AddListAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector& attribProp) + { + AddAttribDescriptor(ptr->_name, getEntityList(), ptr->_handle->DataBegin(), attrib, attribProp); + } + + bool CreateAttribDescriptor(const PointerToAttribute* ptr, ElementDescriptor::PropertyDescriptor& attrib, std::vector& attribProp) + { + if (ptr->_type == std::type_index(typeid(unsigned char))) + AddScalarAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(char))) + AddScalarAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(unsigned short))) + AddScalarAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(short))) + AddScalarAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(unsigned int))) + AddScalarAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(int))) + AddScalarAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(float))) + AddScalarAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(double))) + AddScalarAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point2s))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point2i))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point2f))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point2d))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point3s))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point3i))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point3f))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point3d))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point4s))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point4i))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point4f))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Point4d))) + AddPointAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Color4b))) + AddColorAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Color4f))) + AddColorAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Color4d))) + AddColorAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(vcg::Color4d))) + AddColorAttribDescriptor(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(std::vector))) + AddListAttribDescriptor, unsigned char>(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(std::vector))) + AddListAttribDescriptor,char>(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(std::vector))) + AddListAttribDescriptor, unsigned short>(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(std::vector))) + AddListAttribDescriptor, short>(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(std::vector))) + AddListAttribDescriptor, unsigned int>(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(std::vector))) + AddListAttribDescriptor, int>(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(std::vector))) + AddListAttribDescriptor, float>(ptr, attrib, attribProp); + else if (ptr->_type == std::type_index(typeid(std::vector))) + AddListAttribDescriptor, double>(ptr, attrib, attribProp); + else + return false; + return true; + } + + + template + void AddScalarAttrib(MeshType& m, const std::string& name, PlyType& type) + { + if (ActionType == 0) //vertex + { + auto h = vcg::tri::Allocator::GetPerVertexAttribute(m, name); + AddVertexAttribDescriptor(name, type, h._handle->DataBegin()); + } + else if (ActionType == 1) //Edge + { + auto h = vcg::tri::Allocator::GetPerEdgeAttribute(m, name); + AddEdgeAttribDescriptor(name, type, h._handle->DataBegin()); + } + else if (ActionType == 2) //Face + { + auto h = vcg::tri::Allocator::GetPerFaceAttribute(m, name); + AddFaceAttribDescriptor(name, type, h._handle->DataBegin()); + } + } + + template + void AddPointAttrib(MeshType& m, const std::string& name, std::vector& prop) + { + if (ActionType == 0) //vertex + { + auto h = vcg::tri::Allocator::GetPerVertexAttribute(m, name); + for (int i = 0; i < prop.size(); i++) + AddVertexAttribDescriptor(prop[i].name, prop[i].type, &h[0][i]); + } + else if (ActionType == 1) //Edge + { + auto h = vcg::tri::Allocator::GetPerEdgeAttribute(m, name); + for (int i = 0; i < prop.size(); i++) + AddEdgeAttribDescriptor(prop[i].name, prop[i].type, &h[0][i]); + } + else if (ActionType == 2) //Face + { + auto h = vcg::tri::Allocator::GetPerFaceAttribute(m, name); + for (int i = 0; i < prop.size(); i++) + AddFaceAttribDescriptor(prop[i].name, prop[i].type, &h[0][i]); + } + } + + + template + void AddListAttrib(MeshType& m, const std::string& name, PlyType& type) + { + if (ActionType == 0) //vertex + { + auto h = vcg::tri::Allocator::GetPerVertexAttribute(m, name); + AddVertexAttribDescriptor(name, type, h._handle->DataBegin()); + } + else if (ActionType == 1) //Edge + { + auto h = vcg::tri::Allocator::GetPerEdgeAttribute(m, name); + AddEdgeAttribDescriptor(name, type, h._handle->DataBegin()); + } + else if (ActionType == 2) //Face + { + auto h = vcg::tri::Allocator::GetPerFaceAttribute(m, name); + AddFaceAttribDescriptor(name, type, h._handle->DataBegin()); + } + } + + + template + bool AddCustomAttrib(MeshType& m, std::set& ptrAttrib, PlyElement* elem, ElementDescriptor::PropertyDescriptor& attrib) + { + //Custom attribute with already a data descriptor + std::set validCustomAttrib; + for (int i = 0; i < attrib.size(); i++) + { + if (attrib[i]->base == NULL) + { + std::set::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, int>> customAttribName; + std::vector attribName((*elem).propVec.size()); + for (int 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::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, int>>::iterator mapIter; + for (mapIter = customAttribName.begin(); mapIter != customAttribName.end(); mapIter++) + { + unsigned int bitType = 0; + std::vector tempProp((*mapIter).second.first.size()); + int checkMask = (1 << (*mapIter).second.first.size()) - 1; + for (int 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)); + if (tempProp.size() > 1 && ((bitType & (~tempProp[0].type)) == 0)) + { + if (tempProp.size() == 2) + { + switch (tempProp[0].type) + { + case NNP_FLOAT32: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_FLOAT64: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_INT8: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_INT16: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_INT32: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_UINT8: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_UINT16: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_UINT32: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + } + } + else if (tempProp.size() == 3) + { + switch (tempProp[0].type) + { + case NNP_FLOAT32: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_FLOAT64: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_INT8: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_INT16: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_INT32: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_UINT8: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_UINT16: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_UINT32: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + } + } + else if (tempProp.size() == 4 && (*mapIter).second.second != (checkMask << 4)) + { + switch (tempProp[0].type) + { + case NNP_FLOAT32: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_FLOAT64: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_INT8: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_INT16: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_INT32: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_UINT8: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_UINT16: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + case NNP_UINT32: AddPointAttrib>(m, (*mapIter).first, tempProp); break; + } + } + 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(m, (*mapIter).first, tempProp); break; + case NNP_FLOAT64: AddPointAttrib(m, (*mapIter).first, tempProp); break; + case NNP_UINT8: AddPointAttrib(m, (*mapIter).first, tempProp); break; + } + } + } + else + { + for (int i = 0; i < tempProp.size(); i++) + { + switch (tempProp[i].type) + { + case NNP_FLOAT32: AddScalarAttrib(m, tempProp[i].name, tempProp[i].type); break; + case NNP_FLOAT64: AddScalarAttrib(m, tempProp[i].name, tempProp[i].type); break; + case NNP_INT8: AddScalarAttrib(m, tempProp[i].name, tempProp[i].type); break; + case NNP_INT16: AddScalarAttrib(m, tempProp[i].name, tempProp[i].type); break; + case NNP_INT32: AddScalarAttrib(m, tempProp[i].name, tempProp[i].type); break; + case NNP_UINT8: AddScalarAttrib(m, tempProp[i].name, tempProp[i].type); break; + case NNP_UINT16: AddScalarAttrib(m, tempProp[i].name, tempProp[i].type); break; + case NNP_UINT32: AddScalarAttrib(m, tempProp[i].name, tempProp[i].type); break; + case NNP_LIST_UINT8_UINT32: + case NNP_LIST_INT8_UINT32: AddListAttrib, unsigned int>(m, tempProp[i].name, tempProp[i].type); break; + case NNP_LIST_UINT8_INT32: + case NNP_LIST_INT8_INT32: AddListAttrib, int>(m, tempProp[i].name, tempProp[i].type); break; + case NNP_LIST_UINT8_FLOAT32: + case NNP_LIST_INT8_FLOAT32: AddListAttrib, float>(m, tempProp[i].name, tempProp[i].type); break; + case NNP_LIST_UINT8_FLOAT64: + case NNP_LIST_INT8_FLOAT64: AddListAttrib, double>(m, tempProp[i].name, tempProp[i].type); break; + case NNP_LIST_UINT8_UINT8: + case NNP_LIST_INT8_UINT8: AddListAttrib, unsigned char>(m, tempProp[i].name, tempProp[i].type); break; + case NNP_LIST_UINT8_INT8: + case NNP_LIST_INT8_INT8: AddListAttrib, char>(m, tempProp[i].name, tempProp[i].type); break; + case NNP_LIST_UINT8_UINT16: + case NNP_LIST_INT8_UINT16: AddListAttrib, unsigned short>(m, tempProp[i].name, tempProp[i].type); break; + case NNP_LIST_UINT8_INT16: + case NNP_LIST_INT8_INT16: AddListAttrib, short>(m, tempProp[i].name, tempProp[i].type); break; + } + } + } + } + return true; + } + + }; + template + struct OcfManager + { + typedef typename T::VertexType VType; + typedef typename T::FaceType FType; + typedef typename T::EdgeType EType; + + + template >::value> + static unsigned int EnableVertexOcf(typename T::VertContainer& cont, unsigned int mask) { + return 0; + } + + template <> + static unsigned int EnableVertexOcf(typename T::VertContainer& cont, unsigned int mask ) + { + unsigned int enabledMask = 0; + 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 >::value> + static unsigned int EnableFaceOcf(typename T::FaceContainer& cont, unsigned int mask) { + return 0; + } + + template <> + static unsigned int EnableFaceOcf(typename T::FaceContainer& cont, unsigned int mask) + { + unsigned int enabledMask = 0; + 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 >::value> + static unsigned int VertexOcfMask(typename T::VertContainer& cont) { + return 0; + } + + template <> + static unsigned int VertexOcfMask(typename T::VertContainer& cont) + { + unsigned int enabledMask = 0; + 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 >::value> + static unsigned int FaceOcfMask(typename T::FaceContainer& cont) { + return 0; + } + + template <> + static unsigned int FaceOcfMask(typename T::FaceContainer& cont) + { + unsigned int enabledMask = 0; + 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 (int j = 0; j < info.elemVec.size(); j++) + { + PlyElement& elem = info.elemVec[j]; + if (elem.plyElem == PlyElemEntity::NNP_VERTEX_ELEM) + { + for (int 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; + } + } + } + else if (elem.plyElem == PlyElemEntity::NNP_EDGE_ELEM) + { + for (int 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; + } + } + } + else if (elem.plyElem == PlyElemEntity::NNP_FACE_ELEM) + { + for (int 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; + } + } + } + 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; - - //Camera + + unsigned int headerMask = GetFileBitMask(info); + bitMask &= headerMask; + unsigned int ocfVertexMask = OcfManager::EnableVertexOcf(mesh.vert, bitMask); + unsigned int ocfFaceMask = OcfManager::EnableFaceOcf(mesh.face, bitMask); + + //Camera ElementDescriptor cameraDescr(std::string("camera")); vcg::Point3 tra; vcg::Matrix44 rot; @@ -299,46 +962,82 @@ namespace nanoply vcg::tri::Allocator::AddVertices(mesh, count); if ((bitMask & BitMask::IO_VERTCOORD) && VertexType::HasCoord()) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_PXYZ, (*mesh.vert.begin()).P().V())); - if ((bitMask & BitMask::IO_VERTNORMAL) && vcg::tri::HasPerVertexNormal(mesh)) - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_NXYZ, (*mesh.vert.begin()).N().V())); - if ((bitMask & BitMask::IO_VERTCOLOR) && vcg::tri::HasPerVertexColor(mesh)) - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_CRGBA, (*mesh.vert.begin()).C().V())); - if ((bitMask & BitMask::IO_VERTQUALITY) && vcg::tri::HasPerVertexQuality(mesh)) - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_QUALITY, &(*mesh.vert.begin()).Q())); + if ((bitMask & BitMask::IO_VERTNORMAL) && vcg::tri::HasPerVertexNormal(mesh)) + { + if (ocfVertexMask & BitMask::IO_VERTNORMAL) + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_NXYZ, (*mesh.vert.begin()).N().V())); + else + vertexDescr.dataDescriptor.push_back(new DataDescriptor(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(NNP_CRGBA, (*mesh.vert.begin()).C().V())); + else + vertexDescr.dataDescriptor.push_back(new DataDescriptor(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(NNP_QUALITY, &(*mesh.vert.begin()).Q())); + else + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_QUALITY, &(*mesh.vert.begin()).Q())); + } if ((bitMask & BitMask::IO_VERTFLAGS) && vcg::tri::HasPerVertexFlags(mesh)) vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_BITFLAG, &(*mesh.vert.begin()).Flags())); - if ((bitMask & BitMask::IO_VERTRADIUS) && vcg::tri::HasPerVertexRadius(mesh)) - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_DENSITY, &(*mesh.vert.begin()).R())); - if ((bitMask & BitMask::IO_VERTTEXCOORD) && vcg::tri::HasPerVertexTexCoord(mesh)) - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); - if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) + if ((bitMask & BitMask::IO_VERTRADIUS) && vcg::tri::HasPerVertexRadius(mesh)) + { + if (ocfVertexMask & BitMask::IO_VERTRADIUS) + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_DENSITY, &(*mesh.vert.begin()).R())); + else + vertexDescr.dataDescriptor.push_back(new DataDescriptor(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(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); + else + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V())); + } + if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) { - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); + if (ocfVertexMask & BitMask::IO_VERTCURV) + { + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); + } + else + { + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KG, &(*mesh.vert.begin()).Kg())); + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_KH, &(*mesh.vert.begin()).Kh())); + } } if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) { - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.vert.begin()).K1())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2, &(*mesh.vert.begin()).K2())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1DIR, (*mesh.vert.begin()).PD1().V())); - vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2DIR, (*mesh.vert.begin()).PD2().V())); - } - if ((bitMask & BitMask::IO_VERTATTRIB) && custom.vertexAttrib.size() > 0) - { - for (int i = 0; i < custom.vertexAttrib.size(); i++) - { - std::set::iterator ai; - for (ai = mesh.vert_attr.begin(); ai != mesh.vert_attr.end(); ++ai) - { - if ((*custom.vertexAttrib[i]).name == (*ai)._name) - { - custom.vertexAttrib[i]->base = ai->_handle->DataBegin(); - break; - } - } - vertexDescr.dataDescriptor.push_back(custom.vertexAttrib[i]); - } - } + if (ocfVertexMask & BitMask::IO_VERTCURVDIR) + { + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.vert.begin()).K1())); + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2, &(*mesh.vert.begin()).K2())); + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1DIR, (*mesh.vert.begin()).PD1().V())); + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2DIR, (*mesh.vert.begin()).PD2().V())); + } + else + { + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.vert.begin()).K1())); + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2, &(*mesh.vert.begin()).K2())); + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1DIR, (*mesh.vert.begin()).PD1().V())); + vertexDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2DIR, (*mesh.vert.begin()).PD2().V())); + } + } + if (bitMask & BitMask::IO_VERTATTRIB) + { + custom.AddVertexAttrib(mesh, mesh.vert_attr, info.GetVertexElement()); + for (int i = 0; i < custom.vertexAttrib.size(); i++) + { + if ((*custom.vertexAttrib[i]).base != NULL) + vertexDescr.dataDescriptor.push_back(custom.vertexAttrib[i]); + } + } } //Edge @@ -362,22 +1061,15 @@ namespace nanoply edgeDescr.dataDescriptor.push_back(new DataDescriptor(NNP_CRGBA, (*mesh.edge.begin()).C().V())); if ((bitMask & BitMask::IO_EDGEFLAGS) && vcg::tri::HasPerEdgeFlags(mesh)) edgeDescr.dataDescriptor.push_back(new DataDescriptor(NNP_BITFLAG, &(*mesh.edge.begin()).Flags())); - if ((bitMask & BitMask::IO_EDGEATTRIB) && custom.edgeAttrib.size() > 0) - { + if (bitMask & BitMask::IO_EDGEATTRIB) + { + custom.AddEdgeAttrib(mesh, mesh.edge_attr, info.GetEdgeElement()); for (int i = 0; i < custom.edgeAttrib.size(); i++) { - std::set::iterator ai; - for (ai = mesh.edge_attr.begin(); ai != mesh.edge_attr.end(); ++ai) - { - if ((*custom.edgeAttrib[i]).name == (*ai)._name) - { - custom.edgeAttrib[i]->base = ai->_handle->DataBegin(); - break; - } - } - edgeDescr.dataDescriptor.push_back(custom.edgeAttrib[i]); + if ((*custom.edgeAttrib[i]).base != NULL) + edgeDescr.dataDescriptor.push_back(custom.edgeAttrib[i]); } - } + } } //Face @@ -385,7 +1077,7 @@ namespace nanoply FaceType::Name(nameList); ElementDescriptor faceDescr(NNP_FACE_ELEM); count = info.GetFaceCount(); - std::vector faceIndex; + std::vector> faceIndex; std::vector> wedgeTexCoord; if (nameList.size() > 0 && count > 0) { @@ -393,52 +1085,83 @@ namespace nanoply if ((bitMask & BitMask::IO_FACEINDEX) && FaceType::HasVertexRef()) { faceIndex.resize(count); - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_FACE_VERTEX_LIST, (*faceIndex.begin()).V())); + faceDescr.dataDescriptor.push_back(new DataDescriptor,0, unsigned int>(NNP_FACE_VERTEX_LIST, &faceIndex[0])); } if ((bitMask & BitMask::IO_FACEFLAGS) && vcg::tri::HasPerFaceFlags(mesh)) faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_BITFLAG, &(*mesh.face.begin()).Flags())); - if ((bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh)) - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_CRGBA, (*mesh.face.begin()).C().V())); - if ((bitMask & BitMask::IO_FACEQUALITY) && vcg::tri::HasPerFaceQuality(mesh)) - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_QUALITY, &(*mesh.face.begin()).Q())); - if ((bitMask & BitMask::IO_FACENORMAL) && vcg::tri::HasPerFaceNormal(mesh)) - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_NXYZ, (*mesh.face.begin()).N().V())); - if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerFaceCurvatureDir(mesh)) + if ((bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh)) + { + if (ocfFaceMask & BitMask::IO_FACECOLOR) + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_CRGBA, (*mesh.face.begin()).C().V())); + else + faceDescr.dataDescriptor.push_back(new DataDescriptor(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(NNP_QUALITY, &(*mesh.face.begin()).Q())); + else + faceDescr.dataDescriptor.push_back(new DataDescriptor(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(NNP_NXYZ, (*mesh.face.begin()).N().V())); + else + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_NXYZ, (*mesh.face.begin()).N().V())); + } + if ((bitMask & BitMask::IO_FACECURVDIR) && vcg::tri::HasPerFaceCurvatureDir(mesh)) { - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.face.begin()).K1())); - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2, &(*mesh.face.begin()).K2())); - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1DIR, (*mesh.face.begin()).PD1().V())); - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2DIR, (*mesh.face.begin()).PD2().V())); + if (ocfFaceMask & BitMask::IO_FACECURVDIR) + { + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.face.begin()).K1())); + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2, &(*mesh.face.begin()).K2())); + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1DIR, (*mesh.face.begin()).PD1().V())); + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2DIR, (*mesh.face.begin()).PD2().V())); + } + else + { + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1, &(*mesh.face.begin()).K1())); + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K2, &(*mesh.face.begin()).K2())); + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_K1DIR, (*mesh.face.begin()).PD1().V())); + faceDescr.dataDescriptor.push_back(new DataDescriptor(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, 6, FaceTexScalar>(NNP_FACE_WEDGE_TEX, (*wedgeTexCoord.begin()).V())); } - if ((bitMask & BitMask::IO_WEDGTEXMULTI) && vcg::tri::HasPerWedgeTexCoord(mesh)) - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N())); - if ((bitMask & BitMask::IO_WEDGCOLOR) && vcg::tri::HasPerWedgeColor(mesh)) - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V())); - if ((bitMask & BitMask::IO_WEDGNORMAL) && vcg::tri::HasPerWedgeNormal(mesh)) - faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V())); - if ((bitMask & BitMask::IO_FACEATTRIB) && custom.faceAttrib.size() > 0) - { - for (int i = 0; i < custom.faceAttrib.size(); i++) - { - std::set::iterator ai; - for (ai = mesh.face_attr.begin(); ai != mesh.face_attr.end(); ++ai) - { - if ((*custom.faceAttrib[i]).name == (*ai)._name) - { - custom.faceAttrib[i]->base = ai->_handle->DataBegin(); - break; - } - } - faceDescr.dataDescriptor.push_back(custom.faceAttrib[i]); - - } - } - + if ((bitMask & BitMask::IO_WEDGTEXMULTI) && vcg::tri::HasPerWedgeTexCoord(mesh)) + { + if (ocfFaceMask & BitMask::IO_WEDGTEXMULTI) + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N())); + else + faceDescr.dataDescriptor.push_back(new DataDescriptor(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(NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V())); + else + faceDescr.dataDescriptor.push_back(new DataDescriptor(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(NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V())); + else + faceDescr.dataDescriptor.push_back(new DataDescriptor(NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V())); + } + if (bitMask & BitMask::IO_FACEATTRIB) + { + custom.AddFaceAttrib(mesh, mesh.face_attr, info.GetFaceElement()); + for (int i = 0; i < custom.faceAttrib.size(); i++) + { + if ((*custom.faceAttrib[i]).base != NULL) + faceDescr.dataDescriptor.push_back(custom.faceAttrib[i]); + } + } } std::vector meshDescr; @@ -468,18 +1191,70 @@ namespace nanoply mesh.shot.SetViewPoint(tra); mesh.shot.Extrinsics.SetRot(rot); + bool triangleMesh = true; for (int i = 0; i < faceIndex.size(); i++) - for (int j = 0; j < 3; j++) - mesh.face[i].V(j) = &mesh.vert[faceIndex[i][j]]; - for (int i = 0; i < wedgeTexCoord.size(); i++) + if (faceIndex[i].size() > 3) + triangleMesh = false; + + if (!triangleMesh && !vcg::tri::HasPolyInfo(mesh)) { - for (int j = 0; j < 3; j++) + 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 (int i = 0; i < faceIndex.size(); i++) { - mesh.face[i].WT(j).U() = wedgeTexCoord[i][j * 2]; - mesh.face[i].WT(j).V() = wedgeTexCoord[i][j * 2 + 1]; + 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::AddFaces(mesh, faceIndex[i].size() - 3); + for (int 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]; } } - for (int i = 0; i < edgeIndex.size(); i++) + else + { + for (int i = 0; i < faceIndex.size(); i++) + { + mesh.face[i].Alloc(faceIndex[i].size()); + for (int j = 0; j < faceIndex[i].size(); j++) + mesh.face[i].V(j) = &mesh.vert[faceIndex[i][j]]; + } + for (int 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]; + } + } + } + + for (int 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()]; @@ -510,6 +1285,9 @@ namespace nanoply static bool SaveModel(const char* filename, MeshType& mesh, unsigned int bitMask, CustomAttributeDescriptor& custom, bool binary) { + unsigned int ocfVertexMask = OcfManager::VertexOcfMask(mesh.vert); + unsigned int ocfFaceMask = OcfManager::FaceOcfMask(mesh.face); + //Camera std::vector cameraProp; ElementDescriptor cameraDescr(std::string("camera")); @@ -526,62 +1304,121 @@ namespace nanoply PushDescriport(cameraProp, cameraDescr, std::string("y_axisx"), &rot[1][0]); PushDescriport(cameraProp, cameraDescr, std::string("y_axisy"), &rot[1][1]); PushDescriport(cameraProp, cameraDescr, std::string("y_axisz"), &rot[1][2]); - PushDescriport(cameraProp, cameraDescr, std::string("z_axisx"), &rot[2][0]); - PushDescriport(cameraProp, cameraDescr, std::string("z_axisy"), &rot[2][1]); - PushDescriport(cameraProp, cameraDescr, std::string("z_axisz"), &rot[2][2]); - PushDescriport(cameraProp, cameraDescr, std::string("focal"), &mesh.shot.Intrinsics.FocalMm); - PushDescriport(cameraProp, cameraDescr, std::string("scalex"), &mesh.shot.Intrinsics.PixelSizeMm[0]); - PushDescriport(cameraProp, cameraDescr, std::string("scaley"), &mesh.shot.Intrinsics.PixelSizeMm[1]); - PushDescriport(cameraProp, cameraDescr, std::string("centerx"), &mesh.shot.Intrinsics.CenterPx[0]); - PushDescriport(cameraProp, cameraDescr, std::string("centery"), &mesh.shot.Intrinsics.CenterPx[1]); - PushDescriport(cameraProp, cameraDescr, std::string("viewportx"), &mesh.shot.Intrinsics.ViewportPx[0]); - PushDescriport(cameraProp, cameraDescr, std::string("viewporty"), &mesh.shot.Intrinsics.ViewportPx[1]); - PushDescriport(cameraProp, cameraDescr, std::string("k1"), &mesh.shot.Intrinsics.k[0]); - PushDescriport(cameraProp, cameraDescr, std::string("k2"), &mesh.shot.Intrinsics.k[1]); - PushDescriport(cameraProp, cameraDescr, std::string("k3"), &mesh.shot.Intrinsics.k[2]); - PushDescriport(cameraProp, cameraDescr, std::string("k4"), &mesh.shot.Intrinsics.k[3]); - } + PushDescriport(cameraProp, cameraDescr, std::string("z_axisx"), &rot[2][0]); + PushDescriport(cameraProp, cameraDescr, std::string("z_axisy"), &rot[2][1]); + PushDescriport(cameraProp, cameraDescr, std::string("z_axisz"), &rot[2][2]); + PushDescriport(cameraProp, cameraDescr, std::string("focal"), &mesh.shot.Intrinsics.FocalMm); + PushDescriport(cameraProp, cameraDescr, std::string("scalex"), &mesh.shot.Intrinsics.PixelSizeMm[0]); + PushDescriport(cameraProp, cameraDescr, std::string("scaley"), &mesh.shot.Intrinsics.PixelSizeMm[1]); + PushDescriport(cameraProp, cameraDescr, std::string("centerx"), &mesh.shot.Intrinsics.CenterPx[0]); + PushDescriport(cameraProp, cameraDescr, std::string("centery"), &mesh.shot.Intrinsics.CenterPx[1]); + PushDescriport(cameraProp, cameraDescr, std::string("viewportx"), &mesh.shot.Intrinsics.ViewportPx[0]); + PushDescriport(cameraProp, cameraDescr, std::string("viewporty"), &mesh.shot.Intrinsics.ViewportPx[1]); + PushDescriport(cameraProp, cameraDescr, std::string("k1"), &mesh.shot.Intrinsics.k[0]); + PushDescriport(cameraProp, cameraDescr, std::string("k2"), &mesh.shot.Intrinsics.k[1]); + PushDescriport(cameraProp, cameraDescr, std::string("k3"), &mesh.shot.Intrinsics.k[2]); + PushDescriport(cameraProp, cameraDescr, std::string("k4"), &mesh.shot.Intrinsics.k[3]); + } - //Vertex - std::vector nameList; - VertexType::Name(nameList); - std::vector vertexProp; - ElementDescriptor vertexDescr(NNP_VERTEX_ELEM); - if (nameList.size() > 0 && mesh.vert.size() > 0) - { - if ((bitMask & BitMask::IO_VERTCOORD) && VertexType::HasCoord()) - PushDescriport(vertexProp, vertexDescr, NNP_PXYZ, (*mesh.vert.begin()).P().V()); - if ((bitMask & BitMask::IO_VERTNORMAL) && vcg::tri::HasPerVertexNormal(mesh)) - PushDescriport(vertexProp, vertexDescr, NNP_NXYZ, (*mesh.vert.begin()).N().V()); - if ((bitMask & BitMask::IO_VERTCOLOR) && vcg::tri::HasPerVertexColor(mesh)) - PushDescriport(vertexProp, vertexDescr, NNP_CRGBA, (*mesh.vert.begin()).C().V()); - if ((bitMask & BitMask::IO_VERTQUALITY) && vcg::tri::HasPerVertexQuality(mesh)) - PushDescriport(vertexProp, vertexDescr, NNP_QUALITY, &(*mesh.vert.begin()).Q()); - if ((bitMask & BitMask::IO_VERTFLAGS) && vcg::tri::HasPerVertexFlags(mesh)) - PushDescriport(vertexProp, vertexDescr, NNP_BITFLAG, &(*mesh.vert.begin()).Flags()); - if ((bitMask & BitMask::IO_VERTRADIUS) && vcg::tri::HasPerVertexRadius(mesh)) - PushDescriport(vertexProp, vertexDescr, NNP_DENSITY, &(*mesh.vert.begin()).R()); - if ((bitMask & BitMask::IO_VERTTEXCOORD) && vcg::tri::HasPerVertexTexCoord(mesh)) - PushDescriport(vertexProp, vertexDescr, NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V()); - if ((bitMask & BitMask::IO_VERTCURV) && vcg::tri::HasPerVertexCurvature(mesh)) - { - PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); - PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); - } - if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) - { - PushDescriport(vertexProp, vertexDescr, NNP_K1, &(*mesh.vert.begin()).K1()); - PushDescriport(vertexProp, vertexDescr, NNP_K2, &(*mesh.vert.begin()).K2()); - PushDescriportList(vertexProp, vertexDescr, NNP_K1DIR, (*mesh.vert.begin()).PD1().V()); - PushDescriportList(vertexProp, vertexDescr, NNP_K2DIR, (*mesh.vert.begin()).PD2().V()); - } - if ((bitMask & BitMask::IO_VERTATTRIB) && custom.vertexAttrib.size() > 0) - { - for (int i = 0; i < custom.vertexAttrib.size(); i++) - { - vertexProp.push_back(custom.vertexAttribProp[i]); - vertexDescr.dataDescriptor.push_back(custom.vertexAttrib[i]); - } + //Vertex + std::vector nameList; + VertexType::Name(nameList); + std::vector vertexProp; + ElementDescriptor vertexDescr(NNP_VERTEX_ELEM); + if (nameList.size() > 0 && mesh.vert.size() > 0) + { + if ((bitMask & BitMask::IO_VERTCOORD) && VertexType::HasCoord()) + PushDescriport(vertexProp, vertexDescr, NNP_PXYZ, (*mesh.vert.begin()).P().V()); + if ((bitMask & BitMask::IO_VERTNORMAL) && vcg::tri::HasPerVertexNormal(mesh)) + { + if (ocfVertexMask & BitMask::IO_VERTNORMAL) + PushDescriport(vertexProp, vertexDescr, NNP_NXYZ, (*mesh.vert.begin()).N().V()); + else + PushDescriport(vertexProp, vertexDescr, NNP_NXYZ, (*mesh.vert.begin()).N().V()); + } + if ((bitMask & BitMask::IO_VERTCOLOR) && vcg::tri::HasPerVertexColor(mesh)) + { + if (ocfVertexMask & BitMask::IO_VERTCOLOR) + PushDescriport(vertexProp, vertexDescr, NNP_CRGBA, (*mesh.vert.begin()).C().V()); + else + PushDescriport(vertexProp, vertexDescr, NNP_CRGBA, (*mesh.vert.begin()).C().V()); + } + if ((bitMask & BitMask::IO_VERTQUALITY) && vcg::tri::HasPerVertexQuality(mesh)) + { + if (ocfVertexMask & BitMask::IO_VERTQUALITY) + PushDescriport(vertexProp, vertexDescr, NNP_QUALITY, &(*mesh.vert.begin()).Q()); + else + PushDescriport(vertexProp, vertexDescr, NNP_QUALITY, &(*mesh.vert.begin()).Q()); + } + if ((bitMask & BitMask::IO_VERTFLAGS) && vcg::tri::HasPerVertexFlags(mesh)) + PushDescriport(vertexProp, vertexDescr, NNP_BITFLAG, &(*mesh.vert.begin()).Flags()); + if ((bitMask & BitMask::IO_VERTRADIUS) && vcg::tri::HasPerVertexRadius(mesh)) + { + if (ocfVertexMask & BitMask::IO_VERTRADIUS) + PushDescriport(vertexProp, vertexDescr, NNP_DENSITY, &(*mesh.vert.begin()).R()); + else + PushDescriport(vertexProp, vertexDescr, NNP_DENSITY, &(*mesh.vert.begin()).R()); + } + if ((bitMask & BitMask::IO_VERTTEXCOORD) && vcg::tri::HasPerVertexTexCoord(mesh)) + { + if (ocfVertexMask & BitMask::IO_VERTTEXCOORD) + PushDescriport(vertexProp, vertexDescr, NNP_TEXTURE2D, (*mesh.vert.begin()).T().P().V()); + else + PushDescriport(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(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); + PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); + } + else + { + PushDescriport(vertexProp, vertexDescr, NNP_KG, &(*mesh.vert.begin()).Kg()); + PushDescriport(vertexProp, vertexDescr, NNP_KH, &(*mesh.vert.begin()).Kh()); + } + } + if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerVertexCurvatureDir(mesh)) + { + if (ocfVertexMask & BitMask::IO_VERTCURVDIR) + { + PushDescriport(vertexProp, vertexDescr, NNP_K1, &(*mesh.vert.begin()).K1()); + PushDescriport(vertexProp, vertexDescr, NNP_K2, &(*mesh.vert.begin()).K2()); + PushDescriportList(vertexProp, vertexDescr, NNP_K1DIR, (*mesh.vert.begin()).PD1().V()); + PushDescriportList(vertexProp, vertexDescr, NNP_K2DIR, (*mesh.vert.begin()).PD2().V()); + } + else + { + PushDescriport(vertexProp, vertexDescr, NNP_K1, &(*mesh.vert.begin()).K1()); + PushDescriport(vertexProp, vertexDescr, NNP_K2, &(*mesh.vert.begin()).K2()); + PushDescriportList(vertexProp, vertexDescr, NNP_K1DIR, (*mesh.vert.begin()).PD1().V()); + PushDescriportList(vertexProp, vertexDescr, NNP_K2DIR, (*mesh.vert.begin()).PD2().V()); + } + } + if ((bitMask & BitMask::IO_VERTATTRIB)) + { + std::set::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 (int i = 0; i < custom.vertexAttrib.size(); i++) + { + vertexProp.push_back(custom.vertexAttribProp[i]); + vertexDescr.dataDescriptor.push_back(custom.vertexAttrib[i]); + } } } @@ -606,14 +1443,31 @@ namespace nanoply PushDescriport(edgeProp, edgeDescr, NNP_CRGBA, (*mesh.edge.begin()).C().V()); if ((bitMask & BitMask::IO_EDGEFLAGS) && vcg::tri::HasPerEdgeFlags(mesh)) PushDescriport(edgeProp, edgeDescr, NNP_BITFLAG, &(*mesh.edge.begin()).Flags()); - if ((bitMask & BitMask::IO_EDGEATTRIB) && custom.edgeAttrib.size() > 0) - { - for (int i = 0; i < custom.edgeAttrib.size(); i++) - { - edgeProp.push_back(custom.edgeAttribProp[i]); - edgeDescr.dataDescriptor.push_back(custom.edgeAttrib[i]); - } - } + + if ((bitMask & BitMask::IO_EDGEATTRIB)) + { + std::set::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 (int i = 0; i < custom.edgeAttrib.size(); i++) + { + edgeProp.push_back(custom.edgeAttribProp[i]); + edgeDescr.dataDescriptor.push_back(custom.edgeAttrib[i]); + } + } } //Face @@ -621,11 +1475,14 @@ namespace nanoply FaceType::Name(nameList); std::vector faceProp; ElementDescriptor faceDescr(NNP_FACE_ELEM); - std::vector faceIndex; + std::vector> faceIndex; std::vector> wedgeTexCoord; - for (int i = 0; i < mesh.face.size(); i++) - faceIndex.push_back(vcg::Point3i(vcg::tri::Index(mesh, mesh.face[i].V(0)), vcg::tri::Index(mesh, mesh.face[i].V(1)), vcg::tri::Index(mesh, mesh.face[i].V(2)))); - + for (int i = 0; i < mesh.face.size(); i++) + { + faceIndex.push_back(std::vector()); + 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 (int i = 0; i < mesh.face.size(); i++) @@ -641,39 +1498,94 @@ namespace nanoply if (nameList.size() > 0 && mesh.face.size() > 0) { if ((bitMask & BitMask::IO_FACEINDEX) && FaceType::HasVertexRef()) - PushDescriportList(faceProp, faceDescr, NNP_FACE_VERTEX_LIST, (*faceIndex.begin()).V()); + PushDescriportList, unsigned int, 0>(faceProp, faceDescr, NNP_FACE_VERTEX_LIST, &faceIndex[0]); if ((bitMask & BitMask::IO_FACEFLAGS) && vcg::tri::HasPerFaceFlags(mesh)) PushDescriport(faceProp, faceDescr, NNP_BITFLAG, &(*mesh.face.begin()).Flags()); - if ((bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh)) - PushDescriport(faceProp, faceDescr, NNP_CRGBA, (*mesh.face.begin()).C().V()); - if ((bitMask & BitMask::IO_FACEQUALITY) && vcg::tri::HasPerFaceQuality(mesh)) - PushDescriport(faceProp, faceDescr, NNP_QUALITY, &(*mesh.face.begin()).Q()); - if ((bitMask & BitMask::IO_FACENORMAL) && vcg::tri::HasPerFaceNormal(mesh)) - PushDescriport(faceProp, faceDescr, NNP_NXYZ, (*mesh.face.begin()).N().V()); + if ((bitMask & BitMask::IO_FACECOLOR) && vcg::tri::HasPerFaceColor(mesh)) + { + if (ocfFaceMask & BitMask::IO_FACECOLOR) + PushDescriport(faceProp, faceDescr, NNP_CRGBA, (*mesh.face.begin()).C().V()); + else + PushDescriport(faceProp, faceDescr, NNP_CRGBA, (*mesh.face.begin()).C().V()); + } + if ((bitMask & BitMask::IO_FACEQUALITY) && vcg::tri::HasPerFaceQuality(mesh)) + { + if (ocfFaceMask & BitMask::IO_FACEQUALITY) + PushDescriport(faceProp, faceDescr, NNP_QUALITY, &(*mesh.face.begin()).Q()); + else + PushDescriport(faceProp, faceDescr, NNP_QUALITY, &(*mesh.face.begin()).Q()); + } + if ((bitMask & BitMask::IO_FACENORMAL) && vcg::tri::HasPerFaceNormal(mesh)) + { + if (ocfFaceMask & BitMask::IO_FACENORMAL) + PushDescriport(faceProp, faceDescr, NNP_NXYZ, (*mesh.face.begin()).N().V()); + else + PushDescriport(faceProp, faceDescr, NNP_NXYZ, (*mesh.face.begin()).N().V()); + } if ((bitMask & BitMask::IO_VERTCURVDIR) && vcg::tri::HasPerFaceCurvatureDir(mesh)) { - PushDescriport(faceProp, faceDescr, NNP_K1, &(*mesh.face.begin()).K1()); - PushDescriport(faceProp, faceDescr, NNP_K2, &(*mesh.face.begin()).K2()); - PushDescriportList(faceProp, faceDescr, NNP_K1DIR, (*mesh.face.begin()).PD1().V()); - PushDescriportList(faceProp, faceDescr, NNP_K2DIR, (*mesh.face.begin()).PD2().V()); + if (ocfFaceMask & BitMask::IO_VERTCURVDIR) + { + PushDescriport(faceProp, faceDescr, NNP_K1, &(*mesh.face.begin()).K1()); + PushDescriport(faceProp, faceDescr, NNP_K2, &(*mesh.face.begin()).K2()); + PushDescriportList(faceProp, faceDescr, NNP_K1DIR, (*mesh.face.begin()).PD1().V()); + PushDescriportList(faceProp, faceDescr, NNP_K2DIR, (*mesh.face.begin()).PD2().V()); + } + else + { + PushDescriport(faceProp, faceDescr, NNP_K1, &(*mesh.face.begin()).K1()); + PushDescriport(faceProp, faceDescr, NNP_K2, &(*mesh.face.begin()).K2()); + PushDescriportList(faceProp, faceDescr, NNP_K1DIR, (*mesh.face.begin()).PD1().V()); + PushDescriportList(faceProp, faceDescr, NNP_K2DIR, (*mesh.face.begin()).PD2().V()); + } } if (((bitMask & BitMask::IO_WEDGTEXCOORD) || (bitMask & BitMask::IO_WEDGTEXMULTI)) && vcg::tri::HasPerWedgeTexCoord(mesh)) PushDescriportList, FaceTexScalar, 6>(faceProp, faceDescr, NNP_FACE_WEDGE_TEX, (*wedgeTexCoord.begin()).V()); - if ((bitMask & BitMask::IO_WEDGTEXMULTI) && vcg::tri::HasPerWedgeTexCoord(mesh)) - PushDescriport(faceProp, faceDescr, NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N()); - if ((bitMask & BitMask::IO_WEDGCOLOR) && vcg::tri::HasPerWedgeColor(mesh)) - PushDescriportList(faceProp, faceDescr, NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V()); - if ((bitMask & BitMask::IO_WEDGNORMAL) && vcg::tri::HasPerWedgeNormal(mesh)) - PushDescriportList(faceProp, faceDescr, NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V()); - if ((bitMask & BitMask::IO_FACEATTRIB) && custom.faceAttrib.size() > 0) - { - for (int i = 0; i < custom.faceAttrib.size(); i++) - { - faceProp.push_back(custom.faceAttribProp[i]); - faceDescr.dataDescriptor.push_back(custom.faceAttrib[i]); - } - } - + if ((bitMask & BitMask::IO_WEDGTEXMULTI) && vcg::tri::HasPerWedgeTexCoord(mesh)) + { + if (ocfFaceMask & BitMask::IO_VERTCURVDIR) + PushDescriport(faceProp, faceDescr, NNP_TEXTUREINDEX, &(*mesh.face.begin()).WT(0).N()); + else + PushDescriport(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(faceProp, faceDescr, NNP_FACE_WEDGE_COLOR, (*mesh.face.begin()).WC(0).V()); + else + PushDescriportList(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(faceProp, faceDescr, NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V()); + else + PushDescriportList(faceProp, faceDescr, NNP_FACE_WEDGE_NORMAL, (*mesh.face.begin()).WN(0).V()); + } + if ((bitMask & BitMask::IO_FACEATTRIB)) + { + std::set::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 (int i = 0; i < custom.faceAttrib.size(); i++) + { + faceProp.push_back(custom.faceAttribProp[i]); + faceDescr.dataDescriptor.push_back(custom.faceAttrib[i]); + } + } } Info infoSave;