[Bf-blender-cvs] [5560f324471] master: Fix T94078: Wrong Bound Box calculated for curves

Germano Cavalcante noreply at git.blender.org
Fri Jan 7 14:57:34 CET 2022


Commit: 5560f3244717221600506866bf1c79d370e0045e
Author: Germano Cavalcante
Date:   Tue Jan 4 11:29:15 2022 -0300
Branches: master
https://developer.blender.org/rB5560f3244717221600506866bf1c79d370e0045e

Fix T94078: Wrong Bound Box calculated for curves

`DEG_OBJECT_ITER_FOR_RENDER_ENGINE_BEGIN` creates temporary objects that
correspond to duplicates or instances.

These temporary objects can share same pointers with the original object
as in the case of Bounding Box.

Bound Box of temporary objects is marked dirty in
`BKE_object_replace_data_on_shallow_copy` since `ob->data` is different.

This causes the original Bounding Box, calculated for the evaluated
geometry, to be lost.

The solution in this commit is to change the boundbox reference of the
temporary objects, so the boundbox of the non-temporary object (with
the data curve) is not marked dirty.

Differential Revision: https://developer.blender.org/D13581

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

M	source/blender/depsgraph/intern/depsgraph_query_iter.cc
M	source/blender/draw/intern/draw_manager.c

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

diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index c84adbcde00..0b219dcbf5e 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -76,14 +76,8 @@ void deg_invalidate_iterator_work_data(DEGObjectIterData *data)
 #endif
 }
 
-void verify_id_properties_freed(DEGObjectIterData *data)
+void ensure_id_properties_freed(const Object *dupli_object, Object *temp_dupli_object)
 {
-  if (data->dupli_object_current == nullptr) {
-    /* We didn't enter duplication yet, so we can't have any dangling pointers. */
-    return;
-  }
-  const Object *dupli_object = data->dupli_object_current->ob;
-  Object *temp_dupli_object = &data->temp_dupli_object;
   if (temp_dupli_object->id.properties == nullptr) {
     /* No ID properties in temp data-block -- no leak is possible. */
     return;
@@ -97,6 +91,35 @@ void verify_id_properties_freed(DEGObjectIterData *data)
   temp_dupli_object->id.properties = nullptr;
 }
 
+void ensure_boundbox_freed(const Object *dupli_object, Object *temp_dupli_object)
+{
+  if (temp_dupli_object->runtime.bb == nullptr) {
+    /* No Bounding Box in temp data-block -- no leak is possible. */
+    return;
+  }
+  if (temp_dupli_object->runtime.bb == dupli_object->runtime.bb) {
+    /* Temp copy of object did not modify Bounding Box. */
+    return;
+  }
+  /* Free memory which is owned by temporary storage which is about to get overwritten. */
+  MEM_freeN(temp_dupli_object->runtime.bb);
+  temp_dupli_object->runtime.bb = nullptr;
+}
+
+void free_owned_memory(DEGObjectIterData *data)
+{
+  if (data->dupli_object_current == nullptr) {
+    /* We didn't enter duplication yet, so we can't have any dangling pointers. */
+    return;
+  }
+
+  const Object *dupli_object = data->dupli_object_current->ob;
+  Object *temp_dupli_object = &data->temp_dupli_object;
+
+  ensure_id_properties_freed(dupli_object, temp_dupli_object);
+  ensure_boundbox_freed(dupli_object, temp_dupli_object);
+}
+
 bool deg_object_hide_original(eEvaluationMode eval_mode, Object *ob, DupliObject *dob)
 {
   /* Automatic hiding if this object is being instanced on verts/faces/frames
@@ -153,7 +176,7 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data)
       continue;
     }
 
-    verify_id_properties_freed(data);
+    free_owned_memory(data);
 
     data->dupli_object_current = dob;
 
@@ -169,6 +192,8 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data)
     copy_v4_v4(temp_dupli_object->color, dupli_parent->color);
     temp_dupli_object->runtime.select_id = dupli_parent->runtime.select_id;
     if (dob->ob->data != dob->ob_data) {
+      /* Do not modify the original boundbox. */
+      temp_dupli_object->runtime.bb = nullptr;
       BKE_object_replace_data_on_shallow_copy(temp_dupli_object, dob->ob_data);
     }
 
@@ -192,7 +217,7 @@ bool deg_iterator_duplis_step(DEGObjectIterData *data)
     return true;
   }
 
-  verify_id_properties_freed(data);
+  free_owned_memory(data);
   free_object_duplilist(data->dupli_list);
   data->dupli_parent = nullptr;
   data->dupli_list = nullptr;
diff --git a/source/blender/draw/intern/draw_manager.c b/source/blender/draw/intern/draw_manager.c
index 94950a1ff94..86ed08c5b0f 100644
--- a/source/blender/draw/intern/draw_manager.c
+++ b/source/blender/draw/intern/draw_manager.c
@@ -757,8 +757,11 @@ static void duplidata_key_free(void *key)
   }
   else {
     Object temp_object = *dupli_key->ob;
+    /* Do not modify the original boundbox. */
+    temp_object.runtime.bb = NULL;
     BKE_object_replace_data_on_shallow_copy(&temp_object, dupli_key->ob_data);
     drw_batch_cache_generate_requested(&temp_object);
+    MEM_SAFE_FREE(temp_object.runtime.bb);
   }
   MEM_freeN(key);
 }



More information about the Bf-blender-cvs mailing list