diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index 7e4845a562f..652fcb1daa9 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1437,14 +1437,32 @@ class VIEW3D_MT_particle_specials(Menu): particle_edit = context.tool_settings.particle_edit layout.operator("particle.rekey") + layout.operator("particle.delete") + layout.operator("particle.remove_doubles") - layout.separator() if particle_edit.select_mode == 'POINT': layout.operator("particle.subdivide") + + layout.operator("particle.weight_set") + layout.separator() + + layout.operator("particle.mirror") + + if particle_edit.select_mode == 'POINT': + layout.separator() layout.operator("particle.select_roots") layout.operator("particle.select_tips") - layout.operator("particle.remove_doubles") + layout.separator() + + layout.operator("particle.select_more") + layout.operator("particle.select_less") + + layout.separator() + + layout.operator("particle.select_all").action = 'TOGGLE' + layout.operator("particle.select_linked") + layout.operator("particle.select_all", text="Inverse").action = 'INVERT' class VIEW3D_MT_particle_showhide(ShowHideMenu, Menu): diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index b46c181ebef..f84521fabbf 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -376,6 +376,9 @@ typedef struct PEData { int invert; int tot; float vec[3]; + + int select_action; + int select_toggle_action; } PEData; static void PE_set_data(bContext *C, PEData *data) @@ -1332,6 +1335,34 @@ static void toggle_key_select(PEData *data, int point_index, int key_index) /************************ de select all operator ************************/ +static void select_action_apply(PTCacheEditPoint *point, PTCacheEditKey *key, int action) +{ + switch (action) { + case SEL_SELECT: + if ((key->flag & PEK_SELECT) == 0) { + key->flag |= PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + } + break; + case SEL_DESELECT: + if (key->flag & PEK_SELECT) { + key->flag &= ~PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + } + break; + case SEL_INVERT: + if ((key->flag & PEK_SELECT) == 0) { + key->flag |= PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + } + else { + key->flag &= ~PEK_SELECT; + point->flag |= PEP_EDIT_RECALC; + } + break; + } +} + static int pe_select_all_exec(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); @@ -1355,30 +1386,7 @@ static int pe_select_all_exec(bContext *C, wmOperator *op) LOOP_VISIBLE_POINTS { LOOP_VISIBLE_KEYS { - switch (action) { - case SEL_SELECT: - if ((key->flag & PEK_SELECT) == 0) { - key->flag |= PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; - } - break; - case SEL_DESELECT: - if (key->flag & PEK_SELECT) { - key->flag &= ~PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; - } - break; - case SEL_INVERT: - if ((key->flag & PEK_SELECT) == 0) { - key->flag |= PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; - } - else { - key->flag &= ~PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; - } - break; - } + select_action_apply(point, key, action); } } @@ -1445,22 +1453,39 @@ int PE_mouse_particles(bContext *C, const int mval[2], bool extend, bool deselec return OPERATOR_FINISHED; } -/************************ select first operator ************************/ +/************************ select root operator ************************/ static void select_root(PEData *data, int point_index) { - if (data->edit->points[point_index].flag & PEP_HIDE) + PTCacheEditPoint *point = data->edit->points + point_index; + PTCacheEditKey *key = point->keys; + + if (point->flag & PEP_HIDE) return; - data->edit->points[point_index].keys->flag |= PEK_SELECT; - data->edit->points[point_index].flag |= PEP_EDIT_RECALC; /* redraw selection only */ + if (data->select_action != SEL_TOGGLE) + select_action_apply(point, key, data->select_action); + else if (key->flag & PEK_SELECT) + data->select_toggle_action = SEL_DESELECT; } -static int select_roots_exec(bContext *C, wmOperator *UNUSED(op)) +static int select_roots_exec(bContext *C, wmOperator *op) { PEData data; + int action = RNA_enum_get(op->ptr, "action"); PE_set_data(C, &data); + + if (action == SEL_TOGGLE) { + data.select_action = SEL_TOGGLE; + data.select_toggle_action = SEL_SELECT; + + foreach_point(&data, select_root); + + action = data.select_toggle_action; + } + + data.select_action = action; foreach_point(&data, select_root); PE_update_selection(data.scene, data.ob, 1); @@ -1482,26 +1507,44 @@ void PARTICLE_OT_select_roots(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_select_action(ot, SEL_SELECT); } -/************************ select last operator ************************/ +/************************ select tip operator ************************/ static void select_tip(PEData *data, int point_index) { PTCacheEditPoint *point = data->edit->points + point_index; + PTCacheEditKey *key = &point->keys[point->totkey - 1]; if (point->flag & PEP_HIDE) return; - point->keys[point->totkey - 1].flag |= PEK_SELECT; - point->flag |= PEP_EDIT_RECALC; /* redraw selection only */ + if (data->select_action != SEL_TOGGLE) + select_action_apply(point, key, data->select_action); + else if (key->flag & PEK_SELECT) + data->select_toggle_action = SEL_DESELECT; } -static int select_tips_exec(bContext *C, wmOperator *UNUSED(op)) +static int select_tips_exec(bContext *C, wmOperator *op) { PEData data; + int action = RNA_enum_get(op->ptr, "action"); PE_set_data(C, &data); + + if (action == SEL_TOGGLE) { + data.select_action = SEL_TOGGLE; + data.select_toggle_action = SEL_SELECT; + + foreach_point(&data, select_tip); + + action = data.select_toggle_action; + } + + data.select_action = action; foreach_point(&data, select_tip); PE_update_selection(data.scene, data.ob, 1); @@ -1523,6 +1566,9 @@ void PARTICLE_OT_select_tips(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + + /* properties */ + WM_operator_properties_select_action(ot, SEL_SELECT); } /************************ select linked operator ************************/ diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index fdc6c308cbd..6c0a5424a82 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -4785,11 +4785,10 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) UI_GetThemeColor3fv(TH_VERTEX, nosel_col); /* draw paths */ - if (timed) { - glEnable(GL_BLEND); - steps = (*edit->pathcache)->steps + 1; - pathcol = MEM_callocN(steps * 4 * sizeof(float), "particle path color data"); - } + steps = (*edit->pathcache)->steps + 1; + + glEnable(GL_BLEND); + pathcol = MEM_callocN(steps * 4 * sizeof(float), "particle path color data"); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_COLOR_ARRAY); @@ -4804,11 +4803,19 @@ static void draw_ptcache_edit(Scene *scene, View3D *v3d, PTCacheEdit *edit) } cache = edit->pathcache; - for (i = 0; i < totpoint; i++) { + for (i = 0, point = edit->points; i < totpoint; i++, point++) { path = cache[i]; glVertexPointer(3, GL_FLOAT, sizeof(ParticleCacheKey), path->co); - if (timed) { + if (point->flag & PEP_HIDE) { + for (k = 0, pcol = pathcol; k < steps; k++, pcol += 4) { + copy_v3_v3(pcol, path->col); + pcol[3] = 0.25f; + } + + glColorPointer(4, GL_FLOAT, 4 * sizeof(float), pathcol); + } + else if (timed) { for (k = 0, pcol = pathcol, pkey = path; k < steps; k++, pkey++, pcol += 4) { copy_v3_v3(pcol, pkey->col); pcol[3] = 1.0f - fabsf((float)(CFRA) -pkey->time) / (float)pset->fade_frames; diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c index 07aaa30f7ef..158377f6a8f 100644 --- a/source/blender/makesrna/intern/rna_particle.c +++ b/source/blender/makesrna/intern/rna_particle.c @@ -2294,7 +2294,7 @@ static void rna_def_particle_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "hair_step", PROP_INT, PROP_NONE); RNA_def_property_range(prop, 2, 50); RNA_def_property_ui_text(prop, "Segments", "Number of hair segments"); - RNA_def_property_update(prop, 0, "rna_Particle_redo"); + RNA_def_property_update(prop, 0, "rna_Particle_reset"); /*TODO: not found in UI, readonly? */ diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index cfa914091f1..585201bc559 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -243,6 +243,7 @@ void WM_operator_properties_gesture_border(struct wmOperatorType *ot, bool exte void WM_operator_properties_mouse_select(struct wmOperatorType *ot); void WM_operator_properties_gesture_straightline(struct wmOperatorType *ot, bool cursor); void WM_operator_properties_select_all(struct wmOperatorType *ot); +void WM_operator_properties_select_action(struct wmOperatorType *ot, int default_action); bool WM_operator_check_ui_enabled(const struct bContext *C, const char *idname); wmOperator *WM_operator_last_redo(const struct bContext *C); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 4dce99dd017..bb29ec9000f 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1109,9 +1109,9 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type, RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE); } -void WM_operator_properties_select_all(wmOperatorType *ot) +void WM_operator_properties_select_action(wmOperatorType *ot, int default_action) { - static EnumPropertyItem select_all_actions[] = { + static EnumPropertyItem select_actions[] = { {SEL_TOGGLE, "TOGGLE", 0, "Toggle", "Toggle selection for all elements"}, {SEL_SELECT, "SELECT", 0, "Select", "Select all elements"}, {SEL_DESELECT, "DESELECT", 0, "Deselect", "Deselect all elements"}, @@ -1119,7 +1119,12 @@ void WM_operator_properties_select_all(wmOperatorType *ot) {0, NULL, 0, NULL, NULL} }; - RNA_def_enum(ot->srna, "action", select_all_actions, SEL_TOGGLE, "Action", "Selection action to execute"); + RNA_def_enum(ot->srna, "action", select_actions, default_action, "Action", "Selection action to execute"); +} + +void WM_operator_properties_select_all(wmOperatorType *ot) +{ + WM_operator_properties_select_action(ot, SEL_TOGGLE); } void WM_operator_properties_border(wmOperatorType *ot)