[Bf-blender-cvs] [dca907005ac] usd-importer-T81257-merge: USD Import: merge prim with parent xform.
makowalski
noreply at git.blender.org
Sat Apr 24 03:17:24 CEST 2021
Commit: dca907005ac9258677e31e59f4b685ceb73ebadc
Author: makowalski
Date: Fri Apr 23 21:08:33 2021 -0400
Branches: usd-importer-T81257-merge
https://developer.blender.org/rBdca907005ac9258677e31e59f4b685ceb73ebadc
USD Import: merge prim with parent xform.
Added logic to merge a USD prim and its parent
Xform into a single Blender object representation.
Added a USDXformReader::use_parent_xform_ flag
which, if true, causes the USDXformReader to
use the parent of the encapsulated prim to compute
the object's transform.
===================================================================
M source/blender/io/usd/intern/usd_reader_stage.cc
M source/blender/io/usd/intern/usd_reader_xform.cc
M source/blender/io/usd/intern/usd_reader_xform.h
===================================================================
diff --git a/source/blender/io/usd/intern/usd_reader_stage.cc b/source/blender/io/usd/intern/usd_reader_stage.cc
index 180de601dd6..fc015199900 100644
--- a/source/blender/io/usd/intern/usd_reader_stage.cc
+++ b/source/blender/io/usd/intern/usd_reader_stage.cc
@@ -176,11 +176,48 @@ static bool _prune_by_purpose(const pxr::UsdGeomImageable &imageable,
return false;
}
+/* Determine if the given reader can use the parent of the encapsulated USD prim
+ * to compute the Blender object's transform. If so, the reader is appropriately
+ * flagged and the function returns true. Otherwise, the function returns false. */
+static bool _merge_with_parent(USDPrimReader *reader)
+{
+ USDXformReader *xform_reader = dynamic_cast<USDXformReader *>(reader);
+
+ if (!xform_reader) {
+ return false;
+ }
+
+ /* Check if the Xform reader is already merged. */
+ if (xform_reader->use_parent_xform()) {
+ return false;
+ }
+
+ /* Only merge if the parent is an Xform. */
+ if (!xform_reader->prim().GetParent().IsA<pxr::UsdGeomXform>()) {
+ return false;
+ }
+
+ /* Don't merge Xform and Scope prims. */
+ if (xform_reader->prim().IsA<pxr::UsdGeomXform>() ||
+ xform_reader->prim().IsA<pxr::UsdGeomScope>()) {
+ return false;
+ }
+
+ /* Don't merge if the prim has authored transform ops. */
+ if (xform_reader->prim_has_xform_ops()) {
+ return false;
+ }
+
+ /* Flag the Xform reader as merged. */
+ xform_reader->set_use_parent_xform(true);
+
+ return true;
+}
+
static USDPrimReader *_handlePrim(Main *bmain,
pxr::UsdStageRefPtr stage,
const USDImportParams ¶ms,
pxr::UsdPrim prim,
- USDPrimReader *parent_reader,
std::vector<USDPrimReader *> &readers,
const ImportSettings &settings)
{
@@ -196,35 +233,51 @@ static USDPrimReader *_handlePrim(Main *bmain,
}
}
- USDPrimReader *reader = NULL;
+ pxr::Usd_PrimFlagsPredicate filter_predicate = pxr::UsdPrimDefaultPredicate;
- // This check prevents the stage pseudo 'root' prim
- // or the root prims of scenegraph 'master' prototypes
- // from being added.
- if (!(prim.IsPseudoRoot() || prim.IsMaster())) {
- reader = USDStageReader::create_reader(prim, params, settings);
+ if (params.import_instance_proxies) {
+ filter_predicate = pxr::UsdTraverseInstanceProxies(filter_predicate);
+ }
- if (reader == NULL) {
- return NULL;
- }
+ pxr::UsdPrimSiblingRange children = prim.GetFilteredChildren(filter_predicate);
- reader->parent(parent_reader);
- reader->create_object(bmain, 0.0);
+ std::vector<USDPrimReader *> child_readers;
- readers.push_back(reader);
- reader->incref();
+ for (const auto &childPrim : children) {
+ USDPrimReader *child_reader = _handlePrim(bmain, stage, params, childPrim, readers, settings);
+ if (child_reader) {
+ child_readers.push_back(child_reader);
+ }
}
- pxr::Usd_PrimFlagsPredicate filter_predicate = pxr::UsdPrimDefaultPredicate;
+ /* Check if we can merge an Xform with its child prim. */
+ if (child_readers.size() == 1) {
- if (params.import_instance_proxies) {
- filter_predicate = pxr::UsdTraverseInstanceProxies(filter_predicate);
+ USDPrimReader *child_reader = child_readers.front();
+
+ if (_merge_with_parent(child_reader)) {
+ return child_reader;
+ }
}
- pxr::UsdPrimSiblingRange children = prim.GetFilteredChildren(filter_predicate);
+ USDPrimReader *reader = nullptr;
- for (const auto &childPrim : children) {
- _handlePrim(bmain, stage, params, childPrim, reader, readers, settings);
+ if (!prim.IsPseudoRoot()) {
+ reader = USDStageReader::create_reader(prim, params, settings);
+
+ if (reader == nullptr) {
+ return nullptr;
+ }
+
+ reader->create_object(bmain, 0.0);
+
+ readers.push_back(reader);
+ reader->incref();
+
+ /* Set each child reader's parent. */
+ for (USDPrimReader *child_reader : child_readers) {
+ child_reader->parent(reader);
+ }
}
return reader;
@@ -262,7 +315,7 @@ void USDStageReader::collect_readers(Main *bmain,
}
stage_->SetInterpolationType(pxr::UsdInterpolationType::UsdInterpolationTypeHeld);
- _handlePrim(bmain, stage_, params, root, NULL, readers_, settings);
+ _handlePrim(bmain, stage_, params, root, readers_, settings);
}
void USDStageReader::clear_readers(bool decref)
diff --git a/source/blender/io/usd/intern/usd_reader_xform.cc b/source/blender/io/usd/intern/usd_reader_xform.cc
index 16c6ee4c0f6..46f8331c3c7 100644
--- a/source/blender/io/usd/intern/usd_reader_xform.cc
+++ b/source/blender/io/usd/intern/usd_reader_xform.cc
@@ -66,7 +66,11 @@ void USDXformReader::read_object_data(Main * /* bmain */, const double motionSam
bConstraint *con = BKE_constraint_add_for_object(
object_, NULL, CONSTRAINT_TYPE_TRANSFORM_CACHE);
bTransformCacheConstraint *data = static_cast<bTransformCacheConstraint *>(con->data);
- BLI_strncpy(data->object_path, prim_.GetPath().GetText(), FILE_MAX);
+
+ std::string prim_path = use_parent_xform_ ? prim_.GetParent().GetPath().GetAsString() :
+ prim_path_;
+
+ BLI_strncpy(data->object_path, prim_path.c_str(), FILE_MAX);
data->cache_file = settings_->cache_file;
id_us_plus(&data->cache_file->id);
@@ -83,7 +87,14 @@ void USDXformReader::read_matrix(float r_mat[4][4] /* local matrix */,
is_constant = true;
unit_m4(r_mat);
- pxr::UsdGeomXformable xformable(prim_);
+ pxr::UsdGeomXformable xformable;
+
+ if (use_parent_xform_) {
+ xformable = pxr::UsdGeomXformable(prim_.GetParent());
+ }
+ else {
+ xformable = pxr::UsdGeomXformable(prim_);
+ }
if (!xformable) {
// This might happen if the prim is a Scope.
@@ -116,6 +127,20 @@ void USDXformReader::read_matrix(float r_mat[4][4] /* local matrix */,
}
}
+bool USDXformReader::prim_has_xform_ops() const
+{
+ pxr::UsdGeomXformable xformable(prim_);
+
+ if (!xformable) {
+ // This might happen if the prim is a Scope.
+ return false;
+ }
+
+ bool reset_xform_stack = false;
+
+ return !xformable.GetOrderedXformOps(&reset_xform_stack).empty();
+}
+
bool USDXformReader::is_root_xform_object() const
{
// It's not sufficient to check for a null parent to determine
diff --git a/source/blender/io/usd/intern/usd_reader_xform.h b/source/blender/io/usd/intern/usd_reader_xform.h
index 197451c680b..4afc994157b 100644
--- a/source/blender/io/usd/intern/usd_reader_xform.h
+++ b/source/blender/io/usd/intern/usd_reader_xform.h
@@ -21,12 +21,14 @@
namespace blender::io::usd {
class USDXformReader : public USDPrimReader {
+ private:
+ bool use_parent_xform_;
public:
USDXformReader(const pxr::UsdPrim &prim,
const USDImportParams &import_params,
const ImportSettings &settings)
- : USDPrimReader(prim, import_params, settings)
+ : USDPrimReader(prim, import_params, settings), use_parent_xform_(false)
{
}
@@ -35,6 +37,17 @@ class USDXformReader : public USDPrimReader {
void read_matrix(float r_mat[4][4], const float time, const float scale, bool &is_constant);
+ bool use_parent_xform() const
+ {
+ return use_parent_xform_;
+ }
+ void set_use_parent_xform(bool flag)
+ {
+ use_parent_xform_ = flag;
+ }
+
+ bool prim_has_xform_ops() const;
+
// Returns true if this reader represents an object that is the root of the
// transform hierarchy.
bool is_root_xform_object() const;
More information about the Bf-blender-cvs
mailing list