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:
Diffstat (limited to 'source/blender/editors/object/object_modifier.c')
-rw-r--r--source/blender/editors/object/object_modifier.c283
1 files changed, 238 insertions, 45 deletions
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)