[Bf-blender-cvs] [8ddf7556a51] master: Fix T78718: Crash when deleting particle system modifier with the X Shortcut.

Bastien Montagne noreply at git.blender.org
Thu Jul 9 11:53:40 CEST 2020


Commit: 8ddf7556a512b2b2ce89b75c9660e01a7aba8675
Author: Bastien Montagne
Date:   Thu Jul 9 11:44:11 2020 +0200
Branches: master
https://developer.blender.org/rB8ddf7556a512b2b2ce89b75c9660e01a7aba8675

Fix T78718: Crash when deleting particle system modifier with the X Shortcut.

Duplication and deletion code of modifiers was totally wrong for
particle system, that special weird thing needs its own custom
management.

Note that for now I chose not to duplicate the particle settings ID when
duplicating the modifier...

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

M	source/blender/blenkernel/BKE_particle.h
M	source/blender/blenkernel/intern/particle.c
M	source/blender/editors/include/ED_object.h
M	source/blender/editors/object/object_edit.c
M	source/blender/editors/object/object_modifier.c
M	source/blender/editors/space_outliner/outliner_tools.c
M	source/blender/makesrna/intern/rna_object.c
M	source/blender/makesrna/intern/rna_object_force.c

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

diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index a22cb9ef126..7de588450d6 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -365,6 +365,10 @@ struct ModifierData *object_add_particle_system(struct Main *bmain,
                                                 struct Scene *scene,
                                                 struct Object *ob,
                                                 const char *name);
+struct ModifierData *object_copy_particle_system(struct Main *bmain,
+                                                 struct Scene *scene,
+                                                 struct Object *ob,
+                                                 const struct ParticleSystem *psys_orig);
 void object_remove_particle_system(struct Main *bmain, struct Scene *scene, struct Object *ob);
 struct ParticleSettings *BKE_particlesettings_add(struct Main *bmain, const char *name);
 struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain,
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 942f3e0ca2b..cb1b523a7a9 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -3611,7 +3611,8 @@ void psys_mat_hair_to_global(
 /************************************************/
 /*          ParticleSettings handling           */
 /************************************************/
-ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob, const char *name)
+static ModifierData *object_add_or_copy_particle_system(
+    Main *bmain, Scene *scene, Object *ob, const char *name, const ParticleSystem *psys_orig)
 {
   ParticleSystem *psys;
   ModifierData *md;
@@ -3622,7 +3623,7 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
   }
 
   if (name == NULL) {
-    name = DATA_("ParticleSettings");
+    name = (psys_orig != NULL) ? psys_orig->name : DATA_("ParticleSettings");
   }
 
   psys = ob->particlesystem.first;
@@ -3635,8 +3636,13 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
   BLI_addtail(&ob->particlesystem, psys);
   psys_unique_name(ob, psys, name);
 
-  psys->part = BKE_particlesettings_add(bmain, psys->name);
-
+  if (psys_orig != NULL) {
+    psys->part = psys_orig->part;
+    id_us_plus(&psys->part->id);
+  }
+  else {
+    psys->part = BKE_particlesettings_add(bmain, psys->name);
+  }
   md = BKE_modifier_new(eModifierType_ParticleSystem);
   BLI_strncpy(md->name, psys->name, sizeof(md->name));
   BKE_modifier_unique_name(&ob->modifiers, md);
@@ -3656,6 +3662,20 @@ ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob,
 
   return md;
 }
+
+ModifierData *object_add_particle_system(Main *bmain, Scene *scene, Object *ob, const char *name)
+{
+  return object_add_or_copy_particle_system(bmain, scene, ob, name, NULL);
+}
+
+ModifierData *object_copy_particle_system(Main *bmain,
+                                          Scene *scene,
+                                          Object *ob,
+                                          const ParticleSystem *psys_orig)
+{
+  return object_add_or_copy_particle_system(bmain, scene, ob, NULL, psys_orig);
+}
+
 void object_remove_particle_system(Main *bmain, Scene *UNUSED(scene), Object *ob)
 {
   ParticleSystem *psys = psys_get_current(ob);
diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h
index 5ec4de5d597..d8f55a0f60a 100644
--- a/source/blender/editors/include/ED_object.h
+++ b/source/blender/editors/include/ED_object.h
@@ -362,9 +362,10 @@ struct ModifierData *ED_object_modifier_add(struct ReportList *reports,
                                             int type);
 bool ED_object_modifier_remove(struct ReportList *reports,
                                struct Main *bmain,
+                               struct Scene *scene,
                                struct Object *ob,
                                struct ModifierData *md);
-void ED_object_modifier_clear(struct Main *bmain, struct Object *ob);
+void ED_object_modifier_clear(struct Main *bmain, struct Scene *scene, struct Object *ob);
 bool ED_object_modifier_move_down(struct ReportList *reports,
                                   struct Object *ob,
                                   struct ModifierData *md);
@@ -392,6 +393,8 @@ bool ED_object_modifier_apply(struct Main *bmain,
                               int mode,
                               bool keep_modifier);
 int ED_object_modifier_copy(struct ReportList *reports,
+                            struct Main *bmain,
+                            struct Scene *scene,
                             struct Object *ob,
                             struct ModifierData *md);
 
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index a9eb454eb04..04113f70e52 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -895,7 +895,7 @@ void ED_object_check_force_modifiers(Main *bmain, Scene *scene, Object *object)
   else {
     if (!pd || (pd->shape != PFIELD_SHAPE_SURFACE) ||
         ELEM(pd->forcefield, 0, PFIELD_GUIDE, PFIELD_TEXTURE)) {
-      ED_object_modifier_remove(NULL, bmain, object, md);
+      ED_object_modifier_remove(NULL, bmain, scene, object, md);
     }
   }
 }
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 6c929ad781e..6f254ea9400 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -330,10 +330,8 @@ static bool object_modifier_safe_to_delete(Main *bmain,
           !ED_object_iter_other(bmain, ob, false, object_has_modifier_cb, &type));
 }
 
