I would like to generate some shapes in JavaFX and export it to STL format for 3D printing. Is there a library out there to help with the export?
For the first part, related to JavaFX 3D, I suggest you have a look at the FXyz library.
You will find a extense library of custom shapes like: Cone, Pyramid, SegmentedSphere, Spheroid, Torus, SegmentedTorus, Prism, Spring, CurvedSpring, Frustum, Icosahedron, Knot,...
Also, have a look at the sampler application, where you can try easily all these shapes and the different options (lights, materials, textures, ...).
Another option is the JCSG project, that will create CSG (Constructive Solid Geometry) shapes with boolean operations.
For the second part, exporting to STL a TriangleMesh
, as far as I know there's no implementation for JavaFX.
In the mentioned FXyz library you can find an OBJ exporter. Only if you are working with JCSG, there is a STL exporter CSG.toStlString()
, besides the OBJ one CSG.toObj()
.
Anyway, once you have your TriangleMesh
, given the STL format, you can easily create an exporter method:
public class MeshUtils {
public static void mesh2STL(String fileName, Mesh mesh) throws IOException{
if(!(mesh instanceof TriangleMesh)){
return;
}
// 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);
StringBuilder sb = new StringBuilder();
sb.append("solid meshFX\n");
// 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];
Point3D pA=new Point3D(p[3*i0], p[3*i0+1], p[3*i0+2]);
Point3D pB=new Point3D(p[3*i1], p[3*i1+1], p[3*i1+2]);
Point3D pC=new Point3D(p[3*i2], p[3*i2+1], p[3*i2+2]);
Point3D pN=pB.subtract(pA).crossProduct(pC.subtract(pA)).normalize();
sb.append(" facet normal ").append(pN.getX()).append(" ").append(pN.getY()).append(" ").append(pN.getZ()).append("\n");
sb.append(" outer loop\n");
sb.append(" vertex ").append(pA.getX()).append(" ").append(pA.getY()).append(" ").append(pA.getZ()).append("\n");
sb.append(" vertex ").append(pB.getX()).append(" ").append(pB.getY()).append(" ").append(pB.getZ()).append("\n");
sb.append(" vertex ").append(pC.getX()).append(" ").append(pC.getY()).append(" ").append(pC.getZ()).append("\n");
sb.append(" endloop\n");
sb.append(" endfacet\n");
}
sb.append("endsolid meshFX\n");
// write file
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(fileName), Charset.forName("UTF-8"),
StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING)) {
writer.write(sb.toString());
}
}
}
And now you can easily export any of the shapes you create:
@Override
public void start(Stage primaryStage) throws IOException {
FrustumMesh cone = new FrustumMesh(1,0.2,4,2);
MeshUtils.mesh2STL("frustum.stl", cone.getMesh());
}
This is a picture of the exported shape using the 3D model browser from InteractiveMesh to load the STL file: