(résolu) [Java 3D] Changer l'apparence d'objets WaveFront

[Java 3D] Changer l'apparence d'objets WaveFront (résolu) - Java - Programmation

Marsh Posté le 08-04-2006 à 14:43:55    

Tout d'abord, bonjour tout le monde !
 
Alors voilà, mon problème est que je charge plusieurs objets wavefront (*.obj) dans un canvas3d, mais qu'ensuite je voudrais changer leur apparence comme la couleur ou passer en "fil de fer". Ceci marche lorsque je fais appel à une procédure "traverse" (qui me sert à énumérer tous les objets contenus dans ma scène) directement quand je les charge ; mais je voudrais changer l'apparence après avoir chargé mes objets en cliquant sur un bouton par exemple. Mais çà ne marche pas, j'ai toujours une erreur "Cannot modify capability bits on a live or compiled object", alors que j'ai mis des setCapability et sur l'apparence et sur mes Shape3D...  :cry:  
 
Voici le code associé :
 

Code :
  1. /**
  2. * Chargement de l'objet Wavefront (014_110.obj) ainsi que les materiaux qui
  3. * lui sont associes
  4. * @return BranchGroup branch group contenant l'objet Wavefront
  5. */
  6. private BranchGroup loadWavefrontObject(String filename) {
  7.  ObjectFile waveFrontObject = new ObjectFile(ObjectFile.RESIZE | ObjectFile.STRIPIFY | ObjectFile.TRIANGULATE);
  8.  int error = 0;
  9.  sceneNum++;
  10.  System.out.println("sceneNum = " + sceneNum);
  11.  Scene scene = null;
  12.  try {
  13.   if (!applet) {
  14.   scene = waveFrontObject.load(filename);
  15.   }
  16.   else {
  17.    URL url = this.getCodeBase();
  18.    String path = url.toString() + filename;
  19.    try {
  20.     URL fileUrl = new URL(path);
  21.     scene = waveFrontObject.load(fileUrl);
  22.    }
  23.    catch (MalformedURLException ex2) {
  24.     System.out.println("Impossible de charger le fichier : " + filename);
  25.     error = -1;
  26.    }
  27.   }  // fin else
  28.  }  // fin try
  29.  catch (ParsingErrorException ex) {
  30.   System.out.println("Fichier defectueux" );
  31.   error = -1;
  32.  }
  33.  catch (IncorrectFormatException ex) {
  34.   System.out.println("Mauvais format de fichier" );
  35.   error = -1;
  36.  }
  37.  catch (FileNotFoundException ex) {
  38.   System.out.println("Fichier " + filename + " non trouve" );
  39.   error = -1;
  40.  }
  41.  if (error != 0)
  42.   System.exit(error);
  43.  //Construct and return branch group containing our OBJ scene.
  44.  BranchGroup contentBranchGroup = new BranchGroup();
  45.  contentBranchGroup.setCapability(BranchGroup.ALLOW_DETACH);
  46.  contentBranchGroup.addChild(scene.getSceneGroup());
  47.  en = contentBranchGroup.getAllChildren();
  48.  traverse(en);
  49.  return(contentBranchGroup);
  50. }


 
Et voici le code de la fonction "traverse" :
 

Code :
  1. public void traverse (Enumeration e) {
  2.   int i = 0;
  3.   while(e.hasMoreElements()){
  4.    Object o = e.nextElement();
  5.    if (o instanceof Shape3D){
  6.     i++;
  7.     System.out.println("Enum" + i);
  8.     Shape3D shape = (Shape3D) o;
  9.     /*PolygonAttributes pa = new PolygonAttributes();
  10.     pa.setPolygonMode(PolygonAttributes.POLYGON_LINE);
  11.     pa.setCullFace(PolygonAttributes.CULL_NONE);
  12.     app.setPolygonAttributes(pa);*/
  13.     System.out.println("Appearance" );
  14.     shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE);
  15.     shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
  16.     shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
  17.     shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_READ);
  18.     Material material = new Material(new Color3f(0.0f, 0.0f, 1.0f),
  19.             new Color3f(0.0f, 0.0f, 0.0f),
  20.             new Color3f(0.5f, 0.5f, 0.5f),
  21.             new Color3f(1.0f, 1.0f, 1.0f),
  22.             64);
  23.     appObj.setMaterial(material);
  24.     System.out.println("Capability" );
  25.                 shape.setAppearance(appObj);
  26.                 System.out.println("SetAppearance" );
  27.    }
  28.    if (o instanceof Group) {
  29.     Group g = (Group) o;
  30.     this.traverse(g.getAllChildren());
  31.    }
  32.   } // end while
  33. } // end traverse
  34. public void init() {
  35.  if (applet) {
  36.   lanceApplication();
  37.  }
  38. }


 
