Commit: 6ce3e0495ae11efc91a4bc759609a0317d5baeda Author: Michael Kowalski Date: Fri Dec 9 18:37:54 2022 -0500 Branches: universal-scene-description https://developer.blender.org/rB6ce3e0495ae11efc91a4bc759609a0317d5baeda
USD export: support authoring Kind Added a switch to the exporter to write USD Kind. Added options to add USD Kind to the Default Prim. Added a special case for the IDProperty "usdkind", which is now written as the Kind through the UsdModelAPI. =================================================================== M source/blender/editors/io/io_usd.c M source/blender/io/usd/intern/usd_capi_export.cc M source/blender/io/usd/intern/usd_writer_abstract.cc M source/blender/io/usd/intern/usd_writer_abstract.h 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 e82aefc4383..05dc0cbf986 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -164,6 +164,16 @@ const EnumPropertyItem prop_usdz_downscale_size[] = { {0, NULL, 0, NULL, NULL}, }; +const EnumPropertyItem prop_default_prim_kind_items[] = { + { USD_KIND_NONE, "NONE", 0, "None", "No kind is exported for default prim" }, + { USD_KIND_COMPONENT, "COMPONENT", 0, "Component", "Set Default Prim Kind to Component" }, + { USD_KIND_GROUP, "GROUP", 0, "Group", "Set Default Prim Kind to Group" }, + { USD_KIND_ASSEMBLY, "ASSEMBLY", 0, "Assembly", "Set Default Prim Kind to Assembly" }, + { USD_KIND_CUSTOM, "CUSTOM", 0, "Custom", "Specify a custom Kind for the Default Prim" }, + {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 }; @@ -314,6 +324,11 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op) const bool export_blender_metadata = RNA_boolean_get(op->ptr, "export_blender_metadata"); + /* USDKind support. */ + const bool export_usd_kind = RNA_boolean_get(op->ptr, "export_usd_kind"); + const int default_prim_kind = RNA_enum_get(op->ptr, "default_prim_kind"); + char *default_prim_custom_kind = RNA_string_get_alloc(op->ptr, "default_prim_custom_kind", NULL, 0, NULL); + struct USDExportParams params = {RNA_int_get(op->ptr, "start"), RNA_int_get(op->ptr, "end"), export_animation, @@ -377,7 +392,11 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op) export_blender_metadata, triangulate_meshes, quad_method, - ngon_method}; + ngon_method, + .export_usd_kind = export_usd_kind, + .default_prim_kind = default_prim_kind, + .default_prim_custom_kind = default_prim_custom_kind + }; /* Take some defaults from the scene, if not specified explicitly. */ Scene *scene = CTX_data_scene(C); @@ -427,6 +446,7 @@ static void wm_usd_export_draw(bContext *C, wmOperator *op) uiItemR(box, ptr, "end", 0, NULL, ICON_NONE); uiItemR(box, ptr, "frame_step", 0, NULL, ICON_NONE); } + uiItemR(box, ptr, "export_usd_kind", 0, NULL, ICON_NONE); 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_identity_transforms", 0, NULL, ICON_NONE); @@ -493,6 +513,12 @@ static void wm_usd_export_draw(bContext *C, wmOperator *op) uiItemR(box, ptr, "default_prim_path", 0, NULL, ICON_NONE); uiItemR(box, ptr, "root_prim_path", 0, NULL, ICON_NONE); uiItemR(box, ptr, "material_prim_path", 0, NULL, ICON_NONE); + if (RNA_boolean_get(ptr, "export_usd_kind")) { + uiItemR(box, ptr, "default_prim_kind", 0, NULL, ICON_NONE); + if (RNA_enum_get(ptr, "default_prim_kind") == USD_KIND_CUSTOM) { + uiItemR(box, ptr, "default_prim_custom_kind", 0, NULL, ICON_NONE); + } + } box = uiLayoutBox(layout); uiItemL(box, IFACE_("Conversion:"), ICON_ORIENTATION_GLOBAL); @@ -1010,6 +1036,26 @@ void WM_OT_usd_export(struct wmOperatorType *ot) MOD_TRIANGULATE_NGON_BEAUTY, "N-gon Method", "Method for splitting the n-gons into triangles"); + + RNA_def_boolean(ot->srna, + "export_usd_kind", + true, + "Export USD Kind", + "Export Kind per-prim when specified through 'usdkind' custom property."); + + RNA_def_enum(ot->srna, + "default_prim_kind", + prop_default_prim_kind_items, + USD_KIND_NONE, + "Default Prim Kind", + "Kind to author on the Default Prim"); + + RNA_def_string(ot->srna, + "default_prim_custom_kind", + NULL, + 128, + "Default Prim Custom Kind", + "If default_prim_kind is True, author this value as the Default Prim's Kind"); } /* ====== USD Import ====== */ diff --git a/source/blender/io/usd/intern/usd_capi_export.cc b/source/blender/io/usd/intern/usd_capi_export.cc index 4b2d4bf7907..85335172533 100644 --- a/source/blender/io/usd/intern/usd_capi_export.cc +++ b/source/blender/io/usd/intern/usd_capi_export.cc @@ -11,6 +11,8 @@ #include <pxr/base/plug/registry.h> #include <pxr/pxr.h> +#include <pxr/usd/kind/registry.h> +#include <pxr/usd/usd/modelAPI.h> #include <pxr/usd/usd/stage.h> #include <pxr/usd/usdGeom/metrics.h> #include <pxr/usd/usdGeom/scope.h> @@ -99,6 +101,12 @@ static bool validate_params(const USDExportParams ¶ms) valid = false; } + if (params.export_usd_kind && params.default_prim_kind == USD_KIND_CUSTOM && strlen(params.default_prim_custom_kind) == 0) { + WM_reportf(RPT_ERROR, + "USD Export: Default Prim Kind is set to Custom, but the value is empty."); + valid = false; + } + return valid; } @@ -197,6 +205,31 @@ static void ensure_root_prim(pxr::UsdStageRefPtr stage, const USDExportParams &p xf_api.SetRotate(pxr::GfVec3f(eul[0], eul[1], eul[2])); } + + /* Handle root prim USD Kind. */ + if (params.export_usd_kind && params.default_prim_kind) { + pxr::UsdModelAPI api(root_prim); + switch (params.default_prim_kind) { + case USD_KIND_COMPONENT: + api.SetKind(pxr::KindTokens->component); + break; + + case USD_KIND_GROUP: + api.SetKind(pxr::KindTokens->group); + break; + + case USD_KIND_ASSEMBLY: + api.SetKind(pxr::KindTokens->assembly); + break; + + case USD_KIND_CUSTOM: + api.SetKind(pxr::TfToken(params.default_prim_custom_kind)); + break; + + default: + break; + } + } } static void report_job_duration(const ExportJobData *data) diff --git a/source/blender/io/usd/intern/usd_writer_abstract.cc b/source/blender/io/usd/intern/usd_writer_abstract.cc index 70c3268d01d..0e32e37a70e 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.cc +++ b/source/blender/io/usd/intern/usd_writer_abstract.cc @@ -5,6 +5,8 @@ #include "usd_writer_material.h" #include <pxr/base/tf/stringUtils.h> +#include <pxr/usd/kind/registry.h> +#include <pxr/usd/usd/modelAPI.h> #include "BKE_customdata.h" #include "BLI_assert.h" @@ -275,6 +277,12 @@ void USDAbstractWriter::write_visibility(const HierarchyContext &context, usd_value_writer_.SetAttribute(attr_visibility, pxr::VtValue(visibility), timecode); } +void USDAbstractWriter::write_kind(pxr::UsdPrim& prim, pxr::TfToken kind) +{ + pxr::UsdModelAPI api(prim); + api.SetKind(kind); +} + bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim) { BLI_assert(context.is_instance()); @@ -344,8 +352,17 @@ void USDAbstractWriter::write_user_properties(pxr::UsdPrim &prim, return; } + const StringRef kind_identifier = "usdkind"; + IDProperty *prop; for (prop = (IDProperty *)properties->data.group.first; prop; prop = prop->next) { + if (kind_identifier == prop->name) { + if (prop->type == IDP_STRING && usd_export_context_.export_params.export_usd_kind && prop->data.pointer) { + write_kind(prim, pxr::TfToken(static_cast<char*>(prop->data.pointer))); + } + continue; + } + std::string prop_name = pxr::TfMakeValidIdentifier(prop->name); std::string full_prop_name; diff --git a/source/blender/io/usd/intern/usd_writer_abstract.h b/source/blender/io/usd/intern/usd_writer_abstract.h index 973229eb575..ef47348deed 100644 --- a/source/blender/io/usd/intern/usd_writer_abstract.h +++ b/source/blender/io/usd/intern/usd_writer_abstract.h @@ -68,6 +68,8 @@ class USDAbstractWriter : public AbstractHierarchyWriter { const pxr::UsdTimeCode timecode, pxr::UsdGeomImageable &usd_geometry); + void write_kind(pxr::UsdPrim& prim, pxr::TfToken kind); + /** * Turn `prim` into an instance referencing `context.original_export_path`. * Return true when the instancing was successful, false otherwise. diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h index e62cf965424..8e6707b520e 100644 --- a/source/blender/io/usd/usd.h +++ b/source/blender/io/usd/usd.h @@ -71,6 +71,14 @@ typedef enum eUSDAttrImportMode { USD_ATTR_IMPORT_ALL = 2, } eUSDAttrImportMode; +typedef enum eUSDDefaultPrimKind { + USD_KIND_NONE = 0, + USD_KIND_COMPONENT, + USD_KIND_GROUP, + USD_KIND_ASSEMBLY, + USD_KIND_CUSTOM +} eUSDDefaultPrimKind; + struct USDExportParams { double frame_start; double frame_end; @@ -138,6 +146,9 @@ struct USDExportParams { bool triangulate_meshes; int quad_method; int ngon_method; + bool export_usd_kind; + eUSDDefaultPrimKind default_prim_kind; + char *default_prim_custom_kind; }; struct USDImportParams { _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs