74 base_flag =
object->base_flag;
81 object->base_flag = base_flag;
90 : writer_(writer), newly_created_(newly_created)
109 return newly_created_;
112EnsuredWriter::operator bool()
const
114 return writer_ !=
nullptr;
124 Object *
object = context.object;
152 const RigidBodyOb *rbo = context.object->rigidbody_object;
158 const RigidBodyOb *rbo = context.object->rigidbody_object;
189 "release_writers() should be called before the AbstractHierarchyIterator goes out of scope");
194 export_graph_construct();
195 connect_loose_objects();
196 export_graph_prune();
200 export_graph_clear();
233 if (original_name.empty()) {
251 return path_concatenate(context->export_path, get_object_data_name(context->object));
254void AbstractHierarchyIterator::debug_print_export_graph(
const ExportGraph &graph)
const
256 size_t total_graph_size = 0;
257 for (
const auto item : graph.items()) {
262 if (duplicator !=
nullptr) {
263 fmt::println(
" DU {} (as dupped by {}):",
264 export_parent ==
nullptr ?
"-null-" : (export_parent->
id.
name + 2),
268 fmt::println(
" OB {}:",
269 export_parent ==
nullptr ?
"-null-" : (export_parent->
id.
name + 2));
272 total_graph_size += item.value.size();
273 for (HierarchyContext *child_ctx : item.value) {
274 if (child_ctx->duplicator ==
nullptr) {
275 fmt::println(
" - {}{}{}",
276 child_ctx->export_name.c_str(),
277 child_ctx->weak_export ?
" (weak)" :
"",
278 child_ctx->original_export_path.empty() ?
280 (std::string(
"ref ") + child_ctx->original_export_path).c_str());
283 fmt::println(
" - {} (dup by {}{}) {}",
284 child_ctx->export_name.c_str(),
285 child_ctx->duplicator->id.name + 2,
286 child_ctx->weak_export ?
", weak" :
"",
287 child_ctx->original_export_path.empty() ?
289 (std::string(
"ref ") + child_ctx->original_export_path).c_str());
293 fmt::println(
" (Total graph size: {} objects)", total_graph_size);
296void AbstractHierarchyIterator::export_graph_construct()
305 DEGObjectIterSettings deg_iter_settings{};
312 visit_object(
object, object->parent, weak_export);
322 DupliParentFinder dupli_parent_finder;
325 PersistentID persistent_id(dupli_object);
329 dupli_parent_finder.insert(dupli_object);
336 visit_dupli_object(dupli_object,
object, dupli_parent_finder);
345void AbstractHierarchyIterator::connect_loose_objects()
353 for (
const HierarchyContext *child : children) {
356 loose_objects_graph.remove(child_oid);
363 for (
const ObjectIdentifier &graph_key : loose_objects_graph.keys()) {
364 Object *
object = graph_key.object;
371 visit_object(
object, object->
parent,
true);
379 object =
object->parent;
388 bool all_is_weak = context !=
nullptr && context->weak_export;
395 all_is_weak &= child_tree_is_weak;
397 if (child_tree_is_weak) {
399 clean_graph.
lookup(map_key).remove(child_context);
400 delete child_context;
407 clean_graph.
remove(map_key);
413void AbstractHierarchyIterator::export_graph_prune()
420void AbstractHierarchyIterator::export_graph_clear()
423 for (HierarchyContext *context : children) {
431void AbstractHierarchyIterator::visit_object(
Object *
object,
435 HierarchyContext *
context =
new HierarchyContext();
437 context->is_object_data_context =
false;
438 context->export_name = get_object_name(
object, export_parent);
439 context->export_parent = export_parent;
441 context->weak_export = weak_export;
442 context->animation_check_include_parent =
false;
444 context->original_export_path =
"";
445 context->higher_up_export_path =
"";
446 context->is_duplisource =
false;
451 context_update_for_graph_index(context, graph_index);
454 export_graph_.lookup_or_add(graph_index, {}).add_new(context);
471void AbstractHierarchyIterator::visit_dupli_object(
DupliObject *dupli_object,
476 context->object = dupli_object->
ob;
477 context->is_object_data_context =
false;
478 context->duplicator = duplicator;
480 context->weak_export =
false;
481 context->export_path =
"";
482 context->original_export_path =
"";
483 context->animation_check_include_parent =
false;
484 context->is_duplisource =
false;
489 std::string export_name = get_object_name(context->object) +
"-" +
490 context->persistent_id.as_object_name_suffix();
496 context, dupli_object, dupli_parent_finder);
497 context_update_for_graph_index(context, graph_index);
501 if (dupli_object->
ob) {
513 if (dupli_parent !=
nullptr) {
519void AbstractHierarchyIterator::context_update_for_graph_index(
523 context->export_parent = graph_index.
object;
527 const short partype = context->object->partype &
PARTYPE;
530 if (context->export_parent != context->object->parent) {
534 context->animation_check_include_parent =
true;
547void AbstractHierarchyIterator::determine_export_paths(
const HierarchyContext *parent_context)
549 const std::string &parent_export_path = parent_context ? parent_context->
export_path :
"";
556 for (HierarchyContext *context : *children) {
557 context->export_path =
path_concatenate(parent_export_path, context->export_name);
559 if (context->duplicator ==
nullptr) {
562 ID *source_ob = &context->object->id;
565 if (context->object->data !=
nullptr) {
571 determine_export_paths(context);
575bool AbstractHierarchyIterator::determine_duplication_references(
585 bool contains_proxy_prototype =
false;
587 for (HierarchyContext *context : *children) {
588 if (
context->duplicator !=
nullptr) {
593 context->mark_as_not_instanced();
595 contains_proxy_prototype =
true;
598 context->mark_as_instance_of(*source_path);
606 context->mark_as_not_instanced();
616 context->is_duplisource =
true;
620 if (determine_duplication_references(context, indent +
" ")) {
624 context->mark_as_not_instanced();
628 contains_proxy_prototype =
true;
631 return contains_proxy_prototype;
634void AbstractHierarchyIterator::make_writers(
const HierarchyContext *parent_context)
636 float parent_matrix_inv_world[4][4];
638 if (parent_context) {
639 invert_m4_m4(parent_matrix_inv_world, parent_context->matrix_world);
642 unit_m4(parent_matrix_inv_world);
650 for (HierarchyContext *context : *children) {
651 if (parent_context) {
652 if (parent_context->is_point_instance || parent_context->has_point_instance_ancestor) {
653 context->has_point_instance_ancestor =
true;
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)
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 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)
void free_object_duplilist(ListBase *lb)
ListBase * object_duplilist(Depsgraph *depsgraph, Scene *sce, Object *ob, blender::Set< const Object * > *include_objects=nullptr)
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)
#define LISTBASE_FOREACH(type, var, list)
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)