Et pour finir le bouton par lequel j'essaye d'appeler la fonction "traverse" afin de modifier l'apparence de mes objets :
 

Code :
  1. private void processCB(ActionEvent e) {
  2.  if (e.getSource().equals(jButton)) {
  3.   traverse(en);
  4.  }
  5. }


 
Si quelqu'un avait une idée, ce serait vraiment sympa, parce que là je galère... :sweat:  
Merci d'avance !!! ;)


Message édité par Frac10 le 10-04-2006 à 10:16:12
Reply

Marsh Posté le 08-04-2006 à 14:43:55   

Reply

Marsh Posté le 09-04-2006 à 01:00:51    

Les setCapability on les fait une seule fois et avant la compilation de la scène.
Après tu pourras faire autant de setAppearance que tu voudras.


---------------
Incongru : une FAQ abandonnée sur les Standards du Web - FAQ périmée de blabla@Prog
Reply

Marsh Posté le 09-04-2006 à 15:06:25    

Merci bien pour ta réponse, et ok j'ai appelé mes setCapability avant la compilation comme tu me l'as conseillé (dans le BranchGroup loadWaveFrontObject j'appelle une fonction "capacite" avant la complitation de la scène) dans le bout de code qui suit :
 

Code :
  1. public void capacite (Enumeration e) {
  2.  int i = 0;
  3.    while(e.hasMoreElements()){
  4.     Object o = e.nextElement();
  5.     if (o instanceof Shape3D){
  6.      i++;
  7.      System.out.println("Enum" + i);
  8.      Shape3D shape = (Shape3D) o;
  9.      shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE);
  10.      shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
  11.      shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
  12.      shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_READ);
  13.     }
  14.     if (o instanceof Group) {
  15.      Group g = (Group) o;
  16.      this.capacite(g.getAllChildren());
  17.     }
  18.    } // end while
  19. }


 
Je n'ai plus d'erreur, c'est bon, mais apparemment lorsque je clique sur le bouton (jButton) et que celui-ci appelle la fonction "traverse", il ne trouve pas de shape3D puisqu'il ne rentre même pas dans le "while" : il ne trouve pas d'éléments dans mon énumération... Je pense que çà vient du fait que le BranchGroup qui contient la scene est déclaré dans la fonction qui charge les objets (loadWaveFrontObject), mais je sais pas comment faire... :sweat:  
Désolé pour mon ignorance, mais je débute en java... :(  
 
Merci d'avance ! ;)

Reply

Marsh Posté le 09-04-2006 à 16:05:55    

Ben tu déclares ton BranchGroupe "racine" comme objet membre de ta classe pour y accéder de partout...
 
Il faut aussi que tes BranchGroup soient autorisés à ce que leurs enfants soient lus.


---------------
Incongru : une FAQ abandonnée sur les Standards du Web - FAQ périmée de blabla@Prog
Reply

Marsh Posté le 09-04-2006 à 16:58:25    

Heu pour autoriser à ce que les enfants des BranchGroup soient lus, c'est bien avec la capacité "ALLOW_DETACH" ? Si c'est çà, je l'avais déjà mis et pour le BranchGroup "racine", c'est ce que j'ai tenté de faire, mais çà ne marche pas... :(  
 
En fait, lors du chargement des objets, pour chaque objet j'appelle ma fonction "capacite" et là c'est bon, il rentre dans la boucle "while" de celle-ci (donc il trouve des éléments dans mon énumération) : les objets se chargent normalement.
 
Mais ensuite, lorsque j'appuie sur le bouton ( pour changer l'apparence de mes objets via la fonction "traverse" ), il ne rentre plus dans la boucle "while", comme s'il ne trouvait pas d'élément dans mon énumération... :cry:  
 
Merci pour ton attention !  :)

Reply

Marsh Posté le 09-04-2006 à 18:40:15    

Frac10 a écrit :

Heu pour autoriser à ce que les enfants des BranchGroup soient lus, c'est bien avec la capacité "ALLOW_DETACH" ? Si c'est çà, je l'avais déjà mis et pour le BranchGroup "racine", c'est ce que j'ai tenté de faire, mais çà ne marche pas... :(


Non c'est ALLOW_CHILDREN_READ (!). A appliquer au BranchGroup racine mais aussi à tous les sous BranchGroup qui y sont attachés.
 

Frac10 a écrit :

