From 2024fe7acfc8ff078b8e2c6dc7402a217ebdea18 Mon Sep 17 00:00:00 2001 From: jmekaelthas Date: Tue, 26 Apr 2016 21:28:15 +0200 Subject: [PATCH] Reduced the amount of warnings being logged during mesh triangulation. The warnings are now collected and displayed only once for each mesh they appear in. --- .../scene/plugins/blender/meshes/Face.java | 43 ++++++++++++++++--- .../plugins/blender/meshes/TemporalMesh.java | 16 ++++++- 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java index 97c730df1..5890ad234 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java @@ -265,15 +265,16 @@ public class Face implements Comparator { /** * The method triangulates the face. */ - public void triangulate() { + public TriangulationWarning triangulate() { LOGGER.fine("Triangulating face."); assert indexes.size() >= 3 : "Invalid indexes amount for face. 3 is the required minimum!"; triangulatedFaces = new ArrayList(indexes.size() - 2); Integer[] indexes = new Integer[3]; - + TriangulationWarning warning = TriangulationWarning.NONE; + try { List facesToTriangulate = new ArrayList(Arrays.asList(this.clone())); - while (facesToTriangulate.size() > 0) { + while (facesToTriangulate.size() > 0 && warning == TriangulationWarning.NONE) { Face face = facesToTriangulate.remove(0); // two special cases will improve the computations speed if(face.getIndexes().size() == 3) { @@ -287,10 +288,12 @@ public class Face implements Comparator { LOGGER.finer("Veryfying improper triangulation of the temporal mesh."); if (indexes[0] < 0 || indexes[1] < 0 || indexes[2] < 0) { - throw new BlenderFileException("Unable to find two closest vertices while triangulating face in mesh: " + temporalMesh + "Please apply triangulation modifier in blender as a workaround and load again!"); + warning = TriangulationWarning.CLOSEST_VERTS; + break; } if (previousIndex1 == indexes[0] && previousIndex2 == indexes[1] && previousIndex3 == indexes[2]) { - throw new BlenderFileException("Infinite loop detected during triangulation of mesh: " + temporalMesh + "Please apply triangulation modifier in blender as a workaround and load again!"); + warning = TriangulationWarning.INFINITE_LOOP; + break; } previousIndex1 = indexes[0]; previousIndex2 = indexes[1]; @@ -304,6 +307,10 @@ public class Face implements Comparator { } } catch (BlenderFileException e) { LOGGER.log(Level.WARNING, "Errors occured during face triangulation: {0}. The face will be triangulated with the most direct algorithm, but the results might not be identical to blender.", e.getLocalizedMessage()); + warning = TriangulationWarning.UNKNOWN; + } + if(warning != TriangulationWarning.NONE) { + LOGGER.finest("Triangulation the face using the most direct algorithm."); indexes[0] = this.getIndex(0); for (int i = 1; i < this.vertexCount() - 1; ++i) { indexes[1] = this.getIndex(i); @@ -311,6 +318,32 @@ public class Face implements Comparator { triangulatedFaces.add(new IndexesLoop(indexes)); } } + return warning; + } + + /** + * A warning that indicates a problem with face triangulation. The warnings are collected and displayed once for each type for a mesh to + * avoid multiple warning loggings during triangulation. The amount of iterations can be really huge and logging every single failure would + * really slow down the importing process and make logs unreadable. + * + * @author Marcin Roguski (Kaelthas) + */ + public static enum TriangulationWarning { + NONE(null), + CLOSEST_VERTS("Unable to find two closest vertices while triangulating face."), + INFINITE_LOOP("Infinite loop detected during triangulation."), + UNKNOWN("There was an unknown problem with face triangulation. Please see log for details."); + + private String description; + + private TriangulationWarning(String description) { + this.description = description; + } + + @Override + public String toString() { + return description; + } } /** diff --git a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java index da20d3fb4..0416237bb 100644 --- a/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java +++ b/jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java @@ -34,6 +34,7 @@ import com.jme3.scene.plugins.blender.BlenderContext.LoadedDataType; import com.jme3.scene.plugins.blender.file.BlenderFileException; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.materials.MaterialContext; +import com.jme3.scene.plugins.blender.meshes.Face.TriangulationWarning; import com.jme3.scene.plugins.blender.meshes.MeshBuffers.BoneBuffersData; import com.jme3.scene.plugins.blender.modifiers.Modifier; import com.jme3.scene.plugins.blender.objects.Properties; @@ -357,9 +358,22 @@ public class TemporalMesh extends Geometry { * Triangulates the mesh. */ public void triangulate() { + Set warnings = new HashSet<>(TriangulationWarning.values().length - 1); LOGGER.fine("Triangulating temporal mesh."); for (Face face : faces) { - face.triangulate(); + TriangulationWarning warning = face.triangulate(); + if(warning != TriangulationWarning.NONE) { + warnings.add(warning); + } + } + + if(warnings.size() > 0 && LOGGER.isLoggable(Level.WARNING)) { + StringBuilder sb = new StringBuilder(512); + sb.append("There were problems with triangulating the faces of a mesh: ").append(name); + for(TriangulationWarning w : warnings) { + sb.append("\n\t").append(w); + } + LOGGER.warning(sb.toString()); } }