-static bool object_modifier_remove(Main *bmain,
-                                   Object *ob,
-                                   ModifierData *md,
-                                   bool *r_sort_depsgraph)
+static bool object_modifier_remove(
+    Main *bmain, Scene *scene, Object *ob, ModifierData *md, bool *r_sort_depsgraph)
 {
   /* It seems on rapid delete it is possible to
    * get called twice on same modifier, so make
@@ -344,11 +342,8 @@ static bool object_modifier_remove(Main *bmain,
 
   /* special cases */
   if (md->type == eModifierType_ParticleSystem) {
-    ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
-
-    BLI_remlink(&ob->particlesystem, psmd->psys);
-    psys_free(ob, psmd->psys);
-    psmd->psys = NULL;
+    object_remove_particle_system(bmain, scene, ob);
+    return true;
   }
   else if (md->type == eModifierType_Softbody) {
     if (ob->soft) {
@@ -391,12 +386,13 @@ static bool object_modifier_remove(Main *bmain,
   return 1;
 }
 
-bool ED_object_modifier_remove(ReportList *reports, Main *bmain, Object *ob, ModifierData *md)
+bool ED_object_modifier_remove(
+    ReportList *reports, Main *bmain, Scene *scene, Object *ob, ModifierData *md)
 {
   bool sort_depsgraph = false;
   bool ok;
 
-  ok = object_modifier_remove(bmain, ob, md, &sort_depsgraph);
+  ok = object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
 
   if (!ok) {
     BKE_reportf(reports, RPT_ERROR, "Modifier '%s' not in object '%s'", md->name, ob->id.name);
@@ -409,7 +405,7 @@ bool ED_object_modifier_remove(ReportList *reports, Main *bmain, Object *ob, Mod
   return 1;
 }
 
-void ED_object_modifier_clear(Main *bmain, Object *ob)
+void ED_object_modifier_clear(Main *bmain, Scene *scene, Object *ob)
 {
   ModifierData *md = ob->modifiers.first;
   bool sort_depsgraph = false;
@@ -423,7 +419,7 @@ void ED_object_modifier_clear(Main *bmain, Object *ob)
 
     next_md = md->next;
 
-    object_modifier_remove(bmain, ob, md, &sort_depsgraph);
+    object_modifier_remove(bmain, scene, ob, md, &sort_depsgraph);
 
     md = next_md;
   }
@@ -881,14 +877,23 @@ bool ED_object_modifier_apply(Main *bmain,
   return true;
 }
 
-int ED_object_modifier_copy(ReportList *UNUSED(reports), Object *ob, ModifierData *md)
+int ED_object_modifier_copy(
+    ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
 {
   ModifierData *nmd;
 
-  nmd = BKE_modifier_new(md->type);
-  BKE_modifier_copydata(md, nmd);
-  BLI_insertlinkafter(&ob->modifiers, md, nmd);
-  BKE_modifier_unique_name(&ob->modifiers, nmd);
+  if (md->type == eModifierType_ParticleSystem) {
+    nmd = object_copy_particle_system(bmain, scene, ob, ((ParticleSystemModifierData *)md)->psys);
+    BLI_remlink(&ob->modifiers, nmd);
+    BLI_insertlinkafter(&ob->modifiers, md, nmd);
+    return true;
+  }
+  else {
+    nmd = BKE_modifier_new(md->type);
+    BKE_modifier_copydata(md, nmd);
+    BLI_insertlinkafter(&ob->modifiers, md, nmd);
+    BKE_modifier_unique_name(&ob->modifiers, nmd);
+  }
 
   return 1;
 }
@@ -1120,6 +1125,7 @@ ModifierData *edit_modifier_property_get(wmOperator *op, Object *ob, int type)
 static int modifier_remove_exec(bContext *C, wmOperator *op)
 {
   Main *bmain = CTX_data_main(C);
+  Scene *scene = CTX_data_scene(C);
   ViewLayer *view_layer = CTX_data_view_layer(C);
   Object *ob = ED_object_active_context(C);
   ModifierData *md = edit_modifier_property_get(op, ob, 0);
@@ -1133,7 +1139,7 @@ static int modifier_remove_exec(bContext *C, wmOperator *op)
   char name[MAX_NAME];
   strcpy(name, md->name);
 
-  if (!ED_object_modifier_remove(op->reports, bmain, ob, md)) {
+  if (!ED_object_modifier_remove(op->reports, bmain, scene, ob, md)) {
     return OPERATOR_CANCELLED;
   }
 
@@ -1547,10 +1553,12 @@ void OBJECT_OT_modifier_convert(wmOperatorType *ot)
 
 static int modifier_copy_exec(bContext *C, wmOperator *op)
 {
+  Main *bmain = CTX_data_main(C);
+  Scene *scene = CTX_data_scene(C);
   Object *ob = ED_object_active_context(C);
   ModifierData *md = edit_modifier_property_get(op, ob, 0);
 
-  if (!md || !ED_object_modifier_copy(op->reports, ob, md)) {
+  if (!md || !ED_object_modifier_copy(op->reports, bmain, scene, ob, md)) {
     return OPERATOR_CANCELLED;
   }
 
diff --git a/source/blen

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list