[Bf-blender-cvs] [14a84d76e88] sybren-usd: USD: Experimental support for instancing/referencing
Sybren A. Stüvel
noreply at git.blender.org
Fri Jul 19 11:15:27 CEST 2019
Commit: 14a84d76e880572ff93318c1d543bb193413ce98
Author: Sybren A. Stüvel
Date: Thu Jul 18 12:44:48 2019 +0200
Branches: sybren-usd
https://developer.blender.org/rB14a84d76e880572ff93318c1d543bb193413ce98
USD: Experimental support for instancing/referencing
Dupli-object meshes are now written to USD as references to the origina
mesh. This is still very limited in correctness, as there are issues
referencing to materials from a referenced mesh.
I am still committing this, as it also introduces some code clarifications
and gives us a place to start when continuing the quest for proper
instancing in USD.
===================================================================
M source/blender/editors/io/io_usd.c
M source/blender/usd/intern/abstract_hierarchy_iterator.cc
M source/blender/usd/intern/abstract_hierarchy_iterator.h
M source/blender/usd/intern/usd_writer_mesh.cc
M source/blender/usd/usd.h
===================================================================
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index 529a330ca14..71c65eef4f6 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -102,6 +102,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
const bool visible_objects_only = RNA_boolean_get(op->ptr, "visible_objects_only");
const bool export_animation = RNA_boolean_get(op->ptr, "export_animation");
const bool export_hair = RNA_boolean_get(op->ptr, "export_hair");
+ const bool use_instancing = RNA_boolean_get(op->ptr, "use_instancing");
const bool evaluation_mode = RNA_enum_get(op->ptr, "evaluation_mode");
struct USDExportParams params = {
@@ -109,6 +110,7 @@ static int wm_usd_export_exec(bContext *C, wmOperator *op)
export_hair,
selected_objects_only,
visible_objects_only,
+ use_instancing,
evaluation_mode,
};
@@ -154,6 +156,13 @@ void WM_OT_usd_export(struct wmOperatorType *ot)
RNA_def_boolean(
ot->srna, "export_hair", false, "Export Hair", "When true, hair is exported as USD curves");
+ RNA_def_boolean(ot->srna,
+ "use_instancing",
+ false,
+ "Use Instancing (EXPERIMENTAL)",
+ "When true, dupli-objects are written as instances of the original in USD. "
+ "Experimental feature, not working perfectly");
+
RNA_def_enum(ot->srna,
"evaluation_mode",
rna_enum_usd_export_evaluation_mode_items,
diff --git a/source/blender/usd/intern/abstract_hierarchy_iterator.cc b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
index b8a6dcad548..d0492b76d30 100644
--- a/source/blender/usd/intern/abstract_hierarchy_iterator.cc
+++ b/source/blender/usd/intern/abstract_hierarchy_iterator.cc
@@ -38,6 +38,19 @@ bool HierarchyContext::operator<(const HierarchyContext &other) const
return export_parent < other.export_parent;
}
+bool HierarchyContext::is_instance() const
+{
+ return !original_export_path.empty();
+}
+void HierarchyContext::mark_as_instance_of(const std::string &reference_export_path)
+{
+ original_export_path = reference_export_path;
+}
+void HierarchyContext::mark_as_not_instanced()
+{
+ original_export_path.clear();
+}
+
AbstractHierarchyIterator::AbstractHierarchyIterator(Depsgraph *depsgraph)
: depsgraph(depsgraph), writers()
{
@@ -80,15 +93,21 @@ void AbstractHierarchyIterator::debug_print_export_graph() const
total_graph_size += map_iter.second.size();
for (HierarchyContext *child_ctx : map_iter.second) {
if (child_ctx->duplicator == nullptr) {
- printf(" - %s%s\n",
+ printf(" - %s%s%s\n",
child_ctx->object->id.name + 2,
- child_ctx->weak_export ? " \033[97m(weak)\033[0m" : "");
+ child_ctx->weak_export ? " \033[97m(weak)\033[0m" : "",
+ child_ctx->original_export_path.size() ?
+ (std::string("ref ") + child_ctx->original_export_path).c_str() :
+ "");
}
else {
- printf(" - %s (dup by %s%s)\n",
+ printf(" - %s (dup by %s%s) %s\n",
child_ctx->object->id.name + 2,
child_ctx->duplicator->id.name + 2,
- child_ctx->weak_export ? ", \033[97mweak\033[0m" : "");
+ child_ctx->weak_export ? ", \033[97mweak\033[0m" : "",
+ child_ctx->original_export_path.size() ?
+ (std::string("ref ") + child_ctx->original_export_path).c_str() :
+ "");
}
}
}
@@ -99,6 +118,8 @@ void AbstractHierarchyIterator::iterate()
{
export_graph_construct();
export_graph_prune();
+ determine_export_paths(HierarchyContext::root());
+ determine_duplication_references(HierarchyContext::root(), "");
make_writers(HierarchyContext::root());
export_graph_clear();
}
@@ -167,6 +188,7 @@ void AbstractHierarchyIterator::visit_object(Object *object,
context->weak_export = weak_export;
context->animation_check_include_parent = false;
context->export_path = "";
+ context->original_export_path = "";
copy_m4_m4(context->matrix_world, object->obmat);
export_graph[std::make_pair(export_parent, nullptr)].insert(context);
@@ -191,6 +213,7 @@ void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
context->duplicator = duplicator;
context->weak_export = false;
context->export_path = "";
+ context->original_export_path = "";
/* If the dupli-object's scene parent is also instanced by this object, use that as the
* export parent. Otherwise use the dupli-parent as export parent. */
@@ -212,10 +235,6 @@ void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
context->animation_check_include_parent = animation_check_include_parent;
copy_m4_m4(context->matrix_world, dupli_object->mat);
- std::string export_parent_name = context->export_parent ?
- get_object_name(context->export_parent) :
- "/";
-
// Construct export name for the dupli-instance.
std::stringstream suffix_stream;
suffix_stream << std::hex;
@@ -226,6 +245,9 @@ void AbstractHierarchyIterator::visit_dupli_object(DupliObject *dupli_object,
export_graph[graph_index].insert(context);
+ // std::string export_parent_name = context->export_parent ?
+ // get_object_name(context->export_parent) :
+ // "/";
// printf(" DU %30s %p (export-parent=%s; duplicator = %s; world x = %f)\n",
// context->export_name.c_str(),
// context->object,
@@ -284,12 +306,78 @@ void AbstractHierarchyIterator::export_graph_clear()
}
AbstractHierarchyIterator::ExportGraph::mapped_type &AbstractHierarchyIterator::graph_children(
- const HierarchyContext *parent_context)
+ const HierarchyContext *context)
{
- Object *parent_object = parent_context ? parent_context->object : nullptr;
- Object *parent_duplicator = parent_context ? parent_context->duplicator : nullptr;
+ if (context == nullptr) {
+ return export_graph[std::make_pair(nullptr, nullptr)];
+ }
- return export_graph[std::make_pair(parent_object, parent_duplicator)];
+ return export_graph[std::make_pair(context->object, context->duplicator)];
+}
+
+void AbstractHierarchyIterator::determine_export_paths(const HierarchyContext *parent_context)
+{
+ const std::string &parent_export_path = parent_context ? parent_context->export_path : "";
+
+ for (HierarchyContext *context : graph_children(parent_context)) {
+ context->export_path = path_concatenate(parent_export_path, context->export_name);
+
+ if (context->duplicator == nullptr) {
+ /* This is an original object, so we should keep track of where it was exported to, just in
+ * case it gets duplicated somewhere. */
+ ID *orig_ob = &context->object->id;
+ originals_export_paths[orig_ob] = context->export_path;
+
+ if (context->object->data != nullptr) {
+ ID *object_data = static_cast<ID *>(context->object->data);
+ ID *orig_data = object_data;
+ originals_export_paths[orig_data] = get_object_data_path(context);
+ }
+ }
+
+ determine_export_paths(context);
+ }
+}
+
+void AbstractHierarchyIterator::determine_duplication_references(
+ const HierarchyContext *parent_context, std::string indent)
+{
+ ExportGraph::mapped_type children = graph_children(parent_context);
+
+ for (HierarchyContext *context : children) {
+ if (context->duplicator != nullptr) {
+ ID *orig_id = &context->object->id;
+ const ExportPathMap::const_iterator &it = originals_export_paths.find(orig_id);
+
+ if (it == originals_export_paths.end()) {
+ // The original was not found, so mark this instance as "the original".
+ context->mark_as_not_instanced();
+ originals_export_paths[orig_id] = context->export_path;
+ }
+ else {
+ context->mark_as_instance_of(it->second);
+ }
+
+ if (context->object->data) {
+ ID *orig_data_id = (ID *)context->object->data;
+ const ExportPathMap::const_iterator &it = originals_export_paths.find(orig_data_id);
+
+ if (it == originals_export_paths.end()) {
+ // The original was not found, so mark this instance as "original".
+ std::string data_path = get_object_data_path(context);
+ // printf(
+ // "%s\033[93mUSD issue\033[0m: %s is DATA instance of %p, but no original DATA path
+ // " "is known\n", indent.c_str(), data_path.c_str(), orig_data_id);
+
+ context->mark_as_not_instanced();
+ originals_export_paths[orig_id] = context->export_path;
+ originals_export_paths[orig_data_id] = data_path;
+ }
+ }
+ }
+
+ determine_duplication_references(context, indent + " ");
+ }
}
void AbstractHierarchyIterator::make_writers(const HierarchyContext *parent_context)
@@ -307,16 +395,8 @@ void AbstractHierarchyIterator::make_writers(const HierarchyContext *parent_cont
const std::string &parent_export_path = parent_context ? parent_context->export_path : "";
for (HierarchyContext *context : graph_children(parent_context)) {
- std::string export_path = path_concatenate(parent_export_path, context->export_name);
- context->export_path = export_path;
copy_m4_m4(context->parent_matrix_inv_world, parent_matrix_inv_world);
- // printf("'%s' + '%s' = '%s' (exporting object %s)\n",
- // parent_export_path.c_str(),
- // context->export_name.c_str(),
- // export_path.c_str(),
- // context->object->id.name + 2);
-
// Get or create the transform writer.
xform_writer = ensure_writer(context, &AbstractHierarchyIterator::create_xform_writer);
if (xform_writer == nullptr) {
@@ -381,13 +461,19 @@ void AbstractHierarchyIterator::make_writer_object_data(const HierarchyContext *
}
HierarchyContext data_context = *context;
- ID *object_data = static_cast<ID *>(context->object->data);
- std::string data_path = path_conca
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list