[Bf-blender-cvs] [b081108819c] geometry-nodes: Geometry Nodes: support geometry components in depsgraph object iterator

Jacques Lucke noreply at git.blender.org
Thu Nov 12 13:31:08 CET 2020


Commit: b081108819c02f117f6797b1fbaf296bc3aae769
Author: Jacques Lucke
Date:   Thu Nov 12 13:20:23 2020 +0100
Branches: geometry-nodes
https://developer.blender.org/rBb081108819c02f117f6797b1fbaf296bc3aae769

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, those 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.

===================================================================

M	source/blender/depsgraph/DEG_depsgraph_query.h
M	source/blender/depsgraph/intern/depsgraph_query_iter.cc

===================================================================

diff --git a/source/blender/depsgraph/DEG_depsgraph_query.h b/source/blender/depsgraph/DEG_depsgraph_query.h
index 7eb5f1ccec1..f877e99b16b 100644
--- a/source/blender/depsgraph/DEG_depsgraph_query.h
+++ b/source/blender/depsgraph/DEG_depsgraph_query.h
@@ -145,6 +145,16 @@ typedef struct DEGObjectIterData {
 
   eEvaluationMode eval_mode;
 
+  /* **** Iteration over geometry components **** */
+
+  /* The object whose components we currently iterate over.
+   * This might point to #temp_dupli_object. */
+  struct Object *geometry_component_owner;
+  /* Some identifier that is used to determine which geometry component should be returned next. */
+  int geometry_component_id;
+  /* Temporary storage for an object that is created from a component. */
+  struct Object temp_geometry_component_object;
+
   /* **** Iteration over dupli-list. *** */
 
   /* Object which created the dupli-list. */
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 7d47e1fb541..c82584e1858 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"
@@ -60,6 +61,7 @@
 #endif
 
 namespace deg = blender::deg;
+namespace bke = blender::bke;
 
 /* ************************ DEG ITERATORS ********************* */
 
@@ -121,9 +123,83 @@ 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;
+  }
+
+  bke::GeometrySet *geometry_set = bke::unwrap(
+      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;
+      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;
+      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;
@@ -170,72 +246,80 @@ 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;
+      }
     }
-  }
 
-  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;
+    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
@@ -261,46 +345,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

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list