[Bf-blender-cvs] [265df7b3a64] universal-scene-description: USD IO: attribute conversion improvements.

Michael Kowalski noreply at git.blender.org
Tue Oct 26 02:21:22 CEST 2021


Commit: 265df7b3a64a1191333c610871a8174aff2ac948
Author: Michael Kowalski
Date:   Mon Oct 25 20:12:34 2021 -0400
Branches: universal-scene-description
https://developer.blender.org/rB265df7b3a64a1191333c610871a8174aff2ac948

USD IO: attribute conversion improvements.

Initial implementation of logic to import USD
attibutes as Blender custom properites, with options
to import all custom attributes or only those
attibutes in the 'userProperties' namespace.

New export option to add custom properties to the
'userProperties' USD attribute namespace. This
option is enabled by default.

Removed hidden functionality where custom properties named
with the prefix 'USD_' were being saved to properties on the
USD prim that have the same name, without the prefix.  This
code was not type safe and could lead to unexpected behavior
in case of accidental property name collisions.

Added support for converting between USD int, float and
double vectors and Blender array type custom properties.

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

M	source/blender/editors/io/io_usd.c
M	source/blender/io/usd/intern/usd_reader_prim.cc
M	source/blender/io/usd/intern/usd_reader_prim.h
M	source/blender/io/usd/intern/usd_reader_xform.cc
M	source/blender/io/usd/intern/usd_writer_abstract.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 aad7536acd9..9283e2d0427 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -148,6 +148,32 @@ const EnumPropertyItem rna_enum_usd_mtl_name_collision_mode_items[] = {
     {0, NULL, 0, NULL, NULL},
 };
 
+const EnumPropertyItem rna_enum_usd_attr_import_mode_items[] = {
+    {USD_ATTR_IMPORT_NONE,
+     "NONE",
+     0,
+     "None",
+     "Do not import attributes"},
+    {USD_ATTR_IMPORT_USER,
+     "USER",
+     0,
+     "User",
+     "Import attributes in the 'userProperties' namespace as "
+     "Blender custom properties.  The namespace will "
+     "be stripped from the property names. "
+     "Note that attributes in the 'usdProperties:blenderName' namespace "
+     "will not be imported, as use of these attributes is deprecated"},
+    {USD_ATTR_IMPORT_ALL,
+     "ALL",
+     0,
+     "All Custom",
+     "Import all custom attributes as Blender custom properties. "
+     "Attribute namespaces will be retained in the property names. "
+     "Note that attributes in the 'usdProperties:blenderName' namespace "
+     "will not be imported, as use of these attributes is deprecated"},
+    {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 };
@@ -237,6 +263,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
   const bool export_as_overs = RNA_boolean_get(op->ptr, "export_as_overs");
   const bool merge_transform_and_shape = RNA_boolean_get(op->ptr, "merge_transform_and_shape");
   const bool export_custom_properties = RNA_boolean_get(op->ptr, "export_custom_properties");
+  const bool add_properties_namespace = RNA_boolean_get(op->ptr, "add_properties_namespace");
   const bool export_identity_transforms = RNA_boolean_get(op->ptr, "export_identity_transforms");
   const bool apply_subdiv = RNA_boolean_get(op->ptr, "apply_subdiv");
   const bool author_blender_name = RNA_boolean_get(op->ptr, "author_blender_name");
@@ -325,6 +352,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
                                    export_as_overs,
                                    merge_transform_and_shape,
                                    export_custom_properties,
+                                   add_properties_namespace,
                                    export_identity_transforms,
                                    apply_subdiv,
                                    author_blender_name,
@@ -393,7 +421,6 @@ static void wm_usd_export_draw(bContext *C, wmOperator *op)
   }
   uiItemR(box, ptr, "export_as_overs", 0, NULL, ICON_NONE);
   uiItemR(box, ptr, "merge_transform_and_shape", 0, NULL, ICON_NONE);
-  uiItemR(box, ptr, "export_custom_properties", 0, NULL, ICON_NONE);
   uiItemR(box, ptr, "export_identity_transforms", 0, NULL, ICON_NONE);
 
   if (RNA_boolean_get(ptr, "export_hair") || RNA_boolean_get(ptr, "export_particles")) {
@@ -405,6 +432,13 @@ static void wm_usd_export_draw(bContext *C, wmOperator *op)
     uiItemR(box, ptr, "vertex_data_as_face_varying", 0, NULL, ICON_NONE);
   }
 
+  box = uiLayoutBox(layout);
+  uiItemL(box, IFACE_("Attributes:"), ICON_NONE);
+  uiItemR(box, ptr, "export_custom_properties", 0, NULL, ICON_NONE);
+  if (RNA_boolean_get(ptr, "export_custom_properties")) {
+    uiItemR(box, ptr, "add_properties_namespace", 0, NULL, ICON_NONE);
+  }
+
   box = uiLayoutBox(layout);
   uiItemL(box, IFACE_("Cycles Settings:"), ICON_NONE);
   uiItemR(box, ptr, "override_shutter", 0, NULL, ICON_NONE);
@@ -720,6 +754,11 @@ void WM_OT_usd_export(struct wmOperatorType *ot)
                   true,
                   "Export Custom Properties",
                   "When checked, custom properties will be exported as USD User Properties");
+  RNA_def_boolean(ot->srna,
+                  "add_properties_namespace",
+                  true,
+                  "Add Properties Namespace",
+                  "Add exported custom properties to the 'userProperties' USD attribute namespace");
   RNA_def_boolean(ot->srna,
                   "export_identity_transforms",
                   false,
@@ -930,6 +969,9 @@ 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 eUSDAttrImportMode attr_import_mode = RNA_enum_get(op->ptr,
+                                                           "attr_import_mode");
+
   /* TODO(makowalski): Add support for sequences. */
   const bool is_sequence = false;
   int offset = 0;
@@ -972,7 +1014,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
                                    .convert_light_from_nits = convert_light_from_nits,
                                    .scale_light_radius = scale_light_radius,
                                    .create_background_shader = create_background_shader,
-                                   .mtl_name_collision_mode = mtl_name_collision_mode};
+                                   .mtl_name_collision_mode = mtl_name_collision_mode,
+                                   .attr_import_mode = attr_import_mode};
 
   const bool ok = USD_import(C, filename, &params, as_background_job);
 
@@ -1020,6 +1063,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
   uiItemR(box, ptr, "scale_light_radius", 0, NULL, ICON_NONE);
   uiItemR(box, ptr, "create_background_shader", 0, NULL, ICON_NONE);
   uiItemR(box, ptr, "mtl_name_collision_mode", 0, NULL, ICON_NONE);
+  uiItemR(box, ptr, "attr_import_mode", 0, NULL, ICON_NONE);
 
   box = uiLayoutBox(layout);
   col = uiLayoutColumnWithHeading(box, true, IFACE_("Experimental"));
@@ -1202,6 +1246,14 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
       USD_MTL_NAME_COLLISION_MODIFY,
       "Material Name Collision",
       "Behavior when the name of an imported material conflicts with an existing material");
+
+  RNA_def_enum(
+    ot->srna,
+    "attr_import_mode",
+    rna_enum_usd_attr_import_mode_items,
+    USD_ATTR_IMPORT_NONE,
+    "Import Attributes",
+    "Behavior when importing USD attributes as Blender custom properties");
 }
 
 #endif /* WITH_USD */
diff --git a/source/blender/io/usd/intern/usd_reader_prim.cc b/source/blender/io/usd/intern/usd_reader_prim.cc
index abd70f49f23..f2ab4bbe203 100644
--- a/source/blender/io/usd/intern/usd_reader_prim.cc
+++ b/source/blender/io/usd/intern/usd_reader_prim.cc
@@ -21,10 +21,245 @@
 
 #include "usd_reader_prim.h"
 
+#include "BKE_idprop.h"
 #include "BLI_utildefines.h"
