2

我创建了一个简单的盒子模型,并使用纹理贴图创建了一个颜色插值图像。我使用找到的代码将模型导出到 fxml

FXML 导出代码

我有一个我尝试导出的彩色模型的 jpeg 和生成的导入模型,但我是 Stack Overflow 的新手,我还不允许发布图像。

我也找不到附加导出的 FXML 文件内容的方法,但我很乐意分享。

当我使用标准 FXMLLoader 将 fxml 文件导入回我的应用程序时,颜色映射不可见。不知道是导出不完整还是导入不正确。FXML 文件似乎具有正确的网格和纹理贴图指针,但我没有看到纹理贴图的表示。我使用 PhongMaterial setDiffuseMap 方法将图像分配给使用 WritableImage 和 PixelWriter 构造的材质对象以创建颜色带。有谁知道 FXMLExporter 是否支持以这种方式构造的 PhongMaterial 对象的导出,或者 FXMLImporter 是否不支持导入这样的颜色图?

根据 Jose 的建议,我对代码进行了更改,但遇到了一些问题。

我将两个立方体的每个面定义为一个单独的 TriangleMesh,认为最终我希望在选择场景中的对象时能够区分每个面。我有一个 PhongMaterial 对象,该对象将图像作为漫反射贴图。我为两个立方体的每个面分配了相同的材料。

当我导出模型时,导出方法尝试写入图像文件 12 次。似乎应该有一种方法可以向模型定义传达正在使用单一 phong 材料并且它基于单一颜色图像。

我在导出方法中添加了代码来记住用于导出 FXML 文件的文件名,以便我可以根据 FXML 文件名(传递给 exportImage() 的完整路径名)为图像文件分配一个名称。如果没有路径,图像文件将存储在我的 Eclipse 工作区中,而不是与我的 FXML 文件位于同一文件夹中。我不确定应该给 fxmlImage.addProperty("url",filename) 起什么名字。它应该是完整路径名还是文件名?如果我使用完整路径名,那么我在 FXML 文件中有一个硬编码路径,这似乎是个坏主意。我尝试使用和不使用完整路径保存 URL 名称,并且两种方式都得到了相同的结果……也就是说,当我导入 FXML 文件时没有出现任何模型。我也尝试使用和不使用前导@,结果相同。有谁知道我可能做错了什么?

4

1 回答 1

1

如果您查看OpenJFX项目中FXMLExporter该类的最新版本,您将看到对于材质,仅导出了漫反射颜色:3DViewer

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

您提到的项目中也发生了同样的情况。

您可以添加此行:

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"));
}

因此,当您导出 3D 形状时,这将被添加到 fxml 文件中:

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

我们还需要导出图像 url。这可以在exportToFXML方法中完成。

由于Image漫反射贴图不存储任何路径,因此诀窍是将图像保存到导出 fxml 的相同路径。这是一个快速的实现:

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");
    }
}

如果你现在运行它,你会得到:

<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>
于 2015-04-13T13:43:58.760 回答