[Bf-blender-cvs] [5649158db99] tmp-usd-alab-v2-T100452: USD import: Alab v2 load errors.

Michael Kowalski noreply at git.blender.org
Wed Aug 17 04:46:08 CEST 2022


Commit: 5649158db9985608adf3b24d0726cdab35788036
Author: Michael Kowalski
Date:   Tue Aug 16 22:15:13 2022 -0400
Branches: tmp-usd-alab-v2-T100452
https://developer.blender.org/rB5649158db9985608adf3b24d0726cdab35788036

USD import: Alab v2 load errors.

Work in progress addressing issues loading the Alab v2 scene.

Load primvars of type Float2Array as texture coordinates.
Fixed type mismatch loading UsdPrimvarReader_float2 varname input.
For materials that have an authored opacity value, changed the blend
mode from Alpha Blend to Alpha Hashed, to mitigate object soring issue.
Added import option to specify loading materials by purpose to allow
explicitly loading full materials for debugging.

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

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

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

diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index a59cdf60243..6c4c35fe490 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -71,6 +71,28 @@ const EnumPropertyItem rna_enum_usd_mtl_name_collision_mode_items[] = {
     {0, NULL, 0, NULL, NULL},
 };
 
+const EnumPropertyItem rna_enum_usd_mtl_purpose_items[] = {
+    {USD_MTL_PURPOSE_ALL,
+     "MTL_ALL_PURPOSE",
+     0,
+     "All Purpose",
+     "Attempt to import 'allPurpose' materials.  "
+     "Load 'preview' and 'full' materials as a fallback, in that order"},
+    {USD_MTL_PURPOSE_PREVIEW,
+     "MTL_PREVIEW",
+     0,
+     "Preview",
+     "Attempt to import 'preview' materials.  "
+     "Load 'allPurpose' and 'full' materials as a fallback, in that order"},
+    {USD_MTL_PURPOSE_FULL,
+     "MTL_FULL",
+     0,
+     "Full",
+     "Attempt to import 'full' materials.  "
+     "Load 'allPurpose' and 'preview' materials as a fallback, in that order"},
+    {0, NULL, 0, NULL, NULL},
+};
+
 /* Stored in the wmOperator's customdata field to indicate it should run as a background job.
  * This is set when the operator is invoked, and not set when it is only executed. */
 enum { AS_BACKGROUND_JOB = 1 };
@@ -388,6 +410,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
   const eUSDMtlNameCollisionMode mtl_name_collision_mode = RNA_enum_get(op->ptr,
                                                                         "mtl_name_collision_mode");
 
+  const eUSDMtlPurpose mtl_purpose = RNA_enum_get(op->ptr, "mtl_purpose");
+
   /* TODO(makowalski): Add support for sequences. */
   const bool is_sequence = false;
   int offset = 0;
@@ -427,7 +451,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
                                    .import_usd_preview = import_usd_preview,
                                    .set_material_blend = set_material_blend,
                                    .light_intensity_scale = light_intensity_scale,
-                                   .mtl_name_collision_mode = mtl_name_collision_mode};
+                                   .mtl_name_collision_mode = mtl_name_collision_mode,
+                                   .mtl_purpose = mtl_purpose};
 
   const bool ok = USD_import(C, filename, &params, as_background_job);
 
@@ -479,6 +504,8 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
   uiLayout *row = uiLayoutRow(col, true);
   uiItemR(row, ptr, "set_material_blend", 0, NULL, ICON_NONE);
   uiLayoutSetEnabled(row, RNA_boolean_get(ptr, "import_usd_preview"));
+  row = uiLayoutRow(col, true);
+  uiItemR(row, ptr, "mtl_purpose", 0, NULL, ICON_NONE);
 }
 
 void WM_OT_usd_import(struct wmOperatorType *ot)
@@ -585,6 +612,16 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
                   "the material blend method will automatically be set based on the "
                   "shader's opacity and opacityThreshold inputs");
 
+  RNA_def_enum(
+      ot->srna,
+      "mtl_purpose",
+      rna_enum_usd_mtl_purpose_items,
+      USD_MTL_PURPOSE_ALL,
+      "Material Purpose",
+      "Attempt to import materials with the given purpose. "
+      "If no material with this purpose is bound to the primitive, "
+      "fall back on loading any other bound material");
+
   RNA_def_float(ot->srna,
                 "light_intensity_scale",
                 1.0f,
diff --git a/source/blender/io/usd/intern/usd_reader_material.cc b/source/blender/io/usd/intern/usd_reader_material.cc
index f59b8be147e..5d64f3279ee 100644
--- a/source/blender/io/usd/intern/usd_reader_material.cc
+++ b/source/blender/io/usd/intern/usd_reader_material.cc
@@ -393,7 +393,7 @@ void USDMaterialReader::import_usd_preview(Material *mtl,
         mtl->alpha_threshold = opacity_threshold;
       }
       else {
-        mtl->blend_method = MA_BM_BLEND;
+        mtl->blend_method = MA_BM_HASHED;
       }
     }
   }
@@ -740,11 +740,18 @@ void USDMaterialReader::convert_usd_primvar_reader_float2(
   }
 
   /* Set the texmap name. */
