#0 

07-01-2010 16:46:51

shiratori
Petit nouveau
Date d'inscription: 07-01-2010
Messages: 7

Bonjour,
Je dois récupérer les sommets et faces d'un objet chargé avec irrlicht pour déterminer les sommets adjacents à un sommet donné et les faces adjacentes à une face donnée.
J'ai déjà réussi à récupérer les coordonnées des sommets de mon fichier en me basant sur l'algorithme a* donné par neo:

Code c++ :


//  Récupération du maillage
void maillage(irr::scene::IAnimatedMesh *modele) //Modele passé en paramètre
{
    //  Récupération du maillage
    irr::scene::IMesh* Mesh = modele->getMesh(0);

    for(int i=0;i<(int)(Mesh->getMeshBufferCount());i++)    // Balaye chaque partie du même objet 3D
    {
        irr::scene::IMeshBuffer *IMeshBuf = Mesh->getMeshBuffer(i);
        int VertexCount =     IMeshBuf->getVertexCount();    //  Nombre de sommets
        int IndexCount  =     IMeshBuf->getIndexCount();    //  Nombre de faces

        irr::video::S3DVertex* normVerts = (irr::video::S3DVertex*)(IMeshBuf->getVertices()); // Tableau de sommets

        positionSommets(VertexCount, normVerts); // Affiche les coordonnées des sommets
    }
}



Avec la fonction d'affichage des coordonnées des sommets:

Code c++ :


//  Récupération des coordonnées des sommets
void positionSommets(int VertexCount, irr::video::S3DVertex* normVerts)
{
    for(int j=0;j<VertexCount;j++)// Balaye chaque vertex d'une des parties de l'objet 3D
    {
        float PosX = -(float)normVerts[j].Pos.X;            // Récupération de la coordonnée x
        float PosY = (float)normVerts[j].Pos.Y;            // Récupération de la coordonnée y
        float PosZ = (float)normVerts[j].Pos.Z;            // Récupération de la coordonnée z
        printf("position du sommet %d sur %d: x:%f, y:%f, z:%f \n",j, VertexCount,PosX,PosY,PosZ);
    }
}



Je récupère donc les informations contenues dans les lignes de mon fichier de la forme suivante:
v 41.183029 839.117737 51.900291

Je souhaiterais faire la même chose pour parcourir et récupérer les faces. C'est à dire les lignes de la forme:
f 9316/9409 9226/9319 9306/9399 9175/9268

Je pense que pour récupérer le nombre de faces et le tableau des faces, il faut utiliser les méthodes

Code c++ :

IMeshBuf->getIndexCount()

et

Code c++ :

IMeshBuf->getIndices()

mais je ne sais pas comment les utiliser de manière a afficher les valeurs.
Quelqu'un aurait-il une idée d'implémentation pour récupérer les faces de la même manière que j'ai récupéré les sommets?

Hors ligne


#1 

11-01-2010 19:36:09

shiratori
Petit nouveau
Date d'inscription: 07-01-2010
Messages: 7

Bon eh bien j'ai fini par trouver tout seul.
Il suffisait de faire ainsi:

Code c++ :


//  Récupération des sommets constituant les faces et de leurs coordonnées
void recupFaces(int nbFaces, irr::u16* faces, int nbSparf, irr::video::S3DVertex* normVerts)
{
    for (int j=0; j<nbFaces; j+=nbSparf)
    {
        int sommet1 = faces[j]; //  Sommet 1 de la face
        int sommet2 = faces[j+1];   //  Sommet 2 de la face
        int sommet3 = faces[j+2];   //  Sommet 3 de la face
        if(nbSparf == 4){   //  Si il y a 4 sommets par face
            int sommet4 = faces[j+3];   //  Sommet 4 de la face
            printf("position du sommet %d sur %d: x:%f, y:%f, z:%f \n",(j/4)+1,nbFaces/4,sommet1,sommet2,sommet3,sommet4);
            positionUnSommet(sommet1, normVerts);   //  Coordonnées du sommet 1
            positionUnSommet(sommet2, normVerts);   //  Coordonnées du sommet 2
            positionUnSommet(sommet3, normVerts);   //  Coordonnées du sommet 3
            positionUnSommet(sommet4, normVerts);   //  Coordonnées du sommet 4
        }else{
            printf("La face %d sur %d et composee des sommets: %d , %d , %d, %d\n",(j/3)+1,nbFaces/3,sommet1,sommet2,sommet3);
            positionUnSommet(sommet1, normVerts);   //  Coordonnées du sommet 1
            positionUnSommet(sommet2, normVerts);   //  Coordonnées du sommet 2
            positionUnSommet(sommet3, normVerts);   //  Coordonnées du sommet 3
        }
    }
}


Avec, pour récupérer les coordonnées d'un sommet:

Code c++ :


//  Récupération des coordonnées d'un sommet
void positionUnSommet(int numSommet, irr::video::S3DVertex* normVerts)
{
        //  Récupération des coordonnées d'un sommet
        float PosX = -(float)normVerts[numSommet].Pos.X;            // Récupération de la coordonnée x
        float PosY = (float)normVerts[numSommet].Pos.Y;            // Récupération de la coordonnée y
        float PosZ = (float)normVerts[numSommet].Pos.Z;            // Récupération de la coordonnée z
        printf("position du sommet %d sur %d: x:%f, y:%f, z:%f \n",numSommet,PosX,PosY,PosZ);
}


