42 pxr::UsdStageRefPtr stage,
54 switch (object->
type) {
61 return !params_.export_meshes;
63 return !params_.export_cameras;
65 return !params_.export_lights;
68 return !params_.export_curves;
70 return !params_.export_volumes;
72 return !params_.export_armatures;
74 return !params_.export_points;
96 skinned_mesh_export_map_,
97 shape_key_mesh_export_map_,
106 export_time_ = pxr::UsdTimeCode(frame_nr);
113 path = pxr::SdfPath(params_.
root_prim_path + context->export_path);
116 path = pxr::SdfPath(context->export_path);
119 if (params_.
merge_parent_xform && context->is_object_data_context && !context->is_parent) {
120 bool can_merge_with_xform =
true;
122 can_merge_with_xform =
false;
125 if (params_.
use_instancing && (context->is_prototype() || context->is_instance())) {
126 can_merge_with_xform =
false;
129 if (can_merge_with_xform) {
130 path = path.GetParentPath();
136 const pxr::SdfLayerHandle root_layer = stage_->GetRootLayer();
137 const std::string export_file_path = root_layer->GetRealPath();
138 auto get_time_code = [
this]() {
return this->export_time_; };
140 USDExporterContext exporter_context = USDExporterContext{
141 bmain_,
depsgraph_, stage_, path, get_time_code, params_, export_file_path,
nullptr};
146 this->add_usd_skel_export_mapping(obj, usd_path);
149 return exporter_context;
162 bool is_referencing_self =
false;
163 if (context->is_point_instancer()) {
168 pxr::SdfPath instancer_path;
169 if (!params_.root_prim_path.empty()) {
170 instancer_path = pxr::SdfPath(params_.root_prim_path + context->export_path);
173 instancer_path = pxr::SdfPath(context->export_path);
176 if (children !=
nullptr) {
178 if (!child_context->original_export_path.empty()) {
179 const pxr::SdfPath parent_export_path(context->export_path);
180 const pxr::SdfPath children_original_export_path(child_context->original_export_path);
183 if (parent_export_path.HasPrefix(children_original_export_path)) {
184 is_referencing_self =
true;
189 pxr::SdfPath prototype_path;
190 if (child_context->is_instance() && child_context->duplicator !=
nullptr) {
193 if (!params_.root_prim_path.empty()) {
194 prototype_path = pxr::SdfPath(params_.root_prim_path +
195 child_context->original_export_path);
198 prototype_path = pxr::SdfPath(child_context->original_export_path);
201 prototype_paths_.lookup_or_add(instancer_path, {})
202 .
add(std::make_pair(prototype_path, child_context->object));
203 child_context->is_point_instance =
true;
208 if (!params_.root_prim_path.empty()) {
209 prototype_path = pxr::SdfPath(params_.root_prim_path + child_context->export_path);
212 prototype_path = pxr::SdfPath(child_context->export_path);
215 prototype_paths_.lookup_or_add(instancer_path, {})
216 .
add(std::make_pair(prototype_path, child_context->object));
217 child_context->is_point_proto =
true;
225 if (is_referencing_self) {
227 params_.worker_status->reports,
229 "One or more objects used as prototypes in 'Instance on Points' nodes either do not "
230 "have 'As Instance' enabled in their 'Object Info' nodes, or the prototype is the "
231 "base geometry input itself. Both cases prevent valid point instancer export. If it's "
232 "the former, enable 'As Instance' to avoid incorrect self-referencing.");
240 child_context->is_point_instance =
false;
241 child_context->is_point_proto =
false;
246 return !is_referencing_self;
254 if (params_.use_instancing) {
271 usd_export_context.
usd_path.GetParentPath());
272 const bool use_point_instancing = context->is_point_instancer() &&
273 (proto_paths && !proto_paths->
is_empty());
275 switch (context->object->type) {
278 if (params_.use_instancing && use_point_instancing) {
281 std::unique_ptr<USDMeshWriter> mesh_writer = std::make_unique<USDMeshWriter>(
285 usd_export_context, *proto_paths, std::move(mesh_writer));
320 if (params_.use_instancing && use_point_instancing) {
323 std::unique_ptr<USDCurvesWriter> curves_writer = std::make_unique<USDCurvesWriter>(
327 usd_export_context, *proto_paths, std::move(curves_writer));
355 if (params_.use_instancing && use_point_instancing) {
357 context, usd_export_context);
358 std::unique_ptr<USDPointsWriter> point_cloud_writer = std::make_unique<USDPointsWriter>(
359 point_cloud_context);
362 usd_export_context, *proto_paths, std::move(point_cloud_writer));
389 if (data_writer && !data_writer->
is_supported(context)) {
394 if (data_writer && (params_.export_armatures || params_.export_shapekeys)) {
395 add_usd_skel_export_mapping(context->object, data_writer->
usd_path());
403 if (!params_.export_hair) {
406 return new USDHairWriter(create_usd_export_context(context));
419 return !(params_.use_instancing && context->is_instance());
426 return !(params_.use_instancing && context->is_instance());
429void USDHierarchyIterator::add_usd_skel_export_mapping(
const Object *
obj,
const pxr::SdfPath &path)
432 shape_key_mesh_export_map_.
add(
obj, path);
436 armature_export_map_.
add(
obj, path);
442 skinned_mesh_export_map_.
add(obj, path);
450 std::string base_name = std::string(
BKE_id_name(
context->object->id)).append(
"_base");
451 std::string safe_name =
make_safe_name(base_name, export_context.export_params.allow_unicode);
453 pxr::SdfPath base_path = export_context.usd_path.GetParentPath().AppendChild(
454 pxr::TfToken(safe_name));
456 return {export_context.bmain,
457 export_context.depsgraph,
458 export_context.stage,
460 export_context.get_time_code,
461 export_context.export_params,
462 export_context.export_file_path,
463 export_context.export_image_fn,
464 export_context.add_skel_mapping_fn};
const char * BKE_id_name(const ID &id)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
Object is a sort of wrapper for general info.
#define BASE_SELECTED(v3d, base)
BPy_StructRNA * depsgraph
bool add(const Key &key, const Value &value)
ExportChildren * graph_children(const HierarchyContext *context)
AbstractHierarchyIterator(Main *bmain, Depsgraph *depsgraph)
blender::Set< HierarchyContext * > ExportChildren
const pxr::SdfPath & usd_path() const
virtual bool is_supported(const HierarchyContext *context) const
bool mark_as_weak_export(const Object *object) const override
AbstractHierarchyWriter * create_data_writer(const HierarchyContext *context) override
void release_writer(AbstractHierarchyWriter *writer) override
bool determine_point_instancers(const HierarchyContext *context)
AbstractHierarchyWriter * create_particle_writer(const HierarchyContext *context) override
void process_usd_skel() const
USDHierarchyIterator(Main *bmain, Depsgraph *depsgraph, pxr::UsdStageRefPtr stage, const USDExportParams ¶ms)
AbstractHierarchyWriter * create_hair_writer(const HierarchyContext *context) override
bool include_child_writers(const HierarchyContext *context) const override
bool include_data_writers(const HierarchyContext *context) const override
std::string make_valid_name(const std::string &name) const override
AbstractHierarchyWriter * create_transform_writer(const HierarchyContext *context) override
void set_export_frame(float frame_nr)
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
int context(const bContext *C, const char *member, bContextDataResult *result)
void skel_export_chaser(pxr::UsdStageRefPtr stage, const ObjExportMap &armature_export_map, const ObjExportMap &skinned_mesh_export_map, const ObjExportMap &shape_key_mesh_export_map, const Depsgraph *depsgraph)
std::string make_safe_name(const StringRef name, bool allow_unicode)
void create_skel_roots(pxr::UsdStageRefPtr stage, const USDExportParams ¶ms)
bool can_export_skinned_mesh(const Object &obj, const Depsgraph *depsgraph)
bool is_mesh_with_shape_keys(const Object *obj)
std::string root_prim_path
std::function< void(const Object *, const pxr::SdfPath &)> add_skel_mapping_fn
const USDExportParams & export_params
const pxr::SdfPath usd_path