2015-04-12 4 views
2

J'ai créé un modèle simple d'une boîte et créé une image d'interpolation de couleur en utilisant une carte de texture. J'ai exporté le modèle à FXML en utilisant le code trouvé àjavafx 3d export/import vers/depuis fxml est incorrect ou incomplet

FXML export code

J'ai un jpeg du modèle de couleur que j'ai essayé d'exporter et le résultat modèle importé, mais je suis nouveau dépassement de la pile et je ne permettrai pas afficher des images pour le moment.

Je ne pouvais pas trouver un moyen d'attacher le contenu du fichier FXML qui était exporté, mais je serais heureux de le partager.

Lorsque j'importe le fichier fxml dans mon application à l'aide du FXMLLoader standard, le mappage de couleur n'est pas visible. Je ne sais pas si l'exportation était incomplète ou si l'importation était incorrecte. Le fichier FXML semble avoir les bons maillages de maillage et de texture, mais je ne vois pas de représentation de la texture. J'ai utilisé la méthode setDiffuseMap de PhongMaterial pour affecter une image à l'objet matériel qui a été construit en utilisant WritableImage et PixelWriter pour créer une bande de couleurs. Est-ce que quelqu'un sait si l'exportation de l'objet PhongMaterial construit de cette manière est supportée dans FXMLExporter ou si le FXMLImporter ne supporte pas l'importation d'une telle carte de couleurs? Sur la base des suggestions de Jose, j'ai apporté des modifications à mon code, mais j'ai rencontré quelques problèmes.

J'ai défini chaque face de mes deux cubes comme un TriangleMesh distinct, en pensant que finalement je veux être capable de distinguer chaque visage lorsque je sélectionne des objets dans la scène. J'ai un seul objet PhongMaterial qui a l'image comme une carte diffuse. J'ai assigné le même matériel à chaque face de mes deux cubes.

Lorsque j'exporte mon modèle, la méthode d'exportation tente d'écrire le fichier image 12 fois. Il semble qu'il devrait y avoir un moyen de faire comprendre à la définition du modèle qu'un seul matériau phong est utilisé et qu'il est basé sur une seule image couleur.

J'ai ajouté du code à la méthode d'exportation pour me souvenir du nom de fichier utilisé pour exporter le fichier FXML afin que je puisse attribuer un nom au fichier image basé sur le nom de fichier FXML. Sans chemin, le fichier image est stocké dans mon espace de travail Eclipse plutôt que dans le même dossier que mon fichier FXML. Je ne suis pas sûr quel nom devrait être donné à fxmlImage.addProperty ("url", filename). Devrait-il être le nom du chemin d'accès complet ou juste le nom du fichier? Si j'utilise le chemin complet, j'ai un chemin codé en dur dans le fichier FXML et cela me semble être une mauvaise idée. J'ai essayé d'enregistrer le nom de l'URL avec et sans le chemin complet et j'ai obtenu le même résultat dans les deux sens ... ce qui signifie qu'aucun modèle n'est apparu lorsque j'ai importé le fichier FXML. J'ai aussi essayé avec et sans le premier @, avec le même résultat. Est-ce que quelqu'un a une idée de ce que je pourrais faire de mal?

Répondre

1

Si vous avez un oeil à la dernière version de la classe FXMLExporter du projet 3DViewer sur OpenJFX, vous verrez que pour les matériaux que la couleur diffuse est exportée:

if (PhongMaterial.class.isAssignableFrom(aClass)) { 
    res.add(new Property(aClass.getMethod("getDiffuseColor"), "diffuseColor")); 
} 

La même chose se produit dans le projet vous avez mentionné.

Vous pouvez ajouter cette ligne:

res.add(new Property(aClass.getMethod("getDiffuseMap"), "diffuseMap")); 

à getProperties():

if (PhongMaterial.class.isAssignableFrom(aClass)) { 
    res.add(new Property(aClass.getMethod("getDiffuseColor"), "diffuseColor")); 
    res.add(new Property(aClass.getMethod("getDiffuseMap"), "diffuseMap")); 
} 

Ainsi, lorsque vous exportez votre forme 3D, ce sera ajouté au fichier FXML:

<Box id="box" width="100.0" height="100.0" depth="100.0"> 
    <material> 
    <PhongMaterial diffuseColor="0xffffffff"> 
     <diffuseMap> 
     <Image/> 
     </diffuseMap> 
    </PhongMaterial> 
    </material> 
</Box> 

Nous devons également exporter l'image url. Cela peut être fait à la méthode exportToFXML.

Étant donné que le Image de la carte diffuse ne stocke aucun chemin, l'astuce consiste à enregistrer l'image sur le même chemin où le fichier fxml est exporté. Ceci est une mise en œuvre rapide:

private FXML exportToFXML(Object object) { 
    ... 

    for (Property property : properties) { 
     try { 
      Object[] parameters = new Object[property.getter.getParameterTypes().length]; 
      Object value = property.getter.invoke(object, parameters); 
      if (value != null) { 
       ... 
       } else if (value instanceof Image) { 
        FXML container = fxml.addContainer(property.name); 
        FXML fxmlImage=exportToFXML(value); 
        container.addChild(fxmlImage); 
        exportImage((Image)value,"image.png"); 
        fxmlImage.addProperty("url","@image.png"); 
       } else { 
        FXML container = fxml.addContainer(property.name); 
        container.addChild(exportToFXML(value)); 
       } 
      } 
     } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) { 
      Logger.getLogger(FXMLExporter.class.getName()). 
        log(Level.SEVERE, null, ex); 
     } 
    } 

    return fxml; 
} 

private void exportImage(Image image, String fileName){ 
    try { 
     ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", new File(fileName)); 
    } catch (IOException ex) { 
     System.out.println("Error saving image"); 
    } 
} 

Si vous exécutez maintenant, voici ce que vous obtiendrez:

<Box id="box" width="100.0" height="100.0" depth="100.0"> 
    <material> 
    <PhongMaterial diffuseColor="0xffffffff"> 
     <diffuseMap> 
     <Image url="@image.png"/> 
     </diffuseMap> 
    </PhongMaterial> 
    </material> 
</Box> 
+0

Merci beaucoup pour vos suggestions. J'ai rencontré quelques problèmes. J'ai défini chaque face de mes deux cubes comme un TriangleMesh séparé, en pensant que finalement je veux être capable de distinguer chaque visage lors de la sélection des objets dans la scène. J'ai assigné le même matériel assigné à chaque face de mes deux cubes, l'export essaie d'écrire le fichier image 12 fois. Il semble qu'il devrait y avoir un moyen de transmettre à la définition du modèle que toutes les images sont les mêmes. – bluemonkey

+0

Même dans le cas où vous avez plusieurs formes 3D, mais avec le même matériau, vous pouvez implémenter une vérification pour éviter d'exporter à nouveau l'image. Si vous avez des textures différentes, vous devrez ajouter un compteur pour utiliser différentes images. Comme je l'ai dit, c'était une mise en œuvre rapide, vous pouvez donc travailler sur les détails. –

+0

Je suis d'accord que je peux garder une trace des différentes images. Le vrai problème est tel que je l'ai décrit dans les modifications de mon message original ... il n'est pas clair comment contrôler où l'image va et l'importation ne fonctionne plus. – bluemonkey