40 if (
object != other.
object) {
41 return object < other.
object;
81 object->base_flag = base_flag;
92 : writer_(writer), newly_created_(newly_created)
111 return newly_created_;
114 EnsuredWriter::operator
bool()
const
116 return writer_ !=
nullptr;
165 : bmain_(bmain), depsgraph_(
depsgraph), export_subset_({
true,
true})
176 !
"release_writers() should be called before the AbstractHierarchyIterator goes out of scope");
181 export_graph_construct();
182 connect_loose_objects();
183 export_graph_prune();
187 export_graph_clear();
192 for (WriterMap::value_type it :
writers_) {
225 void AbstractHierarchyIterator::debug_print_export_graph(
const ExportGraph &
graph)
const
227 size_t total_graph_size = 0;
228 for (
const ExportGraph::value_type &map_iter :
graph) {
233 if (duplicator !=
nullptr) {
234 printf(
" DU %s (as dupped by %s):\n",
235 export_parent ==
nullptr ?
"-null-" : (export_parent->
id.
name + 2),
239 printf(
" OB %s:\n", export_parent ==
nullptr ?
"-null-" : (export_parent->
id.
name + 2));
242 total_graph_size += map_iter.second.size();
243 for (HierarchyContext *child_ctx : map_iter.second) {
244 if (child_ctx->duplicator ==
nullptr) {
245 printf(
" - %s%s%s\n",
246 child_ctx->export_name.c_str(),
247 child_ctx->weak_export ?
" (weak)" :
"",
248 child_ctx->original_export_path.empty() ?
250 (std::string(
"ref ") + child_ctx->original_export_path).c_str());
253 printf(
" - %s (dup by %s%s) %s\n",
254 child_ctx->export_name.c_str(),
255 child_ctx->duplicator->id.name + 2,
256 child_ctx->weak_export ?
", weak" :
"",
257 child_ctx->original_export_path.empty() ?
259 (std::string(
"ref ") + child_ctx->original_export_path).c_str());
263 printf(
" (Total graph size: %zu objects)\n", total_graph_size);
266 void AbstractHierarchyIterator::export_graph_construct()
281 visit_object(
object, object->parent, weak_export);
291 DupliParentFinder dupli_parent_finder;
294 PersistentID persistent_id(dupli_object);
298 dupli_parent_finder.insert(dupli_object);
305 visit_dupli_object(dupli_object,
object, dupli_parent_finder);
314 void AbstractHierarchyIterator::connect_loose_objects()
321 for (
const ExportGraph::value_type &map_iter :
export_graph_) {
322 for (
const HierarchyContext *child : map_iter.second) {
325 loose_objects_graph.erase(child_oid);
332 for (
const ExportGraph::value_type &map_iter : loose_objects_graph) {
333 const ObjectIdentifier &graph_key = map_iter.first;
334 Object *
object = graph_key.object;
340 ExportGraph::iterator found_parent_iter =
export_graph_.find(
342 visit_object(
object, object->
parent,
true);
350 object =
object->parent;
362 AbstractHierarchyIterator::ExportGraph::const_iterator child_iterator;
364 child_iterator = input_graph.find(map_key);
365 if (child_iterator != input_graph.end()) {
368 all_is_weak &= child_tree_is_weak;
370 if (child_tree_is_weak) {
372 clean_graph[map_key].erase(child_context);
373 delete child_context;
380 clean_graph.erase(map_key);
386 void AbstractHierarchyIterator::export_graph_prune()
393 void AbstractHierarchyIterator::export_graph_clear()
395 for (ExportGraph::iterator::value_type &it :
export_graph_) {
396 for (HierarchyContext *
context : it.second) {
403 void AbstractHierarchyIterator::visit_object(
Object *
object,
407 HierarchyContext *
context =
new HierarchyContext();
409 context->export_name = get_object_name(
object);
410 context->export_parent = export_parent;
412 context->weak_export = weak_export;
413 context->animation_check_include_parent =
false;
415 context->original_export_path =
"";
416 context->higher_up_export_path =
"";
421 context_update_for_graph_index(
context, graph_index);
443 void AbstractHierarchyIterator::visit_dupli_object(
DupliObject *dupli_object,
449 context->duplicator = duplicator;
453 context->original_export_path =
"";
454 context->animation_check_include_parent =
false;
459 std::stringstream export_name_stream;
460 export_name_stream << get_object_name(
context->object) <<
"-"
461 <<
context->persistent_id.as_object_name_suffix();
465 context, dupli_object, dupli_parent_finder);
466 context_update_for_graph_index(
context, graph_index);
478 if (dupli_parent !=
nullptr) {
484 void AbstractHierarchyIterator::context_update_for_graph_index(
488 context->export_parent = graph_index.object;
493 context->animation_check_include_parent =
true;
503 void AbstractHierarchyIterator::determine_export_paths(
const HierarchyContext *parent_context)
505 const std::string &parent_export_path = parent_context ? parent_context->
export_path :
"";
510 if (
context->duplicator ==
nullptr) {
516 if (
context->object->data !=
nullptr) {
517 ID *source_data =
static_cast<ID *
>(
context->object->data);
522 determine_export_paths(
context);
526 void AbstractHierarchyIterator::determine_duplication_references(
527 const HierarchyContext *parent_context, std::string indent)
531 for (HierarchyContext *
context : children) {
532 if (
context->duplicator !=
nullptr) {
538 context->mark_as_not_instanced();
542 context->mark_as_instance_of(it->second);
552 context->mark_as_not_instanced();
559 determine_duplication_references(
context, indent +
" ");
563 void AbstractHierarchyIterator::make_writers(
const HierarchyContext *parent_context)
565 float parent_matrix_inv_world[4][4];
567 if (parent_context) {
568 invert_m4_m4(parent_matrix_inv_world, parent_context->matrix_world);
571 unit_m4(parent_matrix_inv_world);
577 if (parent_context !=
nullptr) {
578 context->higher_up_export_path = parent_context->export_path;
582 EnsuredWriter transform_writer = ensure_writer(
585 if (!transform_writer) {
596 transform_writer->write(*
context);
600 make_writers_particle_systems(
context);
601 make_writer_object_data(
context);
612 HierarchyContext AbstractHierarchyIterator::context_for_object_data(
613 const HierarchyContext *object_context)
const
615 HierarchyContext data_context = *object_context;
616 data_context.higher_up_export_path = object_context->export_path;
617 data_context.export_name = get_object_data_name(data_context.object);
618 data_context.export_path =
path_concatenate(data_context.higher_up_export_path,
619 data_context.export_name);
623 void AbstractHierarchyIterator::make_writer_object_data(
const HierarchyContext *
context)
625 if (
context->object->data ==
nullptr) {
629 HierarchyContext data_context = context_for_object_data(
context);
630 if (data_context.is_instance()) {
631 ID *object_data =
static_cast<ID *
>(
context->object->data);
639 EnsuredWriter data_writer = ensure_writer(&data_context,
646 data_writer->write(data_context);
650 void AbstractHierarchyIterator::make_writers_particle_systems(
651 const HierarchyContext *transform_context)
653 Object *
object = transform_context->object;
655 for (; psys; psys = psys->
next) {
660 HierarchyContext hair_context = *transform_context;
663 hair_context.export_name);
664 hair_context.higher_up_export_path = transform_context->export_path;
665 hair_context.particle_system = psys;
667 EnsuredWriter writer;
691 writer->write(hair_context);
696 std::string AbstractHierarchyIterator::get_object_name(
const Object *
object)
const
701 std::string AbstractHierarchyIterator::get_object_data_name(
const Object *
object)
const
703 ID *object_data =
static_cast<ID *
>(
object->data);
708 const std::string &export_path)
const
710 WriterMap::const_iterator it =
writers_.find(export_path);
722 if (writer !=
nullptr) {
727 if (writer ==
nullptr) {
736 const std::string &child_path)
const
738 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(struct Object *ob)
General operations, lookup, etc. for blender objects.
int BKE_object_visibility(const struct Object *ob, int dag_eval_mode)
bool psys_check_enabled(struct Object *ob, struct ParticleSystem *psys, 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.
std::map< ObjectIdentifier, ExportChildren > ExportGraph
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_
AbstractHierarchyIterator(Main *bmain, Depsgraph *depsgraph)
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)
static PyObject * create_func(PyObject *, PyObject *args)
struct ModifierData * next
struct ParticleSystem * next
bool is_object_visible(enum eEvaluationMode evaluation_mode) const
void mark_as_not_instanced()
std::string original_export_path
static const HierarchyContext * root()
bool operator<(const HierarchyContext &other) const
void mark_as_instance_of(const std::string &reference_export_path)