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/physics/particle_edit.c')
-rw-r--r--source/blender/editors/physics/particle_edit.c125
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;
+}