En fait, lors du chargement des objets, pour chaque objet j'appelle ma fonction "capacite" et là c'est bon, il rentre dans la boucle "while" de celle-ci (donc il trouve des éléments dans mon énumération) : les objets se chargent normalement.


En fait je me demande à quoi te sert ta méthode capacite(). Pourquoi est-ce que tu n'affectes pas les capacités des tes Shape3D au moment de leur ajout dans leur BranchGroup ?
Quel est l'intérêt de parcourir récursivement l'arbre pour faire des setCapability() ? Pour le passage en fil de fer je le conçois, mais là ça me paraît bizarre.
 

Frac10 a écrit :

Mais ensuite, lorsque j'appuie sur le bouton ( pour changer l'apparence de mes objets via la fonction "traverse" ), il ne rentre plus dans la boucle "while", comme s'il ne trouvait pas d'élément dans mon énumération... :cry:


Là pour l'instant je vois pas trop, mais il y a des points en amont à éclaircir !

Message cité 1 fois
Message édité par gm_superstar le 09-04-2006 à 18:41:15

---------------
Incongru : une FAQ abandonnée sur les Standards du Web - FAQ périmée de blabla@Prog
Reply

Marsh Posté le 09-04-2006 à 21:12:12    

gm_superstar a écrit :

Non c'est ALLOW_CHILDREN_READ (!). A appliquer au BranchGroup racine mais aussi à tous les sous BranchGroup qui y sont attachés.
 
En fait je me demande à quoi te sert ta méthode capacite(). Pourquoi est-ce que tu n'affectes pas les capacités des tes Shape3D au moment de leur ajout dans leur BranchGroup ?
Quel est l'intérêt de parcourir récursivement l'arbre pour faire des setCapability() ? Pour le passage en fil de fer je le conçois, mais là ça me paraît bizarre.


 
Donc OK, j'ai changé ces deux points, mais c'est toujours la même chose. :(  
 
Voilà le loader WaveFront :
 

Code :
  1. private BranchGroup loadWavefrontObject(String filename) {
  2.  ObjectFile waveFrontObject = new ObjectFile(ObjectFile.RESIZE | ObjectFile.TRIANGULATE);
  3.  int error = 0;
  4.  sceneNum++;
  5.  System.out.println("sceneNum = " + sceneNum);
  6.  Scene scene = null;
  7.  try {
  8.   if (!applet) {
  9.   scene = waveFrontObject.load(filename);
  10.   }
  11.   else {
  12.    URL url = this.getCodeBase();
  13.    String path = url.toString() + filename;
  14.    try {
  15.     URL fileUrl = new URL(path);
  16.     scene = waveFrontObject.load(fileUrl);
  17.    }
  18.    catch (MalformedURLException ex2) {
  19.     System.out.println("Impossible de charger le fichier : " + filename);
  20.     error = -1;
  21.    }
  22.   }  // fin else
  23.  }  // fin try
  24.  catch (ParsingErrorException ex) {
  25.   System.out.println("Fichier defectueux" );
  26.   error = -1;
  27.  }
  28.  catch (IncorrectFormatException ex) {
  29.   System.out.println("Mauvais format de fichier" );
  30.   error = -1;
  31.  }
  32.  catch (FileNotFoundException ex) {
  33.   System.out.println("Fichier " + filename + " non trouve" );
  34.   error = -1;
  35.  }
  36.  if (error != 0)
  37.   System.exit(error);
  38.  //Construct and return branch group containing our OBJ scene.
  39.  contentBranchGroup = new BranchGroup();
  40.  contentBranchGroup.setCapability(BranchGroup.ALLOW_DETACH);
  41.  contentBranchGroup.setCapability(BranchGroup.ALLOW_CHILDREN_READ);
  42.  contentBranchGroup.addChild(scene.getSceneGroup());
  43.  en = contentBranchGroup.getAllChildren();
  44.  while(en.hasMoreElements()){
  45.   int i = 0;
  46.   Object o = en.nextElement();
  47.   if (o instanceof Shape3D){
  48.    i++;
  49.    System.out.println("C'est bon !!!" );
  50.    Shape3D shape = (Shape3D) o;
  51.    shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_WRITE);
  52.    shape.setCapability(Shape3D.ALLOW_APPEARANCE_WRITE);
  53.    shape.setCapability(Shape3D.ALLOW_APPEARANCE_READ);
  54.    shape.setCapability(Shape3D.ALLOW_APPEARANCE_OVERRIDE_READ);
  55.    System.out.println("Ayé !!!" );
  56.   }
  57.   if (o instanceof Group) {
  58.    Group g = (Group) o;
  59.    this.capacite(g.getAllChildren());
  60.   }
  61.  } // end while
  62.  appObj = new Appearance();
  63.      appObj.setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_READ);
  64.      appObj.setCapability(Appearance.ALLOW_POLYGON_ATTRIBUTES_WRITE);
  65.      appObj.setCapability(Appearance.ALLOW_MATERIAL_WRITE);
  66.      appObj.setCapability(Appearance.ALLOW_MATERIAL_READ);
  67.  //capacite(en);
  68.  traverse(en);
  69.  return(contentBranchGroup);
  70. }


 
