gKitGL
Mesh.h
00001 /* version allegee ?? mailto:jean-claude.iehl@liris.cnrs.fr */
00002 
00003 #ifndef _MESH_H
00004 #define _MESH_H
00005 
00006 #include <cstring>
00007 #include <vector>
00008 #include <map>
00009 #include <cassert>
00010 
00011 #include "IOResource.h"
00012 #include "MeshMaterial.h"
00013 #include "Geometry.h"
00014 #include "Triangle.h"
00015 #include "PNTriangle.h"
00016 #include "PTNTriangle.h"
00017 #include "Name.h"
00018 
00019 
00020 namespace gk {
00021 
00022 //! representation d'une partie d'un maillage associee a une matiere unique identifiee par son indice 'material_id'.
00023 struct SubMesh
00024 {
00025     int begin;        //!< premier vertex du submesh.
00026     int end;  //!< dernier vertex du submesh.
00027     int material_id;  //!< indice de la matiere associee au submesh, cf. gk::Mesh::m_materials.
00028     
00029     //! constructeur.
00030     SubMesh( )
00031         :
00032         begin(0),
00033         end(0),
00034         material_id(0)
00035     {}
00036     
00037     //! constructeur par defaut.
00038     SubMesh( const int _begin, const int _end, const int _material_id )
00039         :
00040         begin(_begin),
00041         end(_end),
00042         material_id(_material_id)
00043     {}
00044 
00045     //! destructeur.
00046     ~SubMesh( ) {}
00047 };
00048 
00049 //! representation d'un ensemble d'attributs generiques des sommets du maillage. equivalent a un GLBuffer.
00050 struct MeshBuffer
00051 {
00052     Name semantic;      //!< nom de l'attribut
00053     
00054     int count;                  //!< nombre de vecteurs
00055     int size;       //!< 1, 2, 3, 4, dimension des vecteurs
00056     
00057     std::vector<float> data;    //!< stockage des attributs
00058 
00059     //! constructeur par defaut.
00060     MeshBuffer( )
00061         :
00062         count(0), size(0)
00063     {}
00064 
00065     //! constructeur.
00066     MeshBuffer( const Name& _semantic, const int _size )
00067         :
00068         semantic(_semantic),
00069         count(0), size(_size)
00070     {}
00071     
00072     //! insertion d'un attribut generique.
00073     void push( const float *attribute )
00074     {
00075         count++;
00076         
00077         for(int i= 0; i < size; i++)
00078             data.push_back(attribute[i]);
00079     }
00080 
00081     //! insertion d'un attribut float.
00082     int push( const float& attribute )
00083     {
00084         if(size != 1)
00085             return -1;
00086         
00087         push(&attribute);
00088         return 0;
00089     }
00090     
00091     //! insertion d'un attribut point 2d.
00092     int push( const Point2& attribute )
00093     {
00094         if(size != 2)
00095             return -1;
00096         
00097         push(&attribute[0]);
00098         return 0;
00099     }
00100     
00101     //! insertion d'un attribut point 3d.
00102     int push( const Point& attribute )
00103     {
00104         if(size != 3)
00105             return -1;
00106         
00107         push(&attribute[0]);
00108         return 0;
00109     }
00110     
00111     //! insertion d'un attribut vecteur 3d.
00112     int push( const Vector& attribute )
00113     {
00114         if(size != 3)
00115             return -1;
00116         
00117         push(&attribute[0]);
00118         return 0;
00119     }
00120 
00121     //! insertion d'un attribut normale 3d.
00122     int push( const Normal& attribute )
00123     {
00124         if(size != 3)
00125             return -1;
00126         
00127         push(&attribute[0]);
00128         return 0;
00129     }
00130     
00131     //! insertion d'un attribut couleur rgba.
00132     int push( const Color& attribute )
00133     {
00134         if(size != 4)
00135             return -1;
00136         
00137         push(&attribute[0]);
00138         return 0;
00139     }
00140 
00141     //! renvoie le nombre d'attributs stockes.
00142     int attributeCount( ) const
00143     {
00144         return count;
00145     }
00146     
00147     Color asColor( const int id ) const
00148     {
00149         assert(size == 4);
00150         return Color(data[4*id], data[4*id +1], data[4*id +2], data[4*id +3]);
00151     }
00152     
00153     Point asPoint( const int id ) const
00154     {
00155         assert(size == 3);
00156         return Point(data[3*id], data[3*id +1], data[3*id +2]);
00157     }
00158     
00159     Vector asVector( const int id ) const
00160     {
00161         assert(size == 3);
00162         return Vector(data[3*id], data[3*id +1], data[3*id +2]);
00163     }
00164     
00165     Normal asNormal( const int id ) const
00166     {
00167         assert(size == 3);
00168         return Normal(data[3*id], data[3*id +1], data[3*id +2]);
00169     }
00170     
00171     Point2 asPoint2( const int id ) const
00172     {
00173         assert(size == 2);
00174         return Point2(data[2*id], data[2*id +1]);
00175     }
00176     
00177     float asFloat( const int id ) const
00178     {
00179         assert(size == 1);
00180         return data[id];
00181     }
00182 };
00183 
00184 
00185 class Mesh;
00186 
00187 //! representation indexee des sommets d'un triangle.
00188 struct MeshTriangle
00189 {
00190     const Mesh *mesh;
00191     int a, b, c;
00192     
00193     //! constructeur par defaut.
00194     MeshTriangle( ) 
00195         :
00196         mesh(NULL),
00197         a(-1), b(-1), c(-1)
00198     {}
00199     
00200     //! constructeur.
00201     MeshTriangle( const Mesh *_mesh, const int _a, const int _b, const int _c )
00202         :
00203         mesh(_mesh),
00204         a(_a), b(_b), c(_c)
00205     {}
00206     
00207     //! renvoie l'indice du sommet k.
00208     int vertex( const int k ) const
00209     {
00210         assert((&a)[k] != -1);
00211         return (&a)[k];
00212     }
00213     
00214     //! renvoie l'indice du sommet k.
00215     int operator[] ( const int k ) const
00216     {
00217         assert((&a)[k] != -1);
00218         return (&a)[k];        
00219     }
00220     
00221     //! renvoie la position du sommet k.
00222     const Point& position( const int k ) const;
00223     //! renvoie la position du sommet k.
00224     Point position( const int k );
00225     
00226     //! renvoie la normale du sommet k.
00227     const Normal& normal( const int k ) const;
00228     //! renvoie la normale du sommet k.
00229     Normal normal( const int k );
00230     
00231     //! renvoie les coordonnees de texture du sommet k.
00232     const Point2& texcoords( const int k ) const;
00233     //! renvoie les coordonnees de texture du sommet k.
00234     Point2 texcoords( const int k );
00235     
00236     //! renvoie les autres attributs associes au sommet k.
00237     Color asColor( const Name& attribute, const int k );
00238     //! renvoie les autres attributs associes au sommet k.
00239     Color asColor( const int attribute_id, const int k );
00240     
00241     //! renvoie les autres attributs associes au sommet k.
00242     Point asPoint( const Name& attribute, const int k );
00243     //! renvoie les autres attributs associes au sommet k.
00244     Point asPoint( const int attribute_id, const int k );
00245     
00246     //! renvoie les autres attributs associes au sommet k.
00247     Vector asVector( const Name& attribute, const int k );
00248     //! renvoie les autres attributs associes au sommet k.
00249     Vector asVector( const int attribute_id, const int k );
00250     
00251     //! renvoie les autres attributs associes au sommet k.
00252     Normal asNormal( const Name& attribute, const int k );
00253     //! renvoie les autres attributs associes au sommet k.
00254     Normal asNormal( const int attribute_id, const int k );
00255     
00256     //! renvoie les autres attributs associes au sommet k.
00257     Point2 asPoint2( const Name& attribute, const int k );
00258     //! renvoie les autres attributs associes au sommet k.
00259     Point2 asPoint2( const int  attribute_id, const int k );
00260     
00261     //! renvoie les autres attributs associes au sommet k.
00262     float asFloat( const Name& attribute, const int k );
00263     //! renvoie les autres attributs associes au sommet k.
00264     float asFloat( const int attribute_id, const int k );
00265 };
00266 
00267 class MeshIO;
00268 
00269 //! representation d'un maillage triangule.
00270 
00271 //! un mesh est un ensemble de triangles.
00272 //! un triangle est un triplet <abc> d'indices permettant de retrouver la position, la normale et les coordonnees de texture de chaque sommet a, b, c.
00273 //! un triangle (cf. gk::MeshMaterial) a egalement une matiere associee.
00274 //! les triangles partageants la meme matiere peuvent etre groupes dans un gk::SubMesh pour un affichage efficace.
00275 class Mesh : public IOResource
00276 {
00277     friend class MeshIO;
00278     
00279     std::vector<Point> m_positions;
00280     std::vector<Normal> m_normals;
00281     std::vector<Point2> m_texcoords;
00282     
00283     std::vector<int> m_indices;  //!< 3*triangles.size()
00284     std::vector<int> m_materials_id;     //!< triangles.size()
00285 
00286     std::vector<int> m_smooth_groups;   //!< triangles.size()
00287 
00288     std::vector<int> m_position_adjacency;        //!< positions.size(), premier element de la liste d'adjacence du sommet.
00289     std::vector<int> m_adjacency;       //!< 2* positions.size() ? liste globale m_adjacency[m_position_adjacency[id]] .. -1
00290 
00291     std::vector<SubMesh> m_submeshes;
00292     
00293     std::vector<MeshMaterial *> m_materials;
00294     MeshMaterial m_default_material;
00295 
00296     std::vector<MeshBuffer *> m_attributes_buffer;
00297 
00298     BBox m_bbox;
00299 
00300     //! declare un ensemble d'attributs point 2d.
00301     MeshBuffer *attachAttributeBuffer( const Name& semantic, const Point2& attribute_tag )
00302     {
00303         MeshBuffer *buffer= findBuffer(semantic);
00304         if(buffer != NULL)
00305             return NULL;        // deja attache
00306         
00307         buffer= new MeshBuffer(semantic, 2);
00308         m_attributes_buffer.push_back(buffer);
00309         return buffer;
00310     }
00311     
00312     //! declare un ensemble d'attributs point 3d.
00313     MeshBuffer *attachAttributeBuffer( const Name& semantic, const Point& attribute_tag )
00314     {
00315         MeshBuffer *buffer= findBuffer(semantic);
00316         if(buffer != NULL)
00317             return NULL;        // deja attache
00318         
00319         buffer= new MeshBuffer(semantic, 3);
00320         m_attributes_buffer.push_back(buffer);
00321         return buffer;
00322     }
00323     
00324     //! declare un ensemble d'attributs vecteur 3d.
00325     MeshBuffer *attachAttributeBuffer( const Name& semantic, const Vector& attribute_tag )
00326     {
00327         MeshBuffer *buffer= findBuffer(semantic);
00328         if(buffer != NULL)
00329             return NULL;        // deja attache
00330         
00331         buffer= new MeshBuffer(semantic, 3);
00332         m_attributes_buffer.push_back(buffer);
00333         return buffer;
00334     }
00335     
00336     //! declare un ensemble d'attributs normale 3d.
00337     MeshBuffer *attachAttributeBuffer( const Name& semantic, const Normal& attribute_tag )
00338     {
00339         MeshBuffer *buffer= findBuffer(semantic);
00340         if(buffer != NULL)
00341             return NULL;        // deja attache
00342         
00343         buffer= new MeshBuffer(semantic, 3);
00344         m_attributes_buffer.push_back(buffer);
00345         return buffer;
00346     }
00347     
00348     //! declare un ensemble d'attributs couleur rgba.
00349     MeshBuffer *attachAttributeBuffer( const Name& semantic, const Color& attribute_tag )
00350     {
00351         MeshBuffer *buffer= findBuffer(semantic);
00352         if(buffer != NULL)
00353             return NULL;        // deja attache
00354         
00355         buffer= new MeshBuffer(semantic, 4);
00356         m_attributes_buffer.push_back(buffer);
00357         return buffer;
00358     }
00359     
00360     //! declare un ensemble d'attributs float.
00361     MeshBuffer *attachAttributeBuffer( const Name& semantic, const float& attribute_tag )
00362     {
00363         MeshBuffer *buffer= findBuffer(semantic);
00364         if(buffer != NULL)
00365             return NULL;        // deja attache
00366         
00367         buffer= new MeshBuffer(semantic, 1);
00368         m_attributes_buffer.push_back(buffer);
00369         return buffer;
00370     }
00371 
00372 public:
00373     //! renvoie la position d'un sommet.
00374     Point& position( const int id )
00375     {
00376         assert(id >= 0 && id < (int) m_positions.size());
00377         return m_positions[id];
00378     }
00379     
00380     //! renvoie la position d'un sommet.
00381     const Point& position( const int id ) const
00382     {
00383         assert(id >= 0 && id < (int) m_positions.size());
00384         return m_positions[id];
00385     }
00386     
00387     //! renvoie la normale d'un sommet.
00388     Normal& normal( const int id )
00389     {
00390         return m_normals[id];
00391     }
00392     
00393     //! renvoie la normale d'un sommet.
00394     const Normal& normal( const int id ) const
00395     {
00396         return m_normals[id];
00397     }
00398     
00399     //! renvoie la coordonnee de texture d'un sommet.
00400     Point2& texcoords( const int id )
00401     {
00402         return m_texcoords[id];
00403     }
00404     
00405     //! renvoie la coordonnees de texture d'un sommet.
00406     const Point2& texcoords( const int id ) const
00407     {
00408         return m_texcoords[id];
00409     }
00410 
00411     
00412     //! constructeur par defaut.
00413     Mesh( ) 
00414         :
00415         IOResource(),
00416         m_default_material("default")
00417     {}
00418     
00419     //! destructeur.
00420     ~Mesh( )
00421     {
00422         const int n= (int) m_attributes_buffer.size();
00423         for(int i= 0; i < n; i++)
00424             delete m_attributes_buffer[i];
00425     }
00426     
00427     //! ajoute un sommet.
00428     int pushPosition( const Point& point )
00429     {
00430         m_positions.push_back( point );
00431         m_bbox.Union(point);
00432         return m_positions.size() -1;
00433     }
00434     
00435     //! ajoute un ensemble de sommets.
00436     void attachPositionBuffer( const std::vector<Point>& positions )
00437     {
00438         m_positions= positions;
00439     }
00440 
00441     //! ajoute un ensemble de sommets.
00442     void attachPositionBuffer( const int n, const Point *positions )
00443     {
00444         m_positions= std::vector<Point>(&positions[0], &positions[n]);
00445     }
00446 
00447     //! renvoie le nombre de sommets du maillage.
00448     int positionCount( ) const
00449     {
00450         return (int) m_positions.size();
00451     }
00452     
00453     //! renvoie les positions des sommets du maillage. 
00454     std::vector<Point>& positions( )
00455     {
00456         return m_positions;
00457     }
00458     
00459     //! renvoie les positions des sommets du maillage. 
00460     const std::vector<Point>& positions( ) const
00461     {
00462         return m_positions;
00463     }
00464     
00465     //! ajoute une normale.
00466     int pushNormal( const Normal& normal )
00467     {
00468         m_normals.push_back( normal );
00469         return m_normals.size() -1;
00470     }
00471     
00472     //! ajoute un ensemble de normales
00473     void attachNormalBuffer( const std::vector<Normal>& normals )
00474     {
00475         m_normals= normals;
00476     }
00477         
00478     //! ajoute un ensemble de normales
00479     void attachNormalBuffer( const int n, const Normal *normals )
00480     {
00481         m_normals= std::vector<Normal>(&normals[0], &normals[n]);
00482     }
00483 
00484     //! renvoie le nombre de normales du maillage.
00485     int normalCount( ) const
00486     {
00487         return (int) m_normals.size();
00488     }
00489     
00490     //! renvoie les normales.
00491     std::vector<Normal>& normals( )
00492     {
00493         return m_normals;
00494     }
00495     
00496     //! renvoie les normales.
00497     const std::vector<Normal>& normals( ) const
00498     {
00499         return m_normals;
00500     }
00501 
00502     //! ajoute une coordonnee de texture.
00503     int pushTexcoord( const Point2& texcoord )
00504     {
00505         m_texcoords.push_back( texcoord );
00506         return m_texcoords.size() -1;
00507     }
00508     
00509     //! ajoute un ensemble de coordonnees de texture.
00510     void attachTexcoordBuffer( const std::vector<Point2>& texcoords )
00511     {
00512         m_texcoords= texcoords;
00513     }
00514     
00515     //! ajoute un ensemble de coordonnees de texture.
00516     void attachTexcoordBuffer( const int n, const Point2 *texcoords )
00517     {
00518         m_texcoords= std::vector<Point2>(&texcoords[0], &texcoords[n]);
00519     }
00520 
00521     //! renvoie le nombre de coordonnees de textures des sommets du maillage.
00522     int texcoordCount( ) const
00523     {
00524         return (int) m_texcoords.size();
00525     }
00526     
00527     //! renvoie les coordonnees de textures des sommets du maillage.
00528     std::vector<Point2>& texcoords( )
00529     {
00530         return m_texcoords;
00531     }
00532     
00533     //! renvoie les coordonnees de textures des sommets du maillage.
00534     const std::vector<Point2>& texcoords( ) const
00535     {
00536         return m_texcoords;
00537     }
00538     
00539     //! renvoie les groupes de lissage de normales du maillage.
00540     const std::vector<int>& smoothGroups( )
00541     {
00542         return m_smooth_groups;
00543     }
00544     
00545     //! renvoie les groupes de lissage de normales du maillage.
00546     const std::vector<int>& smoothGroups( ) const
00547     {
00548         return m_smooth_groups;
00549     }
00550     
00551     //! attache un ensemble d'attributs.
00552     template< class T >
00553     int attachAttributeBuffer( const Name& semantic, const std::vector<T>& attributes )
00554     {
00555         MeshBuffer *buffer= attachAttributeBuffer(semantic, T());
00556         if(buffer == NULL)
00557             return -1;
00558         
00559         const int n= (int) attributes.size();
00560         for(int i= 0; i < n; i++)
00561             buffer->push(attributes[i]);
00562         return 0;
00563     }
00564     
00565     //! attache un ensemble d'attributs.
00566     template< class T >
00567     int attachAttributeBuffer( const Name& semantic, const int n, const T *attributes )
00568     {
00569         MeshBuffer *buffer= attachAttributeBuffer(semantic, T());
00570         if(buffer == NULL)
00571             return -1;
00572         
00573         for(int i= 0; i < n; i++)
00574             buffer->push(attributes[i]);
00575         return 0;
00576     }
00577 
00578     //! renvoie un buffer d'apres son nom / semantique.
00579     MeshBuffer *findBuffer( const Name& semantic ) const
00580     {
00581         const int n= (int) m_attributes_buffer.size();
00582         for(int i= 0; i < n; i++)
00583             if(m_attributes_buffer[i]->semantic == semantic)
00584                 return m_attributes_buffer[i];
00585         
00586         return NULL;
00587     }
00588     
00589     //! renvoie le nombre de buffers d'attributs.
00590     int bufferCount( ) const
00591     {
00592         return (int) m_attributes_buffer.size();
00593     }
00594     
00595     //! renvoie un buffer.
00596     MeshBuffer *buffer( const int id ) 
00597     {
00598         return m_attributes_buffer[id];
00599     }
00600     
00601     //! renvoie un buffer.
00602     const MeshBuffer *buffer( const int id ) const
00603     {
00604         return m_attributes_buffer[id];
00605     }
00606     
00607     //! insere un attribut dans l'ensemble associe.
00608     template < class T >
00609     void pushAttribute( const Name& semantic, const T& attribute )
00610     {
00611         MeshBuffer *buffer= findBuffer(semantic);
00612         if(buffer == NULL)
00613             return;
00614         buffer->push(attribute);
00615     }
00616     
00617     //! ajoute un triangle
00618     void pushTriangle( const int a, const int b, const int c, const int material_id, const int smooth_group= -1 )
00619     {
00620         m_indices.push_back(a);
00621         m_indices.push_back(b);
00622         m_indices.push_back(c);
00623         
00624         m_materials_id.push_back(material_id);
00625         m_smooth_groups.push_back(smooth_group);
00626     }
00627     
00628     //! renvoie la bbox du mesh.
00629     BBox& bbox( )
00630     {
00631         return m_bbox;
00632     }
00633 
00634     const BBox& getBBox( ) const
00635     {
00636         return m_bbox;
00637     }
00638     
00639     //! renvoie le nombre de triangles du maillage.
00640     int triangleCount( ) const
00641     {
00642         return (int) m_indices.size() / 3;
00643     }
00644     
00645     //! renvoie le nombre d'indices du maillage.
00646     int indiceCount( ) const
00647     {
00648         return (int) m_indices.size();
00649     }
00650     
00651     //! renvoie les indices du maillage.
00652     std::vector<int>& indices( )
00653     {
00654         return m_indices;
00655     }
00656     
00657     //! renvoie les indices du maillage.
00658     const std::vector<int>& indices( ) const
00659     {
00660         return m_indices;
00661     }
00662     
00663     //! ajoute un submesh.
00664     void pushSubMesh( const int begin, const int end, const int material_id )
00665     {
00666         m_submeshes.push_back( SubMesh(begin, end, material_id) );
00667     }
00668 
00669     //! renvoie le nombre de submesh.
00670     int subMeshCount( ) const
00671     {
00672         return (int) m_submeshes.size();
00673     }
00674     
00675     //! renvoie un submesh.
00676     SubMesh& subMesh( const int submesh_id )
00677     {
00678         return m_submeshes[submesh_id];
00679     }
00680     
00681     //! renvoie un submesh.
00682     const SubMesh& subMesh( const int submesh_id ) const
00683     {
00684         return m_submeshes[submesh_id];
00685     }
00686     
00687     //! renvoie la matiere d'un submesh.
00688     const MeshMaterial& subMeshMaterial( const int id ) const
00689     {
00690         const int material_id= m_submeshes[id].material_id;
00691         if(material_id < 0)
00692             return m_default_material;
00693         else
00694             return *m_materials[material_id];
00695     }
00696 
00697     //! renvoie la matiere d'un submesh.
00698     const MeshMaterial& subMeshMaterial( const int id )
00699     {
00700         const int material_id= m_submeshes[id].material_id;
00701         if(material_id < 0)
00702             return m_default_material;
00703         else
00704             return *m_materials[material_id];
00705     }
00706     
00707     //! renvoie les parties du maillage.
00708     const std::vector<SubMesh>& subMeshes( )
00709     {
00710         return m_submeshes;
00711     }
00712 
00713     //! renvoie les parties du maillage.
00714     const std::vector<SubMesh>& subMeshes( ) const
00715     {
00716         return m_submeshes;
00717     }
00718     
00719     //! construit les submeshes, sequences de triangles utilisant la meme matiere.
00720     //! tri les triangles en fonction de leur indice de matiere, eventuellement utilise un autre tableau d'indices, cf map).
00721     int buildSubMeshes( std::vector<int> *map= NULL );
00722     
00723     //! definit la matiere par defaut.
00724     int pushDefaultMaterial( )
00725     {
00726         m_materials.push_back(&m_default_material);
00727         return (int) m_materials.size() - 1;
00728     }
00729     
00730     //! insere une matiere.
00731     int pushMaterial( MeshMaterial *material )
00732     {
00733         m_materials.push_back(material);
00734         return (int) m_materials.size() - 1;
00735     }
00736     
00737     //! remplace l'ensemble de matieres.
00738     void attachMaterials( const std::vector<MeshMaterial *>& materials )
00739     {
00740         m_materials= materials;
00741     }
00742     
00743     //! renvoie le nombre de matieres.
00744     int materialCount( ) const
00745     {
00746         return (int) m_materials.size();
00747     }
00748     
00749     //! renvoie une matiere.
00750     MeshMaterial& material( const int material_id ) 
00751     {
00752         if(m_materials.empty())
00753             return m_default_material;
00754         else
00755             return *m_materials[material_id];
00756     }
00757     
00758     //! renvoie une matiere.
00759     const MeshMaterial& material( const int material_id ) const
00760     {
00761         if(m_materials.empty())
00762             return m_default_material;
00763         else
00764             return *m_materials[material_id];
00765     }
00766     
00767     //! renvoie l'ensemble de matieres.
00768     std::vector<MeshMaterial *>& materials( )
00769     {
00770         return m_materials;
00771     }
00772     
00773     //! renvoie l'ensemble de matieres.
00774     const std::vector<MeshMaterial *>& materials( ) const
00775     {
00776         return m_materials;
00777     }
00778     
00779     //! renvoie l'ensemble d'identifiants de matieres des triangles.
00780     const std::vector<int>& triangleMaterialsId( ) const
00781     {
00782         return m_materials_id;
00783     }
00784     
00785     //! renvoie l'ensemble d'identifiants de matieres des triangles.
00786     std::vector<int>& triangleMaterialsId( )
00787     {
00788         return m_materials_id;
00789     }
00790     
00791     //! renvoie la matiere d'un triangle.
00792     MeshMaterial& triangleMaterial( const int id )
00793     {
00794         const int material_id= m_materials_id[id];
00795         
00796         if(material_id < 0)
00797             return m_default_material;
00798         else
00799             return material(material_id);
00800     }
00801     
00802     //! renvoie la matiere d'un triangle.
00803     const MeshMaterial& triangleMaterial( const int id ) const
00804     {
00805         const int material_id= m_materials_id[id];
00806         
00807         if(material_id < 0)
00808             return m_default_material;
00809         else
00810             return material(material_id);
00811     }
00812 
00813     //! renvoie l'indice de la matiere d'un triangle.
00814     int getTriangleMaterialId( const int id ) const
00815     {
00816         return m_materials_id[id];
00817     }
00818     
00819     //! renvoie un triangle 'indexe', les 3 indices des sommets du triangle.
00820     MeshTriangle getMeshTriangle( const int id ) const
00821     {
00822         assert(id >= 0 && id < triangleCount());
00823         return MeshTriangle(this, m_indices[3*id], m_indices[3*id +1], m_indices[3*id +2]);
00824     }
00825     //! renvoie un triangle 'geometrique' pour le calcul d'intersection avec un rayon.
00826     //! utiliser les resultats de l'intersection pour calculer la normale et les texcoords interpolees au point d'intersection.
00827     //! cf. Mesh::getUVPoint(), Mesh::getUVNormal(), Mesh::getUVTexcoord().
00828     Triangle getTriangle( const int id ) const
00829     {
00830         const Point& a= position(m_indices[3*id]);
00831         const Point& b= position(m_indices[3*id +1]);
00832         const Point& c= position(m_indices[3*id +2]);
00833         
00834         return Triangle(a, b, c);
00835     }
00836     
00837     //! renvoie un pn triangle.
00838     PNTriangle getPNTriangle( const int id ) const
00839     {
00840         if(m_normals.size() != m_positions.size())
00841         {
00842             // pas de normales associees aux sommets, calcule la normale geometrique.
00843             const Point& a= position(m_indices[3*id]);
00844             const Point& b= position(m_indices[3*id +1]);
00845             const Point& c= position(m_indices[3*id +2]);
00846             const Vector ab(a, b);
00847             const Vector ac(a, c);
00848             Normal nn( Normalize(Cross(ab, ac)) );
00849             
00850             return PNTriangle(getTriangle(id), nn, nn, nn);
00851         }
00852         
00853         // renvoie les normales associees aux sommets du triangle
00854         const Normal& na= normal(m_indices[3*id]);
00855         const Normal& nb= normal(m_indices[3*id +1]);
00856         const Normal& nc= normal(m_indices[3*id +2]);
00857         return PNTriangle(getTriangle(id), na, nb, nc);
00858     }
00859     
00860     //! renvoie un ptn triangle
00861     PTNTriangle getPTNTriangle( const int id ) const
00862     {
00863         if(m_texcoords.size() != m_positions.size())
00864         {
00865             // pas de coordonnees de textures associees aux sommets, domaine parametrique unitaire.
00866             return PTNTriangle(getPNTriangle(id), Point2(0.f, 0.f), Point2(1.f, 0.f), Point2(1.f, 1.f));
00867         }
00868         
00869         // renvoie les normales associees aux sommets du triangle
00870         const Point2& ta= texcoords(m_indices[3*id]);
00871         const Point2& tb= texcoords(m_indices[3*id +1]);
00872         const Point2& tc= texcoords(m_indices[3*id +2]);
00873         return PTNTriangle(getPNTriangle(id), ta, tb, tc);
00874     }
00875     
00876     //! renvoie la boite englobante d'un triangle.
00877     BBox getTriangleBBox( const int id )
00878     {
00879         const Point& a= position(m_indices[3*id]);
00880         const Point& b= position(m_indices[3*id +1]);
00881         const Point& c= position(m_indices[3*id +2]);
00882         
00883         BBox bbox;
00884         bbox.Union(a);
00885         bbox.Union(b);
00886         bbox.Union(c);
00887         
00888         return bbox;
00889     }
00890 
00891     //! renvoie l'aire d'un triangle.
00892     float getTriangleArea( const int id )
00893     {
00894         const Point& a= position(m_indices[3*id]);
00895         const Point& b= position(m_indices[3*id +1]);
00896         const Point& c= position(m_indices[3*id +2]);
00897         const Vector ab(a, b);
00898         const Vector ac(a, c);
00899         return .5f * Cross(ab, ac).Length();
00900     }
00901     
00902     //! calcule et renvoie la normale geometrique d'un triangle.
00903     Normal getTriangleNormal( const int id ) const
00904     {
00905         const Point& a= position(m_indices[3*id]);
00906         const Point& b= position(m_indices[3*id +1]);
00907         const Point& c= position(m_indices[3*id +2]);
00908 
00909         const Vector ab(a, b);
00910         const Vector ac(a, c);
00911         Vector n= Cross(Normalize(ab), Normalize(ac));
00912         return Normal(Normalize(n));
00913     }
00914     
00915     //! interpole une position a l'interieur d'un triangle, connaissant les coordonnees barycentriques du point.
00916     //! convention p(u, v)= (1 - u - v) * a + u * b + v * c
00917     Point getUVPoint( const int id, const float u, const float v ) const
00918     {
00919         const Point& a= position(m_indices[3*id]);
00920         const Point& b= position(m_indices[3*id +1]);
00921         const Point& c= position(m_indices[3*id +2]);
00922         
00923         const float w= 1.f - u - v;
00924         return a * w + b * u + c * v;
00925     }
00926     
00927     //! interpole une normale a l'interieur d'un triangle, connaissant ses coordonnees barycentriques.
00928     //! convention n(u, v)= (1 - u - v) * a + u * b + v * c
00929     Normal getUVNormal( const int id, const float u, const float v ) const
00930     {
00931         if(m_normals.empty())
00932             // renvoie la normale geometrique, si les normales des sommets n'existent pas
00933             return getTriangleNormal(id);
00934         
00935         const Normal& a= normal(m_indices[3*id]);
00936         const Normal& b= normal(m_indices[3*id +1]);
00937         const Normal& c= normal(m_indices[3*id +2]);
00938         
00939         const float w= 1.f - u - v;
00940         return Normalize(a * w + b * u + c * v);
00941     }
00942     
00943     //! interpole une coordonnee de texture a l'interieur du triangle, connaissant ses coordonnees barycentriques.
00944     //! convention t(u, v)= (1 - u - v) * a + u * b + v * c
00945     Point2 getUVTexcoord( const int id, const float u, const float v ) const
00946     {
00947         if(m_texcoords.empty())
00948             // pas de coordonnee de textures dans le maillage.
00949             return Point2();
00950         
00951         const Point2& a= texcoords(m_indices[3*id]);
00952         const Point2& b= texcoords(m_indices[3*id +1]);
00953         const Point2& c= texcoords(m_indices[3*id +2]);
00954         
00955         const float w= 1.f - u - v;
00956         return a * w + b * u + c * v;
00957     }
00958     
00959     //! renvoie le smooth group du triangle.
00960     int getTriangleSmoothGroup( const int id )
00961     {
00962         if(m_smooth_groups.empty())
00963             return -1;
00964         return m_smooth_groups[id];
00965     }
00966     
00967     //! construit la liste d'adjacence des sommets (liste de triangles).
00968     //! \todo acces a l'adjacence.
00969     int buildAdjacency( );
00970     
00971     //! construit les smooth groups en fonction de l'angle entre les normales des triangles adjacents.
00972     int buildNormalSmoothGroups( const float max_angle );
00973     
00974     //! construit les smooth groups en fonction de la distance entre les coordonnees de textures des triangles adjacents. 
00975     int buildTexcoordSmoothGroups( const float max );
00976     
00977     //! construit les normales du maillage. 
00978     //! \todo utiliser les smooth groups s'ils sont presents.
00979     int buildNormals( );
00980 };
00981 
00982 
00983 // mesh triangle impl
00984 inline
00985 const Point& MeshTriangle::position( const int k ) const
00986 {
00987     assert(mesh != NULL);
00988     return mesh->position(vertex(k));
00989 }
00990 
00991 inline
00992 Point MeshTriangle::position( const int k ) 
00993 {
00994     assert(mesh != NULL);
00995     return mesh->position(vertex(k));
00996 }
00997 
00998 inline
00999 const Normal& MeshTriangle::normal( const int k ) const
01000 {
01001     assert(mesh != NULL);
01002     return mesh->normal(vertex(k));
01003 }
01004 
01005 inline
01006 Normal MeshTriangle::normal( const int k )
01007 {
01008     assert(mesh != NULL);
01009     return mesh->normal(vertex(k));
01010 }
01011 
01012 inline
01013 const Point2& MeshTriangle::texcoords( const int k ) const
01014 {
01015     assert(mesh != NULL);
01016     return mesh->texcoords(vertex(k));
01017 }
01018 
01019 inline
01020 Point2 MeshTriangle::texcoords( const int k )
01021 {
01022     assert(mesh != NULL);
01023     return mesh->texcoords(vertex(k));
01024 }
01025 
01026 inline
01027 Color MeshTriangle::asColor( const Name& attribute, const int k )
01028 {
01029     assert(mesh != NULL);
01030     const MeshBuffer *buffer= mesh->findBuffer(attribute);
01031     assert(buffer != NULL);
01032     return buffer->asColor(vertex(k));
01033 }
01034 
01035 inline
01036 Color MeshTriangle::asColor( const int attribute_id, const int k )
01037 {
01038     assert(mesh != NULL);
01039     const MeshBuffer *buffer= mesh->buffer(attribute_id);
01040     assert(buffer != NULL);
01041     return buffer->asColor(vertex(k));
01042 }
01043 
01044 inline 
01045 Point MeshTriangle::asPoint( const Name& attribute, const int  k )
01046 {
01047     assert(mesh != NULL);
01048     const MeshBuffer *buffer= mesh->findBuffer(attribute);
01049     assert(buffer != NULL);
01050     return buffer->asPoint(vertex(k));
01051 }
01052 
01053 inline
01054 Point MeshTriangle::asPoint( const int attribute_id, const int  k )
01055 {
01056     assert(mesh != NULL);
01057     const MeshBuffer *buffer= mesh->buffer(attribute_id);
01058     assert(buffer != NULL);
01059     return buffer->asPoint(vertex(k));
01060 }
01061 
01062 inline 
01063 Vector MeshTriangle::asVector( const Name& attribute, const int  k )
01064 {
01065     assert(mesh != NULL);
01066     const MeshBuffer *buffer= mesh->findBuffer(attribute);
01067     assert(buffer != NULL);
01068     return buffer->asVector(vertex(k));
01069 }
01070 
01071 inline
01072 Vector MeshTriangle::asVector( const int attribute_id, const int  k )
01073 {
01074     assert(mesh != NULL);
01075     const MeshBuffer *buffer= mesh->buffer(attribute_id);
01076     assert(buffer != NULL);
01077     return buffer->asVector(vertex(k));
01078 }
01079 
01080 inline 
01081 Normal MeshTriangle::asNormal( const Name& attribute, const int  k )
01082 {
01083     assert(mesh != NULL);
01084     const MeshBuffer *buffer= mesh->findBuffer(attribute);
01085     assert(buffer != NULL);
01086     return buffer->asNormal(vertex(k));
01087 }
01088 
01089 inline
01090 Normal MeshTriangle::asNormal( const int attribute_id, const int  k )
01091 {
01092     assert(mesh != NULL);
01093     const MeshBuffer *buffer= mesh->buffer(attribute_id);
01094     assert(buffer != NULL);
01095     return buffer->asNormal(vertex(k));
01096 }
01097 
01098 inline
01099 Point2 MeshTriangle::asPoint2( const Name& attribute, const int k )
01100 {
01101     assert(mesh != NULL);
01102     const MeshBuffer *buffer= mesh->findBuffer(attribute);
01103     assert(buffer != NULL);
01104     return buffer->asPoint2(vertex(k));
01105 }
01106 
01107 inline
01108 Point2 MeshTriangle::asPoint2( const int  attribute_id, const int k )
01109 {
01110     assert(mesh != NULL);
01111     const MeshBuffer *buffer= mesh->buffer(attribute_id);
01112     assert(buffer != NULL);
01113     return buffer->asPoint2(vertex(k));
01114 }
01115 
01116 inline
01117 float MeshTriangle::asFloat( const Name& attribute, const int k )
01118 {
01119     assert(mesh != NULL);
01120     const MeshBuffer *buffer= mesh->findBuffer(attribute);
01121     assert(buffer != NULL);
01122     return buffer->asFloat(vertex(k));
01123 }
01124 
01125 inline
01126 float MeshTriangle::asFloat( const int attribute_id, const int k )
01127 {
01128     assert(mesh != NULL);
01129     const MeshBuffer *buffer= mesh->buffer(attribute_id);
01130     assert(buffer != NULL);
01131     return buffer->asFloat(vertex(k));
01132 }
01133 
01134 } // namespace
01135 
01136 #endif
 All Classes Namespaces Functions Variables Typedefs Enumerator Friends