extended support to dump attributes

It was only for vertices, now it is also for faces and mesh attributes.
Compiled gcc and .net. Tested only on toy exmaples
This commit is contained in:
ganovelli 2009-10-07 12:45:21 +00:00
parent b902431bc1
commit 71f0c204d9
1 changed files with 195 additions and 69 deletions

View File

@ -8,7 +8,7 @@
* \ * * \ *
* All rights reserved. * * All rights reserved. *
* * * *
* This program is free software; you can redistribute it and/or modify * * This program is Free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by * * it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or * * the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. * * (at your option) any later version. *
@ -52,58 +52,149 @@ namespace vcg {
namespace tri { namespace tri {
namespace io { namespace io {
/* derivation chain */
template <int N> struct DummyType{ char placeholder[N]; }; template <int N> struct DummyType{ char placeholder[N]; };
/* ------------------------- derivation chain for the vertex attribute ---------------------------*/
/** this class is for testing only the equality with the type optionally provided by the user when calling Open
*/
template <class MeshType, class A, class T> template <class MeshType, class A, class T>
struct Der:public T{ struct Der:public T{
typedef typename std::set<typename MeshType::PointerToAttribute >::iterator HWIte; typedef typename std::set<typename MeshType::PointerToAttribute >::iterator HWIte;
static void AddAttrib(MeshType &m, char * name, int s, void * data){
if(s == sizeof(A)){ template <int VoF>
typename MeshType::template PerVertexAttributeHandle<A> h = vcg::tri::Allocator<MeshType>:: template AddPerVertexAttribute<A>(m,name); static void AddAttrib(MeshType &m, const char * name, unsigned int s, void * data){
for(int i = 0; i < m.vert.size(); ++i) switch(VoF)
memcpy(&h[i], (void*) &((A*)data)[i],sizeof(A)); // we don't want the type conversion {
case 0: if(s == sizeof(A)){
typename MeshType::template PerVertexAttributeHandle<A> h = vcg::tri::Allocator<MeshType>:: template AddPerVertexAttribute<A>(m,name);
for(unsigned int i = 0; i < m.vert.size(); ++i)
memcpy(&h[i], (void*) &((A*)data)[i],sizeof(A)); // we don't want the type conversion
}
else
T::template AddAttrib<0>(m,name,s,data);
break;
case 1: if(s == sizeof(A)){
typename MeshType::template PerFaceAttributeHandle<A> h = vcg::tri::Allocator<MeshType>:: template AddPerFaceAttribute<A>(m,name);
for(unsigned int i = 0; i < m.face.size(); ++i)
memcpy(&h[i], (void*) &((A*)data)[i],sizeof(A)); // we don't want the type conversion
}
else
T::template AddAttrib<0>(m,name,s,data);
break;
case 2:
if(s == sizeof(A)){
typename MeshType::template PerMeshAttributeHandle<A> h = vcg::tri::Allocator<MeshType>:: template AddPerMeshAttribute<A>(m,name);
memcpy(&h(), (void*) ((A*)data),sizeof(A)); // we don't want the type conversion
}
else
T::template AddAttrib<2>(m,name,s,data);
break;
default:break;
} }
else
T::AddAttrib(m,name,s,data);
} }
}; };
/** this class is for testing the list of increasing size types until one is larger than the size of the unknown type
*/
template <class MeshType, class A, class T> template <class MeshType, class A, class T>
struct DerK:public T{ struct DerK:public T{
typedef typename std::set<typename MeshType::PointerToAttribute >::iterator HWIte; typedef typename std::set<typename MeshType::PointerToAttribute >::iterator HWIte;
static void AddAttrib(MeshType &m, char * name, int s, void * data){ template <int VoF>
if(s == sizeof(A)){ static void AddAttrib(MeshType &m, const char * name, unsigned int s, void * data){
typename MeshType::template PerVertexAttributeHandle<A> h = vcg::tri::Allocator<MeshType>::template AddPerVertexAttribute<A>(m,name); switch(VoF){
for(unsigned int i = 0; i < m.vert.size(); ++i) case 0:
memcpy((void*) &(h[i]), (void*) &((A*)data)[i],sizeof(A)); // we don't want the type conversion if(s == sizeof(A)){
} typename MeshType::template PerVertexAttributeHandle<A> h = vcg::tri::Allocator<MeshType>::template AddPerVertexAttribute<A>(m,name);
else for(unsigned int i = 0; i < m.vert.size(); ++i)
if(s < sizeof(A)){ memcpy((void*) &(h[i]), (void*) &((A*)data)[i],sizeof(A)); // we don't want the type conversion
// padding
int padd = sizeof(A) - s;
typename MeshType::template PerVertexAttributeHandle<A> h = vcg::tri::Allocator<MeshType>::template AddPerVertexAttribute<A>(m,name);
for(unsigned int i = 0; i < m.vert.size(); ++i){
char * dest = &((char*)(&h[i]))[padd];
memcpy( (void *)dest , (void*) &((A*)data)[i],s); // we don't want the type conversion
} }
typename MeshType::PointerToAttribute pa; else
pa._name = std::string(name); if(s < sizeof(A)){
HWIte res = m.vert_attr.find(pa); // padding
pa = *res; int padd = sizeof(A) - s;
m.vert_attr.erase(res); typename MeshType::template PerVertexAttributeHandle<A> h = vcg::tri::Allocator<MeshType>::template AddPerVertexAttribute<A>(m,name);
pa._padding = padd; for(unsigned int i = 0; i < m.vert.size(); ++i){
std::pair<HWIte,bool > new_pa = m.vert_attr.insert(pa); char * dest = &((char*)(&h[i]))[0];
assert(new_pa.second); memcpy( (void *)dest , (void*) &((A*)data)[i],s); // we don't want the type conversion
} }
else typename MeshType::PointerToAttribute pa;
T::AddAttrib(m,name,s,data); pa._name = std::string(name);
HWIte res = m.vert_attr.find(pa);
pa = *res;
m.vert_attr.erase(res);
pa._padding = padd;
std::pair<HWIte,bool > new_pa = m.vert_attr.insert(pa);
assert(new_pa.second);
}
else
T::template AddAttrib<0>(m,name,s,data);
break;
case 1:
if(s == sizeof(A)){
typename MeshType::template PerVertexAttributeHandle<A> h = vcg::tri::Allocator<MeshType>::template AddPerVertexAttribute<A>(m,name);
for(unsigned int i = 0; i < m.vert.size(); ++i)
memcpy((void*) &(h[i]), (void*) &((A*)data)[i],sizeof(A)); // we don't want the type conversion
}
else
if(s < sizeof(A)){
// padding
int padd = sizeof(A) - s;
typename MeshType::template PerFaceAttributeHandle<A> h = vcg::tri::Allocator<MeshType>::template AddPerFaceAttribute<A>(m,name);
for(unsigned int i = 0; i < m.face.size(); ++i){
char * dest = &((char*)(&h[i]))[0];
memcpy( (void *)dest , (void*) &((A*)data)[i],s); // we don't want the type conversion
}
typename MeshType::PointerToAttribute pa;
pa._name = std::string(name);
HWIte res = m.face_attr.find(pa);
pa = *res;
m.face_attr.erase(res);
pa._padding = padd;
std::pair<HWIte,bool > new_pa = m.face_attr.insert(pa);
assert(new_pa.second);
}
else
T::template AddAttrib<1>(m,name,s,data);
break;
case 2:
if(s == sizeof(A)){
typename MeshType::template PerMeshAttributeHandle<A> h = vcg::tri::Allocator<MeshType>::template AddPerMeshAttribute<A>(m,name);
memcpy((void*)&h(), (void*)((A*)data),sizeof(A)); // we don't want the type conversion
}
else
if(s < sizeof(A)){
// padding
int padd = sizeof(A) - s;
typename MeshType::template PerMeshAttributeHandle<A> h = vcg::tri::Allocator<MeshType>::template AddPerMeshAttribute<A>(m,name);
char * dest = & ((char*)(&h()))[0];
memcpy( (void *)dest , (void*)((A*)data),s); // we don't want the type conversion
typename MeshType::PointerToAttribute pa;
pa._name = std::string(name);
HWIte res = m.mesh_attr.find(pa);
pa = *res;
m.mesh_attr.erase(res);
pa._padding = padd;
std::pair<HWIte,bool > new_pa = m.mesh_attr.insert(pa);
assert(new_pa.second);
}
else
T::template AddAttrib<2>(m,name,s,data);
break;
default: assert(0);break;
}
} }
}; };
/**
This is the templated derivation chain
*/
template <class MeshType> struct K { template <class MeshType> struct K {
static void AddAttrib(MeshType &m, char * name, int s, void * data){ template <int VoF>
static void AddAttrib(MeshType &m, const char * name, unsigned int s, void * data){
// if yohu got this your attribute is larger than 1048576. Honestly...
assert(0); assert(0);
} }
}; };
@ -144,38 +235,49 @@ namespace io {
template <class MeshType, class A0, class A1, class A2,class A3,class A4> struct AttrAll : public Der< MeshType, A4, C3<MeshType, A0, A1, A2, A3> > {}; template <class MeshType, class A0, class A1, class A2,class A3,class A4> struct AttrAll : public Der< MeshType, A4, C3<MeshType, A0, A1, A2, A3> > {};
/* end derivation chain */
template <class OpenMeshType,class A0 = long, class A1 = double, class A2 = int,class A3 = short, class A4 = char > template <class OpenMeshType,class A0 = long, class A1 = double, class A2 = int,class A3 = short, class A4 = char >
class ImporterVMI: public AttrAll<OpenMeshType,A0,A1,A2,A3,A4> class ImporterVMI: public AttrAll<OpenMeshType,A0,A1,A2,A3,A4>
{ {
public: public:
struct ReadString{ ReadString(FILE * f,std::string & out){
unsigned int l; fread(&l,4,1,f);
char * buf = new char[l+1];
fread(buf,1,l,f);buf[l]='\0';
out = std::string(buf);
delete [] buf;
}
};
struct ReadInt{ ReadInt(FILE *f, unsigned int & i){ fread(&i,1,4,f);}};
static void * Malloc(unsigned int n){ return (n)?malloc(n):0;}
static void Free(void * ptr){ if(ptr) free (ptr);}
typedef typename OpenMeshType::FaceIterator FaceIterator; typedef typename OpenMeshType::FaceIterator FaceIterator;
typedef typename OpenMeshType::VertexIterator VertexIterator; typedef typename OpenMeshType::VertexIterator VertexIterator;
typedef typename OpenMeshType::VertexType VertexType; typedef typename OpenMeshType::VertexType VertexType;
static bool GetHeader(FILE * f,std::vector<std::string>& fnameV, std::vector<std::string>& fnameF, int & vertSize, int &faceSize){ static bool GetHeader(FILE * f,std::vector<std::string>& fnameV, std::vector<std::string>& fnameF, unsigned int & vertSize, unsigned int &faceSize){
char name[100]; std::string name;
char buf[4096]; unsigned int nameFsize,nameVsize,i;
int nameFsize,nameVsize,i;
fgets(buf,4096,f);
sscanf(buf,"%s %d",&name[0],&nameFsize);
for(i=0; i < nameFsize; ++i) {
fgets(buf,4096,f);
sscanf(buf,"%s ",&name[0]);fnameF.push_back(std::string(name));
}
fgets(buf,4096,f);
sscanf(buf,"%s %d",&name[0],&faceSize);
fgets(buf,4096,f); ReadString(f,name); ReadInt(f,nameFsize);
sscanf(buf,"%s %d",&name[0],&nameVsize);
for(i=0; i < nameVsize; ++i) { for(i=0; i < nameFsize; ++i)
fgets(buf,4096,f); {ReadString(f, name);fnameF.push_back( name );}
sscanf(buf,"%s ",&name[0]);fnameV.push_back(std::string(name));}
fgets(buf,4096,f); ReadString(f,name); ReadInt(f , faceSize);
sscanf(buf,"%s %d",&name[0],&vertSize); ReadString(f, name); ReadInt(f,nameVsize);
fgets(buf,4096,f);
assert(strstr(buf,"end_header")!=NULL); for(i=0; i < nameVsize; ++i)
{ReadString(f, name) ;fnameV.push_back( name);}
ReadString(f,name); ReadInt(f,vertSize);
ReadString(f,name);
assert(strstr( name.c_str(),"end_header")!=NULL);
return true; return true;
} }
@ -193,7 +295,7 @@ namespace io {
typename OpenMeshType::VertexIterator vi; typename OpenMeshType::VertexIterator vi;
FILE * f = fopen(filename,"rb"); FILE * f = fopen(filename,"rb");
std::vector<std::string> nameF,nameV,fnameF,fnameV; std::vector<std::string> nameF,nameV,fnameF,fnameV;
int vertSize,faceSize; unsigned int vertSize,faceSize;
/* read the header */ /* read the header */
GetHeader(f,fnameV, fnameF, vertSize, faceSize); GetHeader(f,fnameV, fnameF, vertSize, faceSize);
@ -247,19 +349,43 @@ namespace io {
/* load the per vertex attributes */ /* load the per vertex attributes */
char _string[65536],_trash[65536]; std::string _string,_trash;
int n,sz; unsigned int n,sz;
fscanf(f,"%s %d",&_trash[0],&n); ReadString(f,_trash); ReadInt(f,n);
for(int ia = 0 ; ia < n; ++ia){ for(int ia = 0 ; ia < n; ++ia){
fscanf(f,"%s %s",&_trash[0],&_string[0]); ReadString(f,_trash); ReadString(f,_string);
fscanf(f,"%s %d",&_trash[0],&sz); ReadString(f,_trash); ReadInt(f,sz);
void * data = malloc(sz*m.vert.size());
void * data = Malloc(sz*m.vert.size());
fread(data,sz,m.vert.size(),f); fread(data,sz,m.vert.size(),f);
AddAttrib(m,_string,sz,data); AttrAll<OpenMeshType,A0,A1,A2,A3,A4>::template AddAttrib<0>(m,_string.c_str(),sz,data);
free(data); Free(data);
} }
/* load the per face attributes */
ReadString(f,_trash); ReadInt(f,n);
for(int ia = 0 ; ia < n; ++ia){
ReadString(f,_trash); ReadString(f,_string);
ReadString(f,_trash); ReadInt(f,sz);
void * data = Malloc(sz*m.face.size());
fread(data,sz,m.face.size(),f);
AttrAll<OpenMeshType,A0,A1,A2,A3,A4>::template AddAttrib<1>(m,_string.c_str(),sz,data);
Free(data);
}
/* load the per mesh attributes */
ReadString(f,_trash); ReadInt(f,n);
for(int ia = 0 ; ia < n; ++ia){
ReadString(f,_trash); ReadString(f,_string);
ReadString(f,_trash); ReadInt(f,sz);
void * data = Malloc(sz);
fread(data,1,sz,f);
AttrAll<OpenMeshType,A0,A1,A2,A3,A4>::template AddAttrib<2>(m,_string.c_str(),sz,data);
Free(data);
}
if(FaceType::HasVFAdjacency()) if(FaceType::HasVFAdjacency())
for(vi = m.vert.begin(); vi != m.vert.end(); ++vi){ for(vi = m.vert.begin(); vi != m.vert.end(); ++vi){
(*vi).VFp() = (*vi).VFp()-(FaceType*)offsetF+ &m.face[0]; (*vi).VFp() = (*vi).VFp()-(FaceType*)offsetF+ &m.face[0];