From fb87cfbb1bfad1ab3840f63fb487972d27c49026 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 24 Jan 2009 22:58:22 +0000 Subject: [PATCH] More radial control work. * Added a rotation setting to brush (and brush RNA) * Brought back strength and rotation modes for radial control * Brought back brush texture for radial control * Turned off display of sculpt brush during radial control operator --- source/blender/editors/sculpt/sculpt.c | 244 +++++++----------- .../blender/editors/space_view3d/view3d_ops.c | 6 +- source/blender/makesdna/DNA_brush_types.h | 4 + source/blender/makesrna/intern/rna_brush.c | 20 ++ source/blender/windowmanager/WM_api.h | 1 + .../windowmanager/intern/wm_operators.c | 124 +++++++-- 6 files changed, 222 insertions(+), 177 deletions(-) diff --git a/source/blender/editors/sculpt/sculpt.c b/source/blender/editors/sculpt/sculpt.c index 080fb3cef63..ec19ec08ac3 100644 --- a/source/blender/editors/sculpt/sculpt.c +++ b/source/blender/editors/sculpt/sculpt.c @@ -609,32 +609,6 @@ static void flip_coord(float out[3], float in[3], const char symm) out[2]= in[2]; } -/* Use the warpfac field in MTex to store a rotation value for sculpt textures. Value is in degrees */ -static float sculpt_tex_angle(Sculpt *sd) -{ - Brush *br = sd->brush; - if(br->texact!=-1 && br->mtex[br->texact]) - return br->mtex[br->texact]->warpfac; - return 0; -} - -static void set_tex_angle(Sculpt *sd, const float f) -{ - Brush *br = sd->brush; - if(br->texact != -1 && br->mtex[br->texact]) - br->mtex[br->texact]->warpfac = f; -} - -static float to_rad(const float deg) -{ - return deg * (M_PI/180.0f); -} - -static float to_deg(const float rad) -{ - return rad * (180.0f/M_PI); -} - /* Get a pixel from the texcache at (px, py) */ static unsigned char get_texcache_pixel(const SculptSession *ss, int px, int py) { @@ -701,7 +675,7 @@ static float tex_strength(Sculpt *sd, float *point, const float len) } else if(ss->texcache) { const float bsize= ss->cache->pixel_radius * 2; - const float rot= to_rad(sculpt_tex_angle(sd)) + ss->cache->rotation; + const float rot= sd->brush->rot + ss->cache->rotation; int px, py; float flip[3], point_2d[2]; @@ -1016,7 +990,7 @@ static void projverts_clear_inside(SculptSession *ss) ss->projverts[i].inside = 0; } -static void sculpt_update_tex(Sculpt *sd) +static void sculpt_update_tex(Sculpt *sd, int half_size) { SculptSession *ss= sd->session; Brush *br = sd->brush; @@ -1035,7 +1009,7 @@ static void sculpt_update_tex(Sculpt *sd) } /* Need to allocate a bigger buffer for bigger brush size */ - ss->texcache_side = sd->brush->size * 2; + ss->texcache_side = half_size * 2; if(!ss->texcache || ss->texcache_side > ss->texcache_actual) { ss->texcache = MEM_callocN(sizeof(int) * ss->texcache_side * ss->texcache_side, "Sculpt Texture cache"); ss->texcache_actual = ss->texcache_side; @@ -1074,99 +1048,6 @@ static void sculpt_update_tex(Sculpt *sd) } } -/* XXX: Used anywhere? -void sculptmode_set_strength(const int delta) -{ - int val = sculptmode_brush()->strength + delta; - if(val < 1) val = 1; - if(val > 100) val = 100; - sculptmode_brush()->strength= val; -}*/ - -/* XXX: haven't brought in the radial control files, not sure where to put them. Note that all the paint modes should have access to radial control! */ -#if 0 -static void sculpt_radialcontrol_callback(const int mode, const int val) -{ - SculptSession *ss = sculpt_session(); - BrushData *br = sculptmode_brush(); - - if(mode == RADIALCONTROL_SIZE) - br->size = val; - else if(mode == RADIALCONTROL_STRENGTH) - br->strength = val; - else if(mode == RADIALCONTROL_ROTATION) - set_tex_angle(val); - - ss->radialcontrol = NULL; -} - -/* Returns GL handle to brush texture */ -static GLuint sculpt_radialcontrol_calctex() -{ - Sculpt *sd= sculpt_data(); - SculptSession *ss= sculpt_session(); - int i, j; - const int tsz = ss->texcache_side; - float *texdata= MEM_mallocN(sizeof(float)*tsz*tsz, "Brush preview"); - GLuint tex; - - if(sd->tex_mode!=SCULPTREPT_3D) - sculptmode_update_tex(); - for(i=0; itexfade) - texdata[i*tsz+j]= curve_strength(magn,tsz/2); - else - texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0; - } - if(sd->texact != -1 && ss->texcache) { - for(i=0; itexcache[i*tsz+j]; - texdata[i*tsz+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f; - } - } - - glGenTextures(1, &tex); - glBindTexture(GL_TEXTURE_2D, tex); - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, tsz, tsz, 0, GL_ALPHA, GL_FLOAT, texdata); - MEM_freeN(texdata); - - return tex; -} - -void sculpt_radialcontrol_start(int mode) -{ - Sculpt *sd = sculpt_data(); - SculptSession *ss = sculpt_session(); - BrushData *br = sculptmode_brush(); - int orig=1, max=100; - - if(mode == RADIALCONTROL_SIZE) { - orig = br->size; - max = 200; - } - else if(mode == RADIALCONTROL_STRENGTH) { - orig = br->strength; - max = 100; - } - else if(mode == RADIALCONTROL_ROTATION) { - if(sd->texact!=-1 && sd->mtex[sd->texact]) { - orig = sculpt_tex_angle(); - max = 360; - } - else - mode = RADIALCONTROL_NONE; - } - - if(mode != RADIALCONTROL_NONE) { - ss->radialcontrol= radialcontrol_start(mode, sculpt_radialcontrol_callback, orig, max, - sculpt_radialcontrol_calctex()); - } -} -#endif - void sculptmode_selectbrush_menu(void) { /* XXX: I guess menus belong elsewhere too? @@ -1344,6 +1225,43 @@ void sculptmode_draw_mesh(int only_damaged) } #endif +static int sculpt_poll(bContext *C) +{ + return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D && + CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW; +} + +/*** Sculpt Cursor ***/ +static void draw_paint_cursor(bContext *C, int x, int y, void *customdata) +{ + Sculpt *sd= CTX_data_tool_settings(C)->sculpt; + + glTranslatef((float)x, (float)y, 0.0f); + + glColor4ub(255, 100, 100, 128); + glEnable( GL_LINE_SMOOTH ); + glEnable(GL_BLEND); + glutil_draw_lined_arc(0.0, M_PI*2.0, sd->brush->size, 40); + glDisable(GL_BLEND); + glDisable( GL_LINE_SMOOTH ); + + glTranslatef((float)-x, (float)-y, 0.0f); +} + +static void toggle_paint_cursor(bContext *C) +{ + Sculpt *s = CTX_data_scene(C)->toolsettings->sculpt; + + if(s->session->cursor) { + WM_paint_cursor_end(CTX_wm_manager(C), s->session->cursor); + s->session->cursor = NULL; + } + else { + s->session->cursor = + WM_paint_cursor_activate(CTX_wm_manager(C), sculpt_poll, draw_paint_cursor, NULL); + } +} + static void sculpt_undo_push(bContext *C, Sculpt *sd) { switch(sd->brush->sculpt_tool) { @@ -1366,10 +1284,37 @@ static void sculpt_undo_push(bContext *C, Sculpt *sd) } } -static int sculpt_poll(bContext *C) +static ImBuf *sculpt_radial_control_texture(bContext *C) { - return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D && - CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW; + Sculpt *s = CTX_data_scene(C)->toolsettings->sculpt; + ImBuf *im = MEM_callocN(sizeof(ImBuf), "radial control texture"); + unsigned int *texcache; + int side = 256; + int half = side / 2; + int i, j; + + sculpt_update_tex(s, half); + texcache = s->session->texcache; + im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect"); + im->x = im->y = side; + + for(i=0; irect_float[i*side + j]= curve_strength(s->brush->curve, magn, half); + } + } + + /* Modulate curve with texture */ + if(texcache) { + for(i=0; irect_float[i*side+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f; + } + } + + return im; } static int sculpt_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) @@ -1382,25 +1327,38 @@ static int sculpt_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *ev original_value = br->size; else if(mode == WM_RADIALCONTROL_STRENGTH) original_value = br->alpha; - /*else if(mode == WM_RADIALCONTROL_ANGLE) - original_value = br->rotation;*/ + else if(mode == WM_RADIALCONTROL_ANGLE) + original_value = br->rot; + + toggle_paint_cursor(C); RNA_float_set(op->ptr, "initial_value", original_value); + op->customdata = sculpt_radial_control_texture(C); + return WM_radial_control_invoke(C, op, event); } +static int sculpt_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + int ret = WM_radial_control_modal(C, op, event); + if(ret != OPERATOR_RUNNING_MODAL) + toggle_paint_cursor(C); + return ret; +} + static int sculpt_radial_control_exec(bContext *C, wmOperator *op) { Brush *br = CTX_data_scene(C)->toolsettings->sculpt->brush; int mode = RNA_int_get(op->ptr, "mode"); float new_value = RNA_float_get(op->ptr, "new_value"); + const float conv = 0.017453293; if(mode == WM_RADIALCONTROL_SIZE) br->size = new_value; else if(mode == WM_RADIALCONTROL_STRENGTH) br->alpha = new_value; - /*else if(mode == WM_RADIALCONTROL_ANGLE) - br->rotation = new_value;*/ + else if(mode == WM_RADIALCONTROL_ANGLE) + br->rot = new_value * conv; return OPERATOR_FINISHED; } @@ -1414,6 +1372,7 @@ static void SCULPT_OT_radial_control(wmOperatorType *ot) ot->idname= "SCULPT_OT_radial_control"; ot->invoke= sculpt_radial_control_invoke; + ot->modal= sculpt_radial_control_modal; ot->exec= sculpt_radial_control_exec; ot->poll= sculpt_poll; } @@ -1618,7 +1577,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even /* TODO: Shouldn't really have to do this at the start of every stroke, but sculpt would need some sort of notification when changes are made to the texture. */ - sculpt_update_tex(sd); + sculpt_update_tex(sd, sd->brush->size); /* add modal handler */ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); @@ -1699,7 +1658,7 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op) view3d_operator_needs_opengl(C); sculpt_update_cache_invariants(sd, C, op); sculptmode_update_all_projverts(sd->session); - sculpt_update_tex(sd); + sculpt_update_tex(sd, sd->brush->size); RNA_BEGIN(op->ptr, itemptr, "stroke") { sculpt_update_cache_variants(sd, &itemptr); @@ -1759,23 +1718,6 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot) /**** Toggle operator for turning sculpt mode on or off ****/ -/* XXX: The code for drawing all the paint cursors is really the same, would be better to unify them */ -static void draw_paint_cursor(bContext *C, int x, int y, void *customdata) -{ - Sculpt *sd= CTX_data_tool_settings(C)->sculpt; - - glTranslatef((float)x, (float)y, 0.0f); - - glColor4ub(255, 100, 100, 128); - glEnable( GL_LINE_SMOOTH ); - glEnable(GL_BLEND); - glutil_draw_lined_arc(0.0, M_PI*2.0, sd->brush->size, 40); - glDisable(GL_BLEND); - glDisable( GL_LINE_SMOOTH ); - - glTranslatef((float)-x, (float)-y, 0.0f); -} - static int sculpt_toggle_mode(bContext *C, wmOperator *op) { ToolSettings *ts = CTX_data_tool_settings(C); @@ -1784,7 +1726,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) /* Leave sculptmode */ G.f &= ~G_SCULPTMODE; - WM_paint_cursor_end(CTX_wm_manager(C), ts->sculpt->session->cursor); + toggle_paint_cursor(C); sculptsession_free(ts->sculpt); @@ -1806,9 +1748,7 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) MEM_freeN(ts->sculpt->session); ts->sculpt->session = MEM_callocN(sizeof(SculptSession), "sculpt session"); - /* Activate visible brush */ - ts->sculpt->session->cursor = - WM_paint_cursor_activate(CTX_wm_manager(C), sculpt_poll, draw_paint_cursor, NULL); + toggle_paint_cursor(C); diff --git a/source/blender/editors/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 0d4e6fb9f47..6d4319a495d 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -99,9 +99,9 @@ void view3d_keymap(wmWindowManager *wm) WM_keymap_verify_item(keymap, "SCULPT_OT_brush_stroke", LEFTMOUSE, KM_PRESS, 0, 0); - RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); - //RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); - //RNA_enum_set(WM_keymap_verify_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE); + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, 0, 0)->ptr, "mode", WM_RADIALCONTROL_SIZE); + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", WM_RADIALCONTROL_STRENGTH); + RNA_enum_set(WM_keymap_add_item(keymap, "SCULPT_OT_radial_control", FKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", WM_RADIALCONTROL_ANGLE); WM_keymap_verify_item(keymap, "VIEW3D_OT_cursor3d", ACTIONMOUSE, KM_PRESS, 0, 0); diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 3fe92feb139..359573a141c 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -63,9 +63,13 @@ typedef struct Brush { float rgb[3]; /* color */ float alpha; /* opacity */ + float rot; /* rotation in radians */ + short texact; /* active texture */ char sculpt_tool; /* active tool */ char tex_mode; + + char pad[4]; } Brush; /* Brush.flag */ diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 3dc4b9e6fa4..468a63734c4 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -46,6 +46,20 @@ static void *rna_Brush_active_texture_get(PointerRNA *ptr) return brush->mtex[(int)brush->texact]; } +static float rna_Brush_rotation_get(PointerRNA *ptr) +{ + Brush *brush= (Brush*)ptr->data; + const float conv = 57.295779506; + return brush->rot * conv; +} + +static void rna_Brush_rotation_set(PointerRNA *ptr, float v) +{ + Brush *brush= (Brush*)ptr->data; + const float conv = 0.017453293; + brush->rot = v * conv; +} + #else void rna_def_brush(BlenderRNA *brna) @@ -122,6 +136,12 @@ void rna_def_brush(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "alpha"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Strength", "The amount of pressure on the brush."); + + prop= RNA_def_property(srna, "rotation", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "rot"); + RNA_def_property_range(prop, 0, 360); + RNA_def_property_float_funcs(prop, "rna_Brush_rotation_get", "rna_Brush_rotation_set", NULL); + RNA_def_property_ui_text(prop, "Rotation", "Angle of the brush texture."); /* flag */ prop= RNA_def_property(srna, "airbrush", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index a87937d7cad..9534f853f93 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -158,6 +158,7 @@ void WM_gesture_end(struct bContext *C, struct wmGesture *gesture); /* radial control operator */ int WM_radial_control_invoke(struct bContext *C, struct wmOperator *op, struct wmEvent *event); +int WM_radial_control_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); void WM_OT_radial_control_partial(struct wmOperatorType *ot); /* OpenGL wrappers, mimicking opengl syntax */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 39e197ede0d..dbaa50be92a 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -50,6 +50,7 @@ #include "BIF_gl.h" #include "BIF_glutil.h" /* for paint cursor */ +#include "IMB_imbuf_types.h" #include "ED_fileselect.h" #include "ED_screen.h" @@ -875,35 +876,88 @@ void WM_OT_lasso_gesture(wmOperatorType *ot) /* *********************** radial control ****************** */ +const int WM_RADIAL_CONTROL_DISPLAY_SIZE = 200; + typedef struct wmRadialControl { - float radius; + int mode; + float initial_value, value, max_value; int initial_mouse[2]; void *cursor; - // XXX: texture data + GLuint tex; } wmRadialControl; static void wm_radial_control_paint(bContext *C, int x, int y, void *customdata) { - wmRadialControl *p = (wmRadialControl*)customdata; + wmRadialControl *rc = (wmRadialControl*)customdata; ARegion *ar = CTX_wm_region(C); + float r1, r2, r3, angle; /* Keep cursor in the original place */ - x = p->initial_mouse[0] - ar->winrct.xmin; - y = p->initial_mouse[1] - ar->winrct.ymin; + x = rc->initial_mouse[0] - ar->winrct.xmin; + y = rc->initial_mouse[1] - ar->winrct.ymin; + + glPushMatrix(); glTranslatef((float)x, (float)y, 0.0f); - + + if(rc->mode == WM_RADIALCONTROL_SIZE) { + r1= rc->value; + r2= rc->initial_value; + r3= r1; + } else if(rc->mode == WM_RADIALCONTROL_STRENGTH) { + r1= (1 - rc->value) * WM_RADIAL_CONTROL_DISPLAY_SIZE; + r2= WM_RADIAL_CONTROL_DISPLAY_SIZE; + r3= WM_RADIAL_CONTROL_DISPLAY_SIZE; + } else if(rc->mode == WM_RADIALCONTROL_ANGLE) { + r1= r2= WM_RADIAL_CONTROL_DISPLAY_SIZE; + r3= WM_RADIAL_CONTROL_DISPLAY_SIZE; + angle = rc->value; + } + glColor4ub(255, 255, 255, 128); glEnable( GL_LINE_SMOOTH ); glEnable(GL_BLEND); - glutil_draw_lined_arc(0.0, M_PI*2.0, p->radius, 40); + + if(rc->mode == WM_RADIALCONTROL_ANGLE) + fdrawline(0, 0, WM_RADIAL_CONTROL_DISPLAY_SIZE, 0); + + if(rc->tex) { + const float str = rc->mode == WM_RADIALCONTROL_STRENGTH ? (rc->value + 0.5) : 1; + + glRotatef(angle, 0, 0, 1); + + glBindTexture(GL_TEXTURE_2D, rc->tex); + + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glEnable(GL_TEXTURE_2D); + glBegin(GL_QUADS); + glColor4f(0,0,0, str); + glTexCoord2f(0,0); + glVertex2f(-r3, -r3); + glTexCoord2f(1,0); + glVertex2f(r3, -r3); + glTexCoord2f(1,1); + glVertex2f(r3, r3); + glTexCoord2f(0,1); + glVertex2f(-r3, r3); + glEnd(); + glDisable(GL_TEXTURE_2D); + } + + glColor4ub(255, 255, 255, 128); + if(rc->mode == WM_RADIALCONTROL_ANGLE) + fdrawline(0, 0, WM_RADIAL_CONTROL_DISPLAY_SIZE, 0); + glutil_draw_lined_arc(0.0, M_PI*2.0, r1, 40); + glutil_draw_lined_arc(0.0, M_PI*2.0, r2, 40); glDisable(GL_BLEND); glDisable( GL_LINE_SMOOTH ); - glTranslatef((float)-x, (float)-y, 0.0f); + glPopMatrix(); } -static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event) +int WM_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event) { wmRadialControl *rc = (wmRadialControl*)op->customdata; int mode, initial_mouse[2], delta[2]; @@ -923,13 +977,16 @@ static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event) if(mode == WM_RADIALCONTROL_SIZE) new_value = dist; else if(mode == WM_RADIALCONTROL_STRENGTH) { - float fin = (200.0f - dist) * 0.5f; - new_value = fin>=0 ? fin : 0; + new_value = 1 - dist / WM_RADIAL_CONTROL_DISPLAY_SIZE; } else if(mode == WM_RADIALCONTROL_ANGLE) new_value = ((int)(atan2(delta[1], delta[0]) * (180.0 / M_PI)) + 180); - if(event->ctrl) - new_value = ((int)new_value + 5) / 10*10; + if(event->ctrl) { + if(mode == WM_RADIALCONTROL_STRENGTH) + new_value = ((int)(new_value * 100) / 10*10) / 100.0f; + else + new_value = ((int)new_value + 5) / 10*10; + } break; case ESCKEY: @@ -943,8 +1000,14 @@ static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event) break; } + /* Clamp */ + if(new_value > rc->max_value) + new_value = rc->max_value; + else if(new_value < 0) + new_value = 0; + /* Update paint data */ - rc->radius = new_value; + rc->value = new_value; RNA_float_set(op->ptr, "new_value", new_value); @@ -958,6 +1021,7 @@ static int wm_radial_control_modal(bContext *C, wmOperator *op, wmEvent *event) return ret; } +/* Expects the operator customdata to be an ImBuf (or NULL) */ int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) { wmRadialControl *rc = MEM_callocN(sizeof(wmRadialControl), "radial control"); @@ -965,19 +1029,37 @@ int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) float initial_value = RNA_float_get(op->ptr, "initial_value"); int mouse[2] = {event->x, event->y}; - if(mode == WM_RADIALCONTROL_SIZE) + if(mode == WM_RADIALCONTROL_SIZE) { + rc->max_value = 200; mouse[0]-= initial_value; - else if(mode == WM_RADIALCONTROL_STRENGTH) - mouse[0]-= 200 - 2*initial_value; + } + else if(mode == WM_RADIALCONTROL_STRENGTH) { + rc->max_value = 1; + mouse[0]-= WM_RADIAL_CONTROL_DISPLAY_SIZE * (1 - initial_value); + } else if(mode == WM_RADIALCONTROL_ANGLE) { - mouse[0]-= 200 * cos(initial_value * M_PI / 180.0); - mouse[1]-= 200 * sin(initial_value * M_PI / 180.0); + rc->max_value = 360; + mouse[0]-= WM_RADIAL_CONTROL_DISPLAY_SIZE * cos(initial_value); + mouse[1]-= WM_RADIAL_CONTROL_DISPLAY_SIZE * sin(initial_value); + initial_value *= 180.0f/M_PI; + } + + if(op->customdata) { + ImBuf *im = (ImBuf*)op->customdata; + /* Build GL texture */ + glGenTextures(1, &rc->tex); + glBindTexture(GL_TEXTURE_2D, rc->tex); + glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, im->x, im->y, 0, GL_ALPHA, GL_FLOAT, im->rect_float); + MEM_freeN(im->rect_float); + MEM_freeN(im); } RNA_int_set_array(op->ptr, "initial_mouse", mouse); RNA_float_set(op->ptr, "new_value", initial_value); op->customdata = rc; + rc->mode = mode; + rc->initial_value = initial_value; rc->initial_mouse[0] = mouse[0]; rc->initial_mouse[1] = mouse[1]; rc->cursor = WM_paint_cursor_activate(CTX_wm_manager(C), op->type->poll, @@ -986,7 +1068,7 @@ int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) /* add modal handler */ WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); - wm_radial_control_modal(C, op, event); + WM_radial_control_modal(C, op, event); return OPERATOR_RUNNING_MODAL; } @@ -1001,8 +1083,6 @@ void WM_OT_radial_control_partial(wmOperatorType *ot) {WM_RADIALCONTROL_ANGLE, "ANGLE", "Angle", ""}, {0, NULL, NULL, NULL}}; - ot->modal= wm_radial_control_modal; - /* Should be set in custom invoke() */ RNA_def_float(ot->srna, "initial_value", 0, 0, FLT_MAX, "Initial Value", "", 0, FLT_MAX);