-  pxr::UsdShadeInput varname_input = usd_shader.GetInput(usdtokens::varname);
-  if (varname_input) {
+  if (pxr::UsdShadeInput varname_input = usd_shader.GetInput(usdtokens::varname)) {
+    /* According to the current USD Preview Surface specification, the 'varname' input
+     * is a string.  However, for backward compatibility with previous USD versions, we
+     * also handle TfToken values for this input. */
     pxr::VtValue varname_val;
-    if (varname_input.Get(&varname_val) && varname_val.IsHolding<pxr::TfToken>()) {
-      std::string varname = varname_val.Get<pxr::TfToken>().GetString();
+    if (varname_input.Get(&varname_val)) {
+      std::string varname;
+      if (varname_val.IsHolding<std::string>()) {
+        varname = varname_val.Get<std::string>();
+      } else if (varname_val.IsHolding<pxr::TfToken>()) {
+        varname = varname_val.Get<pxr::TfToken>().GetString();
+      }
       if (!varname.empty()) {
         NodeShaderUVMap *storage = (NodeShaderUVMap *)uv_map->storage;
         BLI_strncpy(storage->uv_map, varname.c_str(), sizeof(storage->uv_map));
diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc
index 103bb0d0cef..fb7f2cfe41c 100644
--- a/source/blender/io/usd/intern/usd_reader_mesh.cc
+++ b/source/blender/io/usd/intern/usd_reader_mesh.cc
@@ -62,21 +62,42 @@ static void build_mat_map(const Main *bmain, std::map<std::string, Material *> *
   }
 }
 
-static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim)
+static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim, eUSDMtlPurpose purpose)
 {
-  pxr::UsdShadeMaterialBindingAPI api = pxr::UsdShadeMaterialBindingAPI(prim);
-
-  /* Compute generically bound ('allPurpose') materials. */
-  pxr::UsdShadeMaterial mtl = api.ComputeBoundMaterial();
+  pxr::UsdShadeMaterial mtl;
 
-  /* If no generic material could be resolved, also check for 'preview' and
-   * 'full' purpose materials as fallbacks. */
-  if (!mtl) {
-    mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->preview);
-  }
+  pxr::UsdShadeMaterialBindingAPI api = pxr::UsdShadeMaterialBindingAPI(prim);
 
-  if (!mtl) {
-    mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->full);
+  switch (purpose) {
+    case USD_MTL_PURPOSE_ALL:
+      mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->allPurpose);
+      if (!mtl) {
+        mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->preview);
+      }
+      if (!mtl) {
+        mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->full);
+      }
+      break;
+    case USD_MTL_PURPOSE_PREVIEW:
+      mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->preview);
+      if (!mtl) {
+        mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->allPurpose);
+      }
+      if (!mtl) {
+        mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->full);
+      }
+      break;
+    case USD_MTL_PURPOSE_FULL:
+      mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->full);
+      if (!mtl) {
+        mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->allPurpose);
+      }
+      if (!mtl) {
+        mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->preview);
+      }
+      break;
+    default:
+      break;
   }
 
   return mtl;
@@ -351,6 +372,14 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
   struct UVSample {
     pxr::VtVec2fArray uvs;
     pxr::TfToken interpolation;
+    /* The following is mutable as it might
+     * be modified for error reporting even
+     * when other members are const. */
+    mutable bool invalid_index_found;
+
+    UVSample() : invalid_index_found(false)
+    {
+    }
   };
 
   std::vector<UVSample> uv_primvars(ldata->totlayer);
@@ -396,6 +425,8 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
     }
   }
 
+  std::vector<int> warned_invalid_index_for_layer(ldata->totlayer);
+
   for (int i = 0; i < face_counts_.size(); i++) {
     const int face_size = face_counts_[i];
 
@@ -435,8 +466,12 @@ void USDMeshReader::read_uvs(Mesh *mesh, const double motionSampleTime, const bo
                                loop_index;
 
         if (usd_uv_index >= sample.uvs.size()) {
-          std::cerr << "WARNING: out of bounds uv index " << usd_uv_index << " for uv "
-                    << layer->name << " of size " << sample.uvs.size() << std::endl;
+          /* Out of bounds index. */
+          if (!sample.invalid_index_found) {
+            sample.invalid_index_found = true;
+            std::cerr << "WARNING: out of bounds index detected for uv layer " << layer->name
+                      << std::endl;
+          }
           continue;
         }
 
@@ -756,7 +791,8 @@ void USDMeshReader::assign_facesets_to_mpoly(double motionSampleTime,
   if (!subsets.empty()) {
     for (const pxr::UsdGeomSubset &subset : subsets) {
 
-      pxr::UsdShadeMaterial subset_mtl = utils::compute_bound_material(subset.GetPrim());
+      pxr::UsdShadeMaterial subset_mtl =
+        utils::compute_bound_material(subset.GetPrim(), import_params_.mtl_purpose);
       if (!subset_mtl) {
         continue;
       }
@@ -786,7 +822,8 @@ void USDMeshReader::assign_facesets_to_mpoly(double motionSampleTime,
 
   if (r_mat_map->empty()) {
 
-    pxr::UsdShadeMaterial mtl = utils::compute_bound_material(prim_);
+    pxr::UsdShadeMaterial mtl =
+      utils::compute_bound_material(prim_, import_params_.mtl_purpose);
     if (mtl) {
       pxr::SdfPath mtl_path = mtl.GetPath();
 
@@ -850,7 +887,8 @@ Mesh *USDMeshReader::read_mesh(Mesh *existing_mesh,
       if (ELEM(type,
                pxr::SdfValueTypeNames->TexCoord2hArray,
                pxr::SdfValueTypeNames->TexCoord2fArray,
-               pxr::SdfValueTypeNames->TexCoord2dArray)) {
+               pxr::SdfValueTypeNames->TexCoord2dArray,
+               pxr::SdfValueTypeNames->Float2Array)) {
         is_uv = true;
       }
       /* In some cases, the st primvar is stored as float2 values. */
diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h
index a07315d8b4e..7caba9dea07 100644
--- a/source/blender/io/usd/usd.h
+++ b/source/blender

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list