J'utilise la bibliothèque JCSG pour JavaFX.Comment convertir un MeshView en objet CSG en utilisant la bibliothèque JCSG dans JavaFX
J'ai quelques MeshView
objets que je veux les convertir en CSG
objets, y at-il un moyen d'y parvenir?
J'utilise la bibliothèque JCSG pour JavaFX.Comment convertir un MeshView en objet CSG en utilisant la bibliothèque JCSG dans JavaFX
J'ai quelques MeshView
objets que je veux les convertir en CSG
objets, y at-il un moyen d'y parvenir?
La meilleure façon de combiner un objet javafx.scene.shape.Mesh
avec un CSG une, à condition d'avoir une TriangleMesh
est de convertir les faces triangulaires de polygones (eu.mihosoft.vrl.v3d.Polygon
).
Une fois que vous avez un objet CSG, vous pouvez y effectuer les opérations habituelles, puis vous pouvez l'exporter vers un MeshView
par exemple.
Le problème avec les formes primitives (Box
, Sphere
, ...) est que vous n'avez pas accès à leur TriangleMesh
. Vous pouvez donc aller à la bibliothèque F(X)yz et choisir l'une des formes 3D disponibles.
Par exemple, utilisons un objet FrustumMesh
.
Vous pouvez facilement créer un:
FrustumMesh cone = new FrustumMesh(1,0.2,4,2);
Et vous aurez accès à son maillage: cone.getMesh()
. Maintenant nous devons convertir ce TriangleMesh
en List<Polygon>
. Pour cela, nous pouvons créer cette classe utilitaire:
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);
}
}
Avec cette méthode, vous pouvez obtenir un cône de CSG:
CSG coneCSG = Mesh2CSG.mesh2CSG(cone.getMesh());
donc vous pouvez combiner avec d'autres formes CSG:
CSG cube = new Cube(2).toCSG().color(Color.RED);
CSG union = cube.union(coneCSG);
et revenir à un maillage JavaFX pour l'afficher:
MeshView unionMesh = coneCSG.toJavaFXMesh().getAsMeshViews().get(0);
Ceci est la classe de l'échantillon complet (à condition d'avoir sur votre classpath les dépendances FXyzLib.jar et 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);
}
}
Belle réponse! La méthode du convertisseur devrait être ajoutée à JCSG. – miho
Merci @miho, les deux frameworks (FXyz et JCSG) pourraient bénéficier d'une interface qui permet une interaction facile entre les deux. Les opérations booléennes sont vraiment une fonctionnalité intéressante pour FXyz, tandis que JCSG pourrait bénéficier de sa collection de formes 3D améliorées. –
Merci beaucoup José Pereda, je l'apprécie vraiment. Merci aussi à miho pour le travail incroyable sur CSG. @ José vous avez dit que JCSG pourrait bénéficier de la collection améliorée de formes 3D de FXyz, eh bien nous avons fait une demande de traction sur github pour ajouter de nouvelles formes 3D à FXyz –