本文介绍了如何使用JavaFX中的JCSG库将MeshView转换为CSG对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用JavaFX的JCSG库。

I'm using the JCSG library for JavaFX.

我有一些 MeshView 我想要的对象将它们转换为 CSG 对象,有没有办法实现这个目标?

I have some MeshView objects that I want to convert them into CSG objects, is there a way to achieve this?

推荐答案

javafx.scene.shape.Mesh 对象与CSG对象组合的最简单方法,假设你有 TriangleMesh 将三角形面转换为多边形( eu.mihosoft.vrl.v3d.Polygon )。

The easiest way to combine a javafx.scene.shape.Mesh object with a CSG one, providing you have a TriangleMesh is converting the triangular faces to polygons (eu.mihosoft.vrl.v3d.Polygon).

一次你有一个CSG对象,你可以对它执行常规操作,然后你可以将它导出回 MeshView

Once you have a CSG object you can perform the regular operations on it, and then you can export it back to a MeshView for instance.

原始形状的问题( Box Sphere ,...)就是你要'可以访问他们的 TriangleMesh 。因此,您可以访问库并选择任何可用的3D形状。

The problem with primitive shapes (Box, Sphere, ...) is that you don't have access to their TriangleMesh. So you can go to F(X)yz library and pick any of the available 3D shapes.

例如,让我们使用 FrustumMesh 对象。

For example, let's use a FrustumMesh object.

您可以轻松创建一个:

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

您将可以访问其网格: cone.getMesh()

And you will have access to its mesh: cone.getMesh().

现在我们需要将此 TriangleMesh 转换为 List< Polygon> 。为此我们可以创建这个实用程序类:

Now we need to convert this TriangleMesh into List<Polygon>. For that we can create this utility class:

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视锥:

With this method, you can get a CSG cone:

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

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

So you can combine it with other CSG forms:

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

并返回JavaFX网格查看它:

and get back to a JavaFX mesh to view it:

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

这是完整的示例类(假设你的类路径中有FXyzLib.jar和JCSG.jar依赖项):

This is the full sample class (providing you have on your classpath the FXyzLib.jar and JCSG.jar dependencies):

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

这篇关于如何使用JavaFX中的JCSG库将MeshView转换为CSG对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-18 21:27