You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
206 lines
5.7 KiB
206 lines
5.7 KiB
#ifndef SIMPLEMESHPROVIDER_H |
|
#define SIMPLEMESHPROVIDER_H |
|
#include <list> |
|
#include <vector> |
|
#include <vcg/space/box3.h> |
|
#include <wrap/ply/plystuff.h> |
|
#include <wrap/io_trimesh/import.h> |
|
|
|
using namespace std; |
|
using namespace vcg; |
|
|
|
template<class TriMeshType> |
|
class MeshCache |
|
{ |
|
class Pair |
|
{ |
|
public: |
|
Pair(){used=0;} |
|
TriMeshType *M; |
|
std::string Name; |
|
int used; // 'data' dell'ultimo accesso. si butta fuori quello lru |
|
}; |
|
|
|
std::list<Pair> MV; |
|
|
|
public: |
|
void clear(); |
|
|
|
MeshCache() {MaxSize=6;} |
|
~MeshCache() { |
|
typename std::list<Pair>::iterator mi; |
|
for(mi=MV.begin();mi!=MV.end();++mi) |
|
delete (*mi).M; |
|
} |
|
// Restituisce true se la mesh e' in cache; |
|
// restituisce in ogni caso il puntatore dove sta (o dovrebbe stare) la mesh |
|
// Gestione LRU |
|
|
|
bool Find(std::string &name, TriMeshType * &sm) |
|
{ |
|
typename std::list<Pair>::iterator mi; |
|
typename std::list<Pair>::iterator oldest; // quello che e' piu' tempo che non viene acceduto. |
|
int last; |
|
|
|
last = std::numeric_limits<int>::max(); |
|
oldest = MV.begin(); |
|
|
|
for(mi=MV.begin();mi!=MV.end();++mi) |
|
{ |
|
if((*mi).used<last) |
|
{ |
|
last=(*mi).used; |
|
oldest=mi; |
|
} |
|
if((*mi).Name==name) { |
|
sm=(*mi).M; |
|
(*mi).used++; |
|
return true; |
|
} |
|
} |
|
|
|
// we have not found the requested mesh |
|
// either allocate a new mesh or give back a previous mesh. |
|
|
|
if(MV.size()>MaxSize) { |
|
sm=(*oldest).M; |
|
(*oldest).used=0; |
|
(*oldest).Name=name; |
|
} else { |
|
MV.push_back(Pair()); |
|
MV.back().Name=name; |
|
MV.back().M=new TriMeshType(); |
|
sm=MV.back().M; |
|
} |
|
return false; |
|
} |
|
|
|
|
|
size_t MaxSize; |
|
size_t size() const {return MV.size();} |
|
}; |
|
|
|
template<class TriMeshType> |
|
class SimpleMeshProvider |
|
{ |
|
std::vector< std::string > meshnames; |
|
std::vector<vcg::Matrix44f> TrV; |
|
std::vector<float> WV; // vettore con i pesi da applicare alla mesh. |
|
std::vector<vcg::Box3f> BBV; // vettore con i bbox trasformati delle mesh da scannare. |
|
vcg::Box3f fullBBox; |
|
MeshCache<TriMeshType> MC; |
|
|
|
public: |
|
|
|
int size() {return meshnames.size();} |
|
|
|
int getCacheSize() {return MC.MaxSize;} |
|
int setCacheSize(size_t newsize) |
|
{ |
|
if(newsize == MC.MaxSize) |
|
return MC.MaxSize; |
|
if(newsize <= 0) |
|
return MC.MaxSize; |
|
|
|
MC.MaxSize = newsize; |
|
return newsize; |
|
} |
|
|
|
bool openALN (const char* alnName) |
|
{ |
|
// vector<RangeMap> rmaps; |
|
// ALNParser::ParseALN(rmaps, alnName); |
|
|
|
// for(size_t i=0; i<rmaps.size(); i++) |
|
// AddSingleMesh(rmaps[i].filename.c_str(), rmaps[i].transformation, rmaps[i].quality); |
|
|
|
return true; |
|
} |
|
|
|
bool AddSingleMesh(const char* meshName, Matrix44f &tr, float meshWeight=1) |
|
{ |
|
assert(WV.size()==meshnames.size() && TrV.size() == WV.size()); |
|
TrV.push_back(tr); |
|
meshnames.push_back(meshName); |
|
WV.push_back(meshWeight); |
|
BBV.push_back(Box3f()); |
|
return true; |
|
} |
|
|
|
bool AddSingleMesh(const char* meshName) |
|
{ |
|
Matrix44f identity; identity.SetIdentity(); |
|
return AddSingleMesh(meshName, identity); |
|
} |
|
|
|
vcg::Box3f bb(int i) {return BBV[i];} |
|
vcg::Box3f fullBB(){ return fullBBox;} |
|
vcg::Matrix44f Tr(int i) const {return TrV[i];} |
|
std::string MeshName(int i) const {return meshnames[i];} |
|
float W(int i) const {return WV[i];} |
|
|
|
void Clear() |
|
{ |
|
meshnames.clear(); |
|
TrV.clear(); |
|
WV.clear(); |
|
BBV.clear(); |
|
fullBBox.SetNull(); |
|
MC.clear(); |
|
} |
|
|
|
bool Find(int i, TriMeshType * &sm) |
|
{ |
|
return MC.Find(meshnames[i],sm); |
|
} |
|
|
|
bool InitBBox() |
|
{ |
|
fullBBox.SetNull(); |
|
|
|
for(int i=0;i<int(meshnames.size());++i) |
|
{ |
|
Box3d b; |
|
bool ret; |
|
Matrix44f mt; |
|
Matrix44f Id; Id.SetIdentity(); |
|
mt.Import(TrV[i]); |
|
printf("bbox scanning %4i/%i [%16s] \r",i+1,(int)meshnames.size(), meshnames[i].c_str()); |
|
if(tri::io::Importer<TriMeshType>::FileExtension(meshnames[i],"PLY") || tri::io::Importer<TriMeshType>::FileExtension(meshnames[i],"ply")) |
|
{ |
|
if(!(TrV[i]==Id)) |
|
ret=ply::ScanBBox(meshnames[i].c_str(),BBV[i],mt,true,0); |
|
else |
|
ret=vcg::ply::ScanBBox(meshnames[i].c_str(),BBV[i]); |
|
|
|
} |
|
else |
|
{ printf("Trying to import a non-ply file %s\n",meshnames[i].c_str());fflush(stdout); |
|
TriMeshType m; |
|
int retVal=tri::io::Importer<TriMeshType>::Open(m,meshnames[i].c_str()); |
|
ret = (retVal==0); |
|
tri::UpdateBounding<TriMeshType>::Box(m); |
|
BBV[i].Import(m.bbox); |
|
} |
|
if( ! ret) |
|
{ |
|
printf("\n\nwarning:\n file '%s' not found\n",meshnames[i].c_str());fflush(stdout); |
|
continue; |
|
} |
|
fullBBox.Add(BBV[i]); |
|
} |
|
return true; |
|
} |
|
|
|
}; |
|
|
|
class SVertex; |
|
class SFace; |
|
class SUsedTypes: public vcg::UsedTypes < vcg::Use<SVertex>::AsVertexType, |
|
vcg::Use<SFace >::AsFaceType >{}; |
|
|
|
class SVertex : public Vertex< SUsedTypes, vertex::Coord3f, vertex::Normal3f,vertex::VFAdj, vertex::BitFlags, vertex::Color4b, vertex::Qualityf>{}; |
|
class SFace : public Face< SUsedTypes, face::VertexRef, face::Normal3f,face::Qualityf, face::VFAdj, face::BitFlags> {}; |
|
class SMesh : public vcg::tri::TriMesh< std::vector< SVertex>, std::vector< SFace > > {}; |
|
|
|
#endif // SIMPLEMESHPROVIDER_H
|
|
|