/** * \file MeshDataSource.h * \brief The base class for mesh data sources * \author O. L * * * */ #ifndef _ASGARD_MESHDATASOURCE_H #define _ASGARD_MESHDATASOURCE_H #include "BaseDataSource.h" #include "CimgConfig.h" #include #include #include using namespace std; using namespace cimg_library; namespace asgard{ /** @brief The class for mesh data sources. */ template class MeshDataSource : public BaseDataSource { public: enum ACCESSTYPE { VERTICESCOORDS, FACESCOLORS, VERTICESCOLORS}; typedef D DType; protected: //! Specifies access to vertices or faces int access_type;//0:vertices coords; 1:faces colors, 2:vertices colors //! Pointer to the data to be accessed CImg* data; //! The mesh points CImg* points; //! The mesh primitives CImgList* primitives; //! The mesh faces' colors CImg* faces_colors; //! The number of vertices per face unsigned int numberOfVerticesPerFaces; /** * \brief Assigns a Mesh Data Source from another * \param d the input mesh data source */ void assign(const MeshDataSource& d){ Delete(); init(); points->assign(*d.getPoints()); primitives->assign(*d.getPrimitives()); faces_colors->assign(*d.getFacesColors()); setNumberOfVerticesPerFaces(d.getNumberOfVerticesPerFaces()); switchTo(d.getAccessType()); } /** * \brief Assigns a Mesh Data Source from another * \param d the input mesh data source */ template void assign(const MeshDataSource& d){ Delete(); init(); points->assign(*d.getPoints()); primitives->assign(*d.getPrimitives()); faces_colors->assign(*d.getFacesColors()); setNumberOfVerticesPerFaces(d.getNumberOfVerticesPerFaces()); switchTo(d.getAccessType()); } public: //! The default mesh data Source constructor MeshDataSource(): points(0), primitives(0), faces_colors(0), data(0) { init(); } /** * \brief Mesh Data Source constructor * \param filename the input mesh file */ MeshDataSource(const char* filename) : points(0), primitives(0), faces_colors(0), data(0) { this->load(filename); } /** * \brief Mesh Data Source constructor * \param d the input Mesh Data Source */ MeshDataSource(const MeshDataSource& d) : points(0), primitives(0), faces_colors(0), data(0) { assign(d); } /** * \brief Mesh Data Source constructor * \param d the input Mesh Data Source */ template MeshDataSource(const MeshDataSource& d): points(0), primitives(0), faces_colors(0), data(0) { assign(d); } //! The Mesh source destructor virtual ~MeshDataSource() { Delete(); } //! finalizes the initialisation of inherited properties void finalize() { unsigned long ni,nd; switch(access_type) { case MeshDataSource::VERTICESCOORDS:ni=points->width();nd=points->height();break; case MeshDataSource::FACESCOLORS:ni=faces_colors->width();nd=faces_colors->height();break; default : ni=points->width();nd=points->height(); } this->setNumberOfInstances(ni); this->setNumberOfDimensions(nd); } //! Mesh data initialization void init() { access_type=MeshDataSource::VERTICESCOORDS; points=new CImg(); data=points; primitives=new CImgList(); faces_colors=new CImg(); numberOfVerticesPerFaces=3; this->finalize(); } //! explicit Mesh source delete void Delete(){ if (points!=0) delete points; points=0; if (primitives!=0) delete primitives; primitives=0; if (faces_colors!=0) delete faces_colors; faces_colors=0; } /** * \brief Sets the type of access to the mesh information * \param a the type of access to the mesh information */ void setAccessType(int a){ access_type=a; } /** * \brief Retrieves the type of access to the mesh information * \return the type of access to the mesh information */ int getAccessType() const{ return access_type; } /** * \brief Switches to another type of access to the mesh information and updates the structure * \param accessType the type of access to the mesh information */ void switchTo(int accessType){ bool ok=true; if (accessType==MeshDataSource::FACESCOLORS && !(faces_colors->size()>0)){ cerr<<"Switch impossible: the required information is not available"<::VERTICESCOORDS) data=points; if(access_type==MeshDataSource::FACESCOLORS) data=faces_colors; finalize(); } } /** * \brief Retrieves the primitives * \return the primitives data */ const CImgList* getPrimitives() const{ return primitives; } /** * \brief Retrieves the primitives * \return the primitives data */ CImgList* getPrimitives(){ return primitives; } /** * \brief Retrieves the points * \return the points data */ CImg* getPoints(){ return points; } /** * \brief Retrieves the points * \return the points data */ const CImg* getPoints() const{ return points; } /** * \brief Retrieves the accessed data * \return the accessed data */ CImg* getData(){ return data; } /** * \brief Retrieves the accessed data * \return the accessed data */ const CImg* getData() const{ return data; } /** * \brief Sets the accessed data * \param d the accessed data */ void setData(CImg* d){ data=d; } /** * \brief Retrieves the faces' colors * \return the faces' colors data */ const CImg* getFacesColors() const{ return faces_colors; } /** * \brief Retrieves the faces' colors * \return the faces' colors data */ CImg* getFacesColors(){ return faces_colors; } /** * \brief Retrieves the number of vertices * \return the number of vertices */ unsigned long getNumberOfVertices() const{ return points->width(); } /** * \brief Retrieves the number of faces * \return the number of faces */ unsigned long getNumberOfFaces() const{ return primitives->size(); } /** * \brief Retrieves the number of vertives per faces * \return the number of vertives per faces */ unsigned int getNumberOfVerticesPerFaces() const{ return numberOfVerticesPerFaces; } /** * \brief Sets the number of vertices per faces * \param n the number of vertives per faces */ void setNumberOfVerticesPerFaces(unsigned int n){ numberOfVerticesPerFaces=n; } /** * \brief Retrieves one face vertex * \param i the face number * \param d the dth vertex of the face * \return the face vertex number */ unsigned long getFaceVertex(unsigned long i, unsigned long d) const{ return primitives->at(i).at(d); } /** * \brief Mesh Data Source copy operator * \param d the input mesh data source * \return the copied Mesh Data Source */ MeshDataSource& operator=(const MeshDataSource& d){ assign(d); return *this; } /** * \brief Mesh Data Source copy operator * \param d the input mesh data source * \return the copied Mesh Data Source */ template MeshDataSource& operator=(const MeshDataSource& d){ assign(d); return *this; } //overrided methods const D& operator()(unsigned long v, unsigned long d) const{ return (*data)(v,d); } D& operator()(unsigned long v, unsigned long d) { return (*data)(v,d); } bool load(const char* filename){ bool success=true; Delete(); init(); CImgList* FC=new CImgList(); points->load_off(*primitives,*FC, filename); faces_colors->assign(FC->get_append('x')); delete FC; setNumberOfVerticesPerFaces((*primitives)(0).height()); switchTo(MeshDataSource::VERTICESCOORDS); this->finalize(); return success; } void save(const char* filename) const{ CImgList* FC=new CImgList(); FC->assign(faces_colors->get_split('x')); points->save_off(*primitives, *FC, filename); delete FC; } bool save_ply_anass(const char* filename) const { //fait convertir un .off vers un .pl cerr << "save ply file" << endl; ofstream ofs(filename, ofstream::out); // magic number ofs << "ply" << endl; // header ofs << "format ascii 1.0" << endl; ofs << "element vertex " << this->getNumberOfVertices() << endl; ofs << "property float x" << endl; ofs << "property float y" << endl; ofs << "property float z" << endl; //ofs << "property uchar red" << endl; //ofs << "property uchar green" << endl; //ofs << "property uchar blue" << endl; ofs << "element face " << this->getNumberOfFaces() << endl; ofs << "property list uchar int vertex_index" << endl; ofs << "end_header" << endl; // vertices for (unsigned long v = 0; v < this->getNumberOfVertices(); v++) { ofs << (*this->getPoints())(v,0) << " " << (*this->getPoints())(v,1) << " " << (*this->getPoints())(v,2) << endl; // << (int)(*vertices_colors)(v,0) << " " // << (int)(*vertices_colors)(v,1) << " " //<< (int)(*vertices_colors)(v,2) } // faces for (unsigned long f = 0; f < this->getNumberOfFaces(); f++){ ofs << "3 " << (*this->getPrimitives())(f)(0) << " " << (*this->getPrimitives())(f)(2)<< " " << (*this->getPrimitives())(f)(1) << endl; //ici on a permuté cette ligne avec celle d'avant pour la préservation des couleurs en niveau de gris (pensez à la normale qui doit tjr pointer vers le haut suivant la convention de la main) } ofs.close(); return true; } }; } #endif