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
diff options
context:
space:
mode:
authorLukas Tönne <lukas.toenne@gmail.com>2016-12-28 19:30:58 +0300
committerLukas Tönne <lukas.toenne@gmail.com>2016-12-28 19:30:58 +0300
commit6ecab6dd8e48d564a2b43e0e81e79d079e8b4c77 (patch)
tree618e2d24eb34a05a81f726dd52eb2b7468e9296d /source/blender/editors/object
parent605263177b8eea24c1449e4dbf0138175ec3dddf (diff)
Revert particle system and point cache removal in blender2.8 branch.
This reverts commit 5aa19be91263a249ffae75573e3b32f24269d890 and b4a721af694817fa921b119df83d33ede7d7fed0. Due to postponement of particle system rewrite it was decided to put particle code back into the 2.8 branch for the time being.
Diffstat (limited to 'source/blender/editors/object')
-rw-r--r--source/blender/editors/object/object_add.c19
-rw-r--r--source/blender/editors/object/object_edit.c22
-rw-r--r--source/blender/editors/object/object_intern.h1
-rw-r--r--source/blender/editors/object/object_modifier.c283
-rw-r--r--source/blender/editors/object/object_ops.c1
-rw-r--r--source/blender/editors/object/object_relations.c5
-rw-r--r--source/blender/editors/object/object_select.c41
7 files changed, 325 insertions, 47 deletions
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index baea0088e1f..f42dafd094c 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -83,6 +83,7 @@
#include "BKE_mesh.h"
#include "BKE_nla.h"
#include "BKE_object.h"
+#include "BKE_particle.h"
#include "BKE_report.h"
#include "BKE_sca.h"
#include "BKE_scene.h"
@@ -2021,6 +2022,24 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
}
}
}
+ if (dupflag & USER_DUP_PSYS) {
+ ParticleSystem *psys;
+ for (psys = obn->particlesystem.first; psys; psys = psys->next) {
+ id = (ID *) psys->part;
+ if (id) {
+ ID_NEW_REMAP_US(psys->part)
+ else {
+ psys->part = ID_NEW_SET(psys->part, BKE_particlesettings_copy(bmain, psys->part));
+ }
+
+ if (dupflag & USER_DUP_ACT) {
+ BKE_animdata_copy_id_action(&psys->part->id, true);
+ }
+
+ id_us_min(id);
+ }
+ }
+ }
id = obn->data;
didit = 0;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 6b3284fe8b1..111afcdc7a7 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -75,6 +75,7 @@
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_object.h"
+#include "BKE_pointcache.h"
#include "BKE_property.h"
#include "BKE_sca.h"
#include "BKE_softbody.h"
@@ -429,9 +430,22 @@ void ED_object_editmode_exit(bContext *C, int flag)
/* freedata only 0 now on file saves and render */
if (freedata) {
+ ListBase pidlist;
+ PTCacheID *pid;
+
/* for example; displist make is different in editmode */
scene->obedit = NULL; // XXX for context
+ /* flag object caches as outdated */
+ BKE_ptcache_ids_from_object(&pidlist, obedit, scene, 0);
+ for (pid = pidlist.first; pid; pid = pid->next) {
+ if (pid->type != PTCACHE_TYPE_PARTICLES) /* particles don't need reset on geometry change */
+ pid->cache->flag |= PTCACHE_OUTDATED;
+ }
+ BLI_freelistN(&pidlist);
+
+ BKE_ptcache_object_reset(scene, obedit, PTCACHE_RESET_OUTDATED);
+
/* also flush ob recalc, doesn't take much overhead, but used for particles */
DAG_id_tag_update(&obedit->id, OB_RECALC_OB | OB_RECALC_DATA);
@@ -1569,9 +1583,13 @@ static EnumPropertyItem *object_mode_set_itemsf(bContext *C, PointerRNA *UNUSED(
ob = CTX_data_active_object(C);
if (ob) {
+ const bool use_mode_particle_edit = (BLI_listbase_is_empty(&ob->particlesystem) == false) ||
+ (ob->soft != NULL) ||
+ (modifiers_findByType(ob, eModifierType_Cloth) != NULL);
while (input->identifier) {
if ((input->value == OB_MODE_EDIT && OB_TYPE_SUPPORT_EDITMODE(ob->type)) ||
(input->value == OB_MODE_POSE && (ob->type == OB_ARMATURE)) ||
+ (input->value == OB_MODE_PARTICLE_EDIT && use_mode_particle_edit) ||
(ELEM(input->value, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT,
OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT) && (ob->type == OB_MESH)) ||
(input->value == OB_MODE_OBJECT))
@@ -1613,6 +1631,8 @@ static const char *object_mode_op_string(int mode)
return "PAINT_OT_weight_paint_toggle";
if (mode == OB_MODE_TEXTURE_PAINT)
return "PAINT_OT_texture_paint_toggle";
+ if (mode == OB_MODE_PARTICLE_EDIT)
+ return "PARTICLE_OT_particle_edit_toggle";
if (mode == OB_MODE_POSE)
return "OBJECT_OT_posemode_toggle";
if (mode == OB_MODE_GPENCIL)
@@ -1634,7 +1654,7 @@ static bool object_mode_compat_test(Object *ob, ObjectMode mode)
switch (ob->type) {
case OB_MESH:
if (mode & (OB_MODE_EDIT | OB_MODE_SCULPT | OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT |
- OB_MODE_TEXTURE_PAINT))
+ OB_MODE_TEXTURE_PAINT | OB_MODE_PARTICLE_EDIT))
{
return true;
}
diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h
index 3a6e585d4c5..9710e4f843d 100644
--- a/source/blender/editors/object/object_intern.h
+++ b/source/blender/editors/object/object_intern.h
@@ -169,6 +169,7 @@ void OBJECT_OT_modifier_remove(struct wmOperatorType *ot);
void OBJECT_OT_modifier_move_up(struct wmOperatorType *ot);
void OBJECT_OT_modifier_move_down(struct wmOperatorType *ot);
void OBJECT_OT_modifier_apply(struct wmOperatorType *ot);
+void OBJECT_OT_modifier_convert(struct wmOperatorType *ot);
void OBJECT_OT_modifier_copy(struct wmOperatorType *ot);
void OBJECT_OT_multires_subdivide(struct wmOperatorType *ot);
void OBJECT_OT_multires_reshape(struct wmOperatorType *ot);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 9175bd69a28..b44ddf925a8 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -41,7 +41,6 @@
#include "DNA_mesh_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_force.h"
-#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BLI_bitmap.h"
@@ -72,6 +71,7 @@
#include "BKE_object_deform.h"
#include "BKE_ocean.h"
#include "BKE_paint.h"
+#include "BKE_particle.h"
#include "BKE_softbody.h"
#include "BKE_editmesh.h"
@@ -111,56 +111,64 @@ ModifierData *ED_object_modifier_add(ReportList *reports, Main *bmain, Scene *sc
}
}
- /* get new modifier data to add */
- new_md = modifier_new(type);
-
- if (mti->flags & eModifierTypeFlag_RequiresOriginalData) {
- md = ob->modifiers.first;
-
- while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
- md = md->next;
-
- BLI_insertlinkbefore(&ob->modifiers, md, new_md);
+ if (type == eModifierType_ParticleSystem) {
+ /* don't need to worry about the new modifier's name, since that is set to the number
+ * of particle systems which shouldn't have too many duplicates
+ */
+ new_md = object_add_particle_system(scene, ob, name);
}
- else
- BLI_addtail(&ob->modifiers, new_md);
+ else {
+ /* get new modifier data to add */
+ new_md = modifier_new(type);
+
+ if (mti->flags & eModifierTypeFlag_RequiresOriginalData) {
+ md = ob->modifiers.first;
+
+ while (md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform)
+ md = md->next;
+
+ BLI_insertlinkbefore(&ob->modifiers, md, new_md);
+ }
+ else
+ BLI_addtail(&ob->modifiers, new_md);
- if (name) {
- BLI_strncpy_utf8(new_md->name, name, sizeof(new_md->name));
- }
+ if (name) {
+ BLI_strncpy_utf8(new_md->name, name, sizeof(new_md->name));
+ }
- /* make sure modifier data has unique name */
+ /* make sure modifier data has unique name */
- modifier_unique_name(&ob->modifiers, new_md);
-
- /* special cases */
- if (type == eModifierType_Softbody) {
- if (!ob->soft) {
- ob->soft = sbNew(scene);
- ob->softflag |= OB_SB_GOAL | OB_SB_EDGES;
- }
- }
- else if (type == eModifierType_Collision) {
- if (!ob->pd)
- ob->pd = object_add_collision_fields(0);
+ modifier_unique_name(&ob->modifiers, new_md);
- ob->pd->deflect = 1;
- }
- else if (type == eModifierType_Surface) {
- /* pass */
- }
- else if (type == eModifierType_Multires) {
- /* set totlvl from existing MDISPS layer if object already had it */
- multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
+ /* special cases */
+ if (type == eModifierType_Softbody) {
+ if (!ob->soft) {
+ ob->soft = sbNew(scene);
+ ob->softflag |= OB_SB_GOAL | OB_SB_EDGES;
+ }
+ }
+ else if (type == eModifierType_Collision) {
+ if (!ob->pd)
+ ob->pd = object_add_collision_fields(0);
+
+ ob->pd->deflect = 1;
+ }
+ else if (type == eModifierType_Surface) {
+ /* pass */
+ }
+ else if (type == eModifierType_Multires) {
+ /* set totlvl from existing MDISPS layer if object already had it */
+ multiresModifier_set_levels_from_disps((MultiresModifierData *)new_md, ob);
- if (ob->mode & OB_MODE_SCULPT) {
- /* ensure that grid paint mask layer is created */
- BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
+ if (ob->mode & OB_MODE_SCULPT) {
+ /* ensure that grid paint mask layer is created */
+ BKE_sculpt_mask_layers_ensure(ob, (MultiresModifierData *)new_md);
+ }
+ }
+ else if (type == eModifierType_Skin) {
+ /* ensure skin-node customdata exists */
+ BKE_mesh_ensure_skin_customdata(ob->data);
}
- }
- else if (type == eModifierType_Skin) {
- /* ensure skin-node customdata exists */
- BKE_mesh_ensure_skin_customdata(ob->data);
}
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
@@ -272,7 +280,14 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md,
}
/* special cases */
- if (md->type == eModifierType_Softbody) {
+ if (md->type == eModifierType_ParticleSystem) {
+ ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)md;
+
+ BLI_remlink(&ob->particlesystem, psmd->psys);
+ psys_free(ob, psmd->psys);
+ psmd->psys = NULL;
+ }
+ else if (md->type == eModifierType_Softbody) {
if (ob->soft) {
sbFree(ob->soft);
ob->soft = NULL;
@@ -299,6 +314,12 @@ static bool object_modifier_remove(Main *bmain, Object *ob, ModifierData *md,
modifier_skin_customdata_delete(ob);
}
+ if (ELEM(md->type, eModifierType_Softbody, eModifierType_Cloth) &&
+ BLI_listbase_is_empty(&ob->particlesystem))
+ {
+ ob->mode &= ~OB_MODE_PARTICLE_EDIT;
+ }
+
DAG_relations_tag_update(bmain);
BLI_remlink(&ob->modifiers, md);
@@ -390,6 +411,115 @@ int ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *
return 1;
}
+int ED_object_modifier_convert(ReportList *UNUSED(reports), Main *bmain, Scene *scene, Object *ob, ModifierData *md)
+{
+ Object *obn;
+ ParticleSystem *psys;
+ ParticleCacheKey *key, **cache;
+ ParticleSettings *part;
+ Mesh *me;
+ MVert *mvert;
+ MEdge *medge;
+ int a, k, kmax;
+ int totvert = 0, totedge = 0, cvert = 0;
+ int totpart = 0, totchild = 0;
+
+ if (md->type != eModifierType_ParticleSystem) return 0;
+ if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) return 0;
+
+ psys = ((ParticleSystemModifierData *)md)->psys;
+ part = psys->part;
+
+ if (part->ren_as != PART_DRAW_PATH || psys->pathcache == NULL)
+ return 0;
+
+ totpart = psys->totcached;
+ totchild = psys->totchildcache;
+
+ if (totchild && (part->draw & PART_DRAW_PARENT) == 0)
+ totpart = 0;
+
+ /* count */
+ cache = psys->pathcache;
+ for (a = 0; a < totpart; a++) {
+ key = cache[a];
+
+ if (key->segments > 0) {
+ totvert += key->segments + 1;
+ totedge += key->segments;
+ }
+ }
+
+ cache = psys->childcache;
+ for (a = 0; a < totchild; a++) {
+ key = cache[a];
+
+ if (key->segments > 0) {
+ totvert += key->segments + 1;
+ totedge += key->segments;
+ }
+ }
+
+ if (totvert == 0) return 0;
+
+ /* add new mesh */
+ obn = BKE_object_add(bmain, scene, OB_MESH, NULL);
+ me = obn->data;
+
+ me->totvert = totvert;
+ me->totedge = totedge;
+
+ me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, totvert);
+ me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
+ me->mface = CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, 0);
+
+ mvert = me->mvert;
+ medge = me->medge;
+
+ /* copy coordinates */
+ cache = psys->pathcache;
+ for (a = 0; a < totpart; a++) {
+ key = cache[a];
+ kmax = key->segments;
+ for (k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
+ copy_v3_v3(mvert->co, key->co);
+ if (k) {
+ medge->v1 = cvert - 1;
+ medge->v2 = cvert;
+ medge->flag = ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
+ medge++;
+ }
+ else {
+ /* cheap trick to select the roots */
+ mvert->flag |= SELECT;
+ }
+ }
+ }
+
+ cache = psys->childcache;
+ for (a = 0; a < totchild; a++) {
+ key = cache[a];
+ kmax = key->segments;
+ for (k = 0; k <= kmax; k++, key++, cvert++, mvert++) {
+ copy_v3_v3(mvert->co, key->co);
+ if (k) {
+ medge->v1 = cvert - 1;
+ medge->v2 = cvert;
+ medge->flag = ME_EDGEDRAW | ME_EDGERENDER | ME_LOOSEEDGE;
+ medge++;
+ }
+ else {
+ /* cheap trick to select the roots */
+ mvert->flag |= SELECT;
+ }
+ }
+ }
+
+ DAG_relations_tag_update(bmain);
+
+ return 1;
+}
+
static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md)
{
const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
@@ -520,6 +650,20 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob,
return 0;
}
+ /* lattice modifier can be applied to particle system too */
+ if (ob->particlesystem.first) {
+
+ ParticleSystem *psys = ob->particlesystem.first;
+
+ for (; psys; psys = psys->next) {
+
+ if (psys->part->type != PART_HAIR)
+ continue;
+
+ psys_apply_hair_lattice(scene, ob, psys);
+ }
+ }
+
return 1;
}
@@ -728,13 +872,21 @@ 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);
Object *ob = ED_object_active_context(C);
ModifierData *md = edit_modifier_property_get(op, ob, 0);
+ int mode_orig = ob->mode;
if (!md || !ED_object_modifier_remove(op->reports, bmain, ob, md))
return OPERATOR_CANCELLED;
WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ /* if cloth/softbody was removed, particle mode could be cleared */
+ if (mode_orig & OB_MODE_PARTICLE_EDIT)
+ if ((ob->mode & OB_MODE_PARTICLE_EDIT) == 0)
+ if (scene->basact && scene->basact->object == ob)
+ WM_event_add_notifier(C, NC_SCENE | ND_MODE | NS_MODE_OBJECT, NULL);
return OPERATOR_FINISHED;
}
@@ -890,6 +1042,47 @@ void OBJECT_OT_modifier_apply(wmOperatorType *ot)
edit_modifier_properties(ot);
}
+/************************ convert modifier operator *********************/
+
+static int modifier_convert_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_convert(op->reports, bmain, scene, ob, md))
+ return OPERATOR_CANCELLED;
+
+ DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+static int modifier_convert_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ if (edit_modifier_invoke_properties(C, op))
+ return modifier_convert_exec(C, op);
+ else
+ return OPERATOR_CANCELLED;
+}
+
+void OBJECT_OT_modifier_convert(wmOperatorType *ot)
+{
+ ot->name = "Convert Modifier";
+ ot->description = "Convert particles to a mesh object";
+ ot->idname = "OBJECT_OT_modifier_convert";
+
+ ot->invoke = modifier_convert_invoke;
+ ot->exec = modifier_convert_exec;
+ ot->poll = edit_modifier_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_INTERNAL;
+ edit_modifier_properties(ot);
+}
+
/************************ copy modifier operator *********************/
static int modifier_copy_exec(bContext *C, wmOperator *op)
diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c
index 4837ca50105..7e7e1ef182c 100644
--- a/source/blender/editors/object/object_ops.c
+++ b/source/blender/editors/object/object_ops.c
@@ -133,6 +133,7 @@ void ED_operatortypes_object(void)
WM_operatortype_append(OBJECT_OT_modifier_move_up);
WM_operatortype_append(OBJECT_OT_modifier_move_down);
WM_operatortype_append(OBJECT_OT_modifier_apply);
+ WM_operatortype_append(OBJECT_OT_modifier_convert);
WM_operatortype_append(OBJECT_OT_modifier_copy);
WM_operatortype_append(OBJECT_OT_multires_subdivide);
WM_operatortype_append(OBJECT_OT_multires_reshape);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index 088ade6963d..d30022c01f8 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -43,6 +43,7 @@
#include "DNA_lattice_types.h"
#include "DNA_material_types.h"
#include "DNA_meta_types.h"
+#include "DNA_particle_types.h"
#include "DNA_scene_types.h"
#include "DNA_world_types.h"
#include "DNA_object_types.h"
@@ -2214,6 +2215,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
Scene *scene = CTX_data_scene(C);
AnimData *adt;
+ ParticleSystem *psys;
Material *ma, ***matarar;
Lamp *la;
ID *id;
@@ -2280,6 +2282,9 @@ static int make_local_exec(bContext *C, wmOperator *op)
}
}
+ for (psys = ob->particlesystem.first; psys; psys = psys->next)
+ id_make_local(bmain, &psys->part->id, false, false);
+
adt = BKE_animdata_from_id(&ob->id);
if (adt) BKE_animdata_make_local(adt);
}
diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c
index 7db32957b42..f1b7186f8a1 100644
--- a/source/blender/editors/object/object_select.c
+++ b/source/blender/editors/object/object_select.c
@@ -37,7 +37,6 @@
#include "DNA_group_types.h"
#include "DNA_material_types.h"
#include "DNA_modifier_types.h"
-#include "DNA_object_types.h"
#include "DNA_property_types.h"
#include "DNA_scene_types.h"
#include "DNA_armature_types.h"
@@ -54,6 +53,7 @@
#include "BKE_group.h"
#include "BKE_main.h"
#include "BKE_material.h"
+#include "BKE_particle.h"
#include "BKE_property.h"
#include "BKE_report.h"
#include "BKE_scene.h"
@@ -192,6 +192,7 @@ enum {
OBJECT_SELECT_LINKED_MATERIAL,
OBJECT_SELECT_LINKED_TEXTURE,
OBJECT_SELECT_LINKED_DUPGROUP,
+ OBJECT_SELECT_LINKED_PARTICLE,
OBJECT_SELECT_LINKED_LIBRARY,
OBJECT_SELECT_LINKED_LIBRARY_OBDATA
};
@@ -202,6 +203,7 @@ static EnumPropertyItem prop_select_linked_types[] = {
{OBJECT_SELECT_LINKED_MATERIAL, "MATERIAL", 0, "Material", ""},
{OBJECT_SELECT_LINKED_TEXTURE, "TEXTURE", 0, "Texture", ""},
{OBJECT_SELECT_LINKED_DUPGROUP, "DUPGROUP", 0, "Dupligroup", ""},
+ {OBJECT_SELECT_LINKED_PARTICLE, "PARTICLE", 0, "Particle System", ""},
{OBJECT_SELECT_LINKED_LIBRARY, "LIBRARY", 0, "Library", ""},
{OBJECT_SELECT_LINKED_LIBRARY_OBDATA, "LIBRARY_OBDATA", 0, "Library (Object Data)", ""},
{0, NULL, 0, NULL, NULL}
@@ -311,6 +313,37 @@ static bool object_select_all_by_dup_group(bContext *C, Object *ob)
return changed;
}
+static bool object_select_all_by_particle(bContext *C, Object *ob)
+{
+ ParticleSystem *psys_act = psys_get_current(ob);
+ bool changed = false;
+
+ CTX_DATA_BEGIN (C, Base *, base, visible_bases)
+ {
+ if ((base->flag & SELECT) == 0) {
+ /* loop through other particles*/
+ ParticleSystem *psys;
+
+ for (psys = base->object->particlesystem.first; psys; psys = psys->next) {
+ if (psys->part == psys_act->part) {
+ base->flag |= SELECT;
+ changed = true;
+ break;
+ }
+
+ if (base->flag & SELECT) {
+ break;
+ }
+ }
+
+ base->object->flag = base->flag;
+ }
+ }
+ CTX_DATA_END;
+
+ return changed;
+}
+
static bool object_select_all_by_library(bContext *C, Library *lib)
{
bool changed = false;
@@ -428,6 +461,12 @@ static int object_select_linked_exec(bContext *C, wmOperator *op)
changed = object_select_all_by_dup_group(C, ob);
}
+ else if (nr == OBJECT_SELECT_LINKED_PARTICLE) {
+ if (BLI_listbase_is_empty(&ob->particlesystem))
+ return OPERATOR_CANCELLED;
+
+ changed = object_select_all_by_particle(C, ob);
+ }
else if (nr == OBJECT_SELECT_LINKED_LIBRARY) {
/* do nothing */
changed = object_select_all_by_library(C, ob->id.lib);