J'ai remarqué une chose : là j'ai juste voulu voir si l'apparence de mes objets changeait quand j'appelle la fonction "traverse" avant la compilation (sans passer par un bouton, mais directement à la fin du loader). Or tel qu'il est le code ne marche pas. Cà ne marche que quand je mets tout le "while" (du code ci-dessus) en commentaire...
Et là je ne vois vraiment pas pourquoi. :??:  
 
Pour ce qui est du bouton, avec le "while" (du loadWaveFrontObject) je n'ai pas d'erreur de "capability" mais il n'entre pas dans la boucle du "while" (de ma fonction "traverse" ) et quand je mets le "while" (du loadWaveFrontObject) en commentaire, j'ai le message d'erreur mais il rentre dans la boucle. Je suis paumé... :cry:  
 
Merci pour ta réponse quand même !  :)

Reply

Marsh Posté le 09-04-2006 à 21:39:40    

Ce que je vois déjà, c'est que tu fais pas de setCapability() sur le BranchGroup renvoyé par scene.getSceneGroup().
 
Essaye aussi de tester tes capacités avec getCapability (par exemple getCapability(Group.ALLOW_CHILDREN_READ) pour voir si elles sont bien positionnées. Essaye aussi de vérifier avec getClass() les classes renvoyées par en.nextElement() des fois qu'il y ait autre chose que des Shape3D ou des BranchGroup sous la racine...
 
Maintenant, j'ai jamais travaillé sur des objets Wavefront donc je peux pas te dire comment est construit l'arbre de la scene. Tu sais où je pourrais trouver des .obj pour tester ?


---------------
Incongru : une FAQ abandonnée sur les Standards du Web - FAQ périmée de blabla@Prog
Reply

Marsh Posté le 09-04-2006 à 21:55:00    

Si tu veux, j'en ai mis plusieurs à cette adresse (en fait ce sont de simples maisons sans texture, c'est le projet sur lequel je travaille) : mfrac10.free.fr
 
J'ai également mis mon fichier .java et le .class pour que tu puisses tester directement
 
Merci pour ta réponse, je vais essayer de voir çà et je te tiens au courant !  :)  
 
P.S. : désolé pour l'agencement de mon fichier java, mais c'est le premier que je fais et je suis pas très très à l'aise...

Reply

Marsh Posté le 09-04-2006 à 22:29:43    

Bon alors j'ai testé en mettant des setCapability sur le scene.getSceneGroup() et toujours la même erreur... :(  
 
Sinon le getClass() sur les éléments me renvoie un Shape3D et un BranchGroup, ce qui semble normal...  :??:

Reply

Marsh Posté le 09-04-2006 à 22:29:43   

Reply

Marsh Posté le 10-04-2006 à 00:25:56    

Ah bah oui je crois comprendre... tu réutilises la même Enumeration (en) à chaque fois, donc si tu as déjà fait un while dessus, tu es à la fin et il n'y a plus de parcours possible.
 
Ne passe pas l'Enumeration en paramètre, passe plutôt le BranchGroup que tu veux parcourir et tu feras un getAllChildren() dans ta méthode traverse()
 
Sinon en testant ton programme on se prend quand même une Exception quand on clique sur le bouton, tout les setCapacity() qui-vont-bien n'ont pas été fait dans cette version.


---------------
Incongru : une FAQ abandonnée sur les Standards du Web - FAQ périmée de blabla@Prog
Reply

Marsh Posté le 10-04-2006 à 10:14:04    

C'est bon, çà marche en passant le BranchGroup en paramètre !!!  :jap:  :bounce:  
 
Merci beaucoup pour ton aide et pour ta patience !  :)  
 
J'avais un autre problème, mais je vais pas t'embêter avec çà, je vais faire un nouveau post.
 :hello:


Message édité par Frac10 le 10-04-2006 à 10:29:35
Reply

Marsh Posté le 06-07-2012 à 15:22:36    

Bonsoir à tous
le lien mfrac10.free.fr  n'existe pas.Il y a quelqu'un qui peut le mettre s'il vous plaît.

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed