From b75bc9260759287d468ef769b4c77e059cab0ec8 Mon Sep 17 00:00:00 2001 From: Sylvain Thery Date: Fri, 1 Jul 2011 13:50:23 +0200 Subject: [PATCH] Ajout import fichier numerisation --- include/Algo/Import/AHEM.h | 167 +++++++ include/Algo/Import/AHEMImporter.h | 136 ++++++ include/Algo/Import/AHEMImporter.hpp | 486 +++++++++++++++++++ include/Algo/Import/AHEMImporterDefAttr.h | 75 +++ include/Algo/Import/AHEMImporterDefAttr.hpp | 260 ++++++++++ include/Algo/Import/import.h | 1 + include/Algo/Import/import2tables.h | 4 +- include/Algo/Import/import2tablesSurface.hpp | 164 ++++++- 8 files changed, 1290 insertions(+), 3 deletions(-) create mode 100644 include/Algo/Import/AHEM.h create mode 100644 include/Algo/Import/AHEMImporter.h create mode 100644 include/Algo/Import/AHEMImporter.hpp create mode 100644 include/Algo/Import/AHEMImporterDefAttr.h create mode 100644 include/Algo/Import/AHEMImporterDefAttr.hpp diff --git a/include/Algo/Import/AHEM.h b/include/Algo/Import/AHEM.h new file mode 100644 index 00000000..0001b3ad --- /dev/null +++ b/include/Algo/Import/AHEM.h @@ -0,0 +1,167 @@ +#ifndef __AHEM_H__ +#define __AHEM_H__ + + + + +#include + + + +#ifdef _WIN32 + +typedef __int8 stInt8; +typedef __int16 stInt16; +typedef __int32 stInt32; +typedef __int64 stInt64; + +typedef unsigned __int8 stUInt8; +typedef unsigned __int16 stUInt16; +typedef unsigned __int32 stUInt32; +typedef unsigned __int64 stUInt64; + + +#else + +#include + +typedef int8_t stInt8; +typedef int16_t stInt16; +typedef int32_t stInt32; +typedef int64_t stInt64; + +typedef uint8_t stUInt8; +typedef uint16_t stUInt16; +typedef uint32_t stUInt32; +typedef uint64_t stUInt64; + +#endif + + +#ifdef _WIN32 +#include +#define DEFINE_GUID_INFUNC(name, dw, w0, w1, b0, b1, b2, b3, b4, b5, b6, b7) static const GUID name = { dw, w0, w1, { b0, b1, b2, b3, b4, b5, b6, b7 } } +#else +#include +#define DEFINE_GUID(name, dw, w0, w1, b0, b1, b2, b3, b4, b5, b6, b7) UUID_DEFINE(name, dw & 0xff, (dw >> 8) & 0xff, (dw >> 16) & 0xff, (dw >> 24) & 0xff, w0 & 0xff, (w0 >> 8) & 0xff, w1 & 0xff, (w1 >> 8) & 0xff, b0, b1, b2, b3, b4, b5, b6, b7) +#define DEFINE_GUID_INFUNC DEFINE_GUID +typedef uuid_t GUID; +#endif + + +inline bool IsEqualGUID(const stUInt8* v1, const GUID& v2) +{ + const stUInt32* w1 = (stUInt32*)v1; + const stUInt32* w2 = (stUInt32*)&v2; + + return w1[0] == w2[0] && w1[1] == w2[1] && w1[2] == w2[2] && w1[3] == w2[3]; +} + + + +// {1B8E15D6-FE16-44E2-BDC8-9FBA3420B267} +DEFINE_GUID(AHEMDATATYPE_INT8, 0x1b8e15d6, 0xfe16, 0x44e2, 0xbd, 0xc8, 0x9f, 0xba, 0x34, 0x20, 0xb2, 0x67); +// {3D772789-9D2A-4527-8709-5B3E08BDD071} +DEFINE_GUID(AHEMDATATYPE_UINT8, 0x3d772789, 0x9d2a, 0x4527, 0x87, 0x9, 0x5b, 0x3e, 0x8, 0xbd, 0xd0, 0x71); +// {E6D2DD95-A4EF-4EA3-82FF-12F4BAB40C51} +DEFINE_GUID(AHEMDATATYPE_INT16, 0xe6d2dd95, 0xa4ef, 0x4ea3, 0x82, 0xff, 0x12, 0xf4, 0xba, 0xb4, 0xc, 0x51); +// {5A926579-9586-413B-BEF5-992E0A9CA8E5} +DEFINE_GUID(AHEMDATATYPE_UINT16, 0x5a926579, 0x9586, 0x413b, 0xbe, 0xf5, 0x99, 0x2e, 0xa, 0x9c, 0xa8, 0xe5); +// {717210F9-4AB4-4ED3-9ACC-8AC89AA6BE55} +DEFINE_GUID(AHEMDATATYPE_INT32, 0x717210f9, 0x4ab4, 0x4ed3, 0x9a, 0xcc, 0x8a, 0xc8, 0x9a, 0xa6, 0xbe, 0x55); +// {9EA6E534-B251-44C7-B40C-C33CCCD6C18F} +DEFINE_GUID(AHEMDATATYPE_UINT32, 0x9ea6e534, 0xb251, 0x44c7, 0xb4, 0xc, 0xc3, 0x3c, 0xcc, 0xd6, 0xc1, 0x8f); +// {F10D01EF-D677-453B-B7A7-E3C85E56A18D} +DEFINE_GUID(AHEMDATATYPE_INT64, 0xf10d01ef, 0xd677, 0x453b, 0xb7, 0xa7, 0xe3, 0xc8, 0x5e, 0x56, 0xa1, 0x8d); +// {C0FD73C4-8A06-4CB0-86D4-1B305BCEC3C7} +DEFINE_GUID(AHEMDATATYPE_UINT64, 0xc0fd73c4, 0x8a06, 0x4cb0, 0x86, 0xd4, 0x1b, 0x30, 0x5b, 0xce, 0xc3, 0xc7); +// {2BD6E606-E3E3-4873-AA23-21D552EB11B3} +DEFINE_GUID(AHEMDATATYPE_FLOAT32, 0x2bd6e606, 0xe3e3, 0x4873, 0xaa, 0x23, 0x21, 0xd5, 0x52, 0xeb, 0x11, 0xb3); +// {4CC5D944-4336-49B0-901D-842E30E87D3E} +DEFINE_GUID(AHEMDATATYPE_FLOAT64, 0x4cc5d944, 0x4336, 0x49b0, 0x90, 0x1d, 0x84, 0x2e, 0x30, 0xe8, 0x7d, 0x3e); + + + +// {0FDAF25D-2389-4A6D-BE3B-F8C00D118F23} +DEFINE_GUID(AHEMATTRIBUTE_POSITION, 0xfdaf25d, 0x2389, 0x4a6d, 0xbe, 0x3b, 0xf8, 0xc0, 0xd, 0x11, 0x8f, 0x23); + + + + +#define AHEM_MAGIC 0x4148454D + +#ifdef _WIN32 +typedef enum : stUInt32 +#else +typedef enum +#endif +{ + AHEMATTROWNER_UNKNOWN = 0, + AHEMATTROWNER_HALFEDGE = 1, + AHEMATTROWNER_VERTEX = 2, + AHEMATTROWNER_FACE = 3, + AHEMATTROWNER_HE_FACECORNER = 4, +#ifndef _WIN32 + AHEMATTROWNER_FORCE_DWORD = 0xffffffff +#endif +} AHEMAttributeOwner; + + +#pragma pack(push, 1) + +typedef struct +{ + stUInt32 meshChunkSize; + + stUInt32 heCount; + stUInt32 vxCount; + stUInt32 faceCount; + + stUInt32 faceMaxSize; +} AHEMTopologyHeader; + + +typedef struct +{ + stUInt32 fileStartOffset; + stUInt32 attributeChunkSize; + + stUInt8 semantic[16]; // Semantic GUID + + AHEMAttributeOwner owner; + stUInt32 attrPodSize; // 0 means non-pod-stored attribute + stUInt8 dataType[16]; // datatype GUID + stUInt32 dimension; + + stUInt32 nameSize; +} AHEMAttributeDescriptor; + + + +#define AHEM_MAGIC 0x4148454D + +typedef struct +{ + stUInt32 magic; + stUInt32 version; + + AHEMTopologyHeader meshHdr; + stUInt32 meshFileStartOffset; + + stUInt32 attributesChunkNumber; +} AHEMHeader; + + +typedef struct +{ + stUInt32 batchLength; + stUInt32 batchFaceSize; +} AHEMFaceBatchDescriptor; + + +#pragma pack(pop) + + + + +#endif // __AHEM_H__ diff --git a/include/Algo/Import/AHEMImporter.h b/include/Algo/Import/AHEMImporter.h new file mode 100644 index 00000000..569399f8 --- /dev/null +++ b/include/Algo/Import/AHEMImporter.h @@ -0,0 +1,136 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: https://iggservis.u-strasbg.fr/CGoGN/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#ifndef __AHEMIMPORTER_H__ +#define __AHEMIMPORTER_H__ + +#include +#include "Algo/Import/AHEM.h" + + + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Import +{ + + +/* + * Actual loaders for attributes + */ + +template +class AttributeImporter +{ +public: +#ifdef _WIN32 + virtual ~AttributeImporter() = 0 {} +#else + virtual ~AttributeImporter() {} +#endif + + virtual bool Handleable(const AHEMAttributeDescriptor* ad) const = 0; + + virtual void ImportAttribute( MapType& map, + const unsigned int* verticesId, + const Dart* facesId, + const AHEMHeader* hdr, + const char* attrName, + const AHEMAttributeDescriptor* ad, + const void* buffer) const = 0; +}; + + + +static const unsigned int ATTRIBUTE_NOTFOUND = (unsigned int)-1; + +/* + * Importer + */ + +template +class AHEMImporter +{ +public: + AHEMImporter(bool useDefaultImporters = true); + ~AHEMImporter(); + + bool Open(typename PFP::MAP* m, const char* filename); + void Close(); + + void LoadMesh(); + bool LoadAttribute(unsigned int attrIx, const char* attrName, const AttributeImporter* imp); + bool LoadAttribute(const GUID& semantic, const char* attrName = NULL); + void LoadAllAttributes(bool* status = NULL); + + // Low-level access to attributes + + inline unsigned int GetAttributesNum(); + inline void GetAttribute(AHEMAttributeDescriptor** ad, char** attrName, unsigned int ix); + inline unsigned int FindAttribute(const GUID& semantic); + + // Attribute importers and helpers + + std::vector*> loadersRegistry; + + inline std::vector*> FindImporters(const GUID& attrSemanticId); + inline std::vector*> FindImporters(const AHEMAttributeDescriptor* ad); + +protected: + + void LoadTopology(); + void LoadPosition(AHEMAttributeDescriptor* posDescr); + + + typename PFP::MAP* map; + std::ifstream f; + + AHEMHeader hdr; + + AHEMAttributeDescriptor* attrDesc; + char** attrNames; + + char* buffer; + unsigned int bufferSize; + + unsigned int* verticesId; + Dart* facesId; +}; + + + + +} // namespace Import + +} // namespace Algo + +} // namespace CGoGN + +#include "Algo/Import/AHEMImporter.hpp" + +#endif diff --git a/include/Algo/Import/AHEMImporter.hpp b/include/Algo/Import/AHEMImporter.hpp new file mode 100644 index 00000000..f3362209 --- /dev/null +++ b/include/Algo/Import/AHEMImporter.hpp @@ -0,0 +1,486 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: https://iggservis.u-strasbg.fr/CGoGN/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "Topology/generic/attributeHandler.h" + +#include "Geometry/matrix.h" + +#include "Algo/Import/AHEMImporterDefAttr.h" + + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Import +{ + + +class HESorter +{ +public: + unsigned int vxIdTo; + unsigned int vxIdFrom; + + Dart d; + + inline bool operator<(const HESorter& h) const + { + return (vxIdTo < h.vxIdTo) || (vxIdTo == h.vxIdTo && vxIdFrom < h.vxIdFrom); + } +}; + + + +#ifdef _WIN32 +int __cdecl OppositeSearch(const void* key, const void* datum) +#else +int OppositeSearch(const void* key, const void* datum) +#endif +{ + HESorter* k = (HESorter*)key; + HESorter* d = (HESorter*)datum; + + int z = (int)k->vxIdFrom - (int)d->vxIdTo; + return z != 0 ? z : ((int)k->vxIdTo - (int)d->vxIdFrom); +} + + + +template +AHEMImporter::AHEMImporter(bool useDefaultImporters) +{ + map = NULL; + + attrDesc = NULL; + attrNames = NULL; + + verticesId = NULL; + facesId = NULL; + + + // Default attribute loaders + + if(useDefaultImporters) + { + loadersRegistry.push_back(new UniversalLoader); + loadersRegistry.push_back(new UniversalLoader); + } +} + + +template +AHEMImporter::~AHEMImporter() +{ + if(f.is_open()) + Close(); + + + // Release all registered attribute loaders + + for(unsigned int i = 0 ; i < loadersRegistry.size() ; i++) + delete loadersRegistry[i]; +} + + + +template +bool AHEMImporter::Open(typename PFP::MAP* m, const char* filename) +{ + // Halt if file is a file is already open + + if(f.is_open() || map) + return false; + + + // Open file + + f.open(filename, std::ios::binary); + + if (!f.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl; + return false; + } + + + // Keep track of current map + + map = m; + + + // Read header + + f.read((char*)&hdr, sizeof(AHEMHeader)); + + if(hdr.magic != AHEM_MAGIC) + CGoGNerr << "Warning: " << filename << " invalid magic" << CGoGNendl; + + + + // Read attributes + + attrDesc = new AHEMAttributeDescriptor[hdr.attributesChunkNumber]; + attrNames = new char*[hdr.attributesChunkNumber]; + + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + { + f.read((char*)(attrDesc + i), sizeof(AHEMAttributeDescriptor)); + + attrNames[i] = new char[attrDesc[i].nameSize + 1]; + f.read(attrNames[i], attrDesc[i].nameSize); + attrNames[i][attrDesc[i].nameSize] = '\0'; + } + + + // Compute buffer size for largest chunk and allocate + + bufferSize = hdr.meshHdr.meshChunkSize; + + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + if(attrDesc[i].attributeChunkSize > bufferSize) + bufferSize = attrDesc[i].attributeChunkSize; + + + buffer = new char[bufferSize]; + + return true; +} + + +template +void AHEMImporter::Close() +{ + map = NULL; + + f.close(); + + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + delete[] attrNames[i]; + + delete[] attrNames; + attrNames = NULL; + + delete[] attrDesc; + attrDesc = NULL; + + delete[] buffer; + buffer = NULL; + + delete[] verticesId; + verticesId = NULL; + + delete[] facesId; + facesId = NULL; +} + + +template +void AHEMImporter::LoadMesh() +{ + // Load mesh topological structure + + LoadTopology(); + + + // Load vertices position + + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + if(IsEqualGUID(attrDesc[i].semantic, AHEMATTRIBUTE_POSITION)) + { + LoadPosition(attrDesc + i); + break; + } +} + + +template +void AHEMImporter::LoadTopology() +{ + // Allocate vertices + + AttributeContainer& vxContainer = map->getAttributeContainer(VERTEX_CELL); + + + verticesId = new unsigned int[hdr.meshHdr.vxCount]; + + for(unsigned int i = 0 ; i < hdr.meshHdr.vxCount ; i++) + verticesId[i] = vxContainer.insertLine(); + + + + // Ensure vertices are created by querying the position attribute + + AttributeHandler position = map->template getAttribute(VERTEX_ORBIT, "position") ; + + if (!position.isValid()) + position = map->template addAttribute(VERTEX_ORBIT, "position") ; + + + + // Read faces stream and create faces [only intra-face links] + + HESorter* addedHE = new HESorter[hdr.meshHdr.heCount]; + + facesId = new Dart[hdr.meshHdr.faceCount]; + + f.read(buffer, hdr.meshHdr.meshChunkSize); + char* batch = buffer; + + unsigned int fId = 0; + unsigned int heId = 0; + + while(fId < hdr.meshHdr.faceCount) + { + AHEMFaceBatchDescriptor* fbd = (AHEMFaceBatchDescriptor*)batch; + stUInt32* ix = (stUInt32*)(batch + sizeof(AHEMFaceBatchDescriptor)); + + for(unsigned int i = 0 ; i < fbd->batchLength ; i++) + { + Dart d = map->newFace(fbd->batchFaceSize); // create face + facesId[fId++] = d; + + unsigned int firstVx = verticesId[*ix++]; // setup face's vertices up to last HE + unsigned int prevVx = firstVx; + + for(unsigned int k = 0 ; k < fbd->batchFaceSize - 1 ; k++) + { + addedHE[heId].d = d; + addedHE[heId].vxIdFrom = prevVx; + addedHE[heId].vxIdTo = verticesId[*ix]; + + map->setDartEmbedding(VERTEX_ORBIT, d, prevVx); + d = map->phi1(d); + + prevVx = *ix++; + heId++; + } + + + // last HE + + addedHE[heId].d = d; + addedHE[heId].vxIdFrom = prevVx; + addedHE[heId].vxIdTo = firstVx; + + map->setDartEmbedding(VERTEX_ORBIT, d, prevVx); + heId++; + } + + batch = (char*)ix; + } + + + // Sort the HE for fast retrieval + + std::sort(addedHE, addedHE + hdr.meshHdr.heCount); + + + // Sew faces [inter-face links] + + for(unsigned int i = 0 ; i < hdr.meshHdr.heCount ; i++) + { + HESorter* opposite = (HESorter*)bsearch(addedHE + i, addedHE, hdr.meshHdr.heCount, sizeof(HESorter), OppositeSearch); + + if(opposite && opposite->d == map->phi2(opposite->d)) + map->sewFaces(addedHE[i].d, opposite->d); + } +} + + + +template +void AHEMImporter::LoadPosition(AHEMAttributeDescriptor* posDescr) +{ + AttributeHandler position = map->template getAttribute(VERTEX_ORBIT, "position") ; + + if (!position.isValid()) + position = map->template addAttribute(VERTEX_ORBIT, "position") ; + + + f.seekg(posDescr->fileStartOffset, std::ios_base::beg); + f.read(buffer, posDescr->attributeChunkSize); + + float* q = (float*)buffer; + + for(unsigned int i = 0 ; i < hdr.meshHdr.vxCount ; i++) + { + position[verticesId[i]] = typename PFP::VEC3(q[0], q[1], q[2]); + q += 3; + } +} + + + +template +bool AHEMImporter::LoadAttribute(unsigned int attrIx, const char* attrName, const AttributeImporter* imp) +{ + if(attrIx >= hdr.attributesChunkNumber) + return false; + + AHEMAttributeDescriptor* ad = attrDesc + attrIx; + + + // Fill buffer from file data + + f.seekg(ad->fileStartOffset, std::ios_base::beg); + f.read(buffer, ad->attributeChunkSize); + + + // Import attribute + + imp->ImportAttribute(*map, verticesId, facesId, &hdr, attrName, ad, buffer); + + return true; +} + + + +template +bool AHEMImporter::LoadAttribute(const GUID& semantic, const char* attrName) +{ + // Locate the descriptor using semantic identifier + + unsigned int ix = FindAttribute(semantic); + + if(ix == ATTRIBUTE_NOTFOUND) + return false; + + AHEMAttributeDescriptor* ad = attrDesc + ix; + const char* name = attrName ? attrName : attrNames[ix]; + + // Find suitable importer + + std::vector*> impList = FindImporters(ad); + + if(impList.empty()) + return false; + + AttributeImporter* imp = impList[0]; + + + // Fill buffer from file data + + f.seekg(ad->fileStartOffset, std::ios_base::beg); + f.read(buffer, ad->attributeChunkSize); + + + // Import attribute + + imp->ImportAttribute(*map, verticesId, facesId, &hdr, name, ad, buffer); + + return true; +} + + +template +void AHEMImporter::LoadAllAttributes(bool* status) +{ + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + { + std::vector*> impList = FindImporters(attrDesc + i); + + if(!impList.empty()) + LoadAttribute(i, attrNames[i], impList[0]); + + if(status) + status[i] = !impList.empty(); + } +} + + +template +unsigned int AHEMImporter::GetAttributesNum() +{ + return hdr.attributesChunkNumber; +} + + +template +void AHEMImporter::GetAttribute(AHEMAttributeDescriptor** ad, char** attrName, unsigned int ix) +{ + if(ix < hdr.attributesChunkNumber) + { + *ad = attrDesc + ix; + *attrName = attrNames[ix]; + } + else + { + *ad = NULL; + *attrName = NULL; + } +} + + +template +unsigned int AHEMImporter::FindAttribute(const GUID& semantic) +{ + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + if(IsEqualGUID(attrDesc[i].semantic, semantic)) + return i; + + return ATTRIBUTE_NOTFOUND; +} + + + +template +std::vector*> AHEMImporter::FindImporters(const GUID& attrSemanticId) +{ + std::vector*> ret; + + unsigned int ix = FindAttribute(attrSemanticId); + + if(ix == ATTRIBUTE_NOTFOUND) + return ret; + + + return FindImporters(attrDesc + ix); +} + + + +template +std::vector*> AHEMImporter::FindImporters(const AHEMAttributeDescriptor* ad) +{ + std::vector*> ret; + + for(unsigned int i = 0 ; i < loadersRegistry.size() ; i++) + if(loadersRegistry[i]->Handleable(ad)) + ret.push_back(loadersRegistry[i]); + + return ret; +} + + +} // namespace Import + +} // namespace Algo + +} // namespace CGoGN + + +#include "Algo/Import/AHEMImporterDefAttr.hpp" diff --git a/include/Algo/Import/AHEMImporterDefAttr.h b/include/Algo/Import/AHEMImporterDefAttr.h new file mode 100644 index 00000000..60b992b5 --- /dev/null +++ b/include/Algo/Import/AHEMImporterDefAttr.h @@ -0,0 +1,75 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: https://iggservis.u-strasbg.fr/CGoGN/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "Geometry/matrix.h" +#include "Algo/Import/AHEM.h" + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Import +{ + + + +/* + * Universal adaptor for standard attribute loaders that should work on every topological entity. + */ + +template +class UniversalLoader : public AttributeImporter +{ +public: + UniversalLoader() {} + virtual ~UniversalLoader() {} + + virtual bool Handleable(const AHEMAttributeDescriptor* ad) const; + + virtual void ImportAttribute( MapType& map, + const unsigned int* verticesId, + const Dart* facesId, + const AHEMHeader* hdr, + const char* attrName, + const AHEMAttributeDescriptor* ad, + const void* buffer) const; + + void UnpackOnVertex(MapType& map, const unsigned int* verticesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const; + void UnpackOnFace(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const; + void UnpackOnHE(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const; + void UnpackOnHEFC(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const; +}; + + +class Vec3FloatLoader; +class Mat44FloatLoader; + + +} // namespace Import + +} // namespace Algo + +} // namespace CGoGN diff --git a/include/Algo/Import/AHEMImporterDefAttr.hpp b/include/Algo/Import/AHEMImporterDefAttr.hpp new file mode 100644 index 00000000..54771320 --- /dev/null +++ b/include/Algo/Import/AHEMImporterDefAttr.hpp @@ -0,0 +1,260 @@ +/******************************************************************************* +* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps * +* version 0.1 * +* Copyright (C) 2009, IGG Team, LSIIT, University of Strasbourg * +* * +* This library is free software; you can redistribute it and/or modify it * +* under the terms of the GNU Lesser General Public License as published by the * +* Free Software Foundation; either version 2.1 of the License, or (at your * +* option) any later version. * +* * +* This library is distributed in the hope that it will be useful, but WITHOUT * +* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * +* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License * +* for more details. * +* * +* You should have received a copy of the GNU Lesser General Public License * +* along with this library; if not, write to the Free Software Foundation, * +* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * +* * +* Web site: https://iggservis.u-strasbg.fr/CGoGN/ * +* Contact information: cgogn@unistra.fr * +* * +*******************************************************************************/ + +#include "Geometry/matrix.h" +#include "Algo/Import/AHEM.h" + +namespace CGoGN +{ + +namespace Algo +{ + +namespace Import +{ + + +template +bool UniversalLoader::Handleable(const AHEMAttributeDescriptor* ad) const +{ + return AttrTypeLoader::Handleable(ad); +} + + +template +void UniversalLoader::ImportAttribute( MapType& map, + const unsigned int* verticesId, + const Dart* facesId, + const AHEMHeader* hdr, + const char* attrName, + const AHEMAttributeDescriptor* ad, + const void* buffer) const +{ + switch(ad->owner) + { + case AHEMATTROWNER_VERTEX: + UnpackOnVertex(map, verticesId, hdr, attrName, buffer); + break; + + case AHEMATTROWNER_FACE: + UnpackOnFace(map, facesId, hdr, attrName, buffer); + break; + + case AHEMATTROWNER_HALFEDGE: + UnpackOnHE(map, facesId, hdr, attrName, buffer); + break; + + case AHEMATTROWNER_HE_FACECORNER: + UnpackOnHEFC(map, facesId, hdr, attrName, buffer); + break; + + default: + break; + } +} + + +template +void UniversalLoader::UnpackOnVertex(MapType& map, const unsigned int* verticesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const +{ + AttributeHandler attr = map.template getAttribute(VERTEX_ORBIT, attrName); + + if (!attr.isValid()) + attr = map.template addAttribute(VERTEX_ORBIT, attrName); + + + char* p = (char*)buffer; + + for(unsigned int i = 0 ; i < hdr->meshHdr.vxCount ; i++) + { + AttrTypeLoader::Extract(&attr[verticesId[i]], p); + p += AttrTypeLoader::TYPE_SIZE_IN_BUFFER; + } +} + + +template +void UniversalLoader:: UnpackOnFace(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const +{ + AttributeHandler attr = map.template getAttribute(FACE_ORBIT, attrName); + + if (!attr.isValid()) + attr = map.template addAttribute(FACE_ORBIT, attrName); + + + + char* p = (char*)buffer; + + for(unsigned int i = 0 ; i < hdr->meshHdr.faceCount ; i++) + { + AttrTypeLoader::Extract(&attr[facesId[i]], p); + p += AttrTypeLoader::TYPE_SIZE_IN_BUFFER; + } +} + + +template +void UniversalLoader:: UnpackOnHE(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const +{ + AttributeHandler attr = map.template getAttribute(DART_ORBIT, attrName); + + if (!attr.isValid()) + attr = map.template addAttribute(DART_ORBIT, attrName); + + + + char* p = (char*)buffer; + + for(unsigned int i = 0 ; i < hdr->meshHdr.faceCount ; i++) + { + Dart start = map.phi_1(facesId[i]); + Dart d = start; + + do + { + AttrTypeLoader::Extract(&attr[d], p); + p += AttrTypeLoader::TYPE_SIZE_IN_BUFFER; + d = map.phi1(d); + } + while(d != start); + } +} + + +template +void UniversalLoader:: UnpackOnHEFC(MapType& map, const Dart* facesId, const AHEMHeader* hdr, const char* attrName, const void* buffer) const +{ + AttributeHandler attr = map.template getAttribute(DART_ORBIT, attrName); + + if (!attr.isValid()) + attr = map.template addAttribute(DART_ORBIT, attrName); + + + char* p = (char*)buffer; + + for(unsigned int i = 0 ; i < hdr->meshHdr.faceCount ; i++) + { + Dart d = facesId[i]; + + do + { + AttrTypeLoader::Extract(&attr[d], p); + p += AttrTypeLoader::TYPE_SIZE_IN_BUFFER; + d = map.phi1(d); + } + while(d != facesId[i]); + } +} + + + + +/* + * Final-glue code for universal parsing of + * [float, float, float] -> Geom::Vector<3, float> + * attribute. + * + * Works with UniversalLoader + */ + + +class Vec3FloatLoader +{ +public: + static const unsigned int TYPE_SIZE_IN_BUFFER = 12; + typedef Geom::Vector<3, float> ATTR_TYPE; + + static inline bool Handleable(const AHEMAttributeDescriptor* ad) + { + return IsEqualGUID(ad->dataType, AHEMDATATYPE_FLOAT32) && ad->dimension == 3; + } + + static inline void Extract(void* val, void* buffer) + { + float* v = (float*)buffer; + *(ATTR_TYPE*)val = ATTR_TYPE(v[0], v[1], v[2]); + } +}; + + + + + +/* + * Final-glue code for universal parsing of + * [float]^16 -> Geom::Matrix<4, 4, float> (column-major order / OpenGL-style) + * attribute + * + * Works with UniversalLoader + */ + + +class Mat44FloatLoader +{ +public: + static const unsigned int TYPE_SIZE_IN_BUFFER = 64; + typedef Geom::Matrix<4, 4, float> ATTR_TYPE; + + static inline bool Handleable(const AHEMAttributeDescriptor* ad) + { + return IsEqualGUID(ad->dataType, AHEMDATATYPE_FLOAT32) && ad->dimension == 16; + } + + static inline void Extract(void* val, void* buffer) + { + float* v = (float*)buffer; + + Geom::Matrix<4, 4, float> m; + + m(0, 0) = v[0]; + m(1, 0) = v[1]; + m(2, 0) = v[2]; + m(3, 0) = v[3]; + + m(0, 1) = v[4]; + m(1, 1) = v[5]; + m(2, 1) = v[6]; + m(3, 1) = v[7]; + + m(0, 2) = v[8]; + m(1, 2) = v[9]; + m(2, 2) = v[10]; + m(3, 2) = v[11]; + + m(0, 3) = v[12]; + m(1, 3) = v[13]; + m(2, 3) = v[14]; + m(3, 3) = v[15]; + + *(ATTR_TYPE*)val = m; + } +}; + + + +} // namespace Import + +} // namespace Algo + +} // namespace CGoGN diff --git a/include/Algo/Import/import.h b/include/Algo/Import/import.h index 4fc2c7fa..495cf8f9 100644 --- a/include/Algo/Import/import.h +++ b/include/Algo/Import/import.h @@ -59,6 +59,7 @@ bool importMesh(typename PFP::MAP& map, const std::string& filename, typename PF //bool importObjWithTex(typename PFP::MAP& map, const std::string& filename); // + /* * TODO a transformer en utilisant un MeshTableVolume. */ diff --git a/include/Algo/Import/import2tables.h b/include/Algo/Import/import2tables.h index 7177fc5a..f05076cc 100644 --- a/include/Algo/Import/import2tables.h +++ b/include/Algo/Import/import2tables.h @@ -50,7 +50,7 @@ namespace Import namespace ImportSurfacique { - enum ImportType { UNKNOWNSURFACE, TRIAN, TRIANBGZ, PLY, PLYPTM, OFF, OBJ, CTM, VRML }; + enum ImportType { UNKNOWNSURFACE, TRIAN, TRIANBGZ, PLY, PLYPTM, OFF, OBJ, CTM, VRML, AHEM }; } namespace ImportVolumique @@ -115,6 +115,8 @@ public: bool importASSIMP(const std::string& filename, std::vector& attrNames); + bool importAHEM(const std::string& filename, std::vector& attrNames); + /** * @param container container of vertex orbite * @param idPositions id of position attribute in the container diff --git a/include/Algo/Import/import2tablesSurface.hpp b/include/Algo/Import/import2tablesSurface.hpp index 0182a292..3d2f1b76 100644 --- a/include/Algo/Import/import2tablesSurface.hpp +++ b/include/Algo/Import/import2tablesSurface.hpp @@ -25,6 +25,7 @@ #include "Algo/Import/importPlyData.h" #include "openctm.h" +#include "Algo/Import/AHEM.h" #include "assimp.h" #include "aiPostProcess.h" @@ -61,9 +62,12 @@ ImportSurfacique::ImportType MeshTablesSurface::getFileType(const std::stri if ((filename.rfind(".obj")!=std::string::npos) || (filename.rfind(".OBJ")!=std::string::npos)) return ImportSurfacique::OBJ; - if ((filename.rfind(".ctm")!=std::string::npos) || (filename.rfind(".OBJ")!=std::string::npos)) + if ((filename.rfind(".ctm")!=std::string::npos) || (filename.rfind(".CTM")!=std::string::npos)) return ImportSurfacique::CTM; + if ((filename.rfind(".ahem")!=std::string::npos) || (filename.rfind(".AHEM")!=std::string::npos)) + return ImportSurfacique::AHEM; + return ImportSurfacique::UNKNOWNSURFACE; } @@ -105,6 +109,10 @@ bool MeshTablesSurface::importMesh(const std::string& filename, std::vector CGoGNout << "TYPE: OBJ" << CGoGNendl; return importObj(filename, attrNames); break; + case ImportSurfacique::AHEM: + CGoGNout << "TYPE: AHEM" << CGoGNendl; + return importAHEM(filename, attrNames); + break; default: CGoGNout << "TYPE: ASSIMP" << CGoGNendl; return importASSIMP(filename, attrNames); @@ -443,7 +451,7 @@ bool MeshTablesSurface::importObj(const std::string& filename, std::vector< oss >> str; unsigned int ind = 0; - while ( (str[ind]!='/')&& (ind 0) @@ -837,6 +845,158 @@ bool MeshTablesSurface::importCTM(const std::string& filename, std::vector< return true; } + + + + +template +bool MeshTablesSurface::importAHEM(const std::string& filename, std::vector& attrNames) +{ + // Open file + + std::ifstream fp(filename.c_str(), std::ios::binary); + + if (!fp.good()) + { + CGoGNerr << "Unable to open file " << filename << CGoGNendl; + return false; + } + + + // Read header + + AHEMHeader hdr; + + fp.read((char*)&hdr, sizeof(AHEMHeader)); + + if(hdr.magic != AHEM_MAGIC) + CGoGNerr << "Warning: " << filename << " invalid magic" << CGoGNendl; + + + m_nbVertices = hdr.meshHdr.vxCount; + m_nbFaces = hdr.meshHdr.faceCount; + + + // Read attributes + + AHEMAttributeDescriptor* ahemAttrDesc = new AHEMAttributeDescriptor[hdr.attributesChunkNumber]; + char** ahemAttrNames = new char*[hdr.attributesChunkNumber]; + + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + { + fp.read((char*)(ahemAttrDesc + i), sizeof(AHEMAttributeDescriptor)); + + ahemAttrNames[i] = new char[ahemAttrDesc[i].nameSize + 1]; + fp.read(ahemAttrNames[i], ahemAttrDesc[i].nameSize); + ahemAttrNames[i][ahemAttrDesc[i].nameSize] = '\0'; + } + + + // Compute buffer size for largest chunk and allocate + + unsigned int bufferSize = hdr.meshHdr.meshChunkSize; + + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + if(ahemAttrDesc[i].attributeChunkSize > bufferSize) + bufferSize = ahemAttrDesc[i].attributeChunkSize; + + + char* buffer = new char[bufferSize]; + + + // Allocate vertices + + AttributeContainer& vxContainer = m_map.getAttributeContainer(VERTEX_CELL); + + + std::vector verticesId; + verticesId.resize(hdr.meshHdr.vxCount); + + for(unsigned int i = 0 ; i < hdr.meshHdr.vxCount ; i++) + verticesId[i] = vxContainer.insertLine(); + + + + // Read faces stream + + m_nbEdges.resize(hdr.meshHdr.faceCount); + m_emb.resize(hdr.meshHdr.heCount); + + fp.read(buffer, hdr.meshHdr.meshChunkSize); + char* batch = buffer; + + unsigned int fCount = 0; + + unsigned int fId = 0; + unsigned int j = 0; + + while(fCount < hdr.meshHdr.faceCount) + { + AHEMFaceBatchDescriptor* fbd = (AHEMFaceBatchDescriptor*)batch; + stUInt32* ix = (stUInt32*)(batch + sizeof(AHEMFaceBatchDescriptor)); + + for(unsigned int i = 0 ; i < fbd->batchLength ; i++) + { + m_nbEdges[fId++] = fbd->batchFaceSize; + + for(unsigned int k = 0 ; k < fbd->batchFaceSize ; k++) + m_emb[j++] = *ix++; + } + + fCount += fbd->batchLength; + batch = (char*)ix; + } + + + + // Read positions + + AttributeHandler position = m_map.template getAttribute(VERTEX_ORBIT, "position") ; + + if (!position.isValid()) + position = m_map.template addAttribute(VERTEX_ORBIT, "position") ; + + attrNames.push_back(position.name()) ; + + AHEMAttributeDescriptor* posDesc = NULL; + + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + if(IsEqualGUID(ahemAttrDesc[i].semantic, AHEMATTRIBUTE_POSITION)) + { + posDesc = ahemAttrDesc + i; + break; + } + + fp.seekg(posDesc->fileStartOffset, std::ios_base::beg); + fp.read(buffer, posDesc->attributeChunkSize); + + float* q = (float*)buffer; + + for(unsigned int i = 0 ; i < hdr.meshHdr.vxCount ; i++) + { + position[verticesId[i]] = VEC3(q[0], q[1], q[2]); + q += 3; + } + + + + + // Close file and release allocated stuff + + fp.close(); + + for(unsigned int i = 0 ; i < hdr.attributesChunkNumber ; i++) + delete[] ahemAttrNames[i]; + + delete[] ahemAttrNames; + delete[] ahemAttrDesc; + delete[] buffer; + + return true; +} + + + template void MeshTablesSurface::extractMeshRec(AttributeContainer& container, AttributeHandler& positions, const struct aiScene* scene, const struct aiNode* nd, struct aiMatrix4x4* trafo) { -- GitLab