While there is nothing wrong about adding multiple triangle meshes to a scene, there is a more straightforward approach when you want to create a mesh like one from the football picture, so you can have the effect of highlighting some edges but not all the triangles from the mesh.
It can be done with a PolygonMesh
that takes any valid close polygon as face.
This implementation already exists, in the 3DViewer project, which is open source and can be found here. There is a PolygonMeshView
control that can render a PolygonMesh
.
Note that if you use those two classes only in your project, you'll have to skip the subdivision mesh for now.
This answer already uses a quadrilateral mesh for a rendering a Box without the diagonal edges of a triangle mesh.
Under the hood, the Polygon mesh uses a triangle mesh, and internally converts the polygons you provide to triangles.
Truncated Icosahedron Mesh
So we can do something similar to generate the mesh of a truncated icosahedron, which is the name of the geometric figure that we can use to generate a simplified football model.
It has 12 regular pentagonal faces, 20 regular hexagonal faces and 60 vertices.
We need the 3D coordinates of those vertices, the 2D coordinates of the textures, and the indices of vertices and textures for each of the 32 faces.
I've used the free online sandbox WolframCloud resource to retrieve those values.
For instance, you can run:
Flatten[PolyhedronData["TruncatedIcosahedron","VertexCoordinates"]//N]
to get the list of vertex coordinates:
Out[1]= {-0.16246,-2.11803,1.27598,-0.16246,2.11803,...}
and, you can get the faces:
PolyhedronData["TruncatedIcosahedron","FaceIndices"]
Out[2]= {{53,11,24,23,9},{51,39,40,52,30},...}
Finally, you need the textures coordinates and indices, and that can be retrieved through the Net of the icosahedron:
PolyhedronData["TruncatedIcosahedron","Net"]
PolyhedronData["TruncatedIcosahedron","NetCoordinates"]
In this case, you get the 2D coordinates of the 32 faces. Given that we want to have the same texture for all the pentagons and the same for all hexagons, I've dome some manipulation of those coordinates to come up with this texture image:

with only 9 vertices, and their coordinates (in the JavaFX coordinate system).
This method contains the required information to create the mesh:
private PolygonMesh getTruncatedIcosahedron() {
float[] points = new float[]{
-0.16246f,-2.11803f,1.27598f, -0.16246f,2.11803f,1.27598f,
0.16246f,-2.11803f,-1.27598f, 0.16246f,2.11803f,-1.27598f,
-0.262866f,-0.809017f,-2.32744f, -0.262866f,-2.42705f,-0.425325f,
-0.262866f,0.809017f,-2.32744f, -0.262866f,2.42705f,-0.425325f,
0.262866f,-0.809017f,2.32744f, 0.262866f,-2.42705f,0.425325f,
0.262866f,0.809017f,2.32744f, 0.262866f,2.42705f,0.425325f,
0.688191f,-0.5f,-2.32744f, 0.688191f,0.5f,-2.32744f,
1.21392f,-2.11803f,0.425325f, 1.21392f,2.11803f,0.425325f,
-2.06457f,-0.5f,1.27598f, -2.06457f,0.5f,1.27598f,
-1.37638f,-1.f,1.80171f, -1.37638f,1.f,1.80171f,
-1.37638f,-1.61803f,-1.27598f, -1.37638f,1.61803f,-1.27598f,
-0.688191f,-0.5f,2.32744f, -0.688191f,0.5f,2.32744f,
1.37638f,-1.f,-1.80171f, 1.37638f,1.f,-1.80171f,
1.37638f,-1.61803f,1.27598f, 1.37638f,1.61803f,1.27598f,
-1.7013f,0.f,-1.80171f, 1.7013f,0.f,1.80171f,
-1.21392f,-2.11803f,-0.425325f, -1.21392f,2.11803f,-0.425325f,
-1.96417f,-0.809017f,-1.27598f, -1.96417f,0.809017f,-1.27598f,
2.06457f,-0.5f,-1.27598f, 2.06457f,0.5f,-1.27598f,
2.22703f,-1.f,-0.425325f, 2.22703f,1.f,-0.425325f,
2.38949f,-0.5f,0.425325f, 2.38949f,0.5f,0.425325f,
-1.11352f,-1.80902f,1.27598f, -1.11352f,1.80902f,1.27598f,
1.11352f,-1.80902f,-1.27598f, 1.11352f,1.80902f,-1.27598f,
-2.38949f,-0.5f,-0.425325f, -2.38949f,0.5f,-0.425325f,
-1.63925f,-1.80902f,0.425325f, -1.63925f,1.80902f,0.425325f,
1.63925f,-1.80902f,-0.425325f, 1.63925f,1.80902f,-0.425325f,
1.96417f,-0.809017f,1.27598f, 1.96417f,0.809017f,1.27598f,
0.850651f,0.f,2.32744f, -2.22703f,-1.f,0.425325f,
-2.22703f,1.f,0.425325f, -0.850651f,0.f,-2.32744f,
-0.525731f,-1.61803f,-1.80171f, -0.525731f,1.61803f,-1.80171f,
0.525731f,-1.61803f,1.80171f, 0.525731f,1.61803f,1.80171f};
float[] texCoords = new float[]{0.904508f,0.820298f, 0.75f,0.529535f, 0.25f,0.529535f, 0.0954915f,0.820298f, 0.5f,1f,
1f,0.264767f, 0.75f,0f, 0.25f,0f, 0f,0.264767f};
int faces[][] = new int[][]{{52,0,10,1,23,2,22,3,8,4},
{50,0,38,1,39,2,51,3,29,4},
{59,0,27,1,15,2,11,3,1,4},
{19,0,41,1,47,2,54,3,17,4},
{18,0,16,1,53,2,46,3,40,4},
{0,0,9,1,14,2,26,3,58,4},
{35,0,25,1,43,2,49,3,37,4},
{3,0,57,1,21,2,31,3,7,4},
{33,0,28,1,32,2,44,3,45,4},
{20,0,56,1,2,2,5,3,30,4},
{36,0,48,1,42,2,24,3,34,4},
{12,0,4,1,55,2,6,3,13,4},
{8,1,58,5,26,6,50,7,29,8,52,2},
{52,1,29,5,51,6,27,7,59,8,10,2},
{10,1,59,5,1,6,41,7,19,8,23,2},
{23,1,19,5,17,6,16,7,18,8,22,2},
{22,1,18,5,40,6,0,7,58,8,8,2},
{12,1,24,5,42,6,2,7,56,8,4,2},
{4,1,56,5,20,6,32,7,28,8,55,2},
{55,1,28,5,33,6,21,7,57,8,6,2},
{6,1,57,5,3,6,43,7,25,8,13,2},
{13,1,25,5,35,6,34,7,24,8,12,2},
{39,1,37,5,49,6,15,7,27,8,51,2},
{15,1,49,5,43,6,3,7,7,8,11,2},
{11,1,7,5,31,6,47,7,41,8,1,2},
{47,1,31,5,21,6,33,7,45,8,54,2},
{54,1,45,5,44,6,53,7,16,8,17,2},
{53,1,44,5,32,6,20,7,30,8,46,2},
{46,1,30,5,5,6,9,7,0,8,40,2},
{9,1,5,5,2,6,42,7,48,8,14,2},
{14,1,48,5,36,6,38,7,50,8,26,2},
{38,1,36,5,34,6,35,7,37,8,39,2}};
int[] smooth = new int[] {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32
};
PolygonMesh mesh = new PolygonMesh(points, texCoords, faces);
mesh.getFaceSmoothingGroups().addAll(smooth);
return mesh;
}
Now you can easily add it to an scene:
private double mouseOldX, mouseOldY = 0;
private final Rotate rotateX = new Rotate(0, Rotate.X_AXIS);
private final Rotate rotateY = new Rotate(0, Rotate.Y_AXIS);
@Override
public void start(Stage primaryStage) {
PolygonMeshView meshView = new PolygonMeshView(getTruncatedIcosahedron());
final PhongMaterial phongMaterial = new PhongMaterial();
meshView.setDrawMode(DrawMode.LINE);
meshView.setMaterial(phongMaterial);
final Group group = new Group(meshView);
group.getTransforms().add(new Scale(50, 50, 50));
Scene scene = new Scene(group, 500, 300, true, SceneAntialiasing.BALANCED);
scene.setOnMousePressed(event -> {
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
scene.setOnMouseDragged(event -> {
rotateX.setAngle(rotateX.getAngle() - (event.getSceneY() - mouseOldY));
rotateY.setAngle(rotateY.getAngle() + (event.getSceneX() - mouseOldX));
mouseOldX = event.getSceneX();
mouseOldY = event.getSceneY();
});
PerspectiveCamera camera = new PerspectiveCamera(false);
camera.setNearClip(0.1);
camera.setFarClip(1000.0);
camera.getTransforms().addAll(rotateX, rotateY, new Translate(-250, -150, 0));
scene.setCamera(camera);
primaryStage.setTitle("JavaFX 3D - Truncated Icosahedron");
primaryStage.setScene(scene);
primaryStage.show();
}
Will give you the wireframe:

And if you add the image of the texture, you will get your football:
phongMaterial.setDiffuseMap(new Image(getClass().getResourceAsStream("net3.png")));
meshView.setDrawMode(DrawMode.FILL);

Now it's up to you to manipulate to your convenience this information, and modify this mesh into the one you are looking for.