Et pour récupérer le tableau des faces et celui des sommets:

Code c++ :


irr::video::S3DVertex* normVerts = (irr::video::S3DVertex*)(IMeshBuf->getVertices());
irr::u16* faces  = IMeshBuf->getIndices();

Hors ligne


#2 

12-01-2010 11:25:16

TUpac
Habitué
Date d'inscription: 08-09-2009
Messages: 387
Corrections: 1

Bravo joli code qui aurait bien sa place dans la rubrique routines wink


"Si vous ne partagez pas votre stabilité avec les pauvres, les pauvres partageront leur instabilité avec vous."

Hors ligne


#3 

24-01-2010 23:12:14

shiratori
Petit nouveau
Date d'inscription: 07-01-2010
Messages: 7

Bonsoir,
Je viens de me rendre compte d'un problème dans mon code.
Le nombre de sommets récupéré par getVertexCount() n'est pas le même que celui dans le fichier .obj.
Par exemple, pour un cube de 12 triangles (faces) et de 8 sommets (dans le .obj), ma fonction me récupère bien 12 faces, mais 15 sommets.
En effet, 7 des huit sommets apparaissent deux fois mais avec des indices différents.
Dans mon fichier par exemple, les sommets 1 et 9 ont les mêmes coordonnées (x=1; y=1; z=0).
Quelqu'un aurait-il une idée pour supprimer les doublons?
Est-ce que, comme pour obtenir le nombre de faces, il faut effectuer un calcul pour obtenir le nombre de sommets ou existe-il une autre fonction que getVertexCount()?
Toutes les idées sont les bienvenues, du moment qu'elles me permettent de résoudre mon problème.

Hors ligne


#4 

25-01-2010 13:16:25

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Tu pourrait stocker tout tes sommets dans un std::vector et utiliser un algorithme de suppression de doublon

Hors ligne


#5 

25-01-2010 13:20:56

shiratori
Petit nouveau
Date d'inscription: 07-01-2010
Messages: 7

Merci de ta réponse!
Je vais tester ca et mettrai le code si ca marche!
Par contre, je ne sais pas si en supprimant les doublons, ca ne risque pas de poser problème au niveau des faces (sommets supprimés inconnus).

Dernière modification par shiratori (25-01-2010 13:42:46)

Hors ligne


#6 

25-01-2010 16:39:39

firnafin
Abonné
Date d'inscription: 31-03-2007
Messages: 150

Il faut faire attention au fait que des sommets apparaissant plusieurs fois n'est pas forcement un erreur :
Sur un cube par exemple, une texture est en générale appliquée sur chaque face du cube or si il y  a que 8 sommets c'est pas possible a cause des coordonnées uv (qui sont unique pour chaque sommet ) donc on rajoute des sommets au meme endroit avec des coordonnées uv differentes ; et on construit les triangles de tel sorte que chaque qu'elle ressemble a ca:

(0,0)___________(1,0)
   |                      |
   |                      |
   |                      |
   |                      |
   |                      |
   |____________ |
(0,1)                   (1,1)

Hors ligne


#7 

25-01-2010 23:57:27

shiratori
Petit nouveau
Date d'inscription: 07-01-2010
Messages: 7

Bonsoir,
Non, mon cube est un obj simple avec juste des sommets (vertex) et des faces.
Il n'y a pas de textures.
Et il faut que je récupère toutes mes faces et tous mes sommets sans avoir aucun doublon.
En fait, je dois créer des demie-arêtes à partir des faces et des sommets, donc je dois déjà bien récupérer mes faces et mes sommets pour m'en sortir.

Hors ligne


#8 

26-01-2010 21:50:36

Ilovechocolat
Abonné
Date d'inscription: 07-10-2009
Messages: 125

Comment on fait pour récupérer le nombre de face d'un meshBuffer ? (pour le donner comme premier argument de ta fonction)

EDIT : j'ai trouvé : getIndexCount()

Dernière modification par Ilovechocolat (26-01-2010 21:52:38)

Hors ligne


#9 

26-01-2010 22:56:14

shiratori
Petit nouveau
Date d'inscription: 07-01-2010
Messages: 7

Exactement, pour récupérer le nombre de faces, il suffit de mettre cette ligne de code
int nbFaces  =     IMeshBuf->getIndexCount();    //  Nombre de faces
Par exemple, pour un cube, ca te donnera 36 comme résultat, soient 12 triangles (on divise par 3) ou 6 quads (on divise par 6 car un rectangle c'est deux triangles).
Mais je ne vois pas où tu veux en venir?
Le nombre de faces je l'ai bien récupéré, c'est le nombre de sommets qui n'est pas bon.

Dernière modification par shiratori (26-01-2010 22:57:01)

Hors ligne


Options Liens officiels Caractéristiques Statistiques Communauté
Corrections
irrlicht
irrklang
irredit
irrxml
xhtml 1.0
css 2.1
Propulsé par FluxBB
Traduit par FluxBB.fr
Analysé par
880 membres
1424 sujets
11113 messages
Dernier membre inscrit: mandrifidy
40 invités en ligne
Aucun membre connecté
RSS Feed