71 base_flag =
object->base_flag;
78 object->base_flag = base_flag;
87 : writer_(writer), newly_created_(newly_created)
106 return newly_created_;
109EnsuredWriter::operator bool()
const
111 return writer_ !=
nullptr;
121 Object *
object = context.object;
149 const RigidBodyOb *rbo = context.object->rigidbody_object;
155 const RigidBodyOb *rbo = context.object->rigidbody_object;
186 "release_writers() should be called before the AbstractHierarchyIterator goes out of scope");
191 export_graph_construct();
192 connect_loose_objects();
193 export_graph_prune();
197 export_graph_clear();
230 if (original_name.empty()) {
248 return path_concatenate(context->export_path, get_object_data_name(context->object));
251void AbstractHierarchyIterator::debug_print_export_graph(
const ExportGraph &graph)
const
253 size_t total_graph_size = 0;
254 for (
const auto item : graph.items()) {
259 if (duplicator !=
nullptr) {
260 fmt::println(
" DU {} (as dupped by {}):",
261 export_parent ==
nullptr ?
"-null-" : (export_parent->
id.
name + 2),
265 fmt::println(
" OB {}:",
266 export_parent ==
nullptr ?
"-null-" : (export_parent->
id.
name + 2));
269 total_graph_size += item.value.size();
270 for (HierarchyContext *child_ctx : item.value) {
271 if (child_ctx->duplicator ==
nullptr) {
272 fmt::println(
" - {}{}{}",
273 child_ctx->export_name.c_str(),
274 child_ctx->weak_export ?
" (weak)" :
"",
275 child_ctx->original_export_path.empty() ?
277 (std::string(
"ref ") + child_ctx->original_export_path).c_str());
280 fmt::println(
" - {} (dup by {}{}) {}",
281 child_ctx->export_name.c_str(),
282 child_ctx->duplicator->id.name + 2,
283 child_ctx->weak_export ?
", weak" :
"",
284 child_ctx->original_export_path.empty() ?
286 (std::string(
"ref ") + child_ctx->original_export_path).c_str());
290 fmt::println(
" (Total graph size: {} objects)", total_graph_size);
293void AbstractHierarchyIterator::export_graph_construct()
302 DEGObjectIterSettings deg_iter_settings{};
310 visit_object(
object, object->parent, weak_export);
320 DupliParentFinder dupli_parent_finder;
322 for (
const DupliObject &dupli_object : duplilist) {
326 dupli_parent_finder.insert(&dupli_object);
329 for (
const DupliObject &dupli_object : duplilist) {
333 visit_dupli_object(&dupli_object,
object, dupli_parent_finder);
342void AbstractHierarchyIterator::connect_loose_objects()
350 for (
const HierarchyContext *child : children) {
353 loose_objects_graph.remove(child_oid);
360 for (
const ObjectIdentifier &graph_key : loose_objects_graph.keys()) {
361 Object *
object = graph_key.object;
368 visit_object(
object, object->
parent,
true);
376 object =
object->parent;
385 bool all_is_weak = context !=
nullptr && context->weak_export;
392 all_is_weak &= child_tree_is_weak;
394 if (child_tree_is_weak) {
396 clean_graph.
lookup(map_key).remove(child_context);
397 delete child_context;
404 clean_graph.
remove(map_key);
410void AbstractHierarchyIterator::export_graph_prune()
417void AbstractHierarchyIterator::export_graph_clear()
420 for (HierarchyContext *context : children) {
428void AbstractHierarchyIterator::visit_object(
Object *
object,
432 HierarchyContext *
context =
new HierarchyContext();
434 context->is_object_data_context =
false;
435 context->export_name = get_object_name(
object, export_parent);
436 context->export_parent = export_parent;
438 context->weak_export = weak_export;
439 context->animation_check_include_parent =
false;
441 context->original_export_path =
"";
442 context->higher_up_export_path =
"";
443 context->is_duplisource =
false;
448 context_update_for_graph_index(context, graph_index);
451 export_graph_.lookup_or_add(graph_index, {}).add_new(context);
468void AbstractHierarchyIterator::visit_dupli_object(
const DupliObject *dupli_object,
473 context->object = dupli_object->
ob;
474 context->is_object_data_context =
false;
475 context->duplicator = duplicator;
477 context->weak_export =
false;
478 context->export_path =
"";
479 context->original_export_path =
"";
480 context->animation_check_include_parent =
false;
481 context->is_duplisource =
false;
486 std::string export_name = get_object_name(context->object) +
"-" +
487 context->persistent_id.as_object_name_suffix();
493 context, dupli_object, dupli_parent_finder);
494 context_update_for_graph_index(context, graph_index);
498 if (dupli_object->
ob) {
510 if (dupli_parent !=
nullptr) {
516void AbstractHierarchyIterator::context_update_for_graph_index(
520 context->export_parent = graph_index.
object;
524 const short partype = context->object->partype &
PARTYPE;
527 if (context->export_parent != context->object->parent) {
531 context->animation_check_include_parent =
true;
544void AbstractHierarchyIterator::determine_export_paths(
const HierarchyContext *parent_context)
546 const std::string &parent_export_path = parent_context ? parent_context->
export_path :
"";
553 for (HierarchyContext *context : *children) {
554 context->export_path =
path_concatenate(parent_export_path, context->export_name);
556 if (context->duplicator ==
nullptr) {
559 ID *source_ob = &context->object->id;
562 if (context->object->data !=
nullptr) {
568 determine_export_paths(context);
572bool AbstractHierarchyIterator::determine_duplication_references(
582 bool contains_proxy_prototype =
false;
584 for (HierarchyContext *context : *children) {
585 if (
context->duplicator !=
nullptr) {
590 context->mark_as_not_instanced();
592 contains_proxy_prototype =
true;
595 context->mark_as_instance_of(*source_path);
603 context->mark_as_not_instanced();
613 context->is_duplisource =
true;
617 if (determine_duplication_references(context, indent +
" ")) {
621 context->mark_as_not_instanced();
625 contains_proxy_prototype =
true;
628 return contains_proxy_prototype;
631void AbstractHierarchyIterator::make_writers(
const HierarchyContext *parent_context)
633 float parent_matrix_inv_world[4][4];
635 if (parent_context) {
636 invert_m4_m4(parent_matrix_inv_world, parent_context->matrix_world);
639 unit_m4(parent_matrix_inv_world);
647 bool has_point_instance_ancestor =
false;
648 if (parent_context &&
649 (parent_context->is_point_instance || parent_context->has_point_instance_ancestor))
651 has_point_instance_ancestor =
true;
654 for (HierarchyContext *context : *children) {
655 context->has_point_instance_ancestor = has_point_instance_ancestor;
659 if (parent_context !=
nullptr) {
660 context->higher_up_export_path = parent_context->export_path;
664 EnsuredWriter transform_writer = ensure_writer(
667 if (!transform_writer) {
673 const bool need_writers =
context->is_point_proto || (!
context->is_point_instance &&
674 !
context->has_point_instance_ancestor);
677 if ((transform_writer.is_newly_created() ||
export_subset_.transforms) && need_writers) {
681 transform_writer->write(*context);
685 make_writers_particle_systems(context);
686 make_writer_object_data(context);
691 make_writers(context);
702 HierarchyContext data_context = *object_context;
704 data_context.higher_up_export_path = object_context->export_path;
705 data_context.export_name = get_object_data_name(data_context.object);
706 data_context.export_path =
path_concatenate(data_context.higher_up_export_path,
707 data_context.export_name);
711 data_context.is_parent = children ? (children->size() > 0) :
false;
716void AbstractHierarchyIterator::make_writer_object_data(
const HierarchyContext *context)
718 if (
context->object->data ==
nullptr) {
722 HierarchyContext data_context = context_for_object_data(context);
723 if (data_context.is_instance()) {
724 ID *object_data =
static_cast<ID *
>(
context->object->data);
732 EnsuredWriter data_writer = ensure_writer(&data_context,
739 data_writer->write(data_context);
743void AbstractHierarchyIterator::make_writers_particle_systems(
746 Object *
object = transform_context->object;
748 for (; psys; psys = psys->
next) {
753 HierarchyContext hair_context = *transform_context;
756 hair_context.export_name);
757 hair_context.higher_up_export_path = transform_context->export_path;
758 hair_context.particle_system = psys;
760 EnsuredWriter writer;
784 writer->write(hair_context);
789std::string AbstractHierarchyIterator::get_object_name(
const Object *
object)
const
794std::string AbstractHierarchyIterator::get_object_name(
const Object *
object,
const Object *parent)
796 Set<std::string> &used_names =
used_names_.lookup_or_add(parent ? parent->
id.
name :
"", {});
800std::string AbstractHierarchyIterator::get_object_data_name(
const Object *
object)
const
802 const ID *object_data =
static_cast<ID *
>(
object->data);
807 const std::string &export_path)
const
809 return writers_.lookup_default(export_path,
nullptr);
816 if (writer !=
nullptr) {
820 writer = (this->*create_func)(context);
821 if (writer ==
nullptr) {
830 const std::string &child_path)
const
832 return parent_path +
"/" + child_path;
bool BKE_animdata_id_is_animated(const ID *id)
blender::VectorList< DupliObject > DupliList
void object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob, blender::Set< const Object * > *include_objects, DupliList &r_duplilist)
Key * BKE_key_from_object(Object *ob)
General operations, lookup, etc. for blender objects.
int BKE_object_visibility(const Object *ob, int dag_eval_mode)
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, bool use_render_params)
#define BLI_assert_msg(a, msg)
void copy_m4_m4(float m1[4][4], const float m2[4][4])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
void unit_m4(float m[4][4])
size_t void BLI_uniquename_cb(blender::FunctionRef< bool(blender::StringRefNull)> unique_check, const char *defname, char delim, char *name, size_t name_maxncpy) ATTR_NONNULL(2
#define DEG_OBJECT_ITER_BEGIN(settings_, instance_)
bool DEG_is_evaluated_id(const ID *id)
#define DEG_OBJECT_ITER_END
Scene * DEG_get_evaluated_scene(const Depsgraph *graph)
@ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY
@ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET
ID and Library types, which are fundamental for SDNA.
Object is a sort of wrapper for general info.
@ PART_FLUID_SPRAYFOAMBUBBLE
struct ParticleSystem ParticleSystem
Types and defines for representing Rigid Body entities.
BPy_StructRNA * depsgraph
const Value * lookup_ptr(const Key &key) const
ValueIterator values() const &
bool add(const Key &key, const Value &value)
const Value & lookup(const Key &key) const
void add_new(const Key &key, const Value &value)
bool remove(const Key &key)
Value & lookup_or_add(const Key &key, const Value &value)
bool contains_as(const ForwardKey &key) const
void add_new(const Key &key)
virtual ObjectIdentifier determine_graph_index_object(const HierarchyContext *context)
virtual bool should_visit_dupli_object(const DupliObject *dupli_object) const
virtual ~AbstractHierarchyIterator()
virtual bool include_child_writers(const HierarchyContext *) const
virtual void release_writer(AbstractHierarchyWriter *writer)=0
ExportChildren * graph_children(const HierarchyContext *context)
virtual bool mark_as_weak_export(const Object *object) const
void set_export_subset(ExportSubset export_subset)
ExportGraph export_graph_
DupliSources duplisources_
virtual std::string get_id_name(const ID *id) const
blender::Map< ObjectIdentifier, ExportChildren > ExportGraph
virtual AbstractHierarchyWriter * create_particle_writer(const HierarchyContext *context)=0
ExportPathMap duplisource_export_path_
virtual AbstractHierarchyWriter * create_transform_writer(const HierarchyContext *context)=0
AbstractHierarchyIterator(Main *bmain, Depsgraph *depsgraph)
virtual void iterate_and_write()
virtual std::string make_unique_name(const std::string &original_name, Set< std::string > &used_names)
virtual std::string path_concatenate(const std::string &parent_path, const std::string &child_path) const
virtual ObjectIdentifier determine_graph_index_dupli(const HierarchyContext *context, const DupliObject *dupli_object, const DupliParentFinder &dupli_parent_finder)
AbstractHierarchyWriter * get_writer(const std::string &export_path) const
virtual AbstractHierarchyWriter * create_data_writer(const HierarchyContext *context)=0
virtual AbstractHierarchyWriter * create_hair_writer(const HierarchyContext *context)=0
ExportUsedNameMap used_names_
virtual std::string make_valid_name(const std::string &name) const
ExportSubset export_subset_
blender::Set< HierarchyContext * > ExportChildren
virtual std::string get_object_data_path(const HierarchyContext *context) const
virtual bool include_data_writers(const HierarchyContext *) const
virtual bool check_is_animated(const HierarchyContext &context) const
static bool check_has_deforming_physics(const HierarchyContext &context)
static bool check_has_physics(const HierarchyContext &context)
const DupliObject * find_suitable_export_parent(const DupliObject *dupli_ob) const
bool is_newly_created() const
static EnsuredWriter empty()
static EnsuredWriter existing(AbstractHierarchyWriter *writer)
static EnsuredWriter newly_created(AbstractHierarchyWriter *writer)
AbstractHierarchyWriter * operator->()
static ObjectIdentifier for_graph_root()
static ObjectIdentifier for_duplicated_object(const DupliObject *dupli_object, Object *duplicated_by)
static ObjectIdentifier for_real_object(Object *object)
static ObjectIdentifier for_hierarchy_context(const HierarchyContext *context)
GPU_SHADER_INTERFACE_INFO(depth_2d_update_iface).smooth(Type fragColor push_constant(Type::float2_t, "extent") .push_constant(Type source_data
GeometrySet object_get_evaluated_geometry_set(const Object &object, bool apply_subdiv=true)
int context(const bContext *C, const char *member, bContextDataResult *result)
static bool remove_weak_subtrees(const HierarchyContext *context, AbstractHierarchyIterator::ExportGraph &clean_graph, const AbstractHierarchyIterator::ExportGraph &input_graph)
static PyObject * create_func(PyObject *, PyObject *args)
struct ModifierData * next
struct ParticleSystem * next
bool has_instances() const
bool is_prototype() const
bool is_point_instancer() const
bool is_object_visible(enum eEvaluationMode evaluation_mode) const
void mark_as_not_instanced()
std::string original_export_path
static const HierarchyContext * root()
bool is_object_data_context
void mark_as_instance_of(const std::string &reference_export_path)