如何使用javafx中的jcsg库将meshview转换为csg对象

nwlqm0z1  于 2021-07-09  发布在  Java
关注(0)|答案(1)|浏览(405)

我正在使用javafx的jcsg库。
我有一些 MeshView 要将其转换为的对象 CSG 物体,有没有办法做到这一点?

moiiocjp

moiiocjp1#

最简单的组合方法 javafx.scene.shape.Mesh 如果你有一个 TriangleMesh 正在将三角形面转换为多边形( eu.mihosoft.vrl.v3d.Polygon ).
一旦有了csg对象,就可以对其执行常规操作,然后可以将其导出回 MeshView 例如。
原始形状的问题( Box , Sphere ,…)是指您无法访问他们的 TriangleMesh . 因此,你可以去f(x)yz库,并选择任何可用的三维形状。
例如,让我们使用 FrustumMesh 对象。
您可以轻松创建一个:

FrustumMesh cone = new FrustumMesh(1,0.2,4,2);


您将可以访问其网格: cone.getMesh() .
现在我们需要转换这个 TriangleMesh 进入 List<Polygon> . 为此,我们可以创建以下实用程序类:

public class Mesh2CSG {
    /**
     * Loads a CSG from TriangleMesh.
     * @param mesh
     * @return CSG
     * @throws IOException if loading failed
     */
    public static CSG mesh2CSG(MeshView mesh) throws IOException {
        return mesh2CSG(mesh.getMesh());
    }
    public static CSG mesh2CSG(Mesh mesh) throws IOException {

        List<Polygon> polygons = new ArrayList<>();
        List<Vector3d> vertices = new ArrayList<>();
        if(mesh instanceof TriangleMesh){
            // Get faces
            ObservableFaceArray faces = ((TriangleMesh)mesh).getFaces();
            int[] f=new int[faces.size()];
            faces.toArray(f);

            // Get vertices
            ObservableFloatArray points = ((TriangleMesh)mesh).getPoints();
            float[] p = new float[points.size()];
            points.toArray(p);

            // convert faces to polygons
            for(int i=0; i<faces.size()/6; i++){
                int i0=f[6*i], i1=f[6*i+2], i2=f[6*i+4];
                vertices.add(new Vector3d(p[3*i0], p[3*i0+1], p[3*i0+2]));
                vertices.add(new Vector3d(p[3*i1], p[3*i1+1], p[3*i1+2]));
                vertices.add(new Vector3d(p[3*i2], p[3*i2+1], p[3*i2+2]));
                polygons.add(Polygon.fromPoints(vertices));
                vertices = new ArrayList<>();
            }
        }

        return CSG.fromPolygons(new PropertyStorage(),polygons);
    }
}

使用此方法,可以获得csg圆锥体:

CSG coneCSG = Mesh2CSG.mesh2CSG(cone.getMesh());

因此,您可以将其与其他csg表格结合使用:

CSG cube = new Cube(2).toCSG().color(Color.RED);
CSG union = cube.union(coneCSG);

然后返回javafx网格查看:

MeshView unionMesh = coneCSG.toJavaFXMesh().getAsMeshViews().get(0);


这是完整的示例类(假设类路径上有fxyzlib.jar和jcsg.jar依赖项):

public class FXyzJCSG extends Application {
    private double mousePosX, mousePosY;
    private double mouseOldX, mouseOldY;
    private final Rotate rotateX = new Rotate(-20, Rotate.X_AXIS);
    private final Rotate rotateY = new Rotate(-20, Rotate.Y_AXIS);

    @Override
    public void start(Stage primaryStage) throws IOException {

        FrustumMesh cone = new FrustumMesh(1,0.2,4,2);
        cone.setDrawMode(DrawMode.LINE);
        cone.setTextureModeNone(Color.ROYALBLUE);

        CSG coneCSG = Mesh2CSG.mesh2CSG(cone.getMesh());

        CSG cube = new Cube(2).toCSG().color(Color.RED);
        CSG union = cube.union(coneCSG);

        MeshView unionMesh = union.toJavaFXMesh().getAsMeshViews().get(0);
//        unionMesh.setDrawMode(DrawMode.LINE);
        PerspectiveCamera camera = new PerspectiveCamera(true);
        camera.getTransforms().addAll (rotateX, rotateY, new Translate(0, 0, -10));

        Group root3D = new Group(camera,unionMesh);

        SubScene subScene = new SubScene(root3D, 600, 400, true, SceneAntialiasing.BALANCED);
        subScene.setFill(Color.AQUAMARINE);
        subScene.setCamera(camera);

        Scene scene = new Scene(new StackPane(subScene), 600, 400);
        scene.setOnMousePressed(me -> {
            mouseOldX = me.getSceneX();
            mouseOldY = me.getSceneY();
        });
        scene.setOnMouseDragged(me -> {
            mousePosX = me.getSceneX();
            mousePosY = me.getSceneY();
            rotateX.setAngle(rotateX.getAngle()-(mousePosY - mouseOldY));
            rotateY.setAngle(rotateY.getAngle()+(mousePosX - mouseOldX));
            mouseOldX = mousePosX;
            mouseOldY = mousePosY;
        });

        primaryStage.setTitle("FXyz & JCSG - JavaFX 3D");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

相关问题