[Bf-blender-cvs] [a067e590046] universal-scene-description: USD Import: validate meshes option.

Michael Kowalski noreply at git.blender.org
Mon Oct 10 18:50:16 CEST 2022


Commit: a067e590046f649b078f770275a3b22be5581431
Author: Michael Kowalski
Date:   Mon Oct 10 12:48:43 2022 -0400
Branches: universal-scene-description
https://developer.blender.org/rBa067e590046f649b078f770275a3b22be5581431

USD Import:  validate meshes option.

Added feature flag "Validate Meshes" to strip invalid geometry
from meshes on import.

===================================================================

M	source/blender/editors/io/io_usd.c
M	source/blender/io/usd/intern/usd_reader_mesh.cc

===================================================================

diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index abc94836d9c..ca0df20a45e 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -1099,6 +1099,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
 
   const eUSDAttrImportMode attr_import_mode = RNA_enum_get(op->ptr, "attr_import_mode");
 
+  const bool validate_meshes = RNA_boolean_get(op->ptr, "validate_meshes");
+
   /* TODO(makowalski): Add support for sequences. */
   const bool is_sequence = false;
   int offset = 0;
@@ -1110,8 +1112,6 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
     ED_object_mode_set(C, OB_MODE_EDIT);
   }
 
-  const bool validate_meshes = false;
-
   struct USDImportParams params = {.scale = scale,
                                    .is_sequence = is_sequence,
                                    .set_frame_range = set_frame_range,
@@ -1177,6 +1177,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
   col = uiLayoutColumnWithHeading(box, true, IFACE_("Mesh Data"));
   uiItemR(col, ptr, "read_mesh_uvs", 0, NULL, ICON_NONE);
   uiItemR(col, ptr, "read_mesh_colors", 0, NULL, ICON_NONE);
+  uiItemR(box, ptr, "validate_meshes", 0, NULL, ICON_NONE);
   col = uiLayoutColumnWithHeading(box, true, IFACE_("Include"));
   uiItemR(col, ptr, "import_subdiv", 0, IFACE_("Subdivision"), ICON_NONE);
   uiItemR(col, ptr, "import_instance_proxies", 0, NULL, ICON_NONE);
@@ -1386,6 +1387,12 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
                USD_ATTR_IMPORT_NONE,
                "Import Attributes",
                "Behavior when importing USD attributes as Blender custom properties");
+
+  RNA_def_boolean(ot->srna,
+                  "validate_meshes",
+                  false,
+                  "Validate Meshes",
+                  "Validate meshes for degenerate geometry on import");
 }
 
 #endif /* WITH_USD */
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc
index 15a5707baa1..7c1b3f0fd71 100644
--- a/source/blender/io/usd/intern/usd_reader_mesh.cc
+++ b/source/blender/io/usd/intern/usd_reader_mesh.cc
@@ -14,10 +14,8 @@
 #include "BKE_object.h"
 
 #include "BLI_math.h"
-#include "BLI_math_geom.h"
 #include "BLI_math_vec_types.hh"
 #include "BLI_span.hh"
-#include "BLI_string.h"
 
 #include "DNA_customdata_types.h"
 #include "DNA_material_types.h"
@@ -299,6 +297,7 @@ bool USDMeshReader::topology_changed(const Mesh *existing_mesh, const double mot
   mesh_prim_.GetFaceVertexCountsAttr().Get(&face_counts_, motionSampleTime);
   mesh_prim_.GetPointsAttr().Get(&positions_, motionSampleTime);
 
+
   /* TODO(makowalski): Reading normals probably doesn't belong in this function,
    * as this is not required to determine if the topology has changed. */
 
@@ -325,9 +324,25 @@ void USDMeshReader::read_mpolys(Mesh *mesh)
 
   int loop_index = 0;
 
+  std::vector<int> degenerate_faces;
+
   for (int i = 0; i < face_counts_.size(); i++) {
     const int face_size = face_counts_[i];
 
+    /* Check for faces with the same vertex specified twice in a row. */
+    if (face_indices_[loop_index] == face_indices_[loop_index+face_size-1]) {
+      /* Loop below does not test first to last. */
+      degenerate_faces.push_back(i);
+    }
+    else {
+      for (int j = loop_index+1; j < loop_index + face_size; j++) {
+        if (face_indices_[j] == face_indices_[j-1]) {
+          degenerate_faces.push_back(i);
+          break;
+        }
+      }
+    }
+
     MPoly &poly = mpolys[i];
     poly.loopstart = loop_index;
     poly.totloop = face_size;
@@ -351,6 +366,10 @@ void USDMeshReader::read_mpolys(Mesh *mesh)
   }
 
   BKE_mesh_calc_edges(mesh, false, false);
+
+  if (!degenerate_faces.empty() && !import_params_.validate_meshes) {
+    WM_reportf(RPT_WARNING, "Prim %s has degenerate faces-- please consider importing with Validate Meshes enabled.", prim_.GetName().GetText());
+  }
 }
 
 void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bool load_uvs)
@@ -931,7 +950,10 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
    * the topology is consistent, as in the Alembic importer. */
 
   ImportSettings settings;
-  settings.read_flag |= read_flag;
+  if (settings_) {
+    settings.validate_meshes = settings_->validate_meshes;
+  }
+  settings.read_flag |= read_flag;  settings.read_flag |= read_flag;
 
   if (topology_changed(existing_mesh, motionSampleTime)) {
     new_mesh = true;
@@ -957,6 +979,12 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
     }
   }
 
+  if (settings.validate_meshes) {
+    if (BKE_mesh_validate(active_mesh, false, false)) {
+      WM_reportf(RPT_INFO, "Fixed mesh for prim: %s", mesh_prim_.GetPath().GetText());
+    }
+  }
+
   return active_mesh;
 }



More information about the Bf-blender-cvs mailing list