23#include <pxr/usd/usdGeom/camera.h>
24#include <pxr/usd/usdGeom/capsule.h>
25#include <pxr/usd/usdGeom/cone.h>
26#include <pxr/usd/usdGeom/cube.h>
27#include <pxr/usd/usdGeom/cylinder.h>
28#include <pxr/usd/usdGeom/mesh.h>
29#include <pxr/usd/usdGeom/nurbsCurves.h>
30#include <pxr/usd/usdGeom/pointInstancer.h>
31#include <pxr/usd/usdGeom/points.h>
32#include <pxr/usd/usdGeom/scope.h>
33#include <pxr/usd/usdGeom/sphere.h>
34#include <pxr/usd/usdGeom/xform.h>
35#include <pxr/usd/usdLux/boundableLightBase.h>
36#include <pxr/usd/usdLux/nonboundableLightBase.h>
37#include <pxr/usd/usdShade/material.h>
54#include <fmt/format.h>
94 if (!instance_reader) {
98 pxr::SdfPath proto_path = instance_reader->
proto_path();
101 if (collection !=
nullptr) {
106 &
LOG,
"Couldn't find prototype collection for %s", instance_reader->
prim_path().c_str());
113 : stage_(
stage), params_(
params), settings_(settings)
127bool USDStageReader::is_primitive_prim(
const pxr::UsdPrim &prim)
const
129 return (prim.IsA<pxr::UsdGeomCapsule>() || prim.IsA<pxr::UsdGeomCylinder>() ||
130 prim.IsA<pxr::UsdGeomCone>() || prim.IsA<pxr::UsdGeomCube>() ||
131 prim.IsA<pxr::UsdGeomSphere>());
142 if (prim.IsA<pxr::UsdGeomPointInstancer>()) {
162 (prim.IsA<pxr::UsdLuxBoundableLightBase>() || prim.IsA<pxr::UsdLuxNonboundableLightBase>()))
175 if (prim.IsA<pxr::UsdGeomImageable>()) {
187 if (is_primitive_prim(prim)) {
190 if (prim.IsA<pxr::UsdGeomCamera>()) {
193 if (prim.IsA<pxr::UsdGeomBasisCurves>()) {
196 if (prim.IsA<pxr::UsdGeomNurbsCurves>()) {
199 if (prim.IsA<pxr::UsdGeomMesh>()) {
202 if (prim.IsA<pxr::UsdLuxDomeLight>()) {
206 if (prim.IsA<pxr::UsdLuxBoundableLightBase>() || prim.IsA<pxr::UsdLuxNonboundableLightBase>()) {
209 if (prim.IsA<pxr::UsdVolVolume>()) {
212 if (prim.IsA<pxr::UsdSkelSkeleton>()) {
215 if (prim.IsA<pxr::UsdGeomPoints>()) {
218 if (prim.IsA<pxr::UsdGeomImageable>()) {
224bool USDStageReader::include_by_visibility(
const pxr::UsdGeomImageable &imageable)
const
231 pxr::UsdAttribute visibility_attr = imageable.GetVisibilityAttr();
233 if (!visibility_attr) {
240 if (visibility_attr.ValueMightBeTimeVarying()) {
244 pxr::TfToken visibility;
245 visibility_attr.Get(&visibility);
246 return visibility != pxr::UsdGeomTokens->invisible;
249bool USDStageReader::include_by_purpose(
const pxr::UsdGeomImageable &imageable)
const
261 pxr::UsdAttribute purpose_attr = imageable.GetPurposeAttr();
268 pxr::TfToken purpose;
269 purpose_attr.Get(&purpose);
271 if (purpose == pxr::UsdGeomTokens->guide) {
274 if (purpose == pxr::UsdGeomTokens->proxy) {
277 if (purpose == pxr::UsdGeomTokens->render) {
301 if (!xform_reader->
prim().GetParent().IsA<pxr::UsdGeomXform>()) {
306 if (xform_reader->
prim().IsA<pxr::UsdGeomXform>() ||
307 xform_reader->
prim().IsA<pxr::UsdGeomScope>())
325 const bool defined_prims_only,
328 if (prim.IsA<pxr::UsdGeomImageable>()) {
329 pxr::UsdGeomImageable imageable(prim);
331 if (!include_by_purpose(imageable)) {
335 if (!include_by_visibility(imageable)) {
340 if (prim.IsA<pxr::UsdLuxDomeLight>()) {
344 pxr::Usd_PrimFlagsConjunction filter_flags = pxr::UsdPrimIsActive && pxr::UsdPrimIsLoaded &&
345 !pxr::UsdPrimIsAbstract;
347 if (defined_prims_only) {
348 filter_flags &= pxr::UsdPrimIsDefined;
351 pxr::Usd_PrimFlagsPredicate filter_predicate(filter_flags);
353 filter_predicate = pxr::UsdTraverseInstanceProxies(filter_predicate);
358 pxr::UsdPrimSiblingRange children = prim.GetFilteredChildren(filter_predicate);
360 for (
const auto &child_prim : children) {
361 if (pruned_prims.contains(child_prim.GetPath())) {
365 child_prim, pruned_prims, defined_prims_only, r_readers))
367 child_readers.
append(child_reader);
371 if (prim.IsPseudoRoot()) {
384 if (child_readers.
size() == 1) {
386 USDPrimReader *child_reader = child_readers.
first();
393 if (prim.IsA<pxr::UsdShadeMaterial>()) {
412 for (USDPrimReader *child_reader : child_readers) {
413 child_reader->parent(reader);
430 UsdPathSet instancer_proto_paths = collect_point_instancer_proto_paths();
433 pxr::UsdPrim root =
stage_->GetPseudoRoot();
435 stage_->SetInterpolationType(pxr::UsdInterpolationType::UsdInterpolationTypeHeld);
442 std::vector<pxr::UsdPrim> protos =
stage_->GetPrototypes();
444 for (
const pxr::UsdPrim &proto_prim : protos) {
446 collect_readers(proto_prim, instancer_proto_paths,
true, proto_readers);
456 if (!instancer_proto_paths.
is_empty()) {
457 create_point_instancer_proto_readers(instancer_proto_paths);
469 usd_path_to_armature.
add(reader->prim_path(), reader->object());
475 if (!reader->object()) {
493 if (
object ==
nullptr) {
496 "%s: Couldn't find armature object corresponding to USD skeleton %s",
516 pxr::UsdPrim prim =
stage_->GetPrimAtPath(pxr::SdfPath(mtl_path));
518 pxr::UsdShadeMaterial usd_mtl(prim);
542 prim.GetPath().GetAsString()) = mtl_name;
553 if (mat ==
nullptr) {
557 if (mat->
id.
us == 0) {
589 const char *na = a ? a->name().c_str() :
"";
590 const char *nb = b ? b->name().c_str() :
"";
591 return BLI_strcasecmp(na, nb) < 0;
603 if (all_protos_collection) {
606 if (parent_collection) {
616 proto_collection_map.
add(path, proto_collection);
631 if (collection ==
nullptr) {
633 "Couldn't find collection when adding objects for prototype %s",
634 item.key.GetAsString().c_str());
639 Object *ob = reader->object();
667 if (!instancer_reader) {
671 const pxr::SdfPath &instancer_path = reader->
prim().GetPath();
673 bmain, all_protos_collection, instancer_path.GetName().c_str());
681 for (
const pxr::SdfPath &proto_path : instancer_reader->
proto_paths()) {
685 std::string coll_name = fmt::format(
"proto_{0:0{1}}", proto_index, max_index_digits);
692 Object *ob = proto->object();
705void USDStageReader::create_point_instancer_proto_readers(
const UsdPathSet &proto_paths)
711 for (
const pxr::SdfPath &path : proto_paths) {
713 pxr::UsdPrim proto_prim =
stage_->GetPrimAtPath(path);
727 for (USDPrimReader *reader : proto_readers) {
728 reader->set_is_in_instancer_proto(
true);
735void USDStageReader::collect_point_instancer_proto_paths(
const pxr::UsdPrim &prim,
741 pxr::Usd_PrimFlagsConjunction filter_flags = pxr::UsdPrimIsActive && pxr::UsdPrimIsLoaded &&
742 !pxr::UsdPrimIsAbstract;
744 pxr::UsdPrimSiblingRange children = prim.GetFilteredChildren(filter_flags);
746 for (
const auto &child_prim : children) {
747 if (pxr::UsdGeomPointInstancer instancer = pxr::UsdGeomPointInstancer(child_prim)) {
750 if (!include_by_purpose(instancer)) {
753 if (!include_by_visibility(instancer)) {
757 pxr::SdfPathVector paths;
758 instancer.GetPrototypesRel().GetTargets(&paths);
759 for (
const pxr::SdfPath &path : paths) {
764 collect_point_instancer_proto_paths(child_prim, r_paths);
768UsdPathSet USDStageReader::collect_point_instancer_proto_paths()
const
776 collect_point_instancer_proto_paths(
stage_->GetPseudoRoot(), result);
778 std::vector<pxr::UsdPrim> protos =
stage_->GetPrototypes();
780 for (
const pxr::UsdPrim &proto_prim : protos) {
781 collect_point_instancer_proto_paths(proto_prim, result);
Collection * BKE_collection_add(Main *bmain, Collection *collection_parent, const char *name_custom)
bool BKE_collection_object_add(Main *bmain, Collection *collection, Object *ob)
void id_fake_user_set(ID *id)
ModifierData * BKE_modifiers_findby_type(const Object *ob, ModifierType type)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert_msg(a, msg)
MINLINE int integer_digits_i(int i)
#define CLOG_WARN(clg_ref,...)
void DEG_id_tag_update(ID *id, unsigned int flags)
Object groups, one object can be in many groups at once.
@ COLLECTION_HIDE_VIEWPORT
Value & lookup_or_add_default(const Key &key)
bool add(const Key &key, const Value &value)
Value lookup_default(const Key &key, const Value &default_value) const
ItemIterator items() const
void append(const T &value)
pxr::SdfPath proto_path() const
void set_instance_collection(Collection *coll)
Material * add_material(const pxr::UsdShadeMaterial &usd_material) const
std::string get_skeleton_path() const
pxr::SdfPathVector proto_paths() const
void set_collection(Main *bmain, Collection &coll)
const std::string & prim_path() const
const pxr::UsdPrim & prim() const
ReportList * reports() const
ProtoReaderMap proto_readers_
USDPrimReader * create_reader(const pxr::UsdPrim &prim)
void fake_users_for_unused_materials()
blender::Vector< pxr::UsdLuxDomeLight > dome_lights_
USDPrimReader * create_reader_if_allowed(const pxr::UsdPrim &prim)
blender::Vector< USDPrimReader * > readers_
pxr::UsdStageRefPtr stage_
blender::Vector< std::string > material_paths_
ProtoReaderMap instancer_proto_readers_
void create_proto_collections(Main *bmain, Collection *parent_collection)
void process_armature_modifiers() const
USDStageReader(pxr::UsdStageRefPtr stage, const USDImportParams ¶ms, const ImportSettings &settings)
void import_all_materials(struct Main *bmain)
local_group_size(16, 16) .push_constant(Type b
void build_material_map(const Main *bmain, blender::Map< std::string, Material * > *r_mat_map)
blender::Set< pxr::SdfPath > UsdPathSet
static void decref(USDPrimReader *reader)
std::string make_safe_name(const std::string &name, bool allow_unicode)
Material * find_existing_material(const pxr::SdfPath &usd_mat_path, const USDImportParams ¶ms, const blender::Map< std::string, Material * > &mat_map, const blender::Map< std::string, std::string > &usd_path_to_mat_name)
static Collection * create_collection(Main *bmain, Collection *parent, const char *name)
static void set_instance_collection(USDInstanceReader *instance_reader, const blender::Map< pxr::SdfPath, Collection * > &proto_collection_map)
@ USD_MTL_NAME_COLLISION_MAKE_UNIQUE
static bool merge_with_parent(USDPrimReader *reader)
void parallel_sort(RandomAccessIterator begin, RandomAccessIterator end)
blender::Map< std::string, Material * > mat_name_to_mat
blender::Map< std::string, std::string > usd_path_to_mat_name
eUSDMtlNameCollisionMode mtl_name_collision_mode
bool support_scene_instancing