如何在JavaFX 8中从STL创建3d形状?

时间:2013-10-19 05:05:47

标签: 3d javafx-2 javafx-8

我有类STLFile,它返回两个数组:一个坐标为法线,另一个坐标为坐标。所以现在我想在我的JavaFX应用程序中使用这些坐标创建3d形状。问题是如何在没有纹理的情况下做到这一点。使用官方指南我用坐标制作了TriangleMesh并将其添加到MeshView。但不幸的是,现场没有任何东西出现。所以有人可以解释我如何做到这一点,因为官方指南中的描述不能称之为足够吗?

1 个答案:

答案 0 :(得分:6)

您可以使用Interactive Mesh JavaFX STL Model Importer加载STL文件。

jewel

JewelViewer.java

import com.interactivemesh.jfx.importer.stl.StlMeshImporter;
import javafx.application.Application;
import javafx.scene.*;
import javafx.scene.paint.Color;
import javafx.scene.paint.PhongMaterial;
import javafx.scene.shape.Mesh;
import javafx.scene.shape.MeshView;
import javafx.scene.transform.Rotate;
import javafx.stage.Stage;

import java.io.File;

public class JewelViewer extends Application {

  private static final String MESH_FILENAME =
    "/Users/lilyshard/Downloads/Perfect Diamond/Perfect Diamond.STL";

  private static final double MODEL_SCALE_FACTOR = 400;
  private static final double MODEL_X_OFFSET = 0; // standard
  private static final double MODEL_Y_OFFSET = 0; // standard

  private static final int VIEWPORT_SIZE = 800;

  private static final Color lightColor = Color.rgb(244, 255, 250);
  private static final Color jewelColor = Color.rgb(0, 190, 222);

  private Group root;
  private PointLight pointLight;

  static MeshView[] loadMeshViews() {
    File file = new File(MESH_FILENAME);
    StlMeshImporter importer = new StlMeshImporter();
    importer.read(file);
    Mesh mesh = importer.getImport();

    return new MeshView[] { new MeshView(mesh) };
  }

  private Group buildScene() {
    MeshView[] meshViews = loadMeshViews();
    for (int i = 0; i < meshViews.length; i++) {
      meshViews[i].setTranslateX(VIEWPORT_SIZE / 2 + MODEL_X_OFFSET);
      meshViews[i].setTranslateY(VIEWPORT_SIZE / 2 + MODEL_Y_OFFSET);
      meshViews[i].setTranslateZ(VIEWPORT_SIZE / 2);
      meshViews[i].setScaleX(MODEL_SCALE_FACTOR);
      meshViews[i].setScaleY(MODEL_SCALE_FACTOR);
      meshViews[i].setScaleZ(MODEL_SCALE_FACTOR);

      PhongMaterial sample = new PhongMaterial(jewelColor);
      sample.setSpecularColor(lightColor);
      sample.setSpecularPower(16);
      meshViews[i].setMaterial(sample);

      meshViews[i].getTransforms().setAll(new Rotate(38, Rotate.Z_AXIS), new Rotate(20, Rotate.X_AXIS));
    }

    pointLight = new PointLight(lightColor);
    pointLight.setTranslateX(VIEWPORT_SIZE*3/4);
    pointLight.setTranslateY(VIEWPORT_SIZE/2);
    pointLight.setTranslateZ(VIEWPORT_SIZE/2);
    PointLight pointLight2 = new PointLight(lightColor);
    pointLight2.setTranslateX(VIEWPORT_SIZE*1/4);
    pointLight2.setTranslateY(VIEWPORT_SIZE*3/4);
    pointLight2.setTranslateZ(VIEWPORT_SIZE*3/4);
    PointLight pointLight3 = new PointLight(lightColor);
    pointLight3.setTranslateX(VIEWPORT_SIZE*5/8);
    pointLight3.setTranslateY(VIEWPORT_SIZE/2);
    pointLight3.setTranslateZ(0);

    Color ambientColor = Color.rgb(80, 80, 80, 0);
    AmbientLight ambient = new AmbientLight(ambientColor);

    root = new Group(meshViews);
    root.getChildren().add(pointLight);
    root.getChildren().add(pointLight2);
    root.getChildren().add(pointLight3);
    root.getChildren().add(ambient);

    return root;
  }

  private PerspectiveCamera addCamera(Scene scene) {
    PerspectiveCamera perspectiveCamera = new PerspectiveCamera();
    System.out.println("Near Clip: " + perspectiveCamera.getNearClip());
    System.out.println("Far Clip:  " + perspectiveCamera.getFarClip());
    System.out.println("FOV:       " + perspectiveCamera.getFieldOfView());

    scene.setCamera(perspectiveCamera);
    return perspectiveCamera;
  }

  @Override
  public void start(Stage primaryStage) {
    Group group = buildScene();
    group.setScaleX(2);
    group.setScaleY(2);
    group.setScaleZ(2);
    group.setTranslateX(50);
    group.setTranslateY(50);

    Scene scene = new Scene(group, VIEWPORT_SIZE, VIEWPORT_SIZE, true);
    scene.setFill(Color.rgb(10, 10, 40));
    addCamera(scene);
    primaryStage.setTitle("Jewel Viewer");
    primaryStage.setScene(scene);
    primaryStage.show();
  }

  public static void main(String[] args) {
    System.setProperty("prism.dirtyopts", "false");
    launch(args);
  }
}

STL源模型信息

-- Model information --

Model Name : Perfect Diamond
Author : Scott Allen
Publisher : mtgtopdeck

You can view this model here :
http://www.3dvia.com/content/024BE6380A1C2E00
More models about this author :
http://www.3dvia.com/mtgtopdeck


-- Attached license --

A license is attached to the Perfect Diamond model and all related media.
You must agree with this licence before using the enclosed media.

License : Attribution-NonCommercial 2.5
Detailed license : http://creativecommons.org/licenses/by-nc/2.5/

The licenses used by 3dvia are based on Creative Commons Licenses.
More info: http://creativecommons.org/about/licenses/meet-the-licenses