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.
define_list_fix
jmekaelthas 9 years ago
parent 310f4db6ad
commit 2024fe7acf
  1. 41
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/Face.java
  2. 16
      jme3-blender/src/main/java/com/jme3/scene/plugins/blender/meshes/TemporalMesh.java

@ -265,15 +265,16 @@ public class Face implements Comparator<Integer> {
/** /**
* The method triangulates the face. * The method triangulates the face.
*/ */
public void triangulate() { public TriangulationWarning triangulate() {
LOGGER.fine("Triangulating face."); LOGGER.fine("Triangulating face.");
assert indexes.size() >= 3 : "Invalid indexes amount for face. 3 is the required minimum!"; assert indexes.size() >= 3 : "Invalid indexes amount for face. 3 is the required minimum!";
triangulatedFaces = new ArrayList<IndexesLoop>(indexes.size() - 2); triangulatedFaces = new ArrayList<IndexesLoop>(indexes.size() - 2);
Integer[] indexes = new Integer[3]; Integer[] indexes = new Integer[3];
TriangulationWarning warning = TriangulationWarning.NONE;
try { try {
List<Face> facesToTriangulate = new ArrayList<Face>(Arrays.asList(this.clone())); List<Face> facesToTriangulate = new ArrayList<Face>(Arrays.asList(this.clone()));
while (facesToTriangulate.size() > 0) { while (facesToTriangulate.size() > 0 && warning == TriangulationWarning.NONE) {
Face face = facesToTriangulate.remove(0); Face face = facesToTriangulate.remove(0);
// two special cases will improve the computations speed // two special cases will improve the computations speed
if(face.getIndexes().size() == 3) { if(face.getIndexes().size() == 3) {
@ -287,10 +288,12 @@ public class Face implements Comparator<Integer> {
LOGGER.finer("Veryfying improper triangulation of the temporal mesh."); LOGGER.finer("Veryfying improper triangulation of the temporal mesh.");
if (indexes[0] < 0 || indexes[1] < 0 || indexes[2] < 0) { 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]) { 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]; previousIndex1 = indexes[0];
previousIndex2 = indexes[1]; previousIndex2 = indexes[1];
@ -304,6 +307,10 @@ public class Face implements Comparator<Integer> {
} }
} catch (BlenderFileException e) { } 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()); 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); indexes[0] = this.getIndex(0);
for (int i = 1; i < this.vertexCount() - 1; ++i) { for (int i = 1; i < this.vertexCount() - 1; ++i) {
indexes[1] = this.getIndex(i); indexes[1] = this.getIndex(i);
@ -311,6 +318,32 @@ public class Face implements Comparator<Integer> {
triangulatedFaces.add(new IndexesLoop(indexes)); 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;
}
} }
/** /**

@ -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.BlenderFileException;
import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.blender.materials.MaterialContext; 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.meshes.MeshBuffers.BoneBuffersData;
import com.jme3.scene.plugins.blender.modifiers.Modifier; import com.jme3.scene.plugins.blender.modifiers.Modifier;
import com.jme3.scene.plugins.blender.objects.Properties; import com.jme3.scene.plugins.blender.objects.Properties;
@ -357,9 +358,22 @@ public class TemporalMesh extends Geometry {
* Triangulates the mesh. * Triangulates the mesh.
*/ */
public void triangulate() { public void triangulate() {
Set<TriangulationWarning> warnings = new HashSet<>(TriangulationWarning.values().length - 1);
LOGGER.fine("Triangulating temporal mesh."); LOGGER.fine("Triangulating temporal mesh.");
for (Face face : faces) { 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());
} }
} }

Loading…
Cancel
Save