+#include "DNA_object_types.h"
+
+#include <iostream>
+
+#include <pxr/usd/usd/attribute.h>
+
+namespace {
+
+template<typename VECT>
+void set_array_prop(IDProperty *idgroup,
+                    const char *prop_name,
+                    const pxr::UsdAttribute &attr,
+                    const double motionSampleTime)
+{
+  if (!idgroup || !attr) {
+    return;
+  }
+
+  VECT vec;
+  if (!attr.Get<VECT>(&vec, motionSampleTime)) {
+    return;
+  }
+
+  IDPropertyTemplate val = { 0 };
+  val.array.len = static_cast<int>(vec.dimension);
+
+  if (val.array.len <= 0) {
+    /* Should never happen. */
+    std::cout << "Invalid array length for prop " << prop_name << std::endl;
+    return;
+  }
+
+  if (std::is_same<float, typename VECT::ScalarType>()) {
+    val.array.type = IDP_FLOAT;
+  }
+  else if (std::is_same<double, typename VECT::ScalarType>()) {
+    val.array.type = IDP_DOUBLE;
+  }
+  else if (std::is_same<int, typename VECT::ScalarType>()) {
+    val.array.type = IDP_INT;
+  }
+  else {
+    std::cout << "Couldn't determine array type for prop " << prop_name << std::endl;
+    return;
+  }
+
+  IDProperty *prop = IDP_New(IDP_ARRAY, &val, prop_name);
+
+  if (!prop) {
+    std::cout << "Couldn't create array prop " << prop_name << std::endl;
+    return;
+  }
+
+  typename VECT::ScalarType *prop_data = static_cast<typename VECT::ScalarType *>(prop->data.pointer);
+
+  for (int i = 0; i < val.array.len; ++i) {
+    prop_data[i] = vec[i];
+  }
+
+  IDP_AddToGroup(idgroup, prop);
+}
+
+} // anonymous namespace
 
 namespace blender::io::usd {
 
+/* TfToken objects are not cheap to construct, so we do it once. */
+namespace usdtokens {
+  static const pxr::TfToken userProperties("userProperties", pxr::TfToken::Immortal);
+}  // namespace usdtokens
+
+static void set_string_prop(IDProperty *idgroup,
+                            const char *prop_name,
+                            const char *str_val)
+{
+  if (!idgroup) {
+    return;
+  }
+
+  IDPropertyTemplate val = { 0 };
+  val.string.str = str_val;
+  /* Note length includes null terminator. */
+  val.string.len = strlen(str_val) + 1;
+  val.string.subtype = IDP_STRING_SUB_UTF8;
+
+  IDProperty *prop = IDP_New(IDP_STRING, &val, prop_name);
+
+  IDP_AddToGroup(idgroup, prop);
+}
+
+static void set_int_prop(IDProperty *idgroup,
+                         const char *prop_name,
+                         const int ival)
+{
+  if (!idgroup) {
+    return;
+  }
+
+  IDPropertyTemplate val = { 0 };
+  val.i = ival;
+  IDProperty *prop = IDP_New(IDP_INT, &val, prop_name);
+
+  IDP_AddToGroup(idgroup, prop);
+}
+
+static void set_float_prop(IDProperty *idgroup,
+                           const char *prop_name,
+                           const float fval)
+{
+  if (!idgroup) {
+    return;
+  }
+
+  IDPropertyTemplate val = { 0 };
+  val.f = fval;
+  IDProperty *prop = IDP_New(IDP_FLOAT, &val, prop_name);
+
+  IDP_AddToGroup(idgroup, prop);
+}
+
+static void set_double_prop(IDProperty *idgroup,
+                            const char *prop_name,
+                            const double dval)
+{
+  if (!idgroup) {
+    return;
+  }
+
+  IDPropertyTemplate val = { 0 };
+  val.d = dval;
+  IDProperty *prop = IDP_New(IDP_DOUBLE, &val, prop_name);
+
+  IDP_AddToGroup(idgroup, prop);
+}
+
+void USDPrimReader::set_props(ID *id, const pxr::UsdPrim &prim, const double motionSampleTime)
+{
+  eUSDAttrImportM

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list