[Bf-blender-cvs] [8aa87972cac] master: Fix T65295: Convert curve to mesh fails with Keep Original.

Bastien Montagne noreply at git.blender.org
Mon Jun 10 11:21:21 CEST 2019


Commit: 8aa87972cac3c9c3c5439b68b62e25c3fd4c4919
Author: Bastien Montagne
Date:   Mon Jun 10 11:06:16 2019 +0200
Branches: master
https://developer.blender.org/rB8aa87972cac3c9c3c5439b68b62e25c3fd4c4919

Fix T65295: Convert curve to mesh fails with Keep Original.

This code now expects to wrok from fully evaluated data, however when we
keep original, we are actually working from data just copied from orig
one.

Ideally, we'd do a single depsgraph update/eval *after* we have created
all new required data, but that is tricky to do properly in that code
without risking breaking one thing or another.

So for now, just going for the simple, if not optimal solution, and just
repeatedly re-evaluating whole deg every time we duplicate an object to
be converted. Yep, dummy, but simple and... safe. ;)

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

M	source/blender/editors/object/object_add.c

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

diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 2881163574b..0b9ced84a59 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -2009,7 +2009,7 @@ static bool convert_poll(bContext *C)
 
 /* Helper for convert_exec */
 static Base *duplibase_for_convert(
-    Main *bmain, Scene *scene, ViewLayer *view_layer, Base *base, Object *ob)
+    Main *bmain, Depsgraph *depsgraph, Scene *scene, ViewLayer *view_layer, Base *base, Object *ob)
 {
   Object *obn;
   Base *basen;
@@ -2019,12 +2019,27 @@ static Base *duplibase_for_convert(
   }
 
   obn = BKE_object_copy(bmain, ob);
-  DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
+  DEG_id_tag_update(&obn->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION);
   BKE_collection_object_add_from(bmain, scene, ob, obn);
 
   basen = BKE_view_layer_base_find(view_layer, obn);
   ED_object_base_select(basen, BA_SELECT);
   ED_object_base_select(base, BA_DESELECT);
+
+  /* XXX Doing that here is stupid, it means we update and re-evaluate the whole depsgraph every
+   * time we need to duplicate an object to convert it. Even worse, this is not 100% correct, since
+   * we do not yet have duplicated obdata.
+   * However, that is a safe solution for now. Proper, longer-term solution is to refactor
+   * convert_exec to:
+   *  - duplicate all data it needs to in a first loop.
+   *  - do a single update.
+   *  - convert data in a second loop. */
+  DEG_graph_tag_relations_update(depsgraph);
+  CustomData_MeshMasks customdata_mask_prev = scene->customdata_mask;
+  CustomData_MeshMasks_update(&scene->customdata_mask, &CD_MASK_MESH);
+  BKE_scene_graph_update_tagged(depsgraph, bmain);
+  scene->customdata_mask = customdata_mask_prev;
+
   return basen;
 }
 
@@ -2131,7 +2146,7 @@ static int convert_exec(bContext *C, wmOperator *op)
       ob->flag |= OB_DONE;
 
       if (keep_original) {
-        basen = duplibase_for_convert(bmain, scene, view_layer, base, NULL);
+        basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
         newob = basen->object;
 
         /* decrement original mesh's usage count  */
@@ -2156,7 +2171,7 @@ static int convert_exec(bContext *C, wmOperator *op)
       ob->flag |= OB_DONE;
 
       if (keep_original) {
-        basen = duplibase_for_convert(bmain, scene, view_layer, base, NULL);
+        basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
         newob = basen->object;
 
         /* decrement original mesh's usage count  */
@@ -2186,7 +2201,7 @@ static int convert_exec(bContext *C, wmOperator *op)
       ob->flag |= OB_DONE;
 
       if (keep_original) {
-        basen = duplibase_for_convert(bmain, scene, view_layer, base, NULL);
+        basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
         newob = basen->object;
 
         /* decrement original curve's usage count  */
@@ -2261,7 +2276,7 @@ static int convert_exec(bContext *C, wmOperator *op)
 
       if (target == OB_MESH) {
         if (keep_original) {
-          basen = duplibase_for_convert(bmain, scene, view_layer, base, NULL);
+          basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, NULL);
           newob = basen->object;
 
           /* decrement original curve's usage count  */
@@ -2296,7 +2311,7 @@ static int convert_exec(bContext *C, wmOperator *op)
       if (!(baseob->flag & OB_DONE)) {
         baseob->flag |= OB_DONE;
 
-        basen = duplibase_for_convert(bmain, scene, view_layer, base, baseob);
+        basen = duplibase_for_convert(bmain, depsgraph, scene, view_layer, base, baseob);
         newob = basen->object;
 
         mb = newob->data;



More information about the Bf-blender-cvs mailing list