Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJacques Lucke <jacques@blender.org>2020-12-02 15:28:08 +0300
committerJacques Lucke <jacques@blender.org>2020-12-02 17:38:47 +0300
commitae0aa4b94c4a9b5b166fbc0b5394dcc47455091d (patch)
treeb2d8eeb30fa148bec0ff9f91a3bd1cf965d9a168 /source/blender/depsgraph/intern/depsgraph_query_iter.cc
parent6be56c13e96048cbc494ba5473a8deaf2cf5a6f8 (diff)
Geometry Nodes: support geometry components in depsgraph object iterator
Objects can evaluate to a geometry set instead of a single ID (only point cloud objects for now). In the depsgraph object iterator, the evaluated geometry components are expanded into temporary objects. It's important to note that instanced objects can also contain geometry components. Therefore, they have to be split up into multiple objects as well in some cases. At a high level the iterator works like so: ``` for object in depsgraph: for component in object: yield object_from_component(component) for dupli in make_duplis_list(object): for component in dupli: yield object_from_component(component) ``` DEG_iterator_objects_next has been cleaned up, to make this structure a bit more apparent. This should not change anything for objects that are not point clouds.
Diffstat (limited to 'source/blender/depsgraph/intern/depsgraph_query_iter.cc')
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query_iter.cc225
1 files changed, 146 insertions, 79 deletions
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index dd5c998466b..b92bf475f49 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -29,6 +29,7 @@
#include "MEM_guardedalloc.h"
#include "BKE_duplilist.h"
+#include "BKE_geometry_set.hh"
#include "BKE_idprop.h"
#include "BKE_layer.h"
#include "BKE_node.h"
@@ -121,9 +122,84 @@ bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject
return false;
}
-bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
+void deg_iterator_components_init(DEGObjectIterData *data, Object *object)
+{
+ data->geometry_component_owner = object;
+ data->geometry_component_id = 0;
+}
+
+/* Returns false when iterator is exhausted. */
+bool deg_iterator_components_step(BLI_Iterator *iter)
{
DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
+ if (data->geometry_component_owner == nullptr) {
+ return false;
+ }
+
+ if (data->geometry_component_owner->type != OB_POINTCLOUD) {
+ /* Only point clouds support multiple geometry components currently. */
+ iter->current = data->geometry_component_owner;
+ data->geometry_component_owner = nullptr;
+ return true;
+ }
+
+ GeometrySet *geometry_set = data->geometry_component_owner->runtime.geometry_set_eval;
+ if (geometry_set == nullptr) {
+ data->geometry_component_owner = nullptr;
+ return false;
+ }
+
+ if (data->geometry_component_id == 0) {
+ data->geometry_component_id++;
+
+ /* The mesh component. */
+ const Mesh *mesh = geometry_set->get_mesh_for_read();
+ if (mesh != nullptr) {
+ Object *temp_object = &data->temp_geometry_component_object;
+ *temp_object = *data->geometry_component_owner;
+ temp_object->type = OB_MESH;
+ temp_object->data = (void *)mesh;
+ temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
+ iter->current = temp_object;
+ return true;
+ }
+ }
+ if (data->geometry_component_id == 1) {
+ data->geometry_component_id++;
+
+ /* The pointcloud component. */
+ const PointCloud *pointcloud = geometry_set->get_pointcloud_for_read();
+ if (pointcloud != nullptr) {
+ Object *temp_object = &data->temp_geometry_component_object;
+ *temp_object = *data->geometry_component_owner;
+ temp_object->type = OB_POINTCLOUD;
+ temp_object->data = (void *)pointcloud;
+ temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
+ iter->current = temp_object;
+ return true;
+ }
+ }
+ data->geometry_component_owner = nullptr;
+ return false;
+}
+
+void deg_iterator_duplis_init(DEGObjectIterData *data, Object *object)
+{
+ if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) &&
+ ((object->transflag & OB_DUPLI) || object->runtime.geometry_set_eval != nullptr)) {
+ data->dupli_parent = object;
+ data->dupli_list = object_duplilist(data->graph, data->scene, object);
+ data->dupli_object_next = (DupliObject *)data->dupli_list->first;
+ }
+}
+
+/* Returns false when iterator is exhausted. */
+bool deg_iterator_duplis_step(DEGObjectIterData *data)
+{
+ if (data->dupli_list == nullptr) {
+ return false;
+ }
+
while (data->dupli_object_next != nullptr) {
DupliObject *dob = data->dupli_object_next;
Object *obd = dob->ob;
@@ -171,73 +247,81 @@ bool deg_objects_dupli_iterator_next(BLI_Iterator *iter)
copy_m4_m4(data->temp_dupli_object.obmat, dob->mat);
invert_m4_m4(data->temp_dupli_object.imat, data->temp_dupli_object.obmat);
- iter->current = &data->temp_dupli_object;
+ deg_iterator_components_init(data, &data->temp_dupli_object);
BLI_assert(deg::deg_validate_copy_on_write_datablock(&data->temp_dupli_object.id));
return true;
}
+ verify_id_properties_freed(data);
+ free_object_duplilist(data->dupli_list);
+ data->dupli_parent = nullptr;
+ data->dupli_list = nullptr;
+ data->dupli_object_next = nullptr;
+ data->dupli_object_current = nullptr;
+ deg_invalidate_iterator_work_data(data);
return false;
}
-void deg_iterator_objects_step(BLI_Iterator *iter, deg::IDNode *id_node)
+/* Returns false when iterator is exhausted. */
+bool deg_iterator_objects_step(DEGObjectIterData *data)
{
- /* Set it early in case we need to exit and we are running from within a loop. */
- iter->skip = true;
+ deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(data->graph);
- if (!id_node->is_directly_visible) {
- return;
- }
+ for (; data->id_node_index < data->num_id_nodes; data->id_node_index++) {
+ deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
- DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
- const ID_Type id_type = GS(id_node->id_orig->name);
+ if (!id_node->is_directly_visible) {
+ continue;
+ }
- if (id_type != ID_OB) {
- return;
- }
+ const ID_Type id_type = GS(id_node->id_orig->name);
- switch (id_node->linked_state) {
- case deg::DEG_ID_LINKED_DIRECTLY:
- if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY) == 0) {
- return;
- }
- break;
- case deg::DEG_ID_LINKED_VIA_SET:
- if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) == 0) {
- return;
- }
- break;
- case deg::DEG_ID_LINKED_INDIRECTLY:
- if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY) == 0) {
- return;
- }
- break;
- }
+ if (id_type != ID_OB) {
+ continue;
+ }
- Object *object = (Object *)id_node->id_cow;
- BLI_assert(deg::deg_validate_copy_on_write_datablock(&object->id));
+ switch (id_node->linked_state) {
+ case deg::DEG_ID_LINKED_DIRECTLY:
+ if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_DIRECTLY) == 0) {
+ continue;
+ }
+ break;
+ case deg::DEG_ID_LINKED_VIA_SET:
+ if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_VIA_SET) == 0) {
+ continue;
+ }
+ break;
+ case deg::DEG_ID_LINKED_INDIRECTLY:
+ if ((data->flag & DEG_ITER_OBJECT_FLAG_LINKED_INDIRECTLY) == 0) {
+ continue;
+ }
+ break;
+ }
- int ob_visibility = OB_VISIBLE_ALL;
- if (data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) {
- ob_visibility = BKE_object_visibility(object, data->eval_mode);
+ Object *object = (Object *)id_node->id_cow;
+ BLI_assert(deg::deg_validate_copy_on_write_datablock(&object->id));
- if (object->type != OB_MBALL && deg_object_hide_original(data->eval_mode, object, nullptr)) {
- return;
+ int ob_visibility = OB_VISIBLE_ALL;
+ if (data->flag & DEG_ITER_OBJECT_FLAG_VISIBLE) {
+ ob_visibility = BKE_object_visibility(object, data->eval_mode);
+
+ if (object->type != OB_MBALL && deg_object_hide_original(data->eval_mode, object, nullptr)) {
+ continue;
+ }
}
- }
- object->runtime.select_id = DEG_get_original_object(object)->runtime.select_id;
- if (ob_visibility & OB_VISIBLE_INSTANCES) {
- if ((data->flag & DEG_ITER_OBJECT_FLAG_DUPLI) && (object->transflag & OB_DUPLI)) {
- data->dupli_parent = object;
- data->dupli_list = object_duplilist(data->graph, data->scene, object);
- data->dupli_object_next = (DupliObject *)data->dupli_list->first;
+ object->runtime.select_id = DEG_get_original_object(object)->runtime.select_id;
+ if (ob_visibility & OB_VISIBLE_INSTANCES) {
+ deg_iterator_duplis_init(data, object);
}
- }
- if (ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) {
- iter->current = object;
- iter->skip = false;
+ if (ob_visibility & (OB_VISIBLE_SELF | OB_VISIBLE_PARTICLES)) {
+ deg_iterator_components_init(data, object);
+ }
+ data->id_node_index++;
+ return true;
}
+ return false;
}
} // namespace
@@ -263,46 +347,29 @@ void DEG_iterator_objects_begin(BLI_Iterator *iter, DEGObjectIterData *data)
data->id_node_index = 0;
data->num_id_nodes = num_id_nodes;
data->eval_mode = DEG_get_mode(depsgraph);
+ data->geometry_component_id = 0;
+ data->geometry_component_owner = nullptr;
deg_invalidate_iterator_work_data(data);
- deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
- deg_iterator_objects_step(iter, id_node);
-
- if (iter->skip) {
- DEG_iterator_objects_next(iter);
- }
+ DEG_iterator_objects_next(iter);
}
void DEG_iterator_objects_next(BLI_Iterator *iter)
{
DEGObjectIterData *data = (DEGObjectIterData *)iter->data;
- Depsgraph *depsgraph = data->graph;
- deg::Depsgraph *deg_graph = reinterpret_cast<deg::Depsgraph *>(depsgraph);
- do {
- iter->skip = false;
- if (data->dupli_list) {
- if (deg_objects_dupli_iterator_next(iter)) {
- return;
- }
-
- verify_id_properties_freed(data);
- free_object_duplilist(data->dupli_list);
- data->dupli_parent = nullptr;
- data->dupli_list = nullptr;
- data->dupli_object_next = nullptr;
- data->dupli_object_current = nullptr;
- deg_invalidate_iterator_work_data(data);
- }
-
- ++data->id_node_index;
- if (data->id_node_index == data->num_id_nodes) {
- iter->valid = false;
+ while (true) {
+ if (deg_iterator_components_step(iter)) {
return;
}
-
- deg::IDNode *id_node = deg_graph->id_nodes[data->id_node_index];
- deg_iterator_objects_step(iter, id_node);
- } while (iter->skip);
+ if (deg_iterator_duplis_step(data)) {
+ continue;
+ }
+ if (deg_iterator_objects_step(data)) {
+ continue;
+ }
+ iter->valid = false;
+ break;
+ }
}
void DEG_iterator_objects_end(BLI_Iterator *iter)