USD: import scenegraph instances. #115076
@ -473,7 +473,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
|
||||
|
||||
const bool import_subdiv = RNA_boolean_get(op->ptr, "import_subdiv");
|
||||
|
||||
const bool import_instance_proxies = RNA_boolean_get(op->ptr, "import_instance_proxies");
|
||||
const bool support_scene_instancing = RNA_boolean_get(op->ptr, "support_scene_instancing");
|
||||
|
||||
const bool import_visible_only = RNA_boolean_get(op->ptr, "import_visible_only");
|
||||
|
||||
@ -537,7 +537,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
|
||||
params.import_blendshapes = import_blendshapes;
|
||||
params.prim_path_mask = prim_path_mask;
|
||||
params.import_subdiv = import_subdiv;
|
||||
params.import_instance_proxies = import_instance_proxies;
|
||||
params.support_scene_instancing = support_scene_instancing;
|
||||
params.create_collection = create_collection;
|
||||
params.import_guide = import_guide;
|
||||
params.import_proxy = import_proxy;
|
||||
@ -593,7 +593,7 @@ static void wm_usd_import_draw(bContext * /*C*/, wmOperator *op)
|
||||
uiItemR(col, ptr, "read_mesh_attributes", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
col = uiLayoutColumnWithHeading(box, true, IFACE_("Include"));
|
||||
uiItemR(col, ptr, "import_subdiv", UI_ITEM_NONE, IFACE_("Subdivision"), ICON_NONE);
|
||||
uiItemR(col, ptr, "import_instance_proxies", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
uiItemR(col, ptr, "support_scene_instancing", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
uiItemR(col, ptr, "import_visible_only", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
uiItemR(col, ptr, "import_guide", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
uiItemR(col, ptr, "import_proxy", UI_ITEM_NONE, nullptr, ICON_NONE);
|
||||
@ -688,10 +688,10 @@ void WM_OT_usd_import(wmOperatorType *ot)
|
||||
"SubdivisionScheme attribute");
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"import_instance_proxies",
|
||||
"support_scene_instancing",
|
||||
true,
|
||||
"Import Instance Proxies",
|
||||
"Create unique Blender objects for USD instances");
|
||||
"Scene Instancing",
|
||||
"Import USD scene graph instances as collection instances");
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"import_visible_only",
|
||||
|
@ -99,6 +99,7 @@ set(SRC
|
||||
intern/usd_reader_camera.cc
|
||||
intern/usd_reader_curve.cc
|
||||
intern/usd_reader_geom.cc
|
||||
intern/usd_reader_instance.cc
|
||||
intern/usd_reader_light.cc
|
||||
intern/usd_reader_material.cc
|
||||
intern/usd_reader_mesh.cc
|
||||
@ -133,6 +134,7 @@ set(SRC
|
||||
intern/usd_reader_camera.h
|
||||
intern/usd_reader_curve.h
|
||||
intern/usd_reader_geom.h
|
||||
intern/usd_reader_instance.h
|
||||
intern/usd_reader_light.h
|
||||
intern/usd_reader_material.h
|
||||
intern/usd_reader_mesh.h
|
||||
|
@ -395,11 +395,18 @@ static void import_endjob(void *customdata)
|
||||
|
||||
lc = BKE_layer_collection_get_active(view_layer);
|
||||
|
||||
/* Create prototype collections for instancing. */
|
||||
data->archive->create_proto_collections(data->bmain, lc->collection);
|
||||
|
||||
/* Add all objects to the collection. */
|
||||
for (USDPrimReader *reader : data->archive->readers()) {
|
||||
if (!reader) {
|
||||
continue;
|
||||
}
|
||||
if (reader->prim().IsInPrototype()) {
|
||||
/* Skip prototype prims, as these are added to prototype collections. */
|
||||
continue;
|
||||
}
|
||||
Object *ob = reader->object();
|
||||
if (!ob) {
|
||||
continue;
|
||||
|
56
source/blender/io/usd/intern/usd_reader_instance.cc
Normal file
@ -0,0 +1,56 @@
|
||||
/* SPDX-FileCopyrightText: 2023 NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "usd_reader_instance.h"
|
||||
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_object.hh"
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
namespace blender::io::usd {
|
||||
makowalski marked this conversation as resolved
|
||||
|
||||
USDInstanceReader::USDInstanceReader(const pxr::UsdPrim &prim,
|
||||
const USDImportParams &import_params,
|
||||
const ImportSettings &settings)
|
||||
: USDXformReader(prim, import_params, settings)
|
||||
{
|
||||
}
|
||||
|
||||
bool USDInstanceReader::valid() const
|
||||
{
|
||||
return prim_.IsValid() && prim_.IsInstance();
|
||||
}
|
||||
|
||||
void USDInstanceReader::create_object(Main *bmain, const double /* motionSampleTime */)
|
||||
{
|
||||
this->object_ = BKE_object_add_only_object(bmain, OB_EMPTY, name_.c_str());
|
||||
this->object_->data = nullptr;
|
||||
this->object_->instance_collection = nullptr;
|
||||
this->object_->transflag |= OB_DUPLICOLLECTION;
|
||||
}
|
||||
|
||||
void USDInstanceReader::set_instance_collection(Collection *coll)
|
||||
{
|
||||
if (this->object_ && this->object_->instance_collection != coll) {
|
||||
if (this->object_->instance_collection) {
|
||||
id_us_min(&this->object_->instance_collection->id);
|
||||
this->object_->instance_collection = nullptr;
|
||||
}
|
||||
id_us_plus(&coll->id);
|
||||
this->object_->instance_collection = coll;
|
||||
}
|
||||
}
|
||||
|
||||
pxr::SdfPath USDInstanceReader::proto_path() const
|
||||
{
|
||||
if (pxr::UsdPrim proto = prim_.GetPrototype()) {
|
||||
return proto.GetPath();
|
||||
}
|
||||
|
||||
return pxr::SdfPath();
|
||||
}
|
||||
|
||||
} // namespace blender::io::usd
|
42
source/blender/io/usd/intern/usd_reader_instance.h
Normal file
@ -0,0 +1,42 @@
|
||||
/* SPDX-FileCopyrightText: 2023 NVIDIA Corporation. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "usd_reader_xform.h"
|
||||
|
||||
#include <pxr/usd/usdGeom/xform.h>
|
||||
|
||||
struct Collection;
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
||||
/**
|
||||
* Convert a USD instanced prim to a blender collection instance.
|
||||
*/
|
||||
class USDInstanceReader : public USDXformReader {
|
||||
|
||||
public:
|
||||
USDInstanceReader(const pxr::UsdPrim &prim,
|
||||
const USDImportParams &import_params,
|
||||
const ImportSettings &settings);
|
||||
|
||||
bool valid() const override;
|
||||
|
||||
/**
|
||||
* Create an object that instances a collection.
|
||||
*/
|
||||
void create_object(Main *bmain, double motionSampleTime) override;
|
||||
|
||||
/**
|
||||
* Assign the given collection to the object.
|
||||
*/
|
||||
void set_instance_collection(Collection *coll);
|
||||
|
||||
/**
|
||||
* Get the path of the USD prototype prim.
|
||||
*/
|
||||
pxr::SdfPath proto_path() const;
|
||||
};
|
||||
|
||||
} // namespace blender::io::usd
|
@ -1144,11 +1144,7 @@ std::string USDMeshReader::get_skeleton_path() const
|
||||
return "";
|
||||
}
|
||||
|
||||
pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI::Apply(prim_);
|
||||
|
||||
if (!skel_api) {
|
||||
return "";
|
||||
}
|
||||
pxr::UsdSkelBindingAPI skel_api(prim_);
|
||||
|
||||
if (pxr::UsdSkelSkeleton skel = skel_api.GetInheritedSkeleton()) {
|
||||
return skel.GetPath().GetAsString();
|
||||
@ -1166,8 +1162,9 @@ std::optional<XformResult> USDMeshReader::get_local_usd_xform(const float time)
|
||||
return USDXformReader::get_local_usd_xform(time);
|
||||
}
|
||||
|
||||
if (pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI::Apply(prim_)) {
|
||||
if (skel_api.GetGeomBindTransformAttr().HasAuthoredValue()) {
|
||||
pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI(prim_);
|
||||
if (pxr::UsdAttribute xf_attr = skel_api.GetGeomBindTransformAttr()) {
|
||||
if (xf_attr.HasAuthoredValue()) {
|
||||
pxr::GfMatrix4d bind_xf;
|
||||
if (skel_api.GetGeomBindTransformAttr().Get(&bind_xf)) {
|
||||
/* The USD bind transform is a matrix of doubles,
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "usd_reader_stage.h"
|
||||
#include "usd_reader_camera.h"
|
||||
#include "usd_reader_curve.h"
|
||||
#include "usd_reader_instance.h"
|
||||
#include "usd_reader_light.h"
|
||||
#include "usd_reader_material.h"
|
||||
#include "usd_reader_mesh.h"
|
||||
@ -42,16 +43,60 @@
|
||||
#include "BLI_sort.hh"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_modifier.hh"
|
||||
#include "BKE_report.h"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "DNA_collection_types.h"
|
||||
#include "DNA_material_types.h"
|
||||
|
||||
#include "WM_api.hh"
|
||||
|
||||
static CLG_LogRef LOG = {"io.usd"};
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
||||
/**
|
||||
* Create a collection with the given parent and name.
|
||||
*/
|
||||
static Collection *create_collection(Main *bmain, Collection *parent, const char *name)
|
||||
{
|
||||
if (!bmain) {
|
||||
return nullptr;
|
||||
}
|
||||
makowalski marked this conversation as resolved
Bastien Montagne
commented
Is that depsgraph tagging actually needed? Afaik newly created data does not exist in the depsgraph, so it is automatically fully evaluated on the next update? In fact, I think it would be much more correct to tag the parent collection, since that one sees its hierarchy modified (and also rather use Is that depsgraph tagging actually needed? Afaik newly created data does not exist in the depsgraph, so it is automatically fully evaluated on the next update?
In fact, I think it would be much more correct to tag the _parent_ collection, since that one sees its hierarchy modified (and also rather use `ID_RECALC_HIERARCHY`).
|
||||
|
||||
makowalski marked this conversation as resolved
Jesse Yurkovich
commented
I want to say that setting the fake user for collections isn't really necessary but will need Bastien to weigh in. I believe they'll always have a real user because there's always a 'parent' collection available. I want to say that setting the fake user for collections isn't really necessary but will need Bastien to weigh in. I believe they'll always have a real user because there's always a 'parent' collection available.
Michael Kowalski
commented
I removed the call to add the fake user. Thanks for catching this. I removed the call to add the fake user. Thanks for catching this.
|
||||
return BKE_collection_add(bmain, parent, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the instance collection on the given instance reader.
|
||||
* The collection is assigned from the given map based on
|
||||
* the prototype prim path.
|
||||
*/
|
||||
static void set_instance_collection(
|
||||
USDInstanceReader *instance_reader,
|
||||
const std::map<pxr::SdfPath, Collection *> &proto_collection_map)
|
||||
{
|
||||
if (!instance_reader) {
|
||||
return;
|
||||
}
|
||||
|
||||
pxr::SdfPath proto_path = instance_reader->proto_path();
|
||||
|
||||
std::map<pxr::SdfPath, Collection *>::const_iterator it = proto_collection_map.find(proto_path);
|
||||
|
||||
if (it != proto_collection_map.end()) {
|
||||
instance_reader->set_instance_collection(it->second);
|
||||
}
|
||||
else {
|
||||
CLOG_WARN(
|
||||
&LOG, "Couldn't find prototype collection for %s", instance_reader->prim_path().c_str());
|
||||
}
|
||||
makowalski marked this conversation as resolved
Bastien Montagne
commented
Should use Should use `CLOG` instead of 'raw' prints.
|
||||
}
|
||||
|
||||
USDStageReader::USDStageReader(pxr::UsdStageRefPtr stage,
|
||||
const USDImportParams ¶ms,
|
||||
const ImportSettings &settings)
|
||||
@ -61,6 +106,7 @@ USDStageReader::USDStageReader(pxr::UsdStageRefPtr stage,
|
||||
|
||||
USDStageReader::~USDStageReader()
|
||||
{
|
||||
clear_proto_readers();
|
||||
clear_readers();
|
||||
}
|
||||
|
||||
@ -78,6 +124,9 @@ bool USDStageReader::is_primitive_prim(const pxr::UsdPrim &prim) const
|
||||
|
||||
USDPrimReader *USDStageReader::create_reader_if_allowed(const pxr::UsdPrim &prim)
|
||||
{
|
||||
if (params_.support_scene_instancing && prim.IsInstance()) {
|
||||
return new USDInstanceReader(prim, params_, settings_);
|
||||
}
|
||||
if (params_.import_shapes && is_primitive_prim(prim)) {
|
||||
return new USDShapeReader(prim, params_, settings_);
|
||||
}
|
||||
@ -117,6 +166,9 @@ USDPrimReader *USDStageReader::create_reader_if_allowed(const pxr::UsdPrim &prim
|
||||
|
||||
USDPrimReader *USDStageReader::create_reader(const pxr::UsdPrim &prim)
|
||||
{
|
||||
if (params_.support_scene_instancing && prim.IsInstance()) {
|
||||
return new USDInstanceReader(prim, params_, settings_);
|
||||
}
|
||||
if (is_primitive_prim(prim)) {
|
||||
return new USDShapeReader(prim, params_, settings_);
|
||||
}
|
||||
@ -249,7 +301,9 @@ static bool merge_with_parent(USDPrimReader *reader)
|
||||
return true;
|
||||
}
|
||||
|
||||
USDPrimReader *USDStageReader::collect_readers(Main *bmain, const pxr::UsdPrim &prim)
|
||||
USDPrimReader *USDStageReader::collect_readers(Main *bmain,
|
||||
const pxr::UsdPrim &prim,
|
||||
std::vector<USDPrimReader *> &r_readers)
|
||||
{
|
||||
if (prim.IsA<pxr::UsdGeomImageable>()) {
|
||||
pxr::UsdGeomImageable imageable(prim);
|
||||
@ -265,7 +319,7 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain, const pxr::UsdPrim &
|
||||
|
||||
pxr::Usd_PrimFlagsPredicate filter_predicate = pxr::UsdPrimDefaultPredicate;
|
||||
|
||||
if (params_.import_instance_proxies) {
|
||||
if (!params_.support_scene_instancing) {
|
||||
filter_predicate = pxr::UsdTraverseInstanceProxies(filter_predicate);
|
||||
}
|
||||
|
||||
@ -274,7 +328,7 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain, const pxr::UsdPrim &
|
||||
std::vector<USDPrimReader *> child_readers;
|
||||
|
||||
for (const auto &childPrim : children) {
|
||||
if (USDPrimReader *child_reader = collect_readers(bmain, childPrim)) {
|
||||
if (USDPrimReader *child_reader = collect_readers(bmain, childPrim, r_readers)) {
|
||||
child_readers.push_back(child_reader);
|
||||
}
|
||||
}
|
||||
@ -316,7 +370,7 @@ USDPrimReader *USDStageReader::collect_readers(Main *bmain, const pxr::UsdPrim &
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
readers_.push_back(reader);
|
||||
r_readers.push_back(reader);
|
||||
reader->incref();
|
||||
|
||||
/* Set each child reader's parent. */
|
||||
@ -334,12 +388,29 @@ void USDStageReader::collect_readers(Main *bmain)
|
||||
}
|
||||
|
||||
clear_readers();
|
||||
clear_proto_readers();
|
||||
|
||||
/* Iterate through the stage. */
|
||||
pxr::UsdPrim root = stage_->GetPseudoRoot();
|
||||
|
||||
stage_->SetInterpolationType(pxr::UsdInterpolationType::UsdInterpolationTypeHeld);
|
||||
collect_readers(bmain, root);
|
||||
collect_readers(bmain, root, readers_);
|
||||
|
||||
if (params_.support_scene_instancing) {
|
||||
/* Collect the scenegraph instance prototypes. */
|
||||
std::vector<pxr::UsdPrim> protos = stage_->GetPrototypes();
|
||||
|
||||
makowalski marked this conversation as resolved
Outdated
Matt McLin
commented
Not so important to me, but just observation that now that scene instances are supported, this reads rather strange, and it may be a good idea to change the name and meaning of the underlying variable. E.g.,
Not so important to me, but just observation that now that scene instances are supported, this reads rather strange, and it may be a good idea to change the name and meaning of the underlying variable.
E.g.,
`if (params_.support_scene_instancing) {`
Michael Kowalski
commented
You make a good point. If I understand your idea correctly, we'd still have just one import option related to instancing: "Convert Instances to Copies", as you suggested above. But the Is that correct? You make a good point.
If I understand your idea correctly, we'd still have just one import option related to instancing: "Convert Instances to Copies", as you suggested above.
But the `params_.import_instance_proxies` variable would be renamed to `params_.support_scene_instancing`, which would be set to `true` if the "Convert Instances to Copies" option is off.
Is that correct?
Michael Kowalski
commented
Per discussion with Matt today, I will replace the "Convert Instances to Copies" option with a "Support Scene Instancing" option in the UI and import params. Per discussion with Matt today, I will replace the "Convert Instances to Copies" option with a "Support Scene Instancing" option in the UI and import params.
Michael Kowalski
commented
I replaced the I replaced the `Import Instance Proxies` with a new `Scene Instancing` option.
|
||||
for (const pxr::UsdPrim &proto_prim : protos) {
|
||||
std::vector<USDPrimReader *> proto_readers;
|
||||
collect_readers(bmain, proto_prim, proto_readers);
|
||||
proto_readers_.insert(std::make_pair(proto_prim.GetPath(), proto_readers));
|
||||
|
||||
for (USDPrimReader *reader : proto_readers) {
|
||||
readers_.push_back(reader);
|
||||
reader->incref();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void USDStageReader::process_armature_modifiers() const
|
||||
@ -466,6 +537,27 @@ void USDStageReader::clear_readers()
|
||||
readers_.clear();
|
||||
}
|
||||
|
||||
void USDStageReader::clear_proto_readers()
|
||||
{
|
||||
for (auto &pair : proto_readers_) {
|
||||
|
||||
for (USDPrimReader *reader : pair.second) {
|
||||
|
||||
if (!reader) {
|
||||
continue;
|
||||
}
|
||||
|
||||
reader->decref();
|
||||
|
||||
if (reader->refcount() == 0) {
|
||||
delete reader;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
proto_readers_.clear();
|
||||
}
|
||||
|
||||
void USDStageReader::sort_readers()
|
||||
{
|
||||
blender::parallel_sort(
|
||||
@ -476,4 +568,66 @@ void USDStageReader::sort_readers()
|
||||
});
|
||||
}
|
||||
|
||||
void USDStageReader::create_proto_collections(Main *bmain, Collection *parent_collection)
|
||||
{
|
||||
if (proto_readers_.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
Collection *all_protos_collection = create_collection(bmain, parent_collection, "prototypes");
|
||||
|
||||
if (all_protos_collection) {
|
||||
all_protos_collection->flag |= COLLECTION_HIDE_VIEWPORT;
|
||||
all_protos_collection->flag |= COLLECTION_HIDE_RENDER;
|
||||
if (parent_collection) {
|
||||
DEG_id_tag_update(&parent_collection->id, ID_RECALC_HIERARCHY);
|
||||
}
|
||||
}
|
||||
|
||||
std::map<pxr::SdfPath, Collection *> proto_collection_map;
|
||||
|
||||
for (const auto &pair : proto_readers_) {
|
||||
Collection *proto_collection = create_collection(bmain, all_protos_collection, "proto");
|
||||
|
||||
proto_collection_map.insert(std::make_pair(pair.first, proto_collection));
|
||||
}
|
||||
|
||||
/* Set the instance collections on the readers, including the prototype
|
||||
* readers (which are included in readers_), as instancing may be nested. */
|
||||
|
||||
for (USDPrimReader *reader : readers_) {
|
||||
if (USDInstanceReader *instance_reader = dynamic_cast<USDInstanceReader *>(reader)) {
|
||||
set_instance_collection(instance_reader, proto_collection_map);
|
||||
}
|
||||
}
|
||||
|
||||
/* Add the prototype objects to the collections. */
|
||||
for (const auto &pair : proto_readers_) {
|
||||
|
||||
std::map<pxr::SdfPath, Collection *>::const_iterator it = proto_collection_map.find(
|
||||
pair.first);
|
||||
|
||||
if (it == proto_collection_map.end()) {
|
||||
makowalski marked this conversation as resolved
Bastien Montagne
commented
Use Use `CLOG` instead.
|
||||
std::cerr << "WARNING: Couldn't find collection when adding objects for prototype "
|
||||
<< pair.first << std::endl;
|
||||
CLOG_WARN(&LOG,
|
||||
"Couldn't find collection when adding objects for prototype %s",
|
||||
pair.first.GetAsString().c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
for (USDPrimReader *reader : pair.second) {
|
||||
Object *ob = reader->object();
|
||||
|
||||
if (!ob) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Collection *coll = it->second;
|
||||
|
||||
BKE_collection_object_add(bmain, coll, ob);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // Namespace blender::io::usd
|
||||
|
@ -19,7 +19,11 @@ struct ImportSettings;
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
||||
typedef std::map<pxr::SdfPath, std::vector<USDPrimReader *>> ProtoReaderMap;
|
||||
/**
|
||||
* Map a USD prototype prim path to the list of readers that convert
|
||||
* the prototype data.
|
||||
*/
|
||||
using ProtoReaderMap = std::map<pxr::SdfPath, std::vector<USDPrimReader *>>;
|
||||
|
||||
class USDStageReader {
|
||||
|
||||
@ -34,6 +38,9 @@ class USDStageReader {
|
||||
* traversal, for importing unused materials. */
|
||||
std::vector<std::string> material_paths_;
|
||||
|
||||
/* Readers for scenegraph instance prototypes. */
|
||||
ProtoReaderMap proto_readers_;
|
||||
|
||||
public:
|
||||
USDStageReader(pxr::UsdStageRefPtr stage,
|
||||
const USDImportParams ¶ms,
|
||||
@ -89,6 +96,8 @@ class USDStageReader {
|
||||
|
||||
void clear_readers();
|
||||
|
||||
void clear_proto_readers();
|
||||
|
||||
const std::vector<USDPrimReader *> &readers() const
|
||||
{
|
||||
return readers_;
|
||||
@ -96,8 +105,15 @@ class USDStageReader {
|
||||
|
||||
void sort_readers();
|
||||
|
||||
/**
|
||||
* Create prototype collections for instancing by the USD instance readers.
|
||||
*/
|
||||
void create_proto_collections(Main *bmain, Collection *parent_collection);
|
||||
|
||||
private:
|
||||
USDPrimReader *collect_readers(Main *bmain, const pxr::UsdPrim &prim);
|
||||
USDPrimReader *collect_readers(Main *bmain,
|
||||
const pxr::UsdPrim &prim,
|
||||
std::vector<USDPrimReader *> &r_readers);
|
||||
|
||||
/**
|
||||
* Returns true if the given prim should be included in the
|
||||
|
@ -354,12 +354,7 @@ void import_blendshapes(Main *bmain,
|
||||
return;
|
||||
}
|
||||
|
||||
pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI::Apply(prim);
|
||||
|
||||
if (!skel_api) {
|
||||
/* No skel binding. */
|
||||
return;
|
||||
}
|
||||
pxr::UsdSkelBindingAPI skel_api(prim);
|
||||
|
||||
/* Get the blend shape targets, which are the USD paths to the
|
||||
* blend shape primitives. */
|
||||
@ -538,14 +533,16 @@ void import_blendshapes(Main *bmain,
|
||||
return;
|
||||
}
|
||||
|
||||
skel_api = pxr::UsdSkelBindingAPI::Apply(skel_prim.GetPrim());
|
||||
|
||||
if (!skel_api) {
|
||||
return;
|
||||
}
|
||||
skel_api = pxr::UsdSkelBindingAPI(skel_prim.GetPrim());
|
||||
|
||||
pxr::UsdPrim anim_prim = skel_api.GetInheritedAnimationSource();
|
||||
|
||||
if (!anim_prim) {
|
||||
/* Querying the directly bound animation source may be necessary
|
||||
* if the prim does not have an applied skel binding API schema. */
|
||||
skel_api.GetAnimationSource(&anim_prim);
|
||||
}
|
||||
|
||||
if (!anim_prim) {
|
||||
return;
|
||||
}
|
||||
@ -896,11 +893,7 @@ void import_mesh_skel_bindings(Main *bmain,
|
||||
return;
|
||||
}
|
||||
|
||||
pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI::Apply(prim);
|
||||
|
||||
if (!skel_api) {
|
||||
return;
|
||||
}
|
||||
pxr::UsdSkelBindingAPI skel_api(prim);
|
||||
|
||||
pxr::UsdSkelSkeleton skel = skel_api.GetInheritedSkeleton();
|
||||
|
||||
|
@ -100,7 +100,7 @@ struct USDImportParams {
|
||||
bool import_blendshapes;
|
||||
char *prim_path_mask;
|
||||
bool import_subdiv;
|
||||
bool import_instance_proxies;
|
||||
bool support_scene_instancing;
|
||||
bool create_collection;
|
||||
bool import_guide;
|
||||
bool import_proxy;
|
||||
|
unused include
Thanks for spotting this!