diff options
Diffstat (limited to 'source/blender/editors/physics/particle_edit.c')
-rw-r--r-- | source/blender/editors/physics/particle_edit.c | 125 |
1 files changed, 109 insertions, 16 deletions
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index 6c3952bce83..cf02d2773c0 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -402,12 +402,12 @@ static void PE_set_view3d_data(bContext *C, PEData *data) /* note, the object argument means the modelview matrix does not account for the objects matrix, use viewmat rather than (obmat * viewmat) */ view3d_get_transformation(data->vc.ar, data->vc.rv3d, NULL, &data->mats); - if ((data->vc.v3d->drawtype>OB_WIRE) && (data->vc.v3d->flag & V3D_ZBUF_SELECT)) { + if (V3D_IS_ZBUF(data->vc.v3d)) { if (data->vc.v3d->flag & V3D_INVALID_BACKBUF) { /* needed or else the draw matrix can be incorrect */ view3d_operator_needs_opengl(C); - view3d_validate_backbuf(&data->vc); + ED_view3d_backbuf_validate(&data->vc); /* we may need to force an update here by setting the rv3d as dirty * for now it seems ok, but take care!: * rv3d->depths->dirty = 1; */ @@ -416,18 +416,18 @@ static void PE_set_view3d_data(bContext *C, PEData *data) } } -static void PE_create_shape_tree(PEData *data, Object *shapeob) +static bool PE_create_shape_tree(PEData *data, Object *shapeob) { DerivedMesh *dm = shapeob->derivedFinal; memset(&data->shape_bvh, 0, sizeof(data->shape_bvh)); if (!dm) { - return; + return false; } DM_ensure_tessface(dm); - bvhtree_from_mesh_faces(&data->shape_bvh, dm, 0.0f, 4, 8); + return bvhtree_from_mesh_faces(&data->shape_bvh, dm, 0.0f, 4, 8); } static void PE_free_shape_tree(PEData *data) @@ -445,8 +445,8 @@ static bool key_test_depth(PEData *data, const float co[3], const int screen_co[ float depth; /* nothing to do */ - if ((v3d->drawtype<=OB_WIRE) || (v3d->flag & V3D_ZBUF_SELECT)==0) - return 1; + if (!V3D_IS_ZBUF(v3d)) + return true; /* used to calculate here but all callers have the screen_co already, so pass as arg */ #if 0 @@ -4069,11 +4069,12 @@ void PARTICLE_OT_brush_edit(wmOperatorType *ot) static int shape_cut_poll(bContext *C) { if (PE_hair_poll(C)) { - Scene *scene= CTX_data_scene(C); - ParticleEditSettings *pset= PE_settings(scene); + Scene *scene = CTX_data_scene(C); + ParticleEditSettings *pset = PE_settings(scene); - if (pset->shape_object) + if (pset->shape_object && (pset->shape_object->type == OB_MESH)) { return true; + } } return false; @@ -4103,6 +4104,8 @@ static bool shape_cut_test_point(PEData *data, ParticleCacheKey *key) userdata.bvhdata = data->shape_bvh; userdata.num_hits = 0; + userdata.bvhdata = data->shape_bvh; + userdata.num_hits = 0; BLI_bvhtree_ray_cast_all(shape_bvh->tree, key->co, dir, 0.0f, point_inside_bvh_cb, &userdata); /* for any point inside a watertight mesh the number of hits is uneven */ @@ -4188,7 +4191,10 @@ static int shape_cut_exec(bContext *C, wmOperator *UNUSED(op)) int removed; PE_set_data(C, &data); - PE_create_shape_tree(&data, shapeob); + if (!PE_create_shape_tree(&data, shapeob)) { + /* shapeob may not have faces... */ + return OPERATOR_CANCELLED; + } if (selected) foreach_selected_point(&data, shape_cut); @@ -4454,7 +4460,7 @@ void PE_undo_step(Scene *scene, int step) DAG_id_tag_update(&OBACT->id, OB_RECALC_DATA); } -int PE_undo_valid(Scene *scene) +bool PE_undo_is_valid(Scene *scene) { PTCacheEdit *edit= PE_get_current(scene, OBACT); @@ -4505,18 +4511,19 @@ void PE_undo_number(Scene *scene, int nr) /* get name of undo item, return null if no item with this index */ /* if active pointer, set it to 1 if true */ -const char *PE_undo_get_name(Scene *scene, int nr, int *active) +const char *PE_undo_get_name(Scene *scene, int nr, bool *r_active) { PTCacheEdit *edit= PE_get_current(scene, OBACT); PTCacheUndo *undo; - if (active) *active= 0; + if (r_active) *r_active = false; if (edit) { undo= BLI_findlink(&edit->undo, nr); if (undo) { - if (active && undo==edit->curundo) - *active= 1; + if (r_active && (undo == edit->curundo)) { + *r_active = true; + } return undo->name; } } @@ -4842,3 +4849,89 @@ void PARTICLE_OT_edited_clear(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; } +/************************ Propagate Shape Key *************************/ + +static int PE_count_keys(PTCacheEdit *edit) +{ + int totkey = 0, p; + for (p = 0; p < edit->totpoint; ++p) { + totkey += edit->points[p].totkey; + } + return totkey; +} + +static void shape_propagate(PTCacheEdit *edit, int totkey, KeyBlock *kb, wmOperator *UNUSED(op)) +{ + PTCacheEditPoint *point; + float *fp; + int i, k; + + if (kb->totelem != totkey) + return; + + fp = kb->data; + point = edit->points; + for (i = 0; i < edit->totpoint; ++i, ++point) { + PTCacheEditKey *key = point->keys; + const bool use_point = !(point->flag & PEP_HIDE); + + for (k = 0; k < point->totkey; ++k, ++key) { + const bool use_key = (key->flag & PEK_SELECT) && !(key->flag & PEK_HIDE); + + if (use_point && use_key) { + copy_v3_v3(fp, key->co); + + point->flag |= PEP_EDIT_RECALC; + } + + fp += 3; + } + } +} + +static int particle_shape_propagate_to_all_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + ParticleEditSettings *pset = PE_settings(scene); + Object *ob = ED_object_context(C); + ParticleSystem *psys = psys_get_current(ob); + PTCacheEdit *edit = psys->edit; + Key *key = psys->key; + KeyBlock *kb; + const int totkey = PE_count_keys(edit); + + if (!key) + return OPERATOR_CANCELLED; + + /* we might need world space coordinates, update to be sure */ + update_world_cos(ob, edit); + + for (kb = key->block.first; kb; kb = kb->next) + shape_propagate(edit, totkey, kb, op); + + update_world_cos(ob, edit); + PE_update_object(scene, ob, 1); + + if (!(pset->flag & PE_KEEP_LENGTHS)) + recalc_lengths(edit); + + WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); + + return OPERATOR_FINISHED; +} + + +void PARTICLE_OT_shape_propagate_to_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Shape Propagate"; + ot->description = "Apply selected vertex locations to all other shape keys"; + ot->idname = "PARTICLE_OT_shape_propagate_to_all"; + + /* api callbacks */ + ot->exec = particle_shape_propagate_to_all_exec; + ot->poll = PE_hair_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} |