56 if (
object != other.
object) {
57 return object < other.
object;
97 object->base_flag = base_flag;
108 : writer_(writer), newly_created_(newly_created)
127 return newly_created_;
130 EnsuredWriter::operator bool()
const
132 return writer_ !=
nullptr;
181 : depsgraph_(
depsgraph), export_subset_({
true,
true})
192 !
"release_writers() should be called before the AbstractHierarchyIterator goes out of scope");
197 export_graph_construct();
198 connect_loose_objects();
199 export_graph_prune();
203 export_graph_clear();
208 for (WriterMap::value_type it :
writers_) {
241 void AbstractHierarchyIterator::debug_print_export_graph(
const ExportGraph &
graph)
const
243 size_t total_graph_size = 0;
244 for (
const ExportGraph::value_type &map_iter :
graph) {
249 if (duplicator !=
nullptr) {
250 printf(
" DU %s (as dupped by %s):\n",
251 export_parent ==
nullptr ?
"-null-" : (export_parent->
id.
name + 2),
255 printf(
" OB %s:\n", export_parent ==
nullptr ?
"-null-" : (export_parent->
id.
name + 2));
258 total_graph_size += map_iter.second.size();
259 for (HierarchyContext *child_ctx : map_iter.second) {
260 if (child_ctx->duplicator ==
nullptr) {
261 printf(
" - %s%s%s\n",
262 child_ctx->export_name.c_str(),
263 child_ctx->weak_export ?
" (weak)" :
"",
264 child_ctx->original_export_path.empty() ?
266 (std::string(
"ref ") + child_ctx->original_export_path).c_str());
269 printf(
" - %s (dup by %s%s) %s\n",
270 child_ctx->export_name.c_str(),
271 child_ctx->duplicator->id.name + 2,
272 child_ctx->weak_export ?
", weak" :
"",
273 child_ctx->original_export_path.empty() ?
275 (std::string(
"ref ") + child_ctx->original_export_path).c_str());
279 printf(
" (Total graph size: %zu objects)\n", total_graph_size);
282 void AbstractHierarchyIterator::export_graph_construct()
292 visit_object(
object, object->parent, weak_export);
302 DupliParentFinder dupli_parent_finder;
305 PersistentID persistent_id(dupli_object);
309 dupli_parent_finder.insert(dupli_object);
316 visit_dupli_object(dupli_object,
object, dupli_parent_finder);
325 void AbstractHierarchyIterator::connect_loose_objects()
332 for (
const ExportGraph::value_type &map_iter :
export_graph_) {
333 for (
const HierarchyContext *child : map_iter.second) {
336 loose_objects_graph.erase(child_oid);
343 for (
const ExportGraph::value_type &map_iter : loose_objects_graph) {
344 const ObjectIdentifier &graph_key = map_iter.first;
345 Object *
object = graph_key.object;
351 ExportGraph::iterator found_parent_iter =
export_graph_.find(
353 visit_object(
object, object->
parent,
true);
361 object =
object->parent;
373 AbstractHierarchyIterator::ExportGraph::const_iterator child_iterator;
375 child_iterator = input_graph.find(map_key);
376 if (child_iterator != input_graph.end()) {
379 all_is_weak &= child_tree_is_weak;
381 if (child_tree_is_weak) {
383 clean_graph[map_key].erase(child_context);
384 delete child_context;
391 clean_graph.erase(map_key);
397 void AbstractHierarchyIterator::export_graph_prune()
404 void AbstractHierarchyIterator::export_graph_clear()
406 for (ExportGraph::iterator::value_type &it :
export_graph_) {
407 for (HierarchyContext *
context : it.second) {
414 void AbstractHierarchyIterator::visit_object(
Object *
object,
418 HierarchyContext *
context =
new HierarchyContext();
420 context->export_name = get_object_name(
object);
421 context->export_parent = export_parent;
423 context->weak_export = weak_export;
424 context->animation_check_include_parent =
false;
426 context->original_export_path =
"";
427 context->higher_up_export_path =
"";
432 context_update_for_graph_index(
context, graph_index);
454 void AbstractHierarchyIterator::visit_dupli_object(
DupliObject *dupli_object,
460 context->duplicator = duplicator;
464 context->original_export_path =
"";
466 context->animation_check_include_parent =
false;
471 std::stringstream export_name_stream;
472 export_name_stream << get_object_name(
context->object) <<
"-"
473 <<
context->persistent_id.as_object_name_suffix();
477 context, dupli_object, dupli_parent_finder);
478 context_update_for_graph_index(
context, graph_index);
490 if (dupli_parent !=
nullptr) {
496 void AbstractHierarchyIterator::context_update_for_graph_index(
500 context->export_parent = graph_index.object;
505 context->animation_check_include_parent =
true;
515 void AbstractHierarchyIterator::determine_export_paths(
const HierarchyContext *parent_context)
517 const std::string &parent_export_path = parent_context ? parent_context->
export_path :
"";
522 if (
context->duplicator ==
nullptr) {
528 if (
context->object->data !=
nullptr) {
529 ID *source_data =
static_cast<ID *
>(
context->object->data);
534 determine_export_paths(
context);
538 void AbstractHierarchyIterator::determine_duplication_references(
539 const HierarchyContext *parent_context, std::string indent)
543 for (HierarchyContext *
context : children) {
544 if (
context->duplicator !=
nullptr) {
550 context->mark_as_not_instanced();
554 context->mark_as_instance_of(it->second);
564 context->mark_as_not_instanced();
571 determine_duplication_references(
context, indent +
" ");
575 void AbstractHierarchyIterator::make_writers(
const HierarchyContext *parent_context)
577 float parent_matrix_inv_world[4][4];
579 if (parent_context) {
580 invert_m4_m4(parent_matrix_inv_world, parent_context->matrix_world);
583 unit_m4(parent_matrix_inv_world);
589 if (parent_context !=
nullptr) {
590 context->higher_up_export_path = parent_context->export_path;
594 EnsuredWriter transform_writer = ensure_writer(
597 if (!transform_writer) {
608 transform_writer->write(*
context);
612 make_writers_particle_systems(
context);
613 make_writer_object_data(
context);
624 HierarchyContext AbstractHierarchyIterator::context_for_object_data(
625 const HierarchyContext *object_context)
const
627 HierarchyContext data_context = *object_context;
628 data_context.higher_up_export_path = object_context->export_path;
629 data_context.export_name = get_object_data_name(data_context.object);
630 data_context.export_path =
path_concatenate(data_context.higher_up_export_path,
631 data_context.export_name);
635 void AbstractHierarchyIterator::make_writer_object_data(
const HierarchyContext *
context)
637 if (
context->object->data ==
nullptr) {
641 HierarchyContext data_context = context_for_object_data(
context);
642 if (data_context.is_instance()) {
643 ID *object_data =
static_cast<ID *
>(
context->object->data);
651 EnsuredWriter data_writer = ensure_writer(&data_context,
658 data_writer->write(data_context);
662 void AbstractHierarchyIterator::make_writers_particle_systems(
663 const HierarchyContext *transform_context)
665 Object *
object = transform_context->object;
667 for (; psys; psys = psys->
next) {
672 HierarchyContext hair_context = *transform_context;
675 hair_context.export_name);
676 hair_context.higher_up_export_path = transform_context->export_path;
677 hair_context.particle_system = psys;
679 EnsuredWriter writer;
703 writer->write(hair_context);
708 std::string AbstractHierarchyIterator::get_object_name(
const Object *
object)
const
713 std::string AbstractHierarchyIterator::get_object_data_name(
const Object *
object)
const
715 ID *object_data =
static_cast<ID *
>(
object->data);
720 const std::string &export_path)
const
722 WriterMap::const_iterator it =
writers_.find(export_path);
734 if (writer !=
nullptr) {
739 if (writer ==
nullptr) {
748 const std::string &child_path)
const
750 return parent_path +
"/" + child_path;
bool BKE_animdata_id_is_animated(const struct ID *id)
struct ListBase * object_duplilist(struct Depsgraph *depsgraph, struct Scene *sce, struct Object *ob)
void free_object_duplilist(struct ListBase *lb)
struct Key * BKE_key_from_object(const struct Object *ob)
General operations, lookup, etc. for blender objects.
int BKE_object_visibility(const struct Object *ob, const int dag_eval_mode)
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, const bool use_render_params)
#define LISTBASE_FOREACH(type, var, list)
void unit_m4(float m[4][4])
bool invert_m4_m4(float R[4][4], const float A[4][4])
void copy_m4_m4(float m1[4][4], const float m2[4][4])
struct Depsgraph Depsgraph
#define DEG_OBJECT_ITER_END
bool DEG_is_evaluated_object(const struct Object *object)
#define DEG_OBJECT_ITER_BEGIN(graph_, instance_, flag_)
@ DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY
@ DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET
struct Scene * DEG_get_evaluated_scene(const struct Depsgraph *graph)
ID and Library types, which are fundamental for sdna.
Object is a sort of wrapper for general info.
@ PART_FLUID_SPRAYFOAMBUBBLE
Types and defines for representing Rigid Body entities.
static PyObject * create_func(PyObject *, PyObject *args)
std::map< ObjectIdentifier, ExportChildren > ExportGraph
AbstractHierarchyIterator(Depsgraph *depsgraph)
virtual ExportGraph::key_type determine_graph_index_object(const HierarchyContext *context)
virtual bool should_visit_dupli_object(const DupliObject *dupli_object) const
virtual ~AbstractHierarchyIterator()
virtual AbstractHierarchyWriter * create_data_writer(const HierarchyContext *context)=0
virtual void release_writer(AbstractHierarchyWriter *writer)=0
virtual AbstractHierarchyWriter * create_transform_writer(const HierarchyContext *context)=0
virtual AbstractHierarchyWriter * create_particle_writer(const HierarchyContext *context)=0
virtual bool mark_as_weak_export(const Object *object) const
ExportGraph export_graph_
virtual std::string get_id_name(const ID *id) const
ExportPathMap duplisource_export_path_
virtual AbstractHierarchyWriter * create_hair_writer(const HierarchyContext *context)=0
void set_export_subset(ExportSubset export_subset_)
virtual void iterate_and_write()
ExportChildren & graph_children(const HierarchyContext *parent_context)
virtual std::string path_concatenate(const std::string &parent_path, const std::string &child_path) const
AbstractHierarchyWriter * get_writer(const std::string &export_path) const
virtual std::string make_valid_name(const std::string &name) const
ExportSubset export_subset_
virtual ExportGraph::key_type determine_graph_index_dupli(const HierarchyContext *context, const DupliObject *dupli_object, const DupliParentFinder &dupli_parent_finder)
virtual std::string get_object_data_path(const HierarchyContext *context) const
std::set< HierarchyContext * > ExportChildren
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)
const Depsgraph * depsgraph
static bool remove_weak_subtrees(const HierarchyContext *context, AbstractHierarchyIterator::ExportGraph &clean_graph, const AbstractHierarchyIterator::ExportGraph &input_graph)
struct SELECTID_Context context
struct ModifierData * next
struct ParticleSystem * next
void mark_as_not_instanced()
std::string original_export_path
static const HierarchyContext * root()
bool operator<(const HierarchyContext &other) const
bool is_object_visible(const enum eEvaluationMode evaluation_mode) const
void mark_as_instance_of(const std::string &reference_export_path)