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:
authorJoshua Leung <aligorith@gmail.com>2009-06-28 07:26:10 +0400
committerJoshua Leung <aligorith@gmail.com>2009-06-28 07:26:10 +0400
commit500507ddb1efdf9f69d8a61e3d03a855ee017902 (patch)
tree2a243c975661b12ff7e66289b714c71b7234f13e /source/blender/editors
parent61e30f0f001285dcbf0c7ec8ba44151544bfc8d9 (diff)
parent7271f86be58d0705dd5abc01ac508e1775951fa8 (diff)
NLA SoC: Merge from 2.5 - 21179 to 21209
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/interface/interface.c9
-rw-r--r--source/blender/editors/interface/interface_panel.c3
-rw-r--r--source/blender/editors/interface/interface_widgets.c2
-rw-r--r--source/blender/editors/interface/view2d.c6
-rw-r--r--source/blender/editors/mesh/editmesh_add.c2
-rw-r--r--source/blender/editors/object/object_edit.c10
-rw-r--r--source/blender/editors/physics/ed_pointcache.c122
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c640
-rw-r--r--source/blender/editors/space_buttons/buttons_header.c4
-rw-r--r--source/blender/editors/space_buttons/buttons_intern.h5
-rw-r--r--source/blender/editors/space_buttons/buttons_ops.c107
-rw-r--r--source/blender/editors/space_buttons/space_buttons.c5
-rw-r--r--source/blender/editors/space_view3d/view3d_toolbar.c98
-rw-r--r--source/blender/editors/transform/transform_conversions.c6
14 files changed, 379 insertions, 640 deletions
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 3a61237e1cb..a9866d8898e 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -2077,13 +2077,10 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
rgb_to_hsv(rgb[0], rgb[1], rgb[2], but->hsv, but->hsv+1, but->hsv+2);
}
- if((block->flag & UI_BLOCK_LOOP) || ELEM7(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU)) {
- but->flag |= UI_TEXT_LEFT;
- }
-
- if(but->type==BUT_TOGDUAL) {
+ if((block->flag & UI_BLOCK_LOOP) || ELEM7(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU))
+ but->flag |= (UI_TEXT_LEFT|UI_ICON_LEFT);
+ else if(but->type==BUT_TOGDUAL)
but->flag |= UI_ICON_LEFT;
- }
but->flag |= (block->flag & UI_BUT_ALIGN);
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 06dc5d1e606..eaf78ae89ef 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1288,6 +1288,7 @@ int ui_handler_panel_region(bContext *C, wmEvent *event)
/**************** window level modal panel interaction **************/
+/* note, this is modal handler and should not swallow events for animation */
static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
{
Panel *panel= userdata;
@@ -1303,8 +1304,6 @@ static int ui_handler_panel(bContext *C, wmEvent *event, void *userdata)
panel_activate_state(C, panel, PANEL_STATE_ANIMATION);
else
panel_activate_state(C, panel, PANEL_STATE_EXIT);
-
- return WM_UI_HANDLER_BREAK;
}
else if(event->type == MOUSEMOVE) {
if(data->state == PANEL_STATE_WAIT_UNTAB)
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index 735cfe742c6..ddf31c0db66 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1028,7 +1028,7 @@ static struct uiWidgetColors wcol_menu_back= {
{0, 0, 0, 255},
{25, 25, 25, 230},
{45, 45, 45, 230},
- {255, 255, 255, 255},
+ {100, 100, 100, 255},
{255, 255, 255, 255},
{255, 255, 255, 255},
diff --git a/source/blender/editors/interface/view2d.c b/source/blender/editors/interface/view2d.c
index aa1cc5790ef..c32c8c817fb 100644
--- a/source/blender/editors/interface/view2d.c
+++ b/source/blender/editors/interface/view2d.c
@@ -333,6 +333,12 @@ void UI_view2d_curRect_validate(View2D *v2d)
if (v2d->keepzoom & V2D_LOCKZOOM_Y)
height= winy;
+ /* values used to divide, so make it safe */
+ if(width<1) width= 1;
+ if(height<1) height= 1;
+ if(winx<1) winx= 1;
+ if(winy<1) winy= 1;
+
/* keepzoom (V2D_KEEPZOOM set), indicates that zoom level on each axis must not exceed limits
* NOTE: in general, it is not expected that the lock-zoom will be used in conjunction with this
*/
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 8483aee52f4..12138ee13d2 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -1295,9 +1295,9 @@ static float new_primitive_matrix(bContext *C, float primmat[][4])
/* center */
curs= give_cursor(scene, v3d);
VECCOPY(primmat[3], curs);
+ VECSUB(primmat[3], primmat[3], obedit->obmat[3]);
Mat3Inv(imat, mat);
Mat3MulVecfl(imat, primmat[3]);
- VECSUB(primmat[3], primmat[3], obedit->obmat[3]);
if(v3d) return v3d->grid;
return 1.0f;
diff --git a/source/blender/editors/object/object_edit.c b/source/blender/editors/object/object_edit.c
index 8102b1bfb9c..c436ccdb328 100644
--- a/source/blender/editors/object/object_edit.c
+++ b/source/blender/editors/object/object_edit.c
@@ -388,7 +388,7 @@ static int object_add_mesh_exec(bContext *C, wmOperator *op)
void OBJECT_OT_mesh_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Mesh";
+ ot->name= "Add Mesh";
ot->description = "Add a mesh object to the scene.";
ot->idname= "OBJECT_OT_mesh_add";
@@ -462,7 +462,7 @@ static int object_add_curve_invoke(bContext *C, wmOperator *op, wmEvent *event)
void OBJECT_OT_curve_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Curve";
+ ot->name= "Add Curve";
ot->description = "Add a curve object to the scene.";
ot->idname= "OBJECT_OT_curve_add";
@@ -520,7 +520,7 @@ static int object_add_surface_exec(bContext *C, wmOperator *op)
void OBJECT_OT_surface_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Surface";
+ ot->name= "Add Surface";
ot->description = "Add a surface object to the scene.";
ot->idname= "OBJECT_OT_surface_add";
@@ -557,7 +557,7 @@ static int object_add_text_exec(bContext *C, wmOperator *op)
void OBJECT_OT_text_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Text";
+ ot->name= "Add Text";
ot->description = "Add a text object to the scene";
ot->idname= "OBJECT_OT_text_add";
@@ -602,7 +602,7 @@ static int object_armature_add_exec(bContext *C, wmOperator *op)
void OBJECT_OT_armature_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Armature";
+ ot->name= "Add Armature";
ot->description = "Add an armature object to the scene.";
ot->idname= "OBJECT_OT_armature_add";
diff --git a/source/blender/editors/physics/ed_pointcache.c b/source/blender/editors/physics/ed_pointcache.c
index 3374e05883c..893c59a521d 100644
--- a/source/blender/editors/physics/ed_pointcache.c
+++ b/source/blender/editors/physics/ed_pointcache.c
@@ -31,6 +31,7 @@
#include "DNA_scene_types.h"
#include "DNA_object_force.h"
+#include "DNA_modifier_types.h"
#include "BKE_context.h"
#include "BKE_particle.h"
@@ -39,7 +40,7 @@
#include "BKE_utildefines.h"
#include "BKE_pointcache.h"
#include "BKE_global.h"
-#include "BKE_multires.h"
+#include "BKE_modifier.h"
#include "BLI_blenlib.h"
@@ -81,6 +82,7 @@ static int ptcache_bake_all_exec(bContext *C, wmOperator *op)
baker.pid = NULL;
baker.bake = RNA_boolean_get(op->ptr, "bake");
baker.render = 0;
+ baker.quick_step = 1;
baker.break_test = cache_break_test;
baker.break_data = NULL;
baker.progressbar = (void (*)(void *, int))WM_timecursor;
@@ -104,12 +106,11 @@ static int ptcache_free_bake_all_exec(bContext *C, wmOperator *op)
for(pid=pidlist.first; pid; pid=pid->next) {
pid->cache->flag &= ~PTCACHE_BAKED;
- BKE_ptcache_id_reset(scene, pid, PTCACHE_RESET_OUTDATED);
}
+
+ BLI_freelistN(&pidlist);
}
- BLI_freelistN(&pidlist);
-
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
return OPERATOR_FINISHED;
@@ -127,6 +128,8 @@ void PTCACHE_OT_bake_all(wmOperatorType *ot)
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
}
void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
{
@@ -142,6 +145,112 @@ void PTCACHE_OT_free_bake_all(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+/**************************** cloth **********************************/
+static int ptcache_bake_cloth_poll(bContext *C)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_active_object(C);
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+
+ if(!scene || !ob || ob->id.lib || !clmd)
+ return 0;
+
+ return 1;
+}
+
+static int ptcache_bake_cloth_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_active_object(C);
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ PTCacheID pid;
+ PTCacheBaker baker;
+
+ BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+
+ baker.scene = scene;
+ baker.pid = &pid;
+ baker.bake = RNA_boolean_get(op->ptr, "bake");
+ baker.render = 0;
+ baker.quick_step = 1;
+ baker.break_test = cache_break_test;
+ baker.break_data = NULL;
+ baker.progressbar = WM_timecursor;
+ baker.progresscontext = CTX_wm_window(C);
+
+ BKE_ptcache_make_cache(&baker);
+
+ WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+ return OPERATOR_FINISHED;
+}
+static int ptcache_free_bake_cloth_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene= CTX_data_scene(C);
+ Object *ob= CTX_data_active_object(C);
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ PTCacheID pid;
+
+ BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+ pid.cache->flag &= ~PTCACHE_BAKED;
+
+ WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
+
+ return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_cache_cloth(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Bake Cloth";
+ ot->idname= "PTCACHE_OT_cache_cloth";
+
+ /* api callbacks */
+ ot->exec= ptcache_bake_cloth_exec;
+ ot->poll= ptcache_bake_cloth_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ RNA_def_boolean(ot->srna, "bake", 0, "Bake", "");
+}
+void PTCACHE_OT_free_bake_cloth(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Free Cloth Bake";
+ ot->idname= "PTCACHE_OT_free_bake_cloth";
+
+ /* api callbacks */
+ ot->exec= ptcache_free_bake_cloth_exec;
+ ot->poll= ptcache_bake_cloth_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+static int ptcache_bake_from_cloth_cache_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_active_object(C);
+ ClothModifierData *clmd = (ClothModifierData *)modifiers_findByType(ob, eModifierType_Cloth);
+ PTCacheID pid;
+
+ BKE_ptcache_id_from_cloth(&pid, ob, clmd);
+ pid.cache->flag |= PTCACHE_BAKED;
+
+ return OPERATOR_FINISHED;
+}
+void PTCACHE_OT_bake_from_cloth_cache(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Bake From Cache";
+ ot->idname= "PTCACHE_OT_bake_from_cloth_cache";
+
+ /* api callbacks */
+ ot->exec= ptcache_bake_from_cloth_cache_exec;
+ ot->poll= ptcache_bake_cloth_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
/**************************** particles **********************************/
static int ptcache_bake_particle_system_poll(bContext *C)
{
@@ -168,6 +277,7 @@ static int ptcache_bake_particle_system_exec(bContext *C, wmOperator *op)
baker.pid = &pid;
baker.bake = RNA_boolean_get(op->ptr, "bake");
baker.render = 0;
+ baker.quick_step = 1;
baker.break_test = cache_break_test;
baker.break_data = NULL;
baker.progressbar = (void (*)(void *, int))WM_timecursor;
@@ -188,7 +298,6 @@ static int ptcache_free_bake_particle_system_exec(bContext *C, wmOperator *op)
BKE_ptcache_id_from_particles(&pid, ob, psys);
psys->pointcache->flag &= ~PTCACHE_BAKED;
- BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
WM_event_add_notifier(C, NC_SCENE|ND_FRAME, scene);
@@ -256,6 +365,9 @@ void ED_operatortypes_pointcache(void)
WM_operatortype_append(PTCACHE_OT_cache_particle_system);
WM_operatortype_append(PTCACHE_OT_free_bake_particle_system);
WM_operatortype_append(PTCACHE_OT_bake_from_particles_cache);
+ WM_operatortype_append(PTCACHE_OT_cache_cloth);
+ WM_operatortype_append(PTCACHE_OT_free_bake_cloth);
+ WM_operatortype_append(PTCACHE_OT_bake_from_cloth_cache);
}
//void ED_keymap_pointcache(wmWindowManager *wm)
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index f40880b901f..8f0b52ef3a1 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -738,37 +738,6 @@ static void sculpt_add_damaged_rect(SculptSession *ss)
}
}
-/* Clears the depth buffer in each modified area. */
-#if 0
-static void sculpt_clear_damaged_areas(SculptSession *ss)
-{
- RectNode *rn= NULL;
-
- for(rn = ss->damaged_rects.first; rn; rn = rn->next) {
- rcti clp = rn->r;
- rcti *win = NULL; /*XXX: &curarea->winrct; */
-
- clp.xmin += win->xmin;
- clp.xmax += win->xmin;
- clp.ymin += win->ymin;
- clp.ymax += win->ymin;
-
- if(clp.xmin < win->xmax && clp.xmax > win->xmin &&
- clp.ymin < win->ymax && clp.ymax > win->ymin) {
- if(clp.xmin < win->xmin) clp.xmin = win->xmin;
- if(clp.ymin < win->ymin) clp.ymin = win->ymin;
- if(clp.xmax > win->xmax) clp.xmax = win->xmax;
- if(clp.ymax > win->ymax) clp.ymax = win->ymax;
-
- glScissor(clp.xmin + 1, clp.ymin + 1,
- clp.xmax - clp.xmin - 2,
- clp.ymax - clp.ymin - 2);
- }
-
- glClear(GL_DEPTH_BUFFER_BIT);
- }
-}
-#endif
static void do_brush_action(Sculpt *sd, StrokeCache *cache)
{
SculptSession *ss = sd->session;
@@ -987,25 +956,6 @@ static void sculpt_update_tex(Sculpt *sd)
}
}
-void sculptmode_selectbrush_menu(void)
-{
- /* XXX: I guess menus belong elsewhere too?
-
- Sculpt *sd= sculpt_data();
- int val;
-
- pupmenu_set_active(sd->brush_type);
-
- val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer|Flatten");
-
- if(val>0) {
- sd->brush_type= val;
-
- allqueue(REDRAWVIEW3D, 1);
- allqueue(REDRAWBUTSEDIT, 1);
- }*/
-}
-
static void sculptmode_update_all_projverts(SculptSession *ss)
{
unsigned i;
@@ -1084,89 +1034,6 @@ static void sculpt_update_mesh_elements(bContext *C)
}
}
-/* XXX: lots of drawing code (partial redraw), has to go elsewhere */
-#if 0
-void sculptmode_draw_wires(SculptSession *ss, int only_damaged)
-{
- Mesh *me = get_mesh(OBACT);
- int i;
-
- bglPolygonOffset(1.0);
- glDepthMask(0);
- BIF_ThemeColor((OBACT==OBACT)?TH_ACTIVE:TH_SELECT);
-
- for(i=0; i<me->totedge; i++) {
- MEdge *med= &me->medge[i];
-
- if((!only_damaged || (ss->projverts[med->v1].inside || ss->projverts[med->v2].inside)) &&
- (med->flag & ME_EDGEDRAW)) {
- glDrawElements(GL_LINES, 2, GL_UNSIGNED_INT, &med->v1);
- }
- }
-
- glDepthMask(1);
- bglPolygonOffset(0.0);
-}
-
-void sculptmode_draw_mesh(int only_damaged)
-{
- int i, j, dt, drawCurrentMat = 1, matnr= -1;
- SculptSession *ss = sculpt_session();
-
- sculpt_update_mesh_elements(ss, OBACT);
-
- persp(PERSP_VIEW);
- mymultmatrix(OBACT->obmat);
- glEnable(GL_DEPTH_TEST);
- glEnable(GL_LIGHTING);
- /* XXX: GPU_set_object_materials(G.scene, OBACT, 0, NULL); */
- glEnable(GL_CULL_FACE);
-
- glShadeModel(GL_SMOOTH);
-
- glVertexPointer(3, GL_FLOAT, sizeof(MVert), &cache->mvert[0].co);
- glNormalPointer(GL_SHORT, sizeof(MVert), &cache->mvert[0].no);
-
- dt= MIN2(G.vd->drawtype, OBACT->dt);
- if(dt==OB_WIRE)
- glColorMask(0,0,0,0);
-
- for(i=0; i<ss->totface; ++i) {
- MFace *f= &ss->mface[i];
- char inside= 0;
- int new_matnr= f->mat_nr + 1;
-
- if(new_matnr != matnr)
- drawCurrentMat= GPU_enable_material(matnr = new_matnr, NULL);
-
- /* If only_damaged!=0, only draw faces that are partially
- inside the area(s) modified by the brush */
- if(only_damaged) {
- for(j=0; j<(f->v4?4:3); ++j) {
- if(ss->projverts[*((&f->v1)+j)].inside) {
- inside= 1;
- break;
- }
- }
- }
- else
- inside= 1;
-
- if(inside && drawCurrentMat)
- glDrawElements(f->v4?GL_QUADS:GL_TRIANGLES, f->v4?4:3, GL_UNSIGNED_INT, &f->v1);
- }
-
- glDisable(GL_CULL_FACE);
- glDisable(GL_LIGHTING);
- glColorMask(1,1,1,1);
-
- if(dt==OB_WIRE || (OBACT->dtx & OB_DRAWWIRE))
- sculptmode_draw_wires(ss, only_damaged);
-
- glDisable(GL_DEPTH_TEST);
-}
-#endif
-
static int sculpt_mode_poll(bContext *C)
{
return G.f & G_SCULPTMODE;
@@ -1476,9 +1343,6 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
view3d_operator_needs_opengl(C);
- sculpt_brush_stroke_init_properties(C, op, event, sd->session);
-
- sculptmode_update_all_projverts(sd->session);
/* TODO: Shouldn't really have to do this at the start of every
stroke, but sculpt would need some sort of notification when
@@ -1547,34 +1411,53 @@ static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event
{
PointerRNA itemptr;
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ ARegion *ar = CTX_wm_region(C);
float center[3];
int mouse[2] = {event->x, event->y};
+ float cur_depth;
sculpt_update_mesh_elements(C);
- unproject(sd->session->cache->mats, center, event->x, event->y,
- read_cached_depth(&sd->session->cache->vc, event->x, event->y));
+ if(!sd->session->cache) {
+ ViewContext vc;
+ view3d_set_viewcontext(C, &vc);
+ cur_depth = read_cached_depth(&vc, event->x, event->y);
- /* Add to stroke */
- RNA_collection_add(op->ptr, "stroke", &itemptr);
- RNA_float_set_array(&itemptr, "location", center);
- RNA_int_set_array(&itemptr, "mouse", mouse);
- RNA_boolean_set(&itemptr, "flip", event->shift);
- sculpt_update_cache_variants(sd, &itemptr);
+ /* Don't start the stroke until a valid depth is found */
+ if(cur_depth < 1.0 - FLT_EPSILON) {
+ sculpt_brush_stroke_init_properties(C, op, event, sd->session);
+ sculptmode_update_all_projverts(sd->session);
+ }
- sculpt_restore_mesh(sd);
- do_symmetrical_brush_actions(CTX_data_tool_settings(C)->sculpt, sd->session->cache);
+ ED_region_tag_redraw(ar);
+ }
- sculpt_flush_update(C);
- sculpt_post_stroke_free(sd->session);
+ if(sd->session->cache) {
+ cur_depth = read_cached_depth(&sd->session->cache->vc, event->x, event->y);
+ unproject(sd->session->cache->mats, center, event->x, event->y, cur_depth);
- /* Finished */
- if(event->type == LEFTMOUSE && event->val == 0) {
- request_depth_update(sd->session->cache->vc.rv3d);
+ /* Add to stroke */
+ RNA_collection_add(op->ptr, "stroke", &itemptr);
+ RNA_float_set_array(&itemptr, "location", center);
+ RNA_int_set_array(&itemptr, "mouse", mouse);
+ RNA_boolean_set(&itemptr, "flip", event->shift);
+ sculpt_update_cache_variants(sd, &itemptr);
- sculpt_cache_free(sd->session->cache);
+ sculpt_restore_mesh(sd);
+ do_symmetrical_brush_actions(CTX_data_tool_settings(C)->sculpt, sd->session->cache);
- sculpt_undo_push(C, sd);
+ sculpt_flush_update(C);
+ sculpt_post_stroke_free(sd->session);
+ }
+
+ /* Finished */
+ if(event->type == LEFTMOUSE && event->val == 0) {
+ if(sd->session->cache) {
+ request_depth_update(sd->session->cache->vc.rv3d);
+ sculpt_cache_free(sd->session->cache);
+ sd->session->cache = NULL;
+ sculpt_undo_push(C, sd);
+ }
return OPERATOR_FINISHED;
}
@@ -1718,454 +1601,3 @@ void ED_operatortypes_sculpt()
WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
WM_operatortype_append(SCULPT_OT_brush_curve_preset);
}
-
-void sculpt(Sculpt *sd)
-{
-#if 0
- SculptSession *ss= sd->session;
- Object *ob= NULL; /*XXX */
- Mesh *me;
- MultiresModifierData *mmd = NULL;
- /* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
- short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
- short modifier_calculations= 0;
- BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
- short spacing= 32000;
- int scissor_box[4];
- float offsetRot;
- int smooth_stroke = 0, i;
- int anchored, rake = 0 /* XXX: rake = ? */;
-
- /* XXX: checking that sculpting is allowed
- if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
- return;
- if(!(ob->lay & G.vd->lay))
- error("Active object is not in this layer");
- if(ob_get_keyblock(ob)) {
- if(!(ob->shapeflag & OB_SHAPE_LOCK)) {
- error("Cannot sculpt on unlocked shape key");
- return;
- }
- }*/
-
- anchored = sd->brush->flag & BRUSH_ANCHORED;
- smooth_stroke = (sd->flags & SCULPT_INPUT_SMOOTH) && (sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) && !anchored;
-
- if(smooth_stroke)
- sculpt_stroke_new(256);
-
- ss->damaged_rects.first = ss->damaged_rects.last = NULL;
- ss->damaged_verts.first = ss->damaged_verts.last = NULL;
- ss->vertexcosnos = NULL;
-
- mmd = sculpt_multires_active(ob);
-
- /* Check that vertex users are up-to-date */
- if(ob != active_ob || !ss->vertex_users || ss->vertex_users_size != cache->totvert) {
- sculpt_vertexusers_free(ss);
- calc_vertex_users(ss);
- if(ss->projverts)
- MEM_freeN(ss->projverts);
- ss->projverts = NULL;
- active_ob= ob;
- }
-
- glEnableClientState(GL_VERTEX_ARRAY);
- glEnableClientState(GL_NORMAL_ARRAY);
-
- /*XXX:
- persp(PERSP_VIEW);
- getmouseco_areawin(mvalo);*/
-
- /* Init texture
- FIXME: Shouldn't be doing this every time! */
- if(sd->tex_mode!=SCULPTREPT_3D)
- sculptmode_update_tex(sd);
-
- /*XXX: getmouseco_areawin(mouse); */
- mvalo[0]= mouse[0];
- mvalo[1]= mouse[1];
- lastSigMouse[0]=mouse[0];
- lastSigMouse[1]=mouse[1];
- mousebut = 0; /* XXX: L_MOUSE; */
-
- /* If modifier_calculations is true, then extra time must be spent
- updating the mesh. This takes a *lot* longer, so it's worth
- skipping if the modifier stack is empty. */
- modifier_calculations= sculpt_modifiers_active(ob);
-
- if(modifier_calculations)
- ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /* XXX: scene = ? */
- sculptmode_update_all_projverts(ss);
-
- /* Capture original copy */
- if(sd->flags & SCULPT_DRAW_FAST)
- glAccum(GL_LOAD, 1);
-
- /* Get original scissor box */
- glGetIntegerv(GL_SCISSOR_BOX, scissor_box);
-
- /* For raking, get the original angle*/
- offsetRot=sculpt_tex_angle(sd);
-
- me = get_mesh(ob);
-
- while (/*XXX:get_mbut() & mousebut*/0) {
- /* XXX: getmouseco_areawin(mouse); */
- /* If rake, and the mouse has moved over 10 pixels (euclidean) (prevents jitter) then get the new angle */
- if (rake && (pow(lastSigMouse[0]-mouse[0],2)+pow(lastSigMouse[1]-mouse[1],2))>100){
- /*Nasty looking, but just orig + new angle really*/
- set_tex_angle(sd, offsetRot+180.+to_deg(atan2((float)(mouse[1]-lastSigMouse[1]),(float)(mouse[0]-lastSigMouse[0]))));
- lastSigMouse[0]=mouse[0];
- lastSigMouse[1]=mouse[1];
- }
-
- if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] ||
- sd->brush->flag & BRUSH_AIRBRUSH) {
- a->firsttime = firsttime;
- firsttime= 0;
-
- if(smooth_stroke)
- sculpt_stroke_add_point(ss->stroke, mouse[0], mouse[1]);
-
- spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
-
- if(modifier_calculations && !ss->vertexcosnos)
- ss->vertexcosnos= mesh_get_mapped_verts_nors(NULL, ob); /*XXX scene = ? */
-
- if(sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) {
- if(anchored) {
- /* Restore the mesh before continuing with anchored stroke */
- /*if(a->mesh_store) {
- for(i = 0; i < cache->totvert; ++i) {
- VecCopyf(cache->mvert[i].co, &a->mesh_store[i].x);
- cache->mvert[i].no[0] = a->orig_norms[i][0];
- cache->mvert[i].no[1] = a->orig_norms[i][1];
- cache->mvert[i].no[2] = a->orig_norms[i][2];
- }
- }*/
-
- //do_symmetrical_brush_actions(sd, a, mouse, NULL);
- }
- else {
- if(smooth_stroke) {
- sculpt_stroke_apply(sd, ss->stroke);
- }
- else if(sd->spacing==0 || spacing>sd->spacing) {
- //do_symmetrical_brush_actions(sd, a, mouse, NULL);
- spacing= 0;
- }
- }
- }
- else {
- //do_symmetrical_brush_actions(sd, a, mouse, mvalo);
- //unproject(ss, sd->pivot, mouse[0], mouse[1], a->depth);
- }
-
- if((!ss->multires && modifier_calculations) || ob_get_keyblock(ob)) {
- /* XXX: DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA); */ }
-
- if(modifier_calculations || sd->brush->sculpt_tool == SCULPT_TOOL_GRAB || !(sd->flags & SCULPT_DRAW_FAST)) {
- calc_damaged_verts(ss, a);
- /*XXX: scrarea_do_windraw(curarea);
- screen_swapbuffers(); */
- } else { /* Optimized drawing */
- calc_damaged_verts(ss, a);
-
- /* Draw the stored image to the screen */
- glAccum(GL_RETURN, 1);
-
- sculpt_clear_damaged_areas(ss);
-
- /* Draw all the polygons that are inside the modified area(s) */
- glScissor(scissor_box[0], scissor_box[1], scissor_box[2], scissor_box[3]);
- /* XXX: sculptmode_draw_mesh(1); */
- glAccum(GL_LOAD, 1);
-
- projverts_clear_inside(ss);
-
- /* XXX: persp(PERSP_WIN); */
- glDisable(GL_DEPTH_TEST);
-
- /* Draw cursor */
- if(sd->flags & SCULPT_TOOL_DRAW)
- fdrawXORcirc((float)mouse[0],(float)mouse[1],sd->brush->size);
- /* XXX: if(smooth_stroke)
- sculpt_stroke_draw();
-
- myswapbuffers(); */
- }
-
- BLI_freelistN(&ss->damaged_rects);
- ss->damaged_rects.first = ss->damaged_rects.last = NULL;
-
- mvalo[0]= mouse[0];
- mvalo[1]= mouse[1];
-
- if(ss->vertexcosnos) {
- MEM_freeN(ss->vertexcosnos);
- ss->vertexcosnos= NULL;
- }
-
- }
- else { /*XXX:BIF_wait_for_statechange();*/ }
- }
-
- /* Set the rotation of the brush back to what it was before any rake */
- set_tex_angle(sd, offsetRot);
-
- if(smooth_stroke) {
- sculpt_stroke_apply_all(sd, ss->stroke);
- calc_damaged_verts(ss, a);
- BLI_freelistN(&ss->damaged_rects);
- }
-
- //if(a->layer_disps) MEM_freeN(a->layer_disps);
- //if(a->mesh_store) MEM_freeN(a->mesh_store);
- //if(a->orig_norms) MEM_freeN(a->orig_norms);
- for(i=0; i<8; ++i)
- BLI_freelistN(&a->grab_active_verts[i]);
- MEM_freeN(a);
- sculpt_stroke_free(ss->stroke);
- ss->stroke = NULL;
-
- if(mmd) {
- if(mmd->undo_verts && mmd->undo_verts != cache->mvert)
- MEM_freeN(mmd->undo_verts);
-
- mmd->undo_verts = cache->mvert;
- mmd->undo_verts_tot = cache->totvert;
- }
-
- //sculpt_undo_push(sd);
-
- /* XXX: if(G.vd->depths) G.vd->depths->damaged= 1;
- allqueue(REDRAWVIEW3D, 0); */
-#endif
-}
-
-/* Partial Mesh Visibility */
-
-/* XXX: Partial vis. always was a mess, have to figure something out */
-#if 0
-/* mode: 0=hide outside selection, 1=hide inside selection */
-static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
-{
- Mesh *me= get_mesh(ob);
- float hidebox[6][3];
- vec3f plane_normals[4];
- float plane_ds[4];
- unsigned i, j;
- unsigned ndx_show, ndx_hide;
- MVert *nve;
- unsigned face_cnt_show= 0, face_ndx_show= 0;
- unsigned edge_cnt_show= 0, edge_ndx_show= 0;
- unsigned *old_map= NULL;
- const unsigned SHOW= 0, HIDE=1;
-
- /* Convert hide box from 2D to 3D */
- unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
- unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
- unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
- unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
- unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
- unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
-
- /* Calculate normals for each side of hide box */
- CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
- CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
- CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
- CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
-
- /* Calculate D for each side of hide box */
- for(i= 0; i<4; ++i)
- plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
- hidebox[i][2]*plane_normals[i].z;
-
- /* Add partial visibility to mesh */
- if(!me->pv) {
- me->pv= MEM_callocN(sizeof(PartialVisibility),"PartialVisibility");
- } else {
- old_map= MEM_callocN(sizeof(unsigned)*me->pv->totvert,"PMV oldmap");
- for(i=0; i<me->pv->totvert; ++i) {
- old_map[i]= me->pv->vert_map[i]<me->totvert?0:1;
- }
- mesh_pmv_revert(ob, me);
- }
-
- /* Kill sculpt data */
- active_ob= NULL;
-
- /* Initalize map with which verts are to be hidden */
- me->pv->vert_map= MEM_mallocN(sizeof(unsigned)*me->totvert, "PMV vertmap");
- me->pv->totvert= me->totvert;
- me->totvert= 0;
- for(i=0; i<me->pv->totvert; ++i) {
- me->pv->vert_map[i]= mode ? HIDE:SHOW;
- for(j=0; j<4; ++j) {
- if(me->mvert[i].co[0] * plane_normals[j].x +
- me->mvert[i].co[1] * plane_normals[j].y +
- me->mvert[i].co[2] * plane_normals[j].z < plane_ds[j] ) {
- me->pv->vert_map[i]= mode ? SHOW:HIDE; /* Vert is outside the hide box */
- break;
- }
- }
- if(old_map && old_map[i]) me->pv->vert_map[i]= 1;
- if(!me->pv->vert_map[i]) ++me->totvert;
-
- }
- if(old_map) MEM_freeN(old_map);
-
- /* Find out how many faces to show */
- for(i=0; i<me->totface; ++i) {
- if(!me->pv->vert_map[me->mface[i].v1] &&
- !me->pv->vert_map[me->mface[i].v2] &&
- !me->pv->vert_map[me->mface[i].v3]) {
- if(me->mface[i].v4) {
- if(!me->pv->vert_map[me->mface[i].v4])
- ++face_cnt_show;
- }
- else ++face_cnt_show;
- }
- }
- /* Find out how many edges to show */
- for(i=0; i<me->totedge; ++i) {
- if(!me->pv->vert_map[me->medge[i].v1] &&
- !me->pv->vert_map[me->medge[i].v2])
- ++edge_cnt_show;
- }
-
- /* Create new vert array and reset each vert's map with map[old]=new index */
- nve= MEM_mallocN(sizeof(MVert)*me->pv->totvert, "PMV verts");
- ndx_show= 0; ndx_hide= me->totvert;
- for(i=0; i<me->pv->totvert; ++i) {
- if(me->pv->vert_map[i]) {
- me->pv->vert_map[i]= ndx_hide;
- nve[me->pv->vert_map[i]]= me->mvert[i];
- ++ndx_hide;
- } else {
- me->pv->vert_map[i]= ndx_show;
- nve[me->pv->vert_map[i]]= me->mvert[i];
- ++ndx_show;
- }
- }
- CustomData_free_layer_active(&me->vdata, CD_MVERT, me->pv->totvert);
- me->mvert= CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, nve, me->totvert);
-
- /* Create new face array */
- me->pv->old_faces= me->mface;
- me->pv->totface= me->totface;
- me->mface= MEM_mallocN(sizeof(MFace)*face_cnt_show, "PMV faces");
- for(i=0; i<me->totface; ++i) {
- MFace *pr_f= &me->pv->old_faces[i];
- char show= 0;
-
- if(me->pv->vert_map[pr_f->v1] < me->totvert &&
- me->pv->vert_map[pr_f->v2] < me->totvert &&
- me->pv->vert_map[pr_f->v3] < me->totvert) {
- if(pr_f->v4) {
- if(me->pv->vert_map[pr_f->v4] < me->totvert)
- show= 1;
- }
- else show= 1;
- }
-
- if(show) {
- MFace *cr_f= &me->mface[face_ndx_show];
- *cr_f= *pr_f;
- cr_f->v1= me->pv->vert_map[pr_f->v1];
- cr_f->v2= me->pv->vert_map[pr_f->v2];
- cr_f->v3= me->pv->vert_map[pr_f->v3];
- cr_f->v4= pr_f->v4 ? me->pv->vert_map[pr_f->v4] : 0;
- test_index_face(cr_f,NULL,0,pr_f->v4?4:3);
- ++face_ndx_show;
- }
- }
- me->totface= face_cnt_show;
- CustomData_set_layer(&me->fdata, CD_MFACE, me->mface);
-
- /* Create new edge array */
- me->pv->old_edges= me->medge;
- me->pv->totedge= me->totedge;
- me->medge= MEM_mallocN(sizeof(MEdge)*edge_cnt_show, "PMV edges");
- me->pv->edge_map= MEM_mallocN(sizeof(int)*me->pv->totedge,"PMV edgemap");
- for(i=0; i<me->totedge; ++i) {
- if(me->pv->vert_map[me->pv->old_edges[i].v1] < me->totvert &&
- me->pv->vert_map[me->pv->old_edges[i].v2] < me->totvert) {
- MEdge *cr_e= &me->medge[edge_ndx_show];
- me->pv->edge_map[i]= edge_ndx_show;
- *cr_e= me->pv->old_edges[i];
- cr_e->v1= me->pv->vert_map[me->pv->old_edges[i].v1];
- cr_e->v2= me->pv->vert_map[me->pv->old_edges[i].v2];
- ++edge_ndx_show;
- }
- else me->pv->edge_map[i]= -1;
- }
- me->totedge= edge_cnt_show;
- CustomData_set_layer(&me->edata, CD_MEDGE, me->medge);
-
- /* XXX: DAG_object_flush_update(G.scene, OBACT, OB_RECALC_DATA); */
-}
-
-static rcti sculptmode_pmv_box()
-{
- /*XXX: short down[2], mouse[2];
- rcti ret;
-
- getmouseco_areawin(down);
-
- while((get_mbut()&L_MOUSE) || (get_mbut()&R_MOUSE)) {
- getmouseco_areawin(mouse);
-
- scrarea_do_windraw(curarea);
-
- persp(PERSP_WIN);
- glLineWidth(2);
- setlinestyle(2);
- sdrawXORline(down[0],down[1],mouse[0],down[1]);
- sdrawXORline(mouse[0],down[1],mouse[0],mouse[1]);
- sdrawXORline(mouse[0],mouse[1],down[0],mouse[1]);
- sdrawXORline(down[0],mouse[1],down[0],down[1]);
- setlinestyle(0);
- glLineWidth(1);
- persp(PERSP_VIEW);
-
- screen_swapbuffers();
- backdrawview3d(0);
- }
-
- ret.xmin= down[0]<mouse[0]?down[0]:mouse[0];
- ret.ymin= down[1]<mouse[1]?down[1]:mouse[1];
- ret.xmax= down[0]>mouse[0]?down[0]:mouse[0];
- ret.ymax= down[1]>mouse[1]?down[1]:mouse[1];
- return ret;*/
-}
-
-void sculptmode_pmv(int mode)
-{
- Object *ob= NULL; /*XXX: OBACT; */
- rcti hb_2d;
-
- if(ob_get_key(ob)) {
- error("Cannot hide mesh with shape keys enabled");
- return;
- }
-
- hb_2d= sculptmode_pmv_box(); /* Get 2D hide box */
-
- sculptmode_correct_state();
-
- waitcursor(1);
-
- if(hb_2d.xmax-hb_2d.xmin > 3 && hb_2d.ymax-hb_2d.ymin > 3) {
- init_sculptmatrices();
-
- sculptmode_do_pmv(ob,&hb_2d,mode);
- }
- else mesh_pmv_off(ob, get_mesh(ob));
-
- /*XXX: scrarea_do_windraw(curarea); */
-
- waitcursor(0);
-}
-#endif
diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c
index 79284ada483..7c622f172a2 100644
--- a/source/blender/editors/space_buttons/buttons_header.c
+++ b/source/blender/editors/space_buttons/buttons_header.c
@@ -173,10 +173,10 @@ void buttons_header_buttons(const bContext *C, ARegion *ar)
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_OBJECT_DATA, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_OBJECT, 0, 0, "Object");
if(sbuts->pathflag & (1<<BCONTEXT_CONSTRAINT))
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_CONSTRAINT, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_CONSTRAINT, 0, 0, "Constraint");
- if(sbuts->pathflag & (1<<BCONTEXT_MODIFIER))
- uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MODIFIER, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
if(sbuts->pathflag & (1<<BCONTEXT_DATA))
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, sbuts->dataicon, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_DATA, 0, 0, "Object Data");
+ if(sbuts->pathflag & (1<<BCONTEXT_MODIFIER))
+ uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_MODIFIER, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_MODIFIER, 0, 0, "Modifier");
if(sbuts->pathflag & (1<<BCONTEXT_BONE))
uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, ICON_BONE_DATA, xco+=XIC, yco, XIC, YIC, &(sbuts->mainb), 0.0, (float)BCONTEXT_BONE, 0, 0, "Bone");
if(sbuts->pathflag & (1<<BCONTEXT_MATERIAL))
diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h
index b213e4288be..13ea778fb00 100644
--- a/source/blender/editors/space_buttons/buttons_intern.h
+++ b/source/blender/editors/space_buttons/buttons_intern.h
@@ -71,5 +71,10 @@ void MATERIAL_OT_new(struct wmOperatorType *ot);
void TEXTURE_OT_new(struct wmOperatorType *ot);
void WORLD_OT_new(struct wmOperatorType *ot);
+void OBJECT_OT_particle_system_slot_add(struct wmOperatorType *ot);
+void OBJECT_OT_particle_system_slot_remove(struct wmOperatorType *ot);
+
+void PARTICLE_OT_new(struct wmOperatorType *ot);
+
#endif /* ED_BUTTONS_INTERN_H */
diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c
index 6755a2be1b7..6ca92674c6e 100644
--- a/source/blender/editors/space_buttons/buttons_ops.c
+++ b/source/blender/editors/space_buttons/buttons_ops.c
@@ -42,6 +42,7 @@
#include "BKE_font.h"
#include "BKE_library.h"
#include "BKE_material.h"
+#include "BKE_particle.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
#include "BKE_world.h"
@@ -407,3 +408,109 @@ void WORLD_OT_new(wmOperatorType *ot)
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
}
+
+
+/********************** particle system slot operators *********************/
+
+static int particle_system_slot_add_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Scene *scene = CTX_data_scene(C);
+
+ if(!scene || !ob)
+ return OPERATOR_CANCELLED;
+
+ object_add_particle_system_slot(scene, ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_slot_add(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Add Particle System Slot";
+ ot->idname= "OBJECT_OT_particle_system_slot_add";
+
+ /* api callbacks */
+ ot->exec= particle_system_slot_add_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+static int particle_system_slot_remove_exec(bContext *C, wmOperator *op)
+{
+ Object *ob= CTX_data_pointer_get_type(C, "object", &RNA_Object).data;
+ Scene *scene = CTX_data_scene(C);
+
+ if(!scene || !ob)
+ return OPERATOR_CANCELLED;
+
+ object_remove_particle_system_slot(scene, ob);
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+
+ return OPERATOR_FINISHED;
+}
+
+void OBJECT_OT_particle_system_slot_remove(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Remove Particle System Slot";
+ ot->idname= "OBJECT_OT_particle_system_slot_remove";
+
+ /* api callbacks */
+ ot->exec= particle_system_slot_remove_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
+
+/********************** new particle settings operator *********************/
+
+static int new_particle_settings_exec(bContext *C, wmOperator *op)
+{
+ Scene *scene = CTX_data_scene(C);
+ ParticleSettings *part= CTX_data_pointer_get_type(C, "particle_settings", &RNA_ParticleSettings).data;
+ Object *ob;
+ PointerRNA ptr;
+
+ /* add or copy particle setting */
+ if(part)
+ part= psys_copy_settings(part);
+ else
+ part= psys_new_settings("PSys", NULL);
+
+ /* attempt to assign to material slot */
+ ptr= CTX_data_pointer_get_type(C, "particle_system", &RNA_ParticleSystem);
+
+ if(ptr.data) {
+ ParticleSystem *psys = (ParticleSystem*)ptr.data;
+ ob= ptr.id.data;
+
+ if(psys->part)
+ psys->part->id.us--;
+
+ psys->part = part;
+
+ DAG_scene_sort(scene);
+ DAG_object_flush_update(scene, ob, OB_RECALC_DATA);
+
+ WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, ob);
+ }
+
+ return OPERATOR_FINISHED;
+}
+
+void PARTICLE_OT_new(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "New Particle Settings";
+ ot->idname= "PARTICLE_OT_new";
+
+ /* api callbacks */
+ ot->exec= new_particle_settings_exec;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+}
diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c
index 483a1dc6100..7954d5254cc 100644
--- a/source/blender/editors/space_buttons/space_buttons.c
+++ b/source/blender/editors/space_buttons/space_buttons.c
@@ -219,6 +219,11 @@ void buttons_operatortypes(void)
WM_operatortype_append(MATERIAL_OT_new);
WM_operatortype_append(TEXTURE_OT_new);
WM_operatortype_append(WORLD_OT_new);
+
+ WM_operatortype_append(OBJECT_OT_particle_system_slot_add);
+ WM_operatortype_append(OBJECT_OT_particle_system_slot_remove);
+
+ WM_operatortype_append(PARTICLE_OT_new);
}
void buttons_keymap(struct wmWindowManager *wm)
diff --git a/source/blender/editors/space_view3d/view3d_toolbar.c b/source/blender/editors/space_view3d/view3d_toolbar.c
index 88af60ac0f4..34a935103a7 100644
--- a/source/blender/editors/space_view3d/view3d_toolbar.c
+++ b/source/blender/editors/space_view3d/view3d_toolbar.c
@@ -148,8 +148,82 @@ static void view3d_panel_operator_redo(const bContext *C, Panel *pa)
uiDefAutoButsRNA(C, pa->layout, &ptr, 1);
}
+/* ******************* */
+
+typedef struct CustomTool {
+ struct CustomTool *next, *prev;
+ char opname[OP_MAX_TYPENAME];
+} CustomTool;
+
+static void operator_call_cb(struct bContext *C, void *arg_listbase, void *arg2)
+{
+ wmOperatorType *ot= arg2;
+
+ if(ot) {
+ CustomTool *ct= MEM_callocN(sizeof(CustomTool), "CustomTool");
+
+ BLI_addtail(arg_listbase, ct);
+ BLI_strncpy(ct->opname, ot->idname, OP_MAX_TYPENAME);
+ }
+
+}
+
+static void operator_search_cb(const struct bContext *C, void *arg, char *str, uiSearchItems *items)
+{
+ wmOperatorType *ot = WM_operatortype_first();
+
+ for(; ot; ot= ot->next) {
+
+ if(BLI_strcasestr(ot->name, str)) {
+ if(ot->poll==NULL || ot->poll((bContext *)C)) {
+
+ if(0==uiSearchItemAdd(items, ot->name, ot, 0))
+ break;
+ }
+ }
+ }
+}
+
+
+/* ID Search browse menu, open */
+static uiBlock *tool_search_menu(bContext *C, ARegion *ar, void *arg_listbase)
+{
+ static char search[OP_MAX_TYPENAME];
+ wmEvent event;
+ wmWindow *win= CTX_wm_window(C);
+ uiBlock *block;
+ uiBut *but;
+
+ /* clear initial search string, then all items show */
+ search[0]= 0;
+
+ block= uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
+ uiBlockSetFlag(block, UI_BLOCK_LOOP|UI_BLOCK_REDRAW|UI_BLOCK_RET_1);
+
+ /* fake button, it holds space for search items */
+ uiDefBut(block, LABEL, 0, "", 10, 15, 150, uiSearchBoxhHeight(), NULL, 0, 0, 0, 0, NULL);
+
+ but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, OP_MAX_TYPENAME, 10, 0, 150, 19, "");
+ uiButSetSearchFunc(but, operator_search_cb, arg_listbase, operator_call_cb);
+
+ uiBoundsBlock(block, 6);
+ uiBlockSetDirection(block, UI_DOWN);
+ uiEndBlock(C, block);
+
+ event= *(win->eventstate); /* XXX huh huh? make api call */
+ event.type= EVT_BUT_OPEN;
+ event.val= KM_PRESS;
+ event.customdata= but;
+ event.customdatafree= FALSE;
+ wm_event_add(win, &event);
+
+ return block;
+}
+
+
static void view3d_panel_tools(const bContext *C, Panel *pa)
{
+ static ListBase tools= {NULL, NULL};
Object *obedit= CTX_data_edit_object(C);
// Object *obact = CTX_data_active_object(C);
uiLayout *col;
@@ -157,24 +231,20 @@ static void view3d_panel_tools(const bContext *C, Panel *pa)
if(obedit) {
if(obedit->type==OB_MESH) {
- // void uiItemFullO(uiLayout *layout, char *name, int icon, char *idname, IDProperty *properties, int context)
- col= uiLayoutColumn(pa->layout, 1);
- uiItemFullO(col, NULL, 0, "MESH_OT_delete", NULL, WM_OP_INVOKE_REGION_WIN);
-
- col= uiLayoutColumn(pa->layout, 1);
- uiItemFullO(col, NULL, 0, "MESH_OT_subdivide", NULL, WM_OP_INVOKE_REGION_WIN);
-
- col= uiLayoutColumn(pa->layout, 1);
- uiItemFullO(col, NULL, 0, "MESH_OT_primitive_monkey_add", NULL, WM_OP_INVOKE_REGION_WIN);
- uiItemFullO(col, NULL, 0, "MESH_OT_primitive_uv_sphere_add", NULL, WM_OP_INVOKE_REGION_WIN);
-
- col= uiLayoutColumn(pa->layout, 1);
- uiItemFullO(col, NULL, 0, "MESH_OT_select_all_toggle", NULL, WM_OP_INVOKE_REGION_WIN);
-
col= uiLayoutColumn(pa->layout, 1);
uiItemFullO(col, NULL, 0, "MESH_OT_spin", NULL, WM_OP_INVOKE_REGION_WIN);
uiItemFullO(col, NULL, 0, "MESH_OT_screw", NULL, WM_OP_INVOKE_REGION_WIN);
+ if(tools.first) {
+ CustomTool *ct;
+
+ for(ct= tools.first; ct; ct= ct->next) {
+ col= uiLayoutColumn(pa->layout, 1);
+ uiItemFullO(col, NULL, 0, ct->opname, NULL, WM_OP_INVOKE_REGION_WIN);
+ }
+ }
+ col= uiLayoutColumn(pa->layout, 1);
+ uiDefBlockBut(uiLayoutGetBlock(pa->layout), tool_search_menu, &tools, "Add Operator", 0, 0, UI_UNIT_X, UI_UNIT_Y, "Add tool");
}
}
else {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 3bc950d5863..d23f8fdfe40 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -4828,6 +4828,12 @@ void special_aftertrans_update(TransInfo *t)
/* pointcache refresh */
if (BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH))
ob->recalc |= OB_RECALC_DATA;
+
+ /* Needed for proper updating of "quick cached" dynamics. */
+ /* Creates troubles for moving animated objects without */
+ /* autokey though, probably needed is an anim sys override? */
+ /* Please remove if some other solution is found. -jahka */
+ DAG_object_flush_update(scene, ob, OB_RECALC_OB);
/* Set autokey if necessary */
if (!cancelled)