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
path: root/source
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2020-07-09 12:44:11 +0300
committerBastien Montagne <bastien@blender.org>2020-07-09 12:46:28 +0300
commit8ddf7556a512b2b2ce89b75c9660e01a7aba8675 (patch)
treeaf98ecda886e9a12f65a30eba87357ea011eed8a /source
parentea5fe7abc183c1e53d327f97280f589499fe60bb (diff)
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...
Diffstat (limited to 'source')
-rw-r--r--source/blender/blenkernel/BKE_particle.h4
-rw-r--r--source/blender/blenkernel/intern/particle.c28
-rw-r--r--source/blender/editors/include/ED_object.h5
-rw-r--r--source/blender/editors/object/object_edit.c2
-rw-r--r--source/blender/editors/object/object_modifier.c48
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c3
-rw-r--r--source/blender/makesrna/intern/rna_object.c5
-rw-r--r--source/blender/makesrna/intern/rna_object_force.c2
8 files changed, 67 insertions, 30 deletions
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/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index a77b5424eb6..419e25d5dca 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -1127,6 +1127,7 @@ static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem
{
bContext *C = (bContext *)Carg;
Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
ModifierData *md = (ModifierData *)te->directdata;
Object *ob = (Object *)outliner_search_back(te, ID_OB);
@@ -1141,7 +1142,7 @@ static void modifier_cb(int event, TreeElement *te, TreeStoreElem *UNUSED(tselem
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
}
else if (event == OL_MODIFIER_OP_DELETE) {
- ED_object_modifier_remove(NULL, bmain, ob, md);
+ ED_object_modifier_remove(NULL, bmain, scene, ob, md);
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER | NA_REMOVED, ob);
te->store_elem->flag &= ~TSE_SELECTED;
}
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index 089410ffd25..00d3a6e84b7 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -1579,7 +1579,8 @@ static void rna_Object_modifier_remove(Object *object,
PointerRNA *md_ptr)
{
ModifierData *md = md_ptr->data;
- if (ED_object_modifier_remove(reports, CTX_data_main(C), object, md) == false) {
+ if (ED_object_modifier_remove(reports, CTX_data_main(C), CTX_data_scene(C), object, md) ==
+ false) {
/* error is already set */
return;
}
@@ -1591,7 +1592,7 @@ static void rna_Object_modifier_remove(Object *object,
static void rna_Object_modifier_clear(Object *object, bContext *C)
{
- ED_object_modifier_clear(CTX_data_main(C), object);
+ ED_object_modifier_clear(CTX_data_main(C), CTX_data_scene(C), object);
WM_main_add_notifier(NC_OBJECT | ND_MODIFIER | NA_REMOVED, object);
}
diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c
index 0b932f3236f..2524f590051 100644
--- a/source/blender/makesrna/intern/rna_object_force.c
+++ b/source/blender/makesrna/intern/rna_object_force.c
@@ -851,7 +851,7 @@ static void rna_CollisionSettings_dependency_update(Main *bmain, Scene *scene, P
ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Collision);
}
else if (!ob->pd->deflect && md) {
- ED_object_modifier_remove(NULL, bmain, ob, md);
+ ED_object_modifier_remove(NULL, bmain, scene, ob, md);
}
WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob);