diff options
author | Benoit Bolsee <benoit.bolsee@online.be> | 2011-06-08 01:20:25 +0400 |
---|---|---|
committer | Benoit Bolsee <benoit.bolsee@online.be> | 2011-06-08 01:20:25 +0400 |
commit | b5bd86e5907c3fa98546dabeda9703dfb15862f4 (patch) | |
tree | eb65895e557f820fca0931c8465571ed0e749860 /source/blender/editors | |
parent | 9de407f13f2e628f67dbcda252febebac6307293 (diff) | |
parent | 7fd1fe9fc8e3154c36a57ed2c69409d526ee1171 (diff) |
svn merge -r 37212:37306 https://svn.blender.org/svnroot/bf-blender/trunk/blender
Diffstat (limited to 'source/blender/editors')
46 files changed, 1865 insertions, 298 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index f755df79986..9145cc2b79d 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -1881,6 +1881,7 @@ static void ANIM_OT_channels_select_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= animchannels_borderselect_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= animedit_poll_channels_nla_tweakmode_off; diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index c802ba621f1..c6e55427034 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -717,7 +717,7 @@ static void ed_marker_move_apply(wmOperator *op) } /* only for modal */ -static void ed_marker_move_cancel(bContext *C, wmOperator *op) +static int ed_marker_move_cancel(bContext *C, wmOperator *op) { RNA_int_set(op->ptr, "frames", 0); ed_marker_move_apply(op); @@ -725,6 +725,8 @@ static void ed_marker_move_cancel(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_SCENE|ND_MARKERS, NULL); WM_event_add_notifier(C, NC_ANIMATION|ND_MARKERS, NULL); + + return OPERATOR_CANCELLED; } @@ -886,6 +888,7 @@ static void MARKER_OT_move(wmOperatorType *ot) ot->invoke= ed_marker_move_invoke_wrapper; ot->modal= ed_marker_move_modal; ot->poll= ed_markers_poll_selected_markers; + ot->cancel= ed_marker_move_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; @@ -980,6 +983,7 @@ static void MARKER_OT_duplicate(wmOperatorType *ot) ot->invoke= ed_marker_duplicate_invoke_wrapper; ot->modal= ed_marker_move_modal; ot->poll= ed_markers_poll_selected_markers; + ot->cancel= ed_marker_move_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -1185,6 +1189,7 @@ static void MARKER_OT_select_border(wmOperatorType *ot) ot->exec= ed_marker_border_select_exec; ot->invoke= ed_marker_select_border_invoke_wrapper; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ed_markers_poll_markers_exist; diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 93d99c59a0e..0e0bf275d8f 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -224,6 +224,7 @@ static void ANIM_OT_previewrange_set(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= previewrange_define_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_animview_active; diff --git a/source/blender/editors/datafiles/startup.blend.c b/source/blender/editors/datafiles/startup.blend.c index 6900f458a2b..1121eb5a299 100644 --- a/source/blender/editors/datafiles/startup.blend.c +++ b/source/blender/editors/datafiles/startup.blend.c @@ -8854,8 +8854,8 @@ char datatoc_startup_blend[]= { 0, 0, 0, 0, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,114,114,114,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,255, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,165,165,165,127, 0, 0, 0,255, 0, 0, 0,255,255,255,255,255,160,160,160,100,127,112,112,100, 0, 0, 0, 0, 64, 64, 64,255, 0, 0, 0,255, -241, 88, 0,255, 0, 0, 0, 40,255,140, 25,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, - 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,255, 32, 32,255, 75, 75, 75,255,204, 0,153,255, 0, 0, 0, 18,255,133, 0, 60, +241, 88, 0,255, 0, 0, 0, 40,255,170, 64,255, 8, 48, 8,255, 85,187, 85,255,255,255,255,255, 0, 0, 0,255,255,133, 0,255, + 0, 0, 0,255,255,160, 0,255,219, 37, 18,255,32, 255,255,255, 75, 75, 75,255,204, 0,153,255, 0, 0, 0, 18,255,133, 0, 60, 255,133, 0,255, 32, 0, 0,255, 0, 32, 0,255, 0, 0,128,255, 0, 0, 0, 0, 34,221,221,255, 35, 97,221,255,200,200,200,255, 80,200,255, 80, 0, 0, 0, 0, 0, 0, 0, 0, 96,192, 64,255,144,144, 0,255,128, 48, 96,255,219, 37, 18,255,240,255, 64,255, 240,144,160,255,255,255,255,255, 0, 0, 0,255,144,144, 0,255, 64,144, 48,255,128, 48, 96,255, 0, 0, 0,255,240,255, 64,255, diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 5c4dfc6ba3d..8bb77ad43a0 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -206,10 +206,10 @@ struct bDeformGroup *ED_vgroup_add(struct Object *ob); struct bDeformGroup *ED_vgroup_add_name(struct Object *ob, const char *name); void ED_vgroup_delete(struct Object *ob, struct bDeformGroup *defgroup); void ED_vgroup_select_by_name(struct Object *ob, const char *name); -void ED_vgroup_data_create(struct ID *id); +int ED_vgroup_data_create(struct ID *id); int ED_vgroup_give_array(struct ID *id, struct MDeformVert **dvert_arr, int *dvert_tot); int ED_vgroup_copy_array(struct Object *ob, struct Object *ob_from); -void ED_vgroup_mirror(struct Object *ob, int mirror_weights, int flip_vgroups); +void ED_vgroup_mirror(struct Object *ob, const short mirror_weights, const short flip_vgroups); int ED_vgroup_object_is_edit_mode(struct Object *ob); diff --git a/source/blender/editors/include/ED_screen.h b/source/blender/editors/include/ED_screen.h index 6e396a1021b..f2ef4e16852 100644 --- a/source/blender/editors/include/ED_screen.h +++ b/source/blender/editors/include/ED_screen.h @@ -107,7 +107,7 @@ void ED_screen_set_subwinactive(struct bContext *C, struct wmEvent *event); void ED_screen_exit(struct bContext *C, struct wmWindow *window, struct bScreen *screen); void ED_screen_animation_timer(struct bContext *C, int redraws, int refresh, int sync, int enable); void ED_screen_animation_timer_update(struct bScreen *screen, int redraws, int refresh); -int ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type); +ScrArea *ED_screen_full_newspace(struct bContext *C, ScrArea *sa, int type); void ED_screen_full_prevspace(struct bContext *C, ScrArea *sa); void ED_screen_full_restore(struct bContext *C, ScrArea *sa); struct ScrArea *ED_screen_full_toggle(struct bContext *C, struct wmWindow *win, struct ScrArea *sa); diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index c431af9fd8e..a21122698d9 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -449,6 +449,45 @@ void uiCenteredBoundsBlock(uiBlock *block, int addval) /* link line drawing is not part of buttons or theme.. so we stick with it here */ +static int ui_but_float_precision(uiBut *but, double value) +{ + int prec; + + /* first check if prec is 0 and fallback to a simple default */ + if((prec= (int)but->a2) == 0) { + prec= (but->hardmax < 10.001f) ? 3 : 2; + } + + /* check on the number of decimal places neede to display + * the number, this is so 0.00001 is not displayed as 0.00, + * _but_, this is only for small values si 10.0001 will not get + * the same treatment */ + if(value != 0.0 && (value= ABS(value)) < 0.1) { + double prec_d= -(log10(value)); + double prec_d_floor = floor(prec_d + FLT_EPSILON); + int test_prec= (int)prec_d_floor; + + /* this check is so 0.00016 from isnt rounded to 0.0001 */ + if(prec_d - prec_d_floor > FLT_EPSILON) { /* not ending with a .0~001 */ + /* check if a second decimal place is needed 0.00015 for eg. */ + if(double_round(value, test_prec + 1) - double_round(value, test_prec + 2) != 0.0) { + test_prec += 2; + } + else { + test_prec += 1; + } + } + + if(test_prec > prec && test_prec <= 7) { + prec= test_prec; + } + } + + CLAMP(prec, 1, 7); + + return prec; +} + static void ui_draw_linkline(uiLinkLine *line) { rcti rect; @@ -1530,10 +1569,7 @@ void ui_get_but_string(uiBut *but, char *str, int maxlen) ui_get_but_string_unit(but, str, maxlen, value, 0); } else { - int prec= (int)but->a2; - if(prec==0) prec= 3; - else CLAMP(prec, 1, 7); - + const int prec= ui_but_float_precision(but, value); BLI_snprintf(str, maxlen, "%.*f", prec, value); } } @@ -2009,10 +2045,7 @@ void ui_check_but(uiBut *but) BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%s", but->str, new_str); } else { - int prec= (int)but->a2; - if(prec==0) prec= (but->hardmax < 10.001f) ? 3 : 2; - else CLAMP(prec, 1, 7); - + const int prec= ui_but_float_precision(but, value); BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); } } @@ -2030,11 +2063,9 @@ void ui_check_but(uiBut *but) case LABEL: if(ui_is_but_float(but)) { - int prec= (int)but->a2; + int prec; value= ui_get_but_val(but); - if(prec==0) prec= 3; - else CLAMP(prec, 1, 7); - + prec= ui_but_float_precision(but, value); BLI_snprintf(but->drawstr, sizeof(but->drawstr), "%s%.*f", but->str, prec, value); } else { diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 710d4d58825..c7f11116834 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -1120,7 +1120,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect) ColorBand *coba; CBData *cbd; float x1, y1, sizex, sizey; - float dx, v3[2], v1[2], v2[2], v1a[2], v2a[2]; + float v3[2], v1[2], v2[2], v1a[2], v2a[2]; int a; float pos, colf[4]= {0,0,0,0}; /* initialize incase the colorband isnt valid */ @@ -1131,18 +1131,17 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect) y1= rect->ymin; sizex= rect->xmax-x1; sizey= rect->ymax-y1; - + /* first background, to show tranparency */ - dx= sizex/12.0f; - v1[0]= x1; - for(a=0; a<12; a++) { - if(a & 1) glColor3f(0.3, 0.3, 0.3); else glColor3f(0.8, 0.8, 0.8); - glRectf(v1[0], y1, v1[0]+dx, y1+0.5f*sizey); - if(a & 1) glColor3f(0.8, 0.8, 0.8); else glColor3f(0.3, 0.3, 0.3); - glRectf(v1[0], y1+0.5f*sizey, v1[0]+dx, y1+sizey); - v1[0]+= dx; - } - + + glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255); + glRectf(x1, y1, x1+sizex, y1+sizey); + glEnable(GL_POLYGON_STIPPLE); + glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255); + glPolygonStipple(checker_stipple_sml); + glRectf(x1, y1, x1+sizex, y1+sizey); + glDisable(GL_POLYGON_STIPPLE); + glShadeModel(GL_FLAT); glEnable(GL_BLEND); diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 3f3665aae38..8475090b468 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -486,6 +486,11 @@ void ui_widget_color_init(struct ThemeUI *tui); void ui_draw_menu_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state); void ui_draw_preview_item(struct uiFontStyle *fstyle, rcti *rect, const char *name, int iconid, int state); +extern unsigned char checker_stipple_sml[]; +/* used for transp checkers */ +#define UI_TRANSP_DARK 100 +#define UI_TRANSP_LIGHT 160 + /* interface_style.c */ void uiStyleInit(void); diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b68634acd1e..55c1488291b 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -651,6 +651,9 @@ PointerRNA uiItemFullO(uiLayout *layout, const char *opname, const char *name, i if (flag & UI_ITEM_R_NO_BG) uiBlockSetEmboss(block, UI_EMBOSS); + if(layout->redalert) + uiButSetFlag(but, UI_BUT_REDALERT); + /* assign properties */ if(properties || (flag & UI_ITEM_O_RETURN_PROPS)) { PointerRNA *opptr= uiButGetOperatorPtrRNA(but); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index f767a432cd0..41bb12e4433 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -159,6 +159,18 @@ static float check_tria_vert[6][2]= { static int check_tria_face[4][3]= { {3, 2, 4}, {3, 4, 5}, {1, 0, 3}, {0, 2, 3}}; +GLubyte checker_stipple_sml[32*32/8] = +{ + 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ + 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ + 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ + 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ + 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ + 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ + 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ + 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ +}; + /* ************************************************* */ void ui_draw_anti_tria(float x1, float y1, float x2, float y2, float x3, float y3) @@ -614,22 +626,10 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) if(wtb->inner) { if(wcol->shaded==0) { if (wcol->alpha_check) { - GLubyte checker_stipple_sml[32*32/8] = - { - 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ - 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ - 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ - 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ - 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ - 255,0,255,0,255,0,255,0,255,0,255,0,255,0,255,0, \ - 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ - 0,255,0,255,0,255,0,255,0,255,0,255,0,255,0,255, \ - }; - float x_mid= 0.0f; /* used for dumb clamping of values */ /* dark checkers */ - glColor4ub(100, 100, 100, 255); + glColor4ub(UI_TRANSP_DARK, UI_TRANSP_DARK, UI_TRANSP_DARK, 255); glBegin(GL_POLYGON); for(a=0; a<wtb->totvert; a++) { glVertex2fv(wtb->inner_v[a]); @@ -638,7 +638,7 @@ static void widgetbase_draw(uiWidgetBase *wtb, uiWidgetColors *wcol) /* light checkers */ glEnable(GL_POLYGON_STIPPLE); - glColor4ub(160, 160, 160, 255); + glColor4ub(UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, UI_TRANSP_LIGHT, 255); glPolygonStipple(checker_stipple_sml); glBegin(GL_POLYGON); for(a=0; a<wtb->totvert; a++) { diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 6d4d88da270..6527e0140b8 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -585,7 +585,7 @@ void ui_theme_init_default(void) SETCOL(btheme->tv3d.wire, 0x0, 0x0, 0x0, 255); SETCOL(btheme->tv3d.lamp, 0, 0, 0, 40); SETCOL(btheme->tv3d.select, 241, 88, 0, 255); - SETCOL(btheme->tv3d.active, 255, 140, 25, 255); + SETCOL(btheme->tv3d.active, 255, 170, 64, 255); SETCOL(btheme->tv3d.group, 8, 48, 8, 255); SETCOL(btheme->tv3d.group_active, 85, 187, 85, 255); SETCOL(btheme->tv3d.transform, 0xff, 0xff, 0xff, 255); @@ -604,7 +604,7 @@ void ui_theme_init_default(void) SETCOL(btheme->tv3d.face_dot, 255, 133, 0, 255); SETCOL(btheme->tv3d.editmesh_active, 255, 255, 255, 128); SETCOLF(btheme->tv3d.edge_crease, 0.8, 0, 0.6, 1.0); - SETCOL(btheme->tv3d.edge_sharp, 255, 32, 32, 255); + SETCOL(btheme->tv3d.edge_sharp, 0, 255, 255, 255); SETCOL(btheme->tv3d.header_text, 0, 0, 0, 255); SETCOL(btheme->tv3d.header_text_hi, 255, 255, 255, 255); SETCOL(btheme->tv3d.button_text, 0, 0, 0, 255); diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index f7bff168a33..434334258af 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -876,6 +876,13 @@ static void view_zoomdrag_exit(bContext *C, wmOperator *op) } } +static int view_zoomdrag_cancel(bContext *C, wmOperator *op) +{ + view_zoomdrag_exit(C, op); + + return OPERATOR_CANCELLED; +} + /* for 'redo' only, with no user input */ static int view_zoomdrag_exec(bContext *C, wmOperator *op) { @@ -1065,6 +1072,7 @@ static void VIEW2D_OT_zoom(wmOperatorType *ot) ot->exec= view_zoomdrag_exec; ot->invoke= view_zoomdrag_invoke; ot->modal= view_zoomdrag_modal; + ot->cancel= view_zoomdrag_cancel; ot->poll= view_zoom_poll; @@ -1165,6 +1173,7 @@ static void VIEW2D_OT_zoom_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= view_borderzoom_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= view_zoom_poll; @@ -1352,7 +1361,14 @@ static void scroller_activate_exit(bContext *C, wmOperator *op) ED_region_tag_redraw(CTX_wm_region(C)); } -} +} + +static int scroller_activate_cancel(bContext *C, wmOperator *op) +{ + scroller_activate_exit(C, op); + + return OPERATOR_CANCELLED; +} /* apply transform to view (i.e. adjust 'cur' rect) */ static void scroller_activate_apply(bContext *C, wmOperator *op) @@ -1561,6 +1577,8 @@ static void VIEW2D_OT_scroller_activate(wmOperatorType *ot) /* api callbacks */ ot->invoke= scroller_activate_invoke; ot->modal= scroller_activate_modal; + ot->cancel= scroller_activate_cancel; + ot->poll= view2d_poll; } diff --git a/source/blender/editors/mesh/editmesh_loop.c b/source/blender/editors/mesh/editmesh_loop.c index d7e59e0a68f..32971ca77ed 100644 --- a/source/blender/editors/mesh/editmesh_loop.c +++ b/source/blender/editors/mesh/editmesh_loop.c @@ -716,6 +716,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot) ot->invoke= WM_gesture_lines_invoke; ot->modal= WM_gesture_lines_modal; ot->exec= knife_cut_exec; + ot->cancel= WM_gesture_lines_cancel; ot->poll= EM_view3d_poll; diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index b513bab3924..565c5810cff 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -22,7 +22,8 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Morten Mikkelsen, + * Sergey Sharybin * * ***** END GPL LICENSE BLOCK ***** */ @@ -44,10 +45,15 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" #include "DNA_world_types.h" +#include "DNA_object_types.h" +#include "DNA_mesh_types.h" +#include "DNA_meshdata_types.h" #include "BLI_blenlib.h" #include "BLI_threads.h" #include "BLI_utildefines.h" +#include "BLI_math.h" +#include "BLI_math_geom.h" #include "BKE_blender.h" #include "BKE_context.h" @@ -56,6 +62,10 @@ #include "BKE_main.h" #include "BKE_multires.h" #include "BKE_report.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_modifier.h" +#include "BKE_DerivedMesh.h" +#include "BKE_subsurf.h" #include "RE_pipeline.h" #include "RE_shader_ext.h" @@ -74,6 +84,1134 @@ #include "object_intern.h" +/* ****************** multires BAKING ********************** */ + +/* holder of per-object data needed for bake job + needed to make job totally thread-safe */ +typedef struct MultiresBakerJobData { + struct MultiresBakerJobData *next, *prev; + DerivedMesh *lores_dm, *hires_dm; + int simple, lvl, tot_lvl; +} MultiresBakerJobData; + +/* data passing to multires-baker job */ +typedef struct { + ListBase data; + int bake_clear, bake_filter; + short mode, use_lores_mesh; +} MultiresBakeJob; + +/* data passing to multires baker */ +typedef struct { + DerivedMesh *lores_dm, *hires_dm; + int simple, lvl, tot_lvl, bake_filter; + short mode, use_lores_mesh; + + int tot_obj, tot_image; + ListBase image; + + int baked_objects, baked_faces; + + short *stop; + short *do_update; + float *progress; +} MultiresBakeRender; + +typedef void (*MPassKnownData)(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, + const int face_index, const int lvl, const float st[2], + float tangmat[3][3], const int x, const int y); + +typedef void* (*MInitBakeData)(MultiresBakeRender *bkr, Image* ima); +typedef void (*MApplyBakeData)(void *bake_data); +typedef void (*MFreeBakeData)(void *bake_data); + +typedef struct { + MVert *mvert; + MFace *mface; + MTFace *mtface; + float *pvtangent; + float *precomputed_normals; + int w, h; + int face_index; + int i0, i1, i2; + DerivedMesh *lores_dm, *hires_dm; + int lvl; + void *bake_data; + MPassKnownData pass_data; +} MResolvePixelData; + +typedef void (*MFlushPixel)(const MResolvePixelData *data, const int x, const int y); + +typedef struct { + int w, h; + char *texels; + const MResolvePixelData *data; + MFlushPixel flush_pixel; +} MBakeRast; + +typedef struct { + float *heights; + float height_min, height_max; + Image *ima; + DerivedMesh *ssdm; +} MHeightBakeData; + +static void multiresbake_get_normal(const MResolvePixelData *data, float norm[], const int face_num, const int vert_index) +{ + unsigned int indices[]= {data->mface[face_num].v1, data->mface[face_num].v2, + data->mface[face_num].v3, data->mface[face_num].v4}; + const int smoothnormal= (data->mface[face_num].flag & ME_SMOOTH); + + if(!smoothnormal) { /* flat */ + if(data->precomputed_normals) { + copy_v3_v3(norm, &data->precomputed_normals[3*face_num]); + } else { + float nor[3]; + float *p0, *p1, *p2; + const int iGetNrVerts= data->mface[face_num].v4!=0 ? 4 : 3; + + p0= data->mvert[indices[0]].co; + p1= data->mvert[indices[1]].co; + p2= data->mvert[indices[2]].co; + + if(iGetNrVerts==4) { + float *p3= data->mvert[indices[3]].co; + normal_quad_v3(nor, p0, p1, p2, p3); + } else { + normal_tri_v3(nor, p0, p1, p2); + } + + copy_v3_v3(norm, nor); + } + } else { + short *no= data->mvert[indices[vert_index]].no; + + normal_short_to_float_v3(norm, no); + normalize_v3(norm); + } +} + +static void init_bake_rast(MBakeRast *bake_rast, const ImBuf *ibuf, const MResolvePixelData *data, MFlushPixel flush_pixel) +{ + memset(bake_rast, 0, sizeof(MBakeRast)); + + bake_rast->texels = ibuf->userdata; + bake_rast->w= ibuf->x; + bake_rast->h= ibuf->y; + bake_rast->data= data; + bake_rast->flush_pixel= flush_pixel; +} + +static void flush_pixel(const MResolvePixelData *data, const int x, const int y) +{ + float st[2]= {(x+0.5f)/data->w, (y+0.5f)/data->h}; + float *st0, *st1, *st2; + float *tang0, *tang1, *tang2; + float no0[3], no1[3], no2[3]; + float fUV[2], from_tang[3][3], to_tang[3][3]; + float u, v, w, sign; + int r; + + const int i0= data->i0; + const int i1= data->i1; + const int i2= data->i2; + + st0= data->mtface[data->face_index].uv[i0]; + st1= data->mtface[data->face_index].uv[i1]; + st2= data->mtface[data->face_index].uv[i2]; + + tang0= data->pvtangent + data->face_index*16 + i0*4; + tang1= data->pvtangent + data->face_index*16 + i1*4; + tang2= data->pvtangent + data->face_index*16 + i2*4; + + multiresbake_get_normal(data, no0, data->face_index, i0); /* can optimize these 3 into one call */ + multiresbake_get_normal(data, no1, data->face_index, i1); + multiresbake_get_normal(data, no2, data->face_index, i2); + + resolve_tri_uv(fUV, st, st0, st1, st2); + + u= fUV[0]; + v= fUV[1]; + w= 1-u-v; + + /* the sign is the same at all face vertices for any non degenerate face. + Just in case we clamp the interpolated value though. */ + sign= (tang0[3]*u + tang1[3]*v + tang2[3]*w)<0 ? (-1.0f) : 1.0f; + + /* this sequence of math is designed specifically as is with great care + to be compatible with our shader. Please don't change without good reason. */ + for(r= 0; r<3; r++) { + from_tang[0][r]= tang0[r]*u + tang1[r]*v + tang2[r]*w; + from_tang[2][r]= no0[r]*u + no1[r]*v + no2[r]*w; + } + + cross_v3_v3v3(from_tang[1], from_tang[2], from_tang[0]); /* B = sign * cross(N, T) */ + mul_v3_fl(from_tang[1], sign); + invert_m3_m3(to_tang, from_tang); + /* sequence end */ + + data->pass_data(data->lores_dm, data->hires_dm, data->bake_data, + data->face_index, data->lvl, st, to_tang, x, y); +} + +static void set_rast_triangle(const MBakeRast *bake_rast, const int x, const int y) +{ + const int w= bake_rast->w; + const int h= bake_rast->h; + + if(x>=0 && x<w && y>=0 && y<h) { + if((bake_rast->texels[y*w+x])==0) { + flush_pixel(bake_rast->data, x, y); + bake_rast->texels[y*w+x]= FILTER_MASK_USED; + } + } +} + +static void rasterize_half(const MBakeRast *bake_rast, + const float s0_s, const float t0_s, const float s1_s, const float t1_s, + const float s0_l, const float t0_l, const float s1_l, const float t1_l, + const int y0_in, const int y1_in, const int is_mid_right) +{ + const int s_stable= fabsf(t1_s-t0_s)>FLT_EPSILON ? 1 : 0; + const int l_stable= fabsf(t1_l-t0_l)>FLT_EPSILON ? 1 : 0; + const int w= bake_rast->w; + const int h= bake_rast->h; + int y, y0, y1; + + if(y1_in<=0 || y0_in>=h) + return; + + y0= y0_in<0 ? 0 : y0_in; + y1= y1_in>=h ? h : y1_in; + + for(y= y0; y<y1; y++) { + /*-b(x-x0) + a(y-y0) = 0 */ + int iXl, iXr, x; + float x_l= s_stable!=0 ? (s0_s + (((s1_s-s0_s)*(y-t0_s))/(t1_s-t0_s))) : s0_s; + float x_r= l_stable!=0 ? (s0_l + (((s1_l-s0_l)*(y-t0_l))/(t1_l-t0_l))) : s0_l; + + if(is_mid_right!=0) + SWAP(float, x_l, x_r); + + iXl= (int)ceilf(x_l); + iXr= (int)ceilf(x_r); + + if(iXr>0 && iXl<w) { + iXl= iXl<0?0:iXl; + iXr= iXr>=w?w:iXr; + + for(x= iXl; x<iXr; x++) + set_rast_triangle(bake_rast, x, y); + } + } +} + +static void bake_rasterize(const MBakeRast *bake_rast, const float st0_in[2], const float st1_in[2], const float st2_in[2]) +{ + const int w= bake_rast->w; + const int h= bake_rast->h; + float slo= st0_in[0]*w - 0.5f; + float tlo= st0_in[1]*h - 0.5f; + float smi= st1_in[0]*w - 0.5f; + float tmi= st1_in[1]*h - 0.5f; + float shi= st2_in[0]*w - 0.5f; + float thi= st2_in[1]*h - 0.5f; + int is_mid_right= 0, ylo, yhi, yhi_beg; + + /* skip degenerates */ + if((slo==smi && tlo==tmi) || (slo==shi && tlo==thi) || (smi==shi && tmi==thi)) + return; + + /* sort by T */ + if(tlo>tmi && tlo>thi) { + SWAP(float, shi, slo); + SWAP(float, thi, tlo); + } else if(tmi>thi) { + SWAP(float, shi, smi); + SWAP(float, thi, tmi); + } + + if(tlo>tmi) { + SWAP(float, slo, smi); + SWAP(float, tlo, tmi); + } + + /* check if mid point is to the left or to the right of the lo-hi edge */ + is_mid_right= (-(shi-slo)*(tmi-thi) + (thi-tlo)*(smi-shi))>0 ? 1 : 0; + ylo= (int) ceilf(tlo); + yhi_beg= (int) ceilf(tmi); + yhi= (int) ceilf(thi); + + /*if(fTmi>ceilf(fTlo))*/ + rasterize_half(bake_rast, slo, tlo, smi, tmi, slo, tlo, shi, thi, ylo, yhi_beg, is_mid_right); + rasterize_half(bake_rast, smi, tmi, shi, thi, slo, tlo, shi, thi, yhi_beg, yhi, is_mid_right); +} + +static int multiresbake_test_break(MultiresBakeRender *bkr) +{ + if(!bkr->stop) { + /* this means baker is executed outside from job system */ + return 0; + } + + return G.afbreek; +} + +static void do_multires_bake(MultiresBakeRender *bkr, Image* ima, MPassKnownData passKnownData, + MInitBakeData initBakeData, MApplyBakeData applyBakeData, MFreeBakeData freeBakeData) +{ + DerivedMesh *dm= bkr->lores_dm; + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + const int lvl= bkr->lvl; + const int tot_face= dm->getNumFaces(dm); + MVert *mvert= dm->getVertArray(dm); + MFace *mface= dm->getFaceArray(dm); + MTFace *mtface= dm->getFaceDataArray(dm, CD_MTFACE); + float *pvtangent= NULL; + + if(CustomData_get_layer_index(&dm->faceData, CD_TANGENT) == -1) + DM_add_tangent_layer(dm); + + pvtangent= DM_get_face_data_layer(dm, CD_TANGENT); + + if(tot_face > 0) { /* sanity check */ + int f= 0; + MBakeRast bake_rast; + MResolvePixelData data={NULL}; + + data.mface= mface; + data.mvert= mvert; + data.mtface= mtface; + data.pvtangent= pvtangent; + data.precomputed_normals= dm->getFaceDataArray(dm, CD_NORMAL); /* don't strictly need this */ + data.w= ibuf->x; + data.h= ibuf->y; + data.lores_dm= dm; + data.hires_dm= bkr->hires_dm; + data.lvl= lvl; + data.pass_data= passKnownData; + + if(initBakeData) + data.bake_data= initBakeData(bkr, ima); + + init_bake_rast(&bake_rast, ibuf, &data, flush_pixel); + + for(f= 0; f<tot_face; f++) { + MTFace *mtfate= &mtface[f]; + int verts[3][2], nr_tris, t; + + if(multiresbake_test_break(bkr)) + break; + + if(mtfate->tpage!=ima) + continue; + + data.face_index= f; + + /* might support other forms of diagonal splits later on such as + split by shortest diagonal.*/ + verts[0][0]=0; + verts[1][0]=1; + verts[2][0]=2; + + verts[0][1]=0; + verts[1][1]=2; + verts[2][1]=3; + + nr_tris= mface[f].v4!=0 ? 2 : 1; + for(t= 0; t<nr_tris; t++) { + data.i0= verts[0][t]; + data.i1= verts[1][t]; + data.i2 =verts[2][t]; + + bake_rasterize(&bake_rast, mtfate->uv[data.i0], mtfate->uv[data.i1], mtfate->uv[data.i2]); + } + + bkr->baked_faces++; + + if(bkr->do_update) + *bkr->do_update= 1; + + if(bkr->progress) + *bkr->progress= ((float)bkr->baked_objects + (float)bkr->baked_faces / tot_face) / bkr->tot_obj; + } + + if(applyBakeData) + applyBakeData(data.bake_data); + + if(freeBakeData) + freeBakeData(data.bake_data); + } +} + +static void interp_bilinear_quad_data(float data[4][3], float u, float v, float res[3]) +{ + float vec[3]; + + copy_v3_v3(res, data[0]); + mul_v3_fl(res, (1-u)*(1-v)); + copy_v3_v3(vec, data[1]); + mul_v3_fl(vec, u*(1-v)); add_v3_v3(res, vec); + copy_v3_v3(vec, data[2]); + mul_v3_fl(vec, u*v); add_v3_v3(res, vec); + copy_v3_v3(vec, data[3]); + mul_v3_fl(vec, (1-u)*v); add_v3_v3(res, vec); +} + +static void interp_barycentric_tri_data(float data[3][3], float u, float v, float res[3]) +{ + float vec[3]; + + copy_v3_v3(res, data[0]); + mul_v3_fl(res, u); + copy_v3_v3(vec, data[1]); + mul_v3_fl(vec, v); add_v3_v3(res, vec); + copy_v3_v3(vec, data[2]); + mul_v3_fl(vec, 1.0f-u-v); add_v3_v3(res, vec); +} + +/* mode = 0: interpolate normals, + mode = 1: interpolate coord */ +static void interp_bilinear_grid(DMGridData *grid, int grid_size, float crn_x, float crn_y, int mode, float res[3]) +{ + int x0, x1, y0, y1; + float u, v; + float data[4][3]; + + x0= (int) crn_x; + x1= x0>=(grid_size-1) ? (grid_size-1) : (x0+1); + + y0= (int) crn_y; + y1= y0>=(grid_size-1) ? (grid_size-1) : (y0+1); + + u= crn_x-x0; + v= crn_y-y0; + + if(mode == 0) { + copy_v3_v3(data[0], grid[y0 * grid_size + x0].no); + copy_v3_v3(data[1], grid[y0 * grid_size + x1].no); + copy_v3_v3(data[2], grid[y1 * grid_size + x1].no); + copy_v3_v3(data[3], grid[y1 * grid_size + x0].no); + } else { + copy_v3_v3(data[0], grid[y0 * grid_size + x0].co); + copy_v3_v3(data[1], grid[y0 * grid_size + x1].co); + copy_v3_v3(data[2], grid[y1 * grid_size + x1].co); + copy_v3_v3(data[3], grid[y1 * grid_size + x0].co); + } + + interp_bilinear_quad_data(data, u, v, res); +} + +static void get_ccgdm_data(DerivedMesh *lodm, DerivedMesh *hidm, const int lvl, const int face_index, const float u, const float v, float co[3], float n[3]) +{ + MFace mface; + DMGridData **grid_data; + float crn_x, crn_y; + int grid_size, S, face_side; + int *grid_offset, g_index; + + lodm->getFace(lodm, face_index, &mface); + + grid_size= hidm->getGridSize(hidm); + grid_data= hidm->getGridData(hidm); + grid_offset= hidm->getGridOffset(hidm); + + face_side= (grid_size<<1)-1; + + if(lvl==0) { + g_index= grid_offset[face_index]; + S= mdisp_rot_face_to_crn(mface.v4 ? 4 : 3, face_side, u*(face_side-1), v*(face_side-1), &crn_x, &crn_y); + } else { + const int *index= lodm->getFaceDataArray(lodm, CD_ORIGINDEX); + int side= (1 << (lvl-1)) + 1; + int grid_index= index[face_index]; + int loc_offs= face_index % (1<<(2*lvl)); + int cell_index= loc_offs % ((side-1)*(side-1)); + int cell_side= grid_size / (side-1); + int row= cell_index / (side-1); + int col= cell_index % (side-1); + + S= face_index / (1<<(2*(lvl-1))) - grid_offset[grid_index]; + g_index= grid_offset[grid_index]; + + crn_y= (row * cell_side) + u * cell_side; + crn_x= (col * cell_side) + v * cell_side; + } + + CLAMP(crn_x, 0.0f, grid_size); + CLAMP(crn_y, 0.0f, grid_size); + + if(n != NULL) + interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 0, n); + + if(co != NULL) + interp_bilinear_grid(grid_data[g_index + S], grid_size, crn_x, crn_y, 1, co); +} + +/* mode = 0: interpolate normals, + mode = 1: interpolate coord */ +static void interp_bilinear_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3]) +{ + float data[4][3]; + + if(mode == 0) { + dm->getVertNo(dm, mface->v1, data[0]); + dm->getVertNo(dm, mface->v2, data[1]); + dm->getVertNo(dm, mface->v3, data[2]); + dm->getVertNo(dm, mface->v4, data[3]); + } else { + dm->getVertCo(dm, mface->v1, data[0]); + dm->getVertCo(dm, mface->v2, data[1]); + dm->getVertCo(dm, mface->v3, data[2]); + dm->getVertCo(dm, mface->v4, data[3]); + } + + interp_bilinear_quad_data(data, u, v, res); +} + +/* mode = 0: interpolate normals, + mode = 1: interpolate coord */ +static void interp_barycentric_mface(DerivedMesh *dm, MFace *mface, const float u, const float v, const int mode, float res[3]) +{ + float data[3][3]; + + if(mode == 0) { + dm->getVertNo(dm, mface->v1, data[0]); + dm->getVertNo(dm, mface->v2, data[1]); + dm->getVertNo(dm, mface->v3, data[2]); + } else { + dm->getVertCo(dm, mface->v1, data[0]); + dm->getVertCo(dm, mface->v2, data[1]); + dm->getVertCo(dm, mface->v3, data[2]); + } + + interp_barycentric_tri_data(data, u, v, res); +} + +static void *init_heights_data(MultiresBakeRender *bkr, Image* ima) +{ + MHeightBakeData *height_data; + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + + height_data= MEM_callocN(sizeof(MHeightBakeData), "MultiresBake heightData"); + + height_data->ima= ima; + height_data->heights= MEM_callocN(sizeof(float)*ibuf->x*ibuf->y, "MultiresBake heights"); + height_data->height_max= -FLT_MAX; + height_data->height_min= FLT_MAX; + + if(!bkr->use_lores_mesh) { + SubsurfModifierData smd= {{NULL}}; + int ss_lvl= bkr->tot_lvl - bkr->lvl; + + CLAMP(ss_lvl, 0, 6); + + smd.levels= smd.renderLevels= ss_lvl; + smd.flags|= eSubsurfModifierFlag_SubsurfUv; + + if(bkr->simple) + smd.subdivType= ME_SIMPLE_SUBSURF; + + height_data->ssdm= subsurf_make_derived_from_derived(bkr->lores_dm, &smd, 0, NULL, 0, 0, 0); + } + + return (void*)height_data; +} + +static void apply_heights_data(void *bake_data) +{ + MHeightBakeData *height_data= (MHeightBakeData*)bake_data; + ImBuf *ibuf= BKE_image_get_ibuf(height_data->ima, NULL); + int x, y, i; + float height, *heights= height_data->heights; + float min= height_data->height_min, max= height_data->height_max; + + for(x= 0; x<ibuf->x; x++) { + for(y =0; y<ibuf->y; y++) { + i= ibuf->x*y + x; + + if(((char*)ibuf->userdata)[i] != FILTER_MASK_USED) + continue; + + if(ibuf->rect_float) { + float *rrgbf= ibuf->rect_float + i*4; + + if(max-min > 1e-5) height= (heights[i]-min)/(max-min); + else height= 0; + + rrgbf[0]=rrgbf[1]=rrgbf[2]= height; + } else { + char *rrgb= (char*)ibuf->rect + i*4; + + if(max-min > 1e-5) height= (heights[i]-min)/(max-min); + else height= 0; + + rrgb[0]=rrgb[1]=rrgb[2]= FTOCHAR(height); + } + } + } + + ibuf->userflags= IB_RECT_INVALID; +} + +static void free_heights_data(void *bake_data) +{ + MHeightBakeData *height_data= (MHeightBakeData*)bake_data; + + if(height_data->ssdm) + height_data->ssdm->release(height_data->ssdm); + + MEM_freeN(height_data->heights); + MEM_freeN(height_data); +} + +/* MultiresBake callback for heights baking + general idea: + - find coord of point with specified UV in hi-res mesh (let's call it p1) + - find coord of point and normal with specified UV in lo-res mesh (or subdivided lo-res + mesh to make texture smoother) let's call this point p0 and n. + - height wound be dot(n, p1-p0) */ +static void apply_heights_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *bake_data, + const int face_index, const int lvl, const float st[2], + float UNUSED(tangmat[3][3]), const int x, const int y) +{ + MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); + MFace mface; + Image *ima= mtface[face_index].tpage; + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + MHeightBakeData *height_data= (MHeightBakeData*)bake_data; + float uv[2], *st0, *st1, *st2, *st3; + int pixel= ibuf->x*y + x; + float vec[3], p0[3], p1[3], n[3], len; + + lores_dm->getFace(lores_dm, face_index, &mface); + + st0= mtface[face_index].uv[0]; + st1= mtface[face_index].uv[1]; + st2= mtface[face_index].uv[2]; + + if(mface.v4) { + st3= mtface[face_index].uv[3]; + resolve_quad_uv(uv, st, st0, st1, st2, st3); + } else + resolve_tri_uv(uv, st, st0, st1, st2); + + CLAMP(uv[0], 0.0f, 1.0f); + CLAMP(uv[1], 0.0f, 1.0f); + + get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], p1, 0); + + if(height_data->ssdm) { + //get_ccgdm_data_ss(lores_dm, height_data->ssdm, lvl, face_index, uv[0], uv[1], p0, n); + get_ccgdm_data(lores_dm, height_data->ssdm, 0, face_index, uv[0], uv[1], p0, n); + } else { + MFace mface; + lores_dm->getFace(lores_dm, face_index, &mface); + + if(mface.v4) { + interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 1, p0); + interp_bilinear_mface(lores_dm, &mface, uv[0], uv[1], 0, n); + } else { + interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 1, p0); + interp_barycentric_mface(lores_dm, &mface, uv[0], uv[1], 0, n); + } + } + + sub_v3_v3v3(vec, p1, p0); + //len= len_v3(vec); + len= dot_v3v3(n, vec); + + height_data->heights[pixel]= len; + if(len<height_data->height_min) height_data->height_min= len; + if(len>height_data->height_max) height_data->height_max= len; + + if(ibuf->rect_float) { + float *rrgbf= ibuf->rect_float + pixel*4; + rrgbf[3]= 1.0f; + + ibuf->userflags= IB_RECT_INVALID; + } else { + char *rrgb= (char*)ibuf->rect + pixel*4; + rrgb[3]= 255; + } +} + +/* MultiresBake callback for normals' baking + general idea: + - find coord and normal of point with specified UV in hi-res mesh + - multiply it by tangmat + - vector in color space would be norm(vec) /2 + (0.5, 0.5, 0.5) */ +static void apply_tangmat_callback(DerivedMesh *lores_dm, DerivedMesh *hires_dm, const void *UNUSED(bake_data), + const int face_index, const int lvl, const float st[2], + float tangmat[3][3], const int x, const int y) +{ + MTFace *mtface= CustomData_get_layer(&lores_dm->faceData, CD_MTFACE); + MFace mface; + Image *ima= mtface[face_index].tpage; + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + float uv[2], *st0, *st1, *st2, *st3; + int pixel= ibuf->x*y + x; + float n[3], vec[3], tmp[3]= {0.5, 0.5, 0.5}; + + lores_dm->getFace(lores_dm, face_index, &mface); + + st0= mtface[face_index].uv[0]; + st1= mtface[face_index].uv[1]; + st2= mtface[face_index].uv[2]; + + if(mface.v4) { + st3= mtface[face_index].uv[3]; + resolve_quad_uv(uv, st, st0, st1, st2, st3); + } else + resolve_tri_uv(uv, st, st0, st1, st2); + + CLAMP(uv[0], 0.0f, 1.0f); + CLAMP(uv[1], 0.0f, 1.0f); + + get_ccgdm_data(lores_dm, hires_dm, lvl, face_index, uv[0], uv[1], NULL, n); + + mul_v3_m3v3(vec, tangmat, n); + normalize_v3(vec); + mul_v3_fl(vec, 0.5); + add_v3_v3(vec, tmp); + + if(ibuf->rect_float) { + float *rrgbf= ibuf->rect_float + pixel*4; + rrgbf[0]= vec[0]; + rrgbf[1]= vec[1]; + rrgbf[2]= vec[2]; + rrgbf[3]= 1.0f; + + ibuf->userflags= IB_RECT_INVALID; + } else { + char *rrgb= (char*)ibuf->rect + pixel*4; + rrgb[0]= FTOCHAR(vec[0]); + rrgb[1]= FTOCHAR(vec[1]); + rrgb[2]= FTOCHAR(vec[2]); + rrgb[3]= 255; + } +} + +static void count_images(MultiresBakeRender *bkr) +{ + int a, totface; + DerivedMesh *dm= bkr->lores_dm; + MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE); + + bkr->image.first= bkr->image.last= NULL; + bkr->tot_image= 0; + + totface= dm->getNumFaces(dm); + + for(a= 0; a<totface; a++) + mtface[a].tpage->id.flag&= ~LIB_DOIT; + + for(a= 0; a<totface; a++) { + Image *ima= mtface[a].tpage; + if((ima->id.flag&LIB_DOIT)==0) { + LinkData *data= BLI_genericNodeN(ima); + BLI_addtail(&bkr->image, data); + bkr->tot_image++; + ima->id.flag|= LIB_DOIT; + } + } + + for(a= 0; a<totface; a++) + mtface[a].tpage->id.flag&= ~LIB_DOIT; +} + +static void bake_images(MultiresBakeRender *bkr) +{ + LinkData *link; + + for(link= bkr->image.first; link; link= link->next) { + Image *ima= (Image*)link->data; + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + + if(ibuf->x>0 && ibuf->y>0) { + ibuf->userdata= MEM_callocN(ibuf->y*ibuf->x, "MultiresBake imbuf mask"); + + switch(bkr->mode) { + case RE_BAKE_NORMALS: + do_multires_bake(bkr, ima, apply_tangmat_callback, NULL, NULL, NULL); + break; + case RE_BAKE_DISPLACEMENT: + do_multires_bake(bkr, ima, apply_heights_callback, init_heights_data, + apply_heights_data, free_heights_data); + break; + } + } + + ima->id.flag|= LIB_DOIT; + } +} + +static void finish_images(MultiresBakeRender *bkr) +{ + LinkData *link; + + for(link= bkr->image.first; link; link= link->next) { + Image *ima= (Image*)link->data; + int i; + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + + if(ibuf->x<=0 || ibuf->y<=0) + continue; + + /* Margin */ + if(bkr->bake_filter) { + char *temprect; + + /* extend the mask +2 pixels from the image, + * this is so colors dont blend in from outside */ + + for(i=0; i<bkr->bake_filter; i++) + IMB_mask_filter_extend((char *)ibuf->userdata, ibuf->x, ibuf->y); + + temprect = MEM_dupallocN(ibuf->userdata); + + /* expand twice to clear this many pixels, so they blend back in */ + IMB_mask_filter_extend(temprect, ibuf->x, ibuf->y); + IMB_mask_filter_extend(temprect, ibuf->x, ibuf->y); + + /* clear all pixels in the margin */ + IMB_mask_clear(ibuf, temprect, FILTER_MASK_MARGIN); + MEM_freeN(temprect); + + for(i= 0; i<bkr->bake_filter; i++) + IMB_filter_extend(ibuf, (char *)ibuf->userdata); + } + + ibuf->userflags|= IB_BITMAPDIRTY; + if(ibuf->mipmap[0]) { + ibuf->userflags|= IB_MIPMAP_INVALID; + imb_freemipmapImBuf(ibuf); + } + + if(ibuf->userdata) { + MEM_freeN(ibuf->userdata); + ibuf->userdata= NULL; + } + } +} + +static void multiresbake_start(MultiresBakeRender *bkr) +{ + count_images(bkr); + bake_images(bkr); + finish_images(bkr); +} + +static int multiresbake_check(bContext *C, wmOperator *op) { + Scene *scene= CTX_data_scene(C); + Object *ob; + Mesh *me; + MultiresModifierData *mmd; + int ok= 1, a; + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + ob= base->object; + + if(ob->type != OB_MESH) { + BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh"); + + ok= 0; + break; + } + + me= (Mesh*)ob->data; + mmd= get_multires_modifier(scene, ob, 0); + + /* Multi-resolution should be and be last in the stack */ + if(ok && mmd) { + ModifierData *md; + + ok= mmd->totlvl>0; + + for(md = (ModifierData*)mmd->modifier.next; md && ok; md = md->next) { + if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) { + ok= 0; + } + } + } else ok= 0; + + if(!ok) { + BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object"); + + break; + } + + if(!me->mtface) { + BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); + + ok= 0; + } else { + a= me->totface; + while (ok && a--) { + Image *ima= me->mtface[a].tpage; + + if(!ima) { + BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker"); + + ok= 0; + } else { + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + + if(!ibuf) { + BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer"); + + ok= 0; + } else { + if(ibuf->rect==NULL && ibuf->rect_float==NULL) + ok= 0; + + if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) + ok= 0; + + if(!ok) + BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); + } + } + } + } + + if(!ok) + break; + } + CTX_DATA_END; + + return ok; +} + +static DerivedMesh *multiresbake_create_loresdm(Scene *scene, Object *ob, int *lvl) +{ + DerivedMesh *dm; + MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0); + Mesh *me= (Mesh*)ob->data; + + *lvl= mmd->lvl; + + if(mmd->lvl==0) { + DerivedMesh *tmp_dm= CDDM_from_mesh(me, ob); + dm= CDDM_copy(tmp_dm); + tmp_dm->release(tmp_dm); + } else { + MultiresModifierData tmp_mmd= *mmd; + DerivedMesh *cddm= CDDM_from_mesh(me, ob); + + tmp_mmd.lvl= mmd->lvl; + dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0); + cddm->release(cddm); + } + + return dm; +} + +static DerivedMesh *multiresbake_create_hiresdm(Scene *scene, Object *ob, int *lvl, int *simple) +{ + Mesh *me= (Mesh*)ob->data; + MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0); + MultiresModifierData tmp_mmd= *mmd; + DerivedMesh *cddm= CDDM_from_mesh(me, ob); + DerivedMesh *dm; + + *lvl= mmd->totlvl; + *simple= mmd->simple; + + tmp_mmd.lvl= mmd->totlvl; + dm= multires_dm_create_from_derived(&tmp_mmd, 1, cddm, ob, 0, 0); + cddm->release(cddm); + + return dm; +} + +static void clear_images(MTFace *mtface, int totface) +{ + int a; + float vec[4]= {0.0f, 0.0f, 0.0f, 0.0f}; + + for(a= 0; a<totface; a++) + mtface[a].tpage->id.flag&= ~LIB_DOIT; + + for(a= 0; a<totface; a++) { + Image *ima= mtface[a].tpage; + + if((ima->id.flag&LIB_DOIT)==0) { + ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); + + IMB_rectfill(ibuf, vec); + ima->id.flag|= LIB_DOIT; + } + } + + for(a= 0; a<totface; a++) + mtface[a].tpage->id.flag&= ~LIB_DOIT; +} + +static int multiresbake_image_exec_locked(bContext *C, wmOperator *op) +{ + Object *ob; + Scene *scene= CTX_data_scene(C); + + if(!multiresbake_check(C, op)) + return OPERATOR_CANCELLED; + + if(scene->r.bake_flag&R_BAKE_CLEAR) { /* clear images */ + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + Mesh *me; + + ob= base->object; + me= (Mesh*)ob->data; + + clear_images(me->mtface, me->totface); + } + CTX_DATA_END; + } + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + MultiresBakeRender bkr= {0}; + + ob= base->object; + + /* copy data stored in job descriptor */ + bkr.bake_filter= scene->r.bake_filter; + bkr.mode= scene->r.bake_mode; + bkr.use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH; + + /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ + bkr.lores_dm= multiresbake_create_loresdm(scene, ob, &bkr.lvl); + bkr.hires_dm= multiresbake_create_hiresdm(scene, ob, &bkr.tot_lvl, &bkr.simple); + + multiresbake_start(&bkr); + + BLI_freelistN(&bkr.image); + + bkr.lores_dm->release(bkr.lores_dm); + bkr.hires_dm->release(bkr.hires_dm); + } + CTX_DATA_END; + + return OPERATOR_FINISHED; +} + +/* Multiresbake adopted for job-system executing */ +static void init_multiresbake_job(bContext *C, MultiresBakeJob *bkj) +{ + Scene *scene= CTX_data_scene(C); + Object *ob; + + /* backup scene settings, so their changing in UI would take no effect on baker */ + bkj->bake_filter= scene->r.bake_filter; + bkj->mode= scene->r.bake_mode; + bkj->use_lores_mesh= scene->r.bake_flag&R_BAKE_LORES_MESH; + bkj->bake_clear= scene->r.bake_flag&R_BAKE_CLEAR; + + CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { + MultiresBakerJobData *data; + ob= base->object; + + data= MEM_callocN(sizeof(MultiresBakerJobData), "multiresBaker derivedMesh_data"); + data->lores_dm = multiresbake_create_loresdm(scene, ob, &data->lvl); + data->hires_dm = multiresbake_create_hiresdm(scene, ob, &data->tot_lvl, &data->simple); + BLI_addtail(&bkj->data, data); + } + CTX_DATA_END; +} + +static void multiresbake_startjob(void *bkv, short *stop, short *do_update, float *progress) +{ + MultiresBakerJobData *data; + MultiresBakeJob *bkj= bkv; + int baked_objects= 0, tot_obj; + + tot_obj= BLI_countlist(&bkj->data); + + if(bkj->bake_clear) { /* clear images */ + for(data= bkj->data.first; data; data= data->next) { + DerivedMesh *dm= data->lores_dm; + MTFace *mtface= CustomData_get_layer(&dm->faceData, CD_MTFACE); + + clear_images(mtface, dm->getNumFaces(dm)); + } + } + + for(data= bkj->data.first; data; data= data->next) { + MultiresBakeRender bkr= {0}; + + /* copy data stored in job descriptor */ + bkr.bake_filter= bkj->bake_filter; + bkr.mode= bkj->mode; + bkr.use_lores_mesh= bkj->use_lores_mesh; + + /* create low-resolution DM (to bake to) and hi-resolution DM (to bake from) */ + bkr.lores_dm= data->lores_dm; + bkr.hires_dm= data->hires_dm; + bkr.tot_lvl= data->tot_lvl; + bkr.lvl= data->lvl; + bkr.simple= data->simple; + + /* needed for proper progress bar */ + bkr.tot_obj= tot_obj; + bkr.baked_objects= baked_objects; + + bkr.stop= stop; + bkr.do_update= do_update; + bkr.progress= progress; + + multiresbake_start(&bkr); + + BLI_freelistN(&bkr.image); + + baked_objects++; + } +} + +static void multiresbake_freejob(void *bkv) +{ + MultiresBakeJob *bkj= bkv; + MultiresBakerJobData *data, *next; + + data= bkj->data.first; + while (data) { + next= data->next; + data->lores_dm->release(data->lores_dm); + data->hires_dm->release(data->hires_dm); + MEM_freeN(data); + data= next; + } + + MEM_freeN(bkj); +} + +static int multiresbake_image_exec(bContext *C, wmOperator *op) +{ + Scene *scene= CTX_data_scene(C); + MultiresBakeJob *bkr; + wmJob *steve; + + if(!multiresbake_check(C, op)) + return OPERATOR_CANCELLED; + + bkr= MEM_callocN(sizeof(MultiresBakeJob), "MultiresBakeJob data"); + init_multiresbake_job(C, bkr); + + /* setup job */ + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Multires Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS); + WM_jobs_customdata(steve, bkr, multiresbake_freejob); + WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ + WM_jobs_callbacks(steve, multiresbake_startjob, NULL, NULL, NULL); + + G.afbreek= 0; + + WM_jobs_start(CTX_wm_manager(C), steve); + WM_cursor_wait(0); + + /* add modal handler for ESC */ + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + /* ****************** render BAKING ********************** */ /* threaded break test */ @@ -147,9 +1285,6 @@ static void init_bake_internal(BakeRender *bkr, bContext *C) { Scene *scene= CTX_data_scene(C); - /* flush multires changes (for sculpt) */ - multires_force_render_update(CTX_data_active_object(C)); - /* get editmode results */ ED_object_exit_editmode(C, 0); /* 0 = does not exit editmode */ @@ -273,43 +1408,59 @@ static int objects_bake_render_modal(bContext *C, wmOperator *UNUSED(op), wmEven return OPERATOR_PASS_THROUGH; } +static int is_multires_bake(Scene *scene) +{ + if ( ELEM(scene->r.bake_mode, RE_BAKE_NORMALS, RE_BAKE_DISPLACEMENT)) + return scene->r.bake_flag & R_BAKE_MULTIRES; + + return 0; +} + static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(_event)) { Scene *scene= CTX_data_scene(C); + int result= OPERATOR_CANCELLED; - /* only one render job at a time */ - if(WM_jobs_test(CTX_wm_manager(C), scene)) - return OPERATOR_CANCELLED; - - if(test_bake_internal(C, op->reports)==0) { - return OPERATOR_CANCELLED; - } - else { - BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake"); - wmJob *steve; + if(is_multires_bake(scene)) { + result= multiresbake_image_exec(C, op); + } else { + /* only one render job at a time */ + if(WM_jobs_test(CTX_wm_manager(C), scene)) + return OPERATOR_CANCELLED; + + if(test_bake_internal(C, op->reports)==0) { + return OPERATOR_CANCELLED; + } + else { + BakeRender *bkr= MEM_callocN(sizeof(BakeRender), "render bake"); + wmJob *steve; - init_bake_internal(bkr, C); - bkr->reports= op->reports; + init_bake_internal(bkr, C); + bkr->reports= op->reports; - /* setup job */ - steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS); - WM_jobs_customdata(steve, bkr, bake_freejob); - WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ - WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL); + /* setup job */ + steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS); + WM_jobs_customdata(steve, bkr, bake_freejob); + WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */ + WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL); - G.afbreek= 0; - G.rendering = 1; + G.afbreek= 0; + G.rendering = 1; - WM_jobs_start(CTX_wm_manager(C), steve); + WM_jobs_start(CTX_wm_manager(C), steve); - WM_cursor_wait(0); - WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene); + WM_cursor_wait(0); - /* add modal handler for ESC */ - WM_event_add_modal_handler(C, op); + /* add modal handler for ESC */ + WM_event_add_modal_handler(C, op); + } + + result= OPERATOR_RUNNING_MODAL; } - return OPERATOR_RUNNING_MODAL; + WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene); + + return result; } @@ -317,46 +1468,53 @@ static int bake_image_exec(bContext *C, wmOperator *op) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); + int result= OPERATOR_CANCELLED; + if(is_multires_bake(scene)) { + result= multiresbake_image_exec_locked(C, op); + } else { + if(test_bake_internal(C, op->reports)==0) { + return OPERATOR_CANCELLED; + } + else { + ListBase threads; + BakeRender bkr= {NULL}; - if(test_bake_internal(C, op->reports)==0) { - return OPERATOR_CANCELLED; - } - else { - ListBase threads; - BakeRender bkr= {NULL}; + init_bake_internal(&bkr, C); + bkr.reports= op->reports; - init_bake_internal(&bkr, C); - bkr.reports= op->reports; + RE_test_break_cb(bkr.re, NULL, thread_break); + G.afbreek= 0; /* blender_test_break uses this global */ - RE_test_break_cb(bkr.re, NULL, thread_break); - G.afbreek= 0; /* blender_test_break uses this global */ + RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL); - RE_Database_Baking(bkr.re, bmain, scene, scene->lay, scene->r.bake_mode, (scene->r.bake_flag & R_BAKE_TO_ACTIVE)? OBACT: NULL); + /* baking itself is threaded, cannot use test_break in threads */ + BLI_init_threads(&threads, do_bake_render, 1); + bkr.ready= 0; + BLI_insert_thread(&threads, &bkr); - /* baking itself is threaded, cannot use test_break in threads */ - BLI_init_threads(&threads, do_bake_render, 1); - bkr.ready= 0; - BLI_insert_thread(&threads, &bkr); + while(bkr.ready==0) { + PIL_sleep_ms(50); + if(bkr.ready) + break; - while(bkr.ready==0) { - PIL_sleep_ms(50); - if(bkr.ready) - break; + /* used to redraw in 2.4x but this is just for exec in 2.5 */ + if (!G.background) + blender_test_break(); + } + BLI_end_threads(&threads); - /* used to redraw in 2.4x but this is just for exec in 2.5 */ - if (!G.background) - blender_test_break(); - } - BLI_end_threads(&threads); + if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); - if(bkr.tot==0) BKE_report(op->reports, RPT_ERROR, "No valid images found to bake to"); + finish_bake_internal(&bkr); - finish_bake_internal(&bkr); + result= OPERATOR_FINISHED; + } } WM_event_add_notifier(C, NC_SCENE|ND_RENDER_RESULT, scene); - return OPERATOR_FINISHED; + + return result; } void OBJECT_OT_bake_image(wmOperatorType *ot) diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index 7c59278dcf5..fd2e7fd7c99 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -203,9 +203,9 @@ static int object_shape_key_mirror(bContext *C, Object *ob) fp1= ((float *)kb->data) + i1*3; fp2= ((float *)kb->data) + i2*3; - VECCOPY(tvec, fp1); - VECCOPY(fp1, fp2); - VECCOPY(fp2, tvec); + copy_v3_v3(tvec, fp1); + copy_v3_v3(fp1, fp2); + copy_v3_v3(fp2, tvec); /* flip x axis */ fp1[0] = -fp1[0]; @@ -217,7 +217,46 @@ static int object_shape_key_mirror(bContext *C, Object *ob) mesh_octree_table(ob, NULL, NULL, 'e'); } - /* todo, other types? */ + else if (ob->type == OB_LATTICE) { + Lattice *lt= ob->data; + int i1, i2; + float *fp1, *fp2; + int u, v, w; + /* half but found up odd value */ + const int pntsu_half = (((lt->pntsu / 2) + (lt->pntsu % 2))) ; + + /* currently editmode isnt supported by mesh so + * ignore here for now too */ + + /* if(lt->editlatt) lt= lt->editlatt->latt; */ + + for(w=0; w<lt->pntsw; w++) { + for(v=0; v<lt->pntsv; v++) { + for(u=0; u<pntsu_half; u++) { + int u_inv= (lt->pntsu - 1) - u; + float tvec[3]; + if(u == u_inv) { + i1= LT_INDEX(lt, u, v, w); + fp1= ((float *)kb->data) + i1*3; + fp1[0]= -fp1[0]; + } + else { + i1= LT_INDEX(lt, u, v, w); + i2= LT_INDEX(lt, u_inv, v, w); + + fp1= ((float *)kb->data) + i1*3; + fp2= ((float *)kb->data) + i2*3; + + copy_v3_v3(tvec, fp1); + copy_v3_v3(fp1, fp2); + copy_v3_v3(fp2, tvec); + fp1[0]= -fp1[0]; + fp2[0]= -fp2[0]; + } + } + } + } + } MEM_freeN(tag_elem); } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 43448198ae1..52ba9460818 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -77,6 +77,7 @@ static void vgroup_remap_update_users(Object *ob, int *map); static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup); static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg); +static void vgroup_delete_all(Object *ob); static Lattice *vgroup_edit_lattice(Object *ob) { @@ -138,22 +139,30 @@ void ED_vgroup_delete(Object *ob, bDeformGroup *defgroup) vgroup_delete_object_mode(ob, dg); } -void ED_vgroup_data_create(ID *id) +int ED_vgroup_data_create(ID *id) { /* create deform verts */ if(GS(id->name)==ID_ME) { Mesh *me= (Mesh *)id; me->dvert= CustomData_add_layer(&me->vdata, CD_MDEFORMVERT, CD_CALLOC, NULL, me->totvert); + return TRUE; } else if(GS(id->name)==ID_LT) { Lattice *lt= (Lattice *)id; lt->dvert= MEM_callocN(sizeof(MDeformVert)*lt->pntsu*lt->pntsv*lt->pntsw, "lattice deformVert"); + return TRUE; + } + else { + return FALSE; } } static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_tot) { + *dvert_tot = 0; + *dvert_arr = NULL; + if(id) { switch(GS(id->name)) { case ID_ME: @@ -166,8 +175,6 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to int i; if (!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) { - *dvert_tot = 0; - *dvert_arr = NULL; return 0; } @@ -195,8 +202,9 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to return 1; } - else + else { return 0; + } } case ID_LT: { @@ -222,8 +230,6 @@ static int ED_vgroup_give_parray(ID *id, MDeformVert ***dvert_arr, int *dvert_to } } - *dvert_arr= NULL; - *dvert_tot= 0; return 0; } @@ -265,13 +271,24 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) int i; int totdef_from= BLI_countlist(&ob_from->defbase); int totdef= BLI_countlist(&ob->defbase); + short new_vgroup= FALSE; ED_vgroup_give_parray(ob_from->data, &dvert_array_from, &dvert_tot_from); ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); + if((dvert_array == NULL) && (dvert_array_from != NULL) && ED_vgroup_data_create(ob->data)) { + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot); + new_vgroup= TRUE; + } + if(ob==ob_from || dvert_tot==0 || (dvert_tot != dvert_tot_from) || dvert_array_from==NULL || dvert_array==NULL) { if (dvert_array) MEM_freeN(dvert_array); if (dvert_array_from) MEM_freeN(dvert_array_from); + + if(new_vgroup == TRUE) { + /* free the newly added vgroup since it wasn't compatible */ + vgroup_delete_all(ob); + } return 0; } @@ -1015,55 +1032,75 @@ static void vgroup_clean_all(Object *ob, float eul, int keep_single) if (dvert_array) MEM_freeN(dvert_array); } -void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups) + +static void dvert_mirror_op(MDeformVert *dvert, MDeformVert *dvert_mirr, + const char sel, const char sel_mirr, + const int *flip_map, + const short mirror_weights, const short flip_vgroups) +{ + BLI_assert(sel || sel_mirr); + + if(sel_mirr && sel) { + /* swap */ + if(mirror_weights) + SWAP(MDeformVert, *dvert, *dvert_mirr); + if(flip_vgroups) { + defvert_flip(dvert, flip_map); + defvert_flip(dvert_mirr, flip_map); + } + } + else { + /* dvert should always be the target */ + if(sel_mirr) { + SWAP(MDeformVert *, dvert, dvert_mirr); + } + + if(mirror_weights) + defvert_copy(dvert, dvert_mirr); + if(flip_vgroups) { + defvert_flip(dvert, flip_map); + } + } +} + +void ED_vgroup_mirror(Object *ob, const short mirror_weights, const short flip_vgroups) { +#define VGROUP_MIRR_OP dvert_mirror_op(dvert, dvert_mirr, sel, sel_mirr, flip_map, mirror_weights, flip_vgroups) + EditVert *eve, *eve_mirr; MDeformVert *dvert, *dvert_mirr; + short sel, sel_mirr; int *flip_map; if(mirror_weights==0 && flip_vgroups==0) return; + flip_map= defgroup_flip_map(ob, 0); + /* only the active group */ if(ob->type == OB_MESH) { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); - EM_cache_x_mirror_vert(ob, em); - if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) + if(!CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) { + MEM_freeN(flip_map); return; + } - flip_map= defgroup_flip_map(ob, 0); + EM_cache_x_mirror_vert(ob, em); /* Go through the list of editverts and assign them */ for(eve=em->verts.first; eve; eve=eve->next){ if((eve_mirr=eve->tmp.v)) { - if((eve_mirr->f & SELECT || eve->f & SELECT) && (eve != eve_mirr)) { + sel= eve->f & SELECT; + sel_mirr= eve_mirr->f & SELECT; + + if((sel || sel_mirr) && (eve != eve_mirr)) { dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); dvert_mirr= CustomData_em_get(&em->vdata, eve_mirr->data, CD_MDEFORMVERT); if(dvert && dvert_mirr) { - if(eve_mirr->f & SELECT && eve->f & SELECT) { - /* swap */ - if(mirror_weights) - SWAP(MDeformVert, *dvert, *dvert_mirr); - if(flip_vgroups) { - defvert_flip(dvert, flip_map); - defvert_flip(dvert_mirr, flip_map); - } - } - else { - /* dvert should always be the target */ - if(eve_mirr->f & SELECT) { - SWAP(MDeformVert *, dvert, dvert_mirr); - } - - if(mirror_weights) - defvert_copy(dvert, dvert_mirr); - if(flip_vgroups) { - defvert_flip(dvert, flip_map); - } - } + VGROUP_MIRR_OP; } } @@ -1071,10 +1108,58 @@ void ED_vgroup_mirror(Object *ob, int mirror_weights, int flip_vgroups) } } - MEM_freeN(flip_map); - BKE_mesh_end_editmesh(me, em); } + else if (ob->type == OB_LATTICE) { + Lattice *lt= ob->data; + int i1, i2; + int u, v, w; + int pntsu_half; + /* half but found up odd value */ + + if(lt->editlatt) lt= lt->editlatt->latt; + + if(lt->pntsu == 1 || lt->dvert == NULL) { + MEM_freeN(flip_map); + return; + } + + /* unlike editmesh we know that by only looping over the first hald of + * the 'u' indicies it will cover all points except the middle which is + * ok in this case */ + pntsu_half= lt->pntsu / 2; + + for(w=0; w<lt->pntsw; w++) { + for(v=0; v<lt->pntsv; v++) { + for(u=0; u<pntsu_half; u++) { + int u_inv= (lt->pntsu - 1) - u; + if(u != u_inv) { + BPoint *bp, *bp_mirr; + + i1= LT_INDEX(lt, u, v, w); + i2= LT_INDEX(lt, u_inv, v, w); + + bp= <->def[i1]; + bp_mirr= <->def[i2]; + + sel= bp->f1 & SELECT; + sel_mirr= bp_mirr->f1 & SELECT; + + if(sel || sel_mirr) { + dvert= <->dvert[i1]; + dvert_mirr= <->dvert[i2]; + + VGROUP_MIRR_OP; + } + } + } + } + } + } + + MEM_freeN(flip_map); + +#undef VGROUP_MIRR_OP } static void vgroup_remap_update_users(Object *ob, int *map) @@ -1920,17 +2005,25 @@ void OBJECT_OT_vertex_group_copy_to_linked(wmOperatorType *ot) ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; } -static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *UNUSED(op)) +static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) { Object *obact= CTX_data_pointer_get_type(C, "object", &RNA_Object).data; + int change= 0; + int fail= 0; CTX_DATA_BEGIN(C, Object*, ob, selected_editable_objects) { - if(obact != ob) - ED_vgroup_copy_array(ob, obact); + if(obact != ob) { + if(ED_vgroup_copy_array(ob, obact)) change++; + else fail++; + } } CTX_DATA_END; + if((change == 0 && fail == 0) || fail) { + BKE_reportf(op->reports, RPT_ERROR, "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indicies", change, fail); + } + return OPERATOR_FINISHED; } diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c index 64a4d47cddc..9dfcde6ed0d 100644 --- a/source/blender/editors/render/render_view.c +++ b/source/blender/editors/render/render_view.c @@ -184,8 +184,7 @@ void render_view_open(bContext *C, int mx, int my) area_was_image = 1; /* this function returns with changed context */ - ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE); - sa= CTX_wm_area(C); + sa= ED_screen_full_newspace(C, CTX_wm_area(C), SPACE_IMAGE); } if(!sa) { diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 828699e85ce..4d531e78ec0 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -1138,7 +1138,7 @@ void ED_area_newspace(bContext *C, ScrArea *sa, int type) /* tell WM to refresh, cursor types etc */ WM_event_add_mousemove(C); - /*send space change notifyer*/ + /*send space change notifier*/ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, sa); ED_area_tag_refresh(sa); @@ -1165,7 +1165,7 @@ void ED_area_prevspace(bContext *C, ScrArea *sa) } ED_area_tag_redraw(sa); - /*send space change notifyer*/ + /*send space change notifier*/ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, sa); } @@ -1213,7 +1213,7 @@ static void spacefunc(struct bContext *C, void *UNUSED(arg1), void *UNUSED(arg2) ED_area_newspace(C, CTX_wm_area(C), CTX_wm_area(C)->butspacetype); ED_area_tag_redraw(CTX_wm_area(C)); - /*send space change notifyer*/ + /*send space change notifier*/ WM_event_add_notifier(C, NC_SPACE|ND_SPACE_CHANGED, CTX_wm_area(C)); } diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c index eb41dcd147b..721ce823351 100644 --- a/source/blender/editors/screen/screen_edit.c +++ b/source/blender/editors/screen/screen_edit.c @@ -1513,7 +1513,7 @@ void ED_screen_delete_scene(bContext *C, Scene *scene) unlink_scene(bmain, scene, newscene); } -int ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) +ScrArea *ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) { wmWindow *win= CTX_wm_window(C); bScreen *screen= CTX_wm_screen(C); @@ -1538,7 +1538,7 @@ int ED_screen_full_newspace(bContext *C, ScrArea *sa, int type) ED_area_newspace(C, newsa, type); - return 1; + return newsa; } void ED_screen_full_prevspace(bContext *C, ScrArea *sa) diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 9e840e75578..f016fb6822a 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -627,6 +627,13 @@ static int actionzone_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +static int actionzone_cancel(bContext *UNUSED(C), wmOperator *op) +{ + actionzone_exit(op); + + return OPERATOR_CANCELLED; +} + static void SCREEN_OT_actionzone(wmOperatorType *ot) { /* identifiers */ @@ -637,6 +644,7 @@ static void SCREEN_OT_actionzone(wmOperatorType *ot) ot->invoke= actionzone_invoke; ot->modal= actionzone_modal; ot->poll= actionzone_area_poll; + ot->cancel= actionzone_cancel; ot->flag= OPTYPE_BLOCKING; @@ -759,6 +767,7 @@ static void SCREEN_OT_area_swap(wmOperatorType *ot) ot->invoke= area_swap_invoke; ot->modal= area_swap_modal; ot->poll= ED_operator_areaactive; + ot->cancel= area_swap_cancel; ot->flag= OPTYPE_BLOCKING; } @@ -1494,6 +1503,7 @@ static void SCREEN_OT_area_split(wmOperatorType *ot) ot->exec= area_split_exec; ot->invoke= area_split_invoke; ot->modal= area_split_modal; + ot->cancel= area_split_cancel; ot->poll= screen_active_editable; ot->flag= OPTYPE_BLOCKING; @@ -1693,6 +1703,13 @@ static int region_scale_modal(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +int region_scale_cancel(bContext *UNUSED(C), wmOperator *op) +{ + MEM_freeN(op->customdata); + op->customdata = NULL; + + return OPERATOR_CANCELLED; +} static void SCREEN_OT_region_scale(wmOperatorType *ot) { @@ -1703,6 +1720,7 @@ static void SCREEN_OT_region_scale(wmOperatorType *ot) ot->invoke= region_scale_invoke; ot->modal= region_scale_modal; + ot->cancel= region_scale_cancel; ot->poll= ED_operator_areaactive; @@ -2257,8 +2275,9 @@ static void SCREEN_OT_area_join(wmOperatorType *ot) ot->invoke= area_join_invoke; ot->modal= area_join_modal; ot->poll= screen_active_editable; + ot->cancel= area_join_cancel; - ot->flag= OPTYPE_BLOCKING; + ot->flag= OPTYPE_BLOCKING|OPTYPE_INTERNAL; /* rna */ RNA_def_int(ot->srna, "min_x", -100, INT_MIN, INT_MAX, "X 1", "", INT_MIN, INT_MAX); @@ -3053,6 +3072,7 @@ static void SCREEN_OT_border_select(wmOperatorType *ot) ot->exec= border_select_do; ot->invoke= WM_border_select_invoke; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_areaactive; diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index db0d2314ad0..cae5c14aa97 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -3692,14 +3692,26 @@ static void do_projectpaint_draw(ProjPaintState *ps, ProjPixel *projPixel, float } } -static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask) { +static void do_projectpaint_draw_f(ProjPaintState *ps, ProjPixel *projPixel, float *rgba, float alpha, float mask, int use_color_correction) { if (ps->is_texbrush) { - rgba[0] *= ps->brush->rgb[0]; - rgba[1] *= ps->brush->rgb[1]; - rgba[2] *= ps->brush->rgb[2]; + /* rgba already holds a texture result here from higher level function */ + float rgba_br[3]; + if(use_color_correction){ + srgb_to_linearrgb_v3_v3(rgba_br, ps->brush->rgb); + mul_v3_v3(rgba, rgba_br); + } + else{ + mul_v3_v3(rgba, ps->brush->rgb); + } } else { - VECCOPY(rgba, ps->brush->rgb); + if(use_color_correction){ + srgb_to_linearrgb_v3_v3(rgba, ps->brush->rgb); + } + else { + VECCOPY(rgba, ps->brush->rgb); + } + rgba[3] = 1.0; } if (ps->is_airbrush==0 && mask < 1.0f) { @@ -3736,6 +3748,7 @@ static void *do_projectpaint_thread(void *ph_v) float falloff; int bucket_index; int is_floatbuf = 0; + int use_color_correction = 0; const short tool = ps->tool; rctf bucket_bounds; @@ -3841,6 +3854,7 @@ static void *do_projectpaint_thread(void *ph_v) last_projIma->touch = 1; is_floatbuf = last_projIma->ibuf->rect_float ? 1 : 0; + use_color_correction = (last_projIma->ibuf->profile == IB_PROFILE_LINEAR_RGB) ? 1 : 0; } last_partial_redraw_cell = last_projIma->partRedrawRect + projPixel->bb_cell_index; @@ -3871,7 +3885,7 @@ static void *do_projectpaint_thread(void *ph_v) else do_projectpaint_smear(ps, projPixel, alpha, mask, smearArena, &smearPixels, co); break; default: - if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask); + if (is_floatbuf) do_projectpaint_draw_f(ps, projPixel, rgba, alpha, mask, use_color_correction); else do_projectpaint_draw(ps, projPixel, rgba, alpha, mask); break; } @@ -3987,7 +4001,7 @@ static int project_paint_sub_stroke(ProjPaintState *ps, BrushPainter *painter, c // we may want to use this later // brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0); - if (brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps)) { + if (brush_painter_paint(painter, project_paint_op, pos, time, pressure, ps, 0)) { return 1; } else return 0; @@ -4058,7 +4072,6 @@ static void imapaint_dirty_region(Image *ima, ImBuf *ibuf, int x, int y, int w, static void imapaint_image_update(SpaceImage *sima, Image *image, ImBuf *ibuf, short texpaint) { if(ibuf->rect_float) - /* TODO - should just update a portion from imapaintpartial! */ ibuf->userflags |= IB_RECT_INVALID; /* force recreate of char rect */ if(ibuf->mipmap[0]) @@ -4255,8 +4268,8 @@ static ImBuf *imapaint_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos) static void imapaint_convert_brushco(ImBuf *ibufb, float *pos, int *ipos) { - ipos[0]= (int)(pos[0] - ibufb->x/2); - ipos[1]= (int)(pos[1] - ibufb->y/2); + ipos[0]= (int)floorf((pos[0] - ibufb->x/2) + 1.0f); + ipos[1]= (int)floorf((pos[1] - ibufb->y/2) + 1.0f); } /* dosnt run for projection painting @@ -4409,7 +4422,7 @@ static int imapaint_paint_sub_stroke(ImagePaintState *s, BrushPainter *painter, brush_painter_require_imbuf(painter, ((ibuf->rect_float)? 1: 0), 0, 0); - if (brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s)) { + if (brush_painter_paint(painter, imapaint_paint_op, pos, time, pressure, s, ibuf->profile == IB_PROFILE_LINEAR_RGB)) { if (update) imapaint_image_update(s->sima, image, ibuf, texpaint); return 1; @@ -4863,12 +4876,7 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) PointerRNA itemptr; float pressure, mousef[2]; double time; - int tablet, mouse[2]; - - // XXX +1 matches brush location better but - // still not exact, find out why and fix .. - mouse[0]= event->mval[0] + 1; - mouse[1]= event->mval[1] + 1; + int tablet; time= PIL_check_seconds_timer(); @@ -4888,8 +4896,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) pressure= pop->prev_pressure ? pop->prev_pressure : 1.0f; if(pop->first) { - pop->prevmouse[0]= mouse[0]; - pop->prevmouse[1]= mouse[1]; + pop->prevmouse[0]= event->mval[0]; + pop->prevmouse[1]= event->mval[1]; pop->starttime= time; /* special exception here for too high pressure values on first touch in @@ -4908,8 +4916,8 @@ static void paint_apply_event(bContext *C, wmOperator *op, wmEvent *event) /* fill in stroke */ RNA_collection_add(op->ptr, "stroke", &itemptr); - mousef[0] = (float)(mouse[0]); - mousef[1] = (float)(mouse[1]); + mousef[0] = (float)(event->mval[0]); + mousef[1] = (float)(event->mval[1]); RNA_float_set_array(&itemptr, "mouse", mousef); RNA_float_set(&itemptr, "time", (float)(time - pop->starttime)); RNA_float_set(&itemptr, "pressure", pressure); @@ -5012,31 +5020,45 @@ static int get_imapaint_zoom(bContext *C, float *zoomx, float *zoomy) static void brush_drawcursor(bContext *C, int x, int y, void *UNUSED(customdata)) { +#define PX_SIZE_FADE_MAX 12.0f +#define PX_SIZE_FADE_MIN 4.0f + Brush *brush= image_paint_brush(C); Paint *paint= paint_get_active(CTX_data_scene(C)); - if(paint && brush) { + if(paint && brush && paint->flags & PAINT_SHOW_BRUSH) { float zoomx, zoomy; + const float size= (float)brush_size(brush); + const short use_zoom= get_imapaint_zoom(C, &zoomx, &zoomy); + const float pixel_size= MAX2(size * zoomx, size * zoomy); + float alpha= 0.5f; - if(!(paint->flags & PAINT_SHOW_BRUSH)) + /* fade out the brush (cheap trick to work around brush interfearing with sampling [#])*/ + if(pixel_size < PX_SIZE_FADE_MIN) { return; + } + else if (pixel_size < PX_SIZE_FADE_MAX) { + alpha *= (pixel_size - PX_SIZE_FADE_MIN) / (PX_SIZE_FADE_MAX - PX_SIZE_FADE_MIN); + } glPushMatrix(); glTranslatef((float)x, (float)y, 0.0f); - if(get_imapaint_zoom(C, &zoomx, &zoomy)) + if(use_zoom) glScalef(zoomx, zoomy, 1.0f); - glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], 0.5f); + glColor4f(brush->add_col[0], brush->add_col[1], brush->add_col[2], alpha); glEnable( GL_LINE_SMOOTH ); glEnable(GL_BLEND); - glutil_draw_lined_arc(0, (float)(M_PI*2.0), (float)brush_size(brush), 40); + glutil_draw_lined_arc(0, (float)(M_PI*2.0), size, 40); glDisable(GL_BLEND); glDisable( GL_LINE_SMOOTH ); glPopMatrix(); } +#undef PX_SIZE_FADE_MAX +#undef PX_SIZE_FADE_MIN } static void toggle_paint_cursor(bContext *C, int enable) diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index bb877e4b1ee..5a0ee19d6c9 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -65,6 +65,7 @@ int paint_space_stroke_enabled(struct Brush *br); int paint_stroke_modal(struct bContext *C, struct wmOperator *op, struct wmEvent *event); int paint_stroke_exec(struct bContext *C, struct wmOperator *op); +int paint_stroke_cancel(struct bContext *C, struct wmOperator *op); struct ViewContext *paint_stroke_view_context(struct PaintStroke *stroke); void *paint_stroke_mode_data(struct PaintStroke *stroke); void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 58c3446673c..7ddf5dff000 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -916,6 +916,19 @@ int paint_stroke_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +int paint_stroke_cancel(bContext *C, wmOperator *op) +{ + PaintStroke *stroke = op->customdata; + + if(stroke->done) + stroke->done(C, stroke); + + MEM_freeN(stroke); + op->customdata = NULL; + + return OPERATOR_CANCELLED; +} + ViewContext *paint_stroke_view_context(PaintStroke *stroke) { return &stroke->vc; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index c35b742eb9e..3da19ba7346 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -1600,6 +1600,13 @@ static int wpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +static int wpaint_cancel(bContext *C, wmOperator *op) +{ + paint_stroke_cancel(C, op); + + return OPERATOR_CANCELLED; +} + void PAINT_OT_weight_paint(wmOperatorType *ot) { @@ -1612,6 +1619,7 @@ void PAINT_OT_weight_paint(wmOperatorType *ot) ot->modal= paint_stroke_modal; /* ot->exec= vpaint_exec; <-- needs stroke property */ ot->poll= weight_paint_poll; + ot->cancel= wpaint_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; @@ -1892,6 +1900,13 @@ static int vpaint_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +static int vpaint_cancel(bContext *C, wmOperator *op) +{ + paint_stroke_cancel(C, op); + + return OPERATOR_CANCELLED; +} + void PAINT_OT_vertex_paint(wmOperatorType *ot) { /* identifiers */ @@ -1903,6 +1918,7 @@ void PAINT_OT_vertex_paint(wmOperatorType *ot) ot->modal= paint_stroke_modal; /* ot->exec= vpaint_exec; <-- needs stroke property */ ot->poll= vertex_paint_poll; + ot->cancel= vpaint_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 20e74702067..cab8c522a89 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3559,6 +3559,24 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +static int sculpt_brush_stroke_cacel(bContext *C, wmOperator *op) +{ + Object *ob= CTX_data_active_object(C); + SculptSession *ss = ob->sculpt; + Sculpt *sd = CTX_data_tool_settings(C)->sculpt; + + paint_stroke_cancel(C, op); + + if(ss->cache) { + sculpt_cache_free(ss->cache); + ss->cache = NULL; + } + + sculpt_brush_exit_tex(sd); + + return OPERATOR_CANCELLED; +} + static void SCULPT_OT_brush_stroke(wmOperatorType *ot) { static EnumPropertyItem stroke_mode_items[] = { @@ -3577,6 +3595,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot) ot->modal= paint_stroke_modal; ot->exec= sculpt_brush_stroke_exec; ot->poll= sculpt_poll; + ot->cancel= sculpt_brush_stroke_cacel; /* flags (sculpt does own undo? (ton) */ ot->flag= OPTYPE_BLOCKING; diff --git a/source/blender/editors/space_action/action_select.c b/source/blender/editors/space_action/action_select.c index be8547afa23..4d0043913ab 100644 --- a/source/blender/editors/space_action/action_select.c +++ b/source/blender/editors/space_action/action_select.c @@ -332,6 +332,7 @@ void ACTION_OT_select_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= actkeys_borderselect_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_action_active; diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index 9662b4b401f..a5d516a1417 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -301,6 +301,7 @@ void FILE_OT_select_border(wmOperatorType *ot) ot->exec= file_border_select_exec; ot->modal= file_border_select_modal; ot->poll= ED_operator_file_active; + ot->cancel= WM_border_select_cancel; /* rna */ WM_operator_properties_gesture_border(ot, 0); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 793267bfa8c..45193a38ef5 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -403,12 +403,10 @@ float file_font_pointsize(void) uiStyleFontSet(&style->widget); s = BLF_height(style->widget.uifont_id, tmp); return style->widget.points; -#elif 0 +#else uiStyle *style= U.uistyles.first; uiStyleFontSet(&style->widget); - return style->widget.points; -#else - return UI_UNIT_Y * 0.6666f; + return style->widget.points * UI_DPI_FAC; #endif } diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 76883027df1..cb799b85d3a 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -344,6 +344,7 @@ void GRAPH_OT_select_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= graphkeys_borderselect_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= graphop_visible_keyframes_poll; diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index f48daa39c59..10b8cb238aa 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -1925,6 +1925,7 @@ void IMAGE_OT_sample_line(wmOperatorType *ot) ot->modal= WM_gesture_straightline_modal; ot->exec= sample_line_exec; ot->poll= space_image_main_area_poll; + ot->cancel= WM_gesture_straightline_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; diff --git a/source/blender/editors/space_info/info_report.c b/source/blender/editors/space_info/info_report.c index 937b683e880..c8bda434227 100644 --- a/source/blender/editors/space_info/info_report.c +++ b/source/blender/editors/space_info/info_report.c @@ -302,6 +302,7 @@ void INFO_OT_select_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= borderselect_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_info_active; diff --git a/source/blender/editors/space_logic/logic_buttons.c b/source/blender/editors/space_logic/logic_buttons.c index e894fd9cff5..16e916928a9 100644 --- a/source/blender/editors/space_logic/logic_buttons.c +++ b/source/blender/editors/space_logic/logic_buttons.c @@ -206,6 +206,7 @@ void LOGIC_OT_links_cut(wmOperatorType *ot) ot->invoke= WM_gesture_lines_invoke; ot->modal= WM_gesture_lines_modal; ot->exec= cut_links_exec; + ot->cancel= WM_gesture_lines_cancel; ot->poll= ED_operator_logic_active; diff --git a/source/blender/editors/space_nla/nla_select.c b/source/blender/editors/space_nla/nla_select.c index 0f0a4c0ad4c..8ef63b9a83d 100644 --- a/source/blender/editors/space_nla/nla_select.c +++ b/source/blender/editors/space_nla/nla_select.c @@ -333,6 +333,7 @@ void NLA_OT_select_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= nlaedit_borderselect_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= nlaop_poll_tweakmode_off; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index d967e2240e6..99f2ea99efc 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1086,6 +1086,13 @@ static int snode_bg_viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +static int snode_bg_viewmove_cancel(bContext *UNUSED(C), wmOperator *op) +{ + MEM_freeN(op->customdata); + op->customdata= NULL; + + return OPERATOR_CANCELLED; +} void NODE_OT_backimage_move(wmOperatorType *ot) { @@ -1098,6 +1105,7 @@ void NODE_OT_backimage_move(wmOperatorType *ot) ot->invoke= snode_bg_viewmove_invoke; ot->modal= snode_bg_viewmove_modal; ot->poll= composite_node_active; + ot->cancel= snode_bg_viewmove_cancel; /* flags */ ot->flag= OPTYPE_BLOCKING; @@ -1384,6 +1392,14 @@ static int node_resize_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH; } +static int node_resize_cancel(bContext *UNUSED(C), wmOperator *op) +{ + MEM_freeN(op->customdata); + op->customdata= NULL; + + return OPERATOR_CANCELLED; +} + void NODE_OT_resize(wmOperatorType *ot) { /* identifiers */ @@ -1394,6 +1410,7 @@ void NODE_OT_resize(wmOperatorType *ot) ot->invoke= node_resize_invoke; ot->modal= node_resize_modal; ot->poll= ED_operator_node_active; + ot->cancel= node_resize_cancel; /* flags */ ot->flag= OPTYPE_BLOCKING; @@ -2279,6 +2296,18 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event) } } +static int node_link_cancel(bContext *C, wmOperator *op) +{ + SpaceNode *snode= CTX_wm_space_node(C); + bNodeLinkDrag *nldrag= op->customdata; + + nodeRemLink(snode->edittree, nldrag->link); + BLI_remlink(&snode->linkdrag, nldrag); + MEM_freeN(nldrag); + + return OPERATOR_CANCELLED; +} + void NODE_OT_link(wmOperatorType *ot) { /* identifiers */ @@ -2290,6 +2319,7 @@ void NODE_OT_link(wmOperatorType *ot) ot->modal= node_link_modal; // ot->exec= node_link_exec; ot->poll= ED_operator_node_active; + ot->cancel= node_link_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; @@ -2402,6 +2432,7 @@ void NODE_OT_links_cut(wmOperatorType *ot) ot->invoke= WM_gesture_lines_invoke; ot->modal= WM_gesture_lines_modal; ot->exec= cut_links_exec; + ot->cancel= WM_gesture_lines_cancel; ot->poll= ED_operator_node_active; diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index a1ef75f3976..1abcaccc939 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -215,6 +215,7 @@ void NODE_OT_select_border(wmOperatorType *ot) ot->invoke= node_border_select_invoke; ot->exec= node_borderselect_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_node_active; diff --git a/source/blender/editors/space_outliner/outliner.c b/source/blender/editors/space_outliner/outliner.c index 037b1db56d6..43e46d485ee 100644 --- a/source/blender/editors/space_outliner/outliner.c +++ b/source/blender/editors/space_outliner/outliner.c @@ -106,21 +106,17 @@ #include "outliner_intern.h" - -#define OL_H 19 -#define OL_X 18 - #define OL_Y_OFFSET 2 -#define OL_TOG_RESTRICT_VIEWX 54 -#define OL_TOG_RESTRICT_SELECTX 36 -#define OL_TOG_RESTRICT_RENDERX 18 +#define OL_TOG_RESTRICT_VIEWX (UI_UNIT_X*3) +#define OL_TOG_RESTRICT_SELECTX (UI_UNIT_X*2) +#define OL_TOG_RESTRICT_RENDERX UI_UNIT_X #define OL_TOGW OL_TOG_RESTRICT_VIEWX -#define OL_RNA_COLX 300 -#define OL_RNA_COL_SIZEX 150 -#define OL_RNA_COL_SPACEX 50 +#define OL_RNA_COLX (UI_UNIT_X*15) +#define OL_RNA_COL_SIZEX (UI_UNIT_X*7.5) +#define OL_RNA_COL_SPACEX (UI_UNIT_X*2.5) #define TS_CHUNK 128 @@ -260,7 +256,7 @@ static void outliner_height(SpaceOops *soops, ListBase *lb, int *h) TreeStoreElem *tselem= TREESTORE(te); if((tselem->flag & TSE_CLOSED)==0) outliner_height(soops, &te->subtree, h); - (*h) += OL_H; + (*h) += UI_UNIT_Y; te= te->next; } } @@ -297,7 +293,7 @@ static void outliner_rna_width(SpaceOops *soops, ListBase *lb, int *w, int start *w = startx+100; if((tselem->flag & TSE_CLOSED)==0) - outliner_rna_width(soops, &te->subtree, w, startx+OL_X); + outliner_rna_width(soops, &te->subtree, w, startx+UI_UNIT_X); te= te->next; } } @@ -2485,13 +2481,13 @@ static int tree_element_type_active(bContext *C, Scene *scene, SpaceOops *soops, static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int extend, const float mval[2]) { - if(mval[1]>te->ys && mval[1]<te->ys+OL_H) { + if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { TreeStoreElem *tselem= TREESTORE(te); int openclose= 0; /* open close icon */ if((te->flag & TE_ICONROW)==0) { // hidden icon, no open/close - if( mval[0]>te->xs && mval[0]<te->xs+OL_X) + if( mval[0]>te->xs && mval[0]<te->xs+UI_UNIT_X) openclose= 1; } @@ -2510,7 +2506,7 @@ static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, Spa return 1; } /* name and first icon */ - else if(mval[0]>te->xs+OL_X && mval[0]<te->xend) { + else if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) { /* always makes active object */ if(tselem->type!=TSE_SEQUENCE && tselem->type!=TSE_SEQ_STRIP && tselem->type!=TSE_SEQUENCE_DUP) @@ -2597,7 +2593,7 @@ static int outliner_item_activate(bContext *C, wmOperator *op, wmEvent *event) int row; /* get row number - 100 here is just a dummy value since we don't need the column */ - UI_view2d_listview_view_to_cell(&ar->v2d, 1000, OL_H, 0.0f, OL_Y_OFFSET, + UI_view2d_listview_view_to_cell(&ar->v2d, 1000, UI_UNIT_Y, 0.0f, OL_Y_OFFSET, fmval[0], fmval[1], NULL, &row); /* select relevant row */ @@ -2631,7 +2627,7 @@ void OUTLINER_OT_item_activate(wmOperatorType *ot) static int do_outliner_item_openclose(bContext *C, SpaceOops *soops, TreeElement *te, int all, const float mval[2]) { - if(mval[1]>te->ys && mval[1]<te->ys+OL_H) { + if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { TreeStoreElem *tselem= TREESTORE(te); /* all below close/open? */ @@ -2696,11 +2692,11 @@ void OUTLINER_OT_item_openclose(wmOperatorType *ot) static int do_outliner_item_rename(bContext *C, ARegion *ar, SpaceOops *soops, TreeElement *te, const float mval[2]) { - if(mval[1]>te->ys && mval[1]<te->ys+OL_H) { + if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { TreeStoreElem *tselem= TREESTORE(te); /* name and first icon */ - if(mval[0]>te->xs+OL_X && mval[0]<te->xend) { + if(mval[0]>te->xs+UI_UNIT_X && mval[0]<te->xend) { /* can't rename rna datablocks entries */ if(ELEM3(tselem->type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) @@ -2861,12 +2857,12 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te, /* store coord and continue, we need coordinates for elements outside view too */ te->xs= (float)startx; te->ys= (float)(*starty); - *starty-= OL_H; + *starty-= UI_UNIT_Y; if((tselem->flag & TSE_CLOSED)==0) { TreeElement *ten; for(ten= te->subtree.first; ten; ten= ten->next) { - outliner_set_coordinates_element(soops, ten, startx+OL_X, starty); + outliner_set_coordinates_element(soops, ten, startx+UI_UNIT_X, starty); } } @@ -2876,7 +2872,7 @@ static void outliner_set_coordinates_element(SpaceOops *soops, TreeElement *te, static void outliner_set_coordinates(ARegion *ar, SpaceOops *soops) { TreeElement *te; - int starty= (int)(ar->v2d.tot.ymax)-OL_H; + int starty= (int)(ar->v2d.tot.ymax)-UI_UNIT_Y; int startx= 0; for(te= soops->tree.first; te; te= te->next) { @@ -3731,7 +3727,7 @@ void OUTLINER_OT_data_operation(wmOperatorType *ot) static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, wmEvent *event, const float mval[2]) { - if(mval[1]>te->ys && mval[1]<te->ys+OL_H) { + if(mval[1]>te->ys && mval[1]<te->ys+UI_UNIT_Y) { int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; TreeStoreElem *tselem= TREESTORE(te); @@ -4309,7 +4305,10 @@ static void tselem_draw_icon_uibut(struct DrawIconArg *arg, int icon) if(arg->x >= arg->xmax) UI_icon_draw(arg->x, arg->y, icon); else { - uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-4, arg->y, ICON_DEFAULT_WIDTH, ICON_DEFAULT_WIDTH, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); + /* XXX investigate: button placement of icons is way different than UI_icon_draw? */ + float ufac= UI_UNIT_X/20.0f; + uiBut *but= uiDefIconBut(arg->block, LABEL, 0, icon, arg->x-3.0f*ufac, arg->y, UI_UNIT_X-4.0f*ufac, UI_UNIT_Y-4.0f*ufac, NULL, 0.0, 0.0, 1.0, arg->alpha, (arg->id && arg->id->lib) ? arg->id->lib->name : ""); + if(arg->id) uiButSetDragID(but, arg->id); } @@ -4572,7 +4571,7 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa for(te= lb->first; te; te= te->next) { /* exit drawing early */ - if((*offsx) - OL_X > xmax) + if((*offsx) - UI_UNIT_X > xmax) break; tselem= TREESTORE(te); @@ -4589,19 +4588,21 @@ static void outliner_draw_iconrow(bContext *C, uiBlock *block, Scene *scene, Spa else active= tree_element_type_active(NULL, scene, soops, te, tselem, 0); if(active) { + float ufac= UI_UNIT_X/20.0f; + uiSetRoundBox(15); glColor4ub(255, 255, 255, 100); - uiRoundBox( (float)*offsx-0.5f, (float)ys-1.0f, (float)*offsx+OL_H-3.0f, (float)ys+OL_H-3.0f, OL_H/2.0f-2.0f); + uiRoundBox( (float)*offsx-0.5f*ufac, (float)ys-1.0f*ufac, (float)*offsx+UI_UNIT_Y-3.0f*ufac, (float)ys+UI_UNIT_Y-3.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac); glEnable(GL_BLEND); /* roundbox disables */ } tselem_draw_icon(block, xmax, (float)*offsx, (float)ys, tselem, te, 0.5f); te->xs= (float)*offsx; te->ys= (float)ys; - te->xend= (short)*offsx+OL_X; + te->xend= (short)*offsx+UI_UNIT_X; te->flag |= TE_ICONROW; // for click - (*offsx) += OL_X; + (*offsx) += UI_UNIT_X; } /* this tree element always has same amount of branches, so dont draw */ @@ -4621,7 +4622,7 @@ static void outliner_set_coord_tree_element(SpaceOops *soops, TreeElement *te, i te->ys= (float)(*starty); for(ten= te->subtree.first; ten; ten= ten->next) { - outliner_set_coord_tree_element(soops, ten, startx+OL_X, starty); + outliner_set_coord_tree_element(soops, ten, startx+UI_UNIT_X, starty); } } @@ -4630,16 +4631,17 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene { TreeElement *ten; TreeStoreElem *tselem; + float ufac= UI_UNIT_X/20.0f; int offsx= 0, active=0; // active=1 active obj, else active data tselem= TREESTORE(te); - if(*starty+2*OL_H >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) { + if(*starty+2*UI_UNIT_Y >= ar->v2d.cur.ymin && *starty<= ar->v2d.cur.ymax) { int xmax= ar->v2d.cur.xmax; /* icons can be ui buts, we dont want it to overlap with restrict */ if((soops->flag & SO_HIDE_RESTRICTCOLS)==0) - xmax-= OL_TOGW+ICON_DEFAULT_WIDTH; + xmax-= OL_TOGW+UI_UNIT_X; glEnable(GL_BLEND); @@ -4708,7 +4710,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* active circle */ if(active) { uiSetRoundBox(15); - uiRoundBox( (float)startx+OL_H-1.5f, (float)*starty+2.0f, (float)startx+2.0f*OL_H-4.0f, (float)*starty+OL_H-1.0f, OL_H/2.0f-2.0f); + uiRoundBox( (float)startx+UI_UNIT_Y-1.5f*ufac, (float)*starty+2.0f*ufac, (float)startx+2.0f*UI_UNIT_Y-4.0f*ufac, (float)*starty+UI_UNIT_Y-1.0f*ufac, UI_UNIT_Y/2.0f-2.0f*ufac); glEnable(GL_BLEND); /* roundbox disables it */ te->flag |= TE_ACTIVE; // for lookup in display hierarchies @@ -4720,35 +4722,35 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene if(tselem->type==0 && ELEM(te->idcode, ID_OB, ID_SCE)) icon_x = startx; else - icon_x = startx+5; + icon_x = startx+5*ufac; // icons a bit higher if(tselem->flag & TSE_CLOSED) - UI_icon_draw((float)icon_x, (float)*starty+2, ICON_DISCLOSURE_TRI_RIGHT); + UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_RIGHT); else - UI_icon_draw((float)icon_x, (float)*starty+2, ICON_DISCLOSURE_TRI_DOWN); + UI_icon_draw((float)icon_x, (float)*starty+2*ufac, ICON_DISCLOSURE_TRI_DOWN); } - offsx+= OL_X; + offsx+= UI_UNIT_X; /* datatype icon */ if(!(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM))) { // icons a bit higher - tselem_draw_icon(block, xmax, (float)startx+offsx, (float)*starty+2, tselem, te, 1.0f); + tselem_draw_icon(block, xmax, (float)startx+offsx, (float)*starty+2*ufac, tselem, te, 1.0f); - offsx+= OL_X; + offsx+= UI_UNIT_X; } else - offsx+= 2; + offsx+= 2*ufac; if(tselem->type==0 && tselem->id->lib) { glPixelTransferf(GL_ALPHA_SCALE, 0.5f); if(tselem->id->flag & LIB_INDIRECT) - UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DATA_INDIRECT); + UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_INDIRECT); else - UI_icon_draw((float)startx+offsx, (float)*starty+2, ICON_LIBRARY_DATA_DIRECT); + UI_icon_draw((float)startx+offsx, (float)*starty+2*ufac, ICON_LIBRARY_DATA_DIRECT); glPixelTransferf(GL_ALPHA_SCALE, 1.0f); - offsx+= OL_X; + offsx+= UI_UNIT_X; } glDisable(GL_BLEND); @@ -4757,9 +4759,9 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene else if(ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.75f); else UI_ThemeColor(TH_TEXT); - UI_DrawString(startx+offsx, *starty+5, te->name); + UI_DrawString(startx+offsx, *starty+5*ufac, te->name); - offsx+= (int)(OL_X + UI_GetStringWidth(te->name)); + offsx+= (int)(UI_UNIT_X + UI_GetStringWidth(te->name)); /* closed item, we draw the icons, not when it's a scene, or master-server list though */ if(tselem->flag & TSE_CLOSED) { @@ -4770,7 +4772,7 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene // divider UI_ThemeColorShade(TH_BACK, -40); - glRecti(tempx -10, *starty+4, tempx -8, *starty+OL_H-4); + glRecti(tempx -10, *starty+4, tempx -8, *starty+UI_UNIT_Y-4); glEnable(GL_BLEND); glPixelTransferf(GL_ALPHA_SCALE, 0.5); @@ -4789,16 +4791,16 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene te->xend= startx+offsx; if((tselem->flag & TSE_CLOSED)==0) { - *starty-= OL_H; + *starty-= UI_UNIT_Y; for(ten= te->subtree.first; ten; ten= ten->next) - outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+OL_X, starty); + outliner_draw_tree_element(C, block, scene, ar, soops, ten, startx+UI_UNIT_X, starty); } else { for(ten= te->subtree.first; ten; ten= ten->next) outliner_set_coord_tree_element(soops, te, startx, starty); - *starty-= OL_H; + *starty-= UI_UNIT_Y; } } @@ -4817,12 +4819,12 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx, /* horizontal line? */ if(tselem->type==0 && (te->idcode==ID_OB || te->idcode==ID_SCE)) - glRecti(startx, *starty, startx+OL_X, *starty-1); + glRecti(startx, *starty, startx+UI_UNIT_X, *starty-1); - *starty-= OL_H; + *starty-= UI_UNIT_Y; if((tselem->flag & TSE_CLOSED)==0) - outliner_draw_hierarchy(soops, &te->subtree, startx+OL_X, starty); + outliner_draw_hierarchy(soops, &te->subtree, startx+UI_UNIT_X, starty); } /* vertical line */ @@ -4831,7 +4833,7 @@ static void outliner_draw_hierarchy(SpaceOops *soops, ListBase *lb, int startx, tselem= TREESTORE(te); if(tselem->type==0 && te->idcode==ID_OB) { - glRecti(startx, y1+OL_H, startx+1, y2); + glRecti(startx, y1+UI_UNIT_Y, startx+1, y2); } } } @@ -4847,13 +4849,13 @@ static void outliner_draw_struct_marks(ARegion *ar, SpaceOops *soops, ListBase * /* selection status */ if((tselem->flag & TSE_CLOSED)==0) if(tselem->type == TSE_RNA_STRUCT) - glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+OL_H-1); + glRecti(0, *starty+1, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, *starty+UI_UNIT_Y-1); - *starty-= OL_H; + *starty-= UI_UNIT_Y; if((tselem->flag & TSE_CLOSED)==0) { outliner_draw_struct_marks(ar, soops, &te->subtree, starty); if(tselem->type == TSE_RNA_STRUCT) - fdrawline(0, (float)*starty+OL_H, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+OL_H); + fdrawline(0, (float)*starty+UI_UNIT_Y, ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, (float)*starty+UI_UNIT_Y); } } } @@ -4868,9 +4870,9 @@ static void outliner_draw_selection(ARegion *ar, SpaceOops *soops, ListBase *lb, /* selection status */ if(tselem->flag & TSE_SELECTED) { - glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+OL_H-1); + glRecti(0, *starty+1, (int)ar->v2d.cur.xmax, *starty+UI_UNIT_Y-1); } - *starty-= OL_H; + *starty-= UI_UNIT_Y; if((tselem->flag & TSE_CLOSED)==0) outliner_draw_selection(ar, soops, &te->subtree, starty); } } @@ -4888,24 +4890,24 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio /* struct marks */ UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); //UI_ThemeColorShade(TH_BACK, -20); - starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET; + starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; outliner_draw_struct_marks(ar, soops, &soops->tree, &starty); } /* always draw selection fill before hierarchy */ UI_GetThemeColor3fv(TH_BACK, col); glColor3f(col[0]+0.06f, col[1]+0.08f, col[2]+0.10f); - starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET; + starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; outliner_draw_selection(ar, soops, &soops->tree, &starty); // grey hierarchy lines UI_ThemeColorBlend(TH_BACK, TH_TEXT, 0.2f); - starty= (int)ar->v2d.tot.ymax-OL_H/2-OL_Y_OFFSET; + starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y/2-OL_Y_OFFSET; startx= 6; outliner_draw_hierarchy(soops, &soops->tree, startx, &starty); // items themselves - starty= (int)ar->v2d.tot.ymax-OL_H-OL_Y_OFFSET; + starty= (int)ar->v2d.tot.ymax-UI_UNIT_Y-OL_Y_OFFSET; startx= 0; for(te= soops->tree.first; te; te= te->next) { outliner_draw_tree_element(C, block, scene, ar, soops, te, startx, &starty); @@ -4919,11 +4921,11 @@ static void outliner_back(ARegion *ar) UI_ThemeColorShade(TH_BACK, 6); ystart= (int)ar->v2d.tot.ymax; - ystart= OL_H*(ystart/(OL_H))-OL_Y_OFFSET; + ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET; - while(ystart+2*OL_H > ar->v2d.cur.ymin) { - glRecti(0, ystart, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, ystart+OL_H); - ystart-= 2*OL_H; + while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) { + glRecti(0, ystart, (int)ar->v2d.cur.xmax+V2D_SCROLL_WIDTH, ystart+UI_UNIT_Y); + ystart-= 2*UI_UNIT_Y; } } @@ -4937,11 +4939,11 @@ static void outliner_draw_restrictcols(ARegion *ar) UI_ThemeColorShade(TH_BACK, 6); ystart= (int)ar->v2d.tot.ymax; - ystart= OL_H*(ystart/(OL_H))-OL_Y_OFFSET; + ystart= UI_UNIT_Y*(ystart/(UI_UNIT_Y))-OL_Y_OFFSET; - while(ystart+2*OL_H > ar->v2d.cur.ymin) { - glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+OL_H); - ystart-= 2*OL_H; + while(ystart+2*UI_UNIT_Y > ar->v2d.cur.ymin) { + glRecti((int)ar->v2d.cur.xmax-OL_TOGW, ystart, (int)ar->v2d.cur.xmax, ystart+UI_UNIT_Y); + ystart-= 2*UI_UNIT_Y; } UI_ThemeColorShadeAlpha(TH_BACK, -15, -200); @@ -5225,7 +5227,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar for(te= lb->first; te; te= te->next) { tselem= TREESTORE(te); - if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { /* objects have toggle-able restriction flags */ if(tselem->type==0 && te->idcode==ID_OB) { PointerRNA ptr; @@ -5235,17 +5237,17 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_VIEW_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &ptr, "hide", -1, 0, 0, -1, -1, NULL); uiButSetFunc(bt, restrictbutton_view_cb, scene, ob); bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_SELECT_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &ptr, "hide_select", -1, 0, 0, -1, -1, NULL); uiButSetFunc(bt, restrictbutton_sel_cb, scene, ob); bt= uiDefIconButR(block, ICONTOG, 0, ICON_RESTRICT_RENDER_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1, + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &ptr, "hide_render", -1, 0, 0, -1, -1, NULL); uiButSetFunc(bt, restrictbutton_rend_cb, scene, ob); @@ -5259,15 +5261,15 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); restrict_bool= group_restrict_flag(gr, OB_RESTRICT_VIEW); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_VIEW_ON : ICON_RESTRICT_VIEW_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_gr_restrict_view, scene, gr); restrict_bool= group_restrict_flag(gr, OB_RESTRICT_SELECT); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_SELECT_ON : ICON_RESTRICT_SELECT_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); uiButSetFunc(bt, restrictbutton_gr_restrict_select, scene, gr); restrict_bool= group_restrict_flag(gr, OB_RESTRICT_RENDER); - bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability"); + bt = uiDefIconBut(block, BUT, 0, restrict_bool ? ICON_RESTRICT_RENDER_ON : ICON_RESTRICT_RENDER_OFF, (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, NULL, 0, 0, 0, 0, "Restrict/Allow renderability"); uiButSetFunc(bt, restrictbutton_gr_restrict_render, scene, gr); uiBlockSetEmboss(block, UI_EMBOSS); @@ -5277,7 +5279,7 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt= uiDefIconButBitI(block, ICONTOGN, SCE_LAY_DISABLE, 0, ICON_CHECKBOX_HLT-1, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, te->directdata, 0, 0, 0, 0, "Render this RenderLayer"); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); uiBlockSetEmboss(block, UI_EMBOSS); @@ -5290,13 +5292,13 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar bt= uiDefIconButBitI(block, ICONTOG, passflag, 0, ICON_CHECKBOX_HLT-1, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Render this Pass"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Render this Pass"); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); layflag++; /* is lay_xor */ if(ELEM8(passflag, SCE_PASS_SPEC, SCE_PASS_SHADOW, SCE_PASS_AO, SCE_PASS_REFLECT, SCE_PASS_REFRACT, SCE_PASS_INDIRECT, SCE_PASS_EMIT, SCE_PASS_ENVIRONMENT)) bt= uiDefIconButBitI(block, TOG, passflag, 0, (*layflag & passflag)?ICON_DOT:ICON_BLANK1, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, layflag, 0, 0, 0, 0, "Exclude this Pass from Combined"); uiButSetFunc(bt, restrictbutton_r_lay_cb, tselem->id, NULL); uiBlockSetEmboss(block, UI_EMBOSS); @@ -5307,11 +5309,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Realtime, 0, ICON_RESTRICT_VIEW_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); bt= uiDefIconButBitI(block, ICONTOGN, eModifierMode_Render, 0, ICON_RESTRICT_RENDER_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, 17, OL_H-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_RENDERX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(md->mode), 0, 0, 0, 0, "Restrict/Allow renderability"); uiButSetFunc(bt, restrictbutton_modifier_cb, scene, ob); } else if(tselem->type==TSE_POSE_CHANNEL) { @@ -5320,11 +5322,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_P, 0, ICON_RESTRICT_VIEW_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_bone_cb, NULL, bone); bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(bone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); uiButSetFunc(bt, restrictbutton_bone_cb, NULL, NULL); } else if(tselem->type==TSE_EBONE) { @@ -5332,11 +5334,11 @@ static void outliner_draw_restrictbuts(uiBlock *block, Scene *scene, ARegion *ar uiBlockSetEmboss(block, UI_EMBOSSN); bt= uiDefIconButBitI(block, ICONTOG, BONE_HIDDEN_A, 0, ICON_RESTRICT_VIEW_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_VIEWX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow visibility in the 3D View"); uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, ebone); bt= uiDefIconButBitI(block, ICONTOG, BONE_UNSELECTABLE, 0, ICON_RESTRICT_SELECT_OFF, - (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, 17, OL_H-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); + (int)ar->v2d.cur.xmax-OL_TOG_RESTRICT_SELECTX, (int)te->ys, UI_UNIT_X-1, UI_UNIT_Y-1, &(ebone->flag), 0, 0, 0, 0, "Restrict/Allow selection in the 3D View"); uiButSetFunc(bt, restrictbutton_ebone_cb, NULL, NULL); } } @@ -5377,19 +5379,19 @@ static void outliner_draw_rnabuts(uiBlock *block, Scene *scene, ARegion *ar, Spa for(te= lb->first; te; te= te->next) { tselem= TREESTORE(te); - if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { if(tselem->type == TSE_RNA_PROPERTY) { ptr= &te->rnaptr; prop= te->directdata; if(!(RNA_property_type(prop) == PROP_POINTER && (tselem->flag & TSE_CLOSED)==0)) - uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1); + uiDefAutoButR(block, ptr, prop, -1, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1); } else if(tselem->type == TSE_RNA_ARRAY_ELEM) { ptr= &te->rnaptr; prop= te->directdata; - uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, OL_H-1); + uiDefAutoButR(block, ptr, prop, te->index, "", ICON_NONE, sizex, (int)te->ys, OL_RNA_COL_SIZEX, UI_UNIT_Y-1); } } @@ -5444,7 +5446,7 @@ static uiBlock *operator_search_menu(bContext *C, ARegion *ar, void *arg_kmi) /* 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, 256, 10, 0, 150, 19, 0, 0, ""); + but= uiDefSearchBut(block, search, 0, ICON_VIEWZOOM, 256, 10, 0, 150, UI_UNIT_Y, 0, 0, ""); uiButSetSearchFunc(but, operator_search_cb, arg_kmi, operator_call_cb, ot); uiBoundsBlock(block, 6); @@ -5583,11 +5585,11 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo for(te= lb->first; te; te= te->next) { tselem= TREESTORE(te); - if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { uiBut *but; const char *str; int xstart= 240; - int butw1= 20; /* operator */ + int butw1= UI_UNIT_X; /* operator */ int butw2= 90; /* event type, menus */ int butw3= 43; /* modifiers */ @@ -5597,7 +5599,7 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo /* modal map? */ if(kmi->propvalue); else { - uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, OL_H-1, "Assign new Operator"); + uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys+1, butw1, UI_UNIT_Y-1, "Assign new Operator"); } xstart+= butw1+10; @@ -5605,43 +5607,43 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo kmi->maptype= keymap_menu_type(kmi->type); str= keymap_type_menu(); - but= uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->maptype, 0, 0, 0, 0, "Event type"); + but= uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->maptype, 0, 0, 0, 0, "Event type"); uiButSetFunc(but, keymap_type_cb, kmi, NULL); xstart+= butw2+5; /* edit actual event */ switch(kmi->maptype) { case OL_KM_KEYBOARD: - uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, "Key code"); + uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, "Key code"); xstart+= butw2+5; break; case OL_KM_MOUSE: str= keymap_mouse_menu(); - uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0, "Mouse button"); + uiDefButS(block, MENU, 0, str, xstart,(int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0, "Mouse button"); xstart+= butw2+5; break; case OL_KM_TWEAK: str= keymap_tweak_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->type, 0, 0, 0, 0, "Tweak gesture"); + uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->type, 0, 0, 0, 0, "Tweak gesture"); xstart+= butw2+5; str= keymap_tweak_dir_menu(); - uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->val, 0, 0, 0, 0, "Tweak gesture direction"); + uiDefButS(block, MENU, 0, str, xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->val, 0, 0, 0, 0, "Tweak gesture direction"); xstart+= butw2+5; break; } /* modifiers */ - uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys+1, butw3+5, OL_H-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5; - uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3; - uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3; - uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3; + uiDefButS(block, OPTION, 0, "Shift", xstart, (int)te->ys+1, butw3+5, UI_UNIT_Y-1, &kmi->shift, 0, 0, 0, 0, "Modifier"); xstart+= butw3+5; + uiDefButS(block, OPTION, 0, "Ctrl", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->ctrl, 0, 0, 0, 0, "Modifier"); xstart+= butw3; + uiDefButS(block, OPTION, 0, "Alt", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->alt, 0, 0, 0, 0, "Modifier"); xstart+= butw3; + uiDefButS(block, OPTION, 0, "OS", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, "Modifier"); xstart+= butw3; xstart+= 5; - uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, OL_H-1, &kmi->keymodifier, "Key Modifier code"); + uiDefKeyevtButS(block, 0, "", xstart, (int)te->ys+1, butw3, UI_UNIT_Y-1, &kmi->keymodifier, "Key Modifier code"); xstart+= butw3+5; /* rna property */ if(kmi->ptr && kmi->ptr->data) { - uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys+1, butw2, OL_H-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2; + uiDefBut(block, LABEL, 0, "(RNA property)", xstart, (int)te->ys+1, butw2, UI_UNIT_Y-1, &kmi->oskey, 0, 0, 0, 0, ""); xstart+= butw2; } (void)xstart; @@ -5662,7 +5664,7 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa for(te= lb->first; te; te= te->next) { tselem= TREESTORE(te); - if(te->ys+2*OL_H >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { + if(te->ys+2*UI_UNIT_Y >= ar->v2d.cur.ymin && te->ys <= ar->v2d.cur.ymax) { if(tselem->flag & TSE_TEXTBUT) { @@ -5679,10 +5681,10 @@ static void outliner_buttons(const bContext *C, uiBlock *block, ARegion *ar, Spa dx= (int)UI_GetStringWidth(te->name); if(dx<100) dx= 100; - spx=te->xs+2*OL_X-4; + spx=te->xs+2*UI_UNIT_X-4; if(spx+dx+10>ar->v2d.cur.xmax) dx = ar->v2d.cur.xmax-spx-10; - bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx+10, OL_H-1, (void *)te->name, 1.0, (float)len, 0, 0, ""); + bt= uiDefBut(block, TEX, OL_NAMEBUTTON, "", spx, (int)te->ys, dx+10, UI_UNIT_Y-1, (void *)te->name, 1.0, (float)len, 0, 0, ""); uiButSetRenameFunc(bt, namebutton_cb, tselem); /* returns false if button got removed */ @@ -5716,7 +5718,7 @@ void draw_outliner(const bContext *C) * (OL_RNA_COL_X), whichever is wider... * - column 2 is fixed at OL_RNA_COL_SIZEX * - * (*) XXX max width for now is a fixed factor of OL_X*(max_indention+100) + * (*) XXX max width for now is a fixed factor of UI_UNIT_X*(max_indention+100) */ /* get actual width of column 1 */ diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index f351d52db07..119c5da309e 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -550,15 +550,17 @@ static void draw_shadedstrip(Sequence *seq, unsigned char col[3], float x1, floa glShadeModel(GL_SMOOTH); glBegin(GL_QUADS); - if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50); + if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; } + else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -50); else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 0); glColor3ubv(col); glVertex2f(x1,y1); glVertex2f(x2,y1); - - if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5); + + if(seq->flag & SEQ_INVALID_EFFECT) { col[0]= 255; col[1]= 0; col[2]= 255; } + else if(seq->flag & SELECT) UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, 5); else UI_GetColorPtrBlendShade3ubv(col, col, col, 0.0, -5); glColor3ubv((GLubyte *)col); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 71ed7928bc8..6900271deea 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -2817,6 +2817,7 @@ void SEQUENCER_OT_view_ghost_border(wmOperatorType *ot) ot->exec= view_ghost_border_exec; ot->modal= WM_border_select_modal; ot->poll= sequencer_view_poll; + ot->cancel= WM_border_select_cancel; /* flags */ ot->flag= 0; diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c index 8b4bfb2e042..8d5f372f55e 100644 --- a/source/blender/editors/space_sequencer/sequencer_select.c +++ b/source/blender/editors/space_sequencer/sequencer_select.c @@ -871,6 +871,7 @@ void SEQUENCER_OT_select_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= sequencer_borderselect_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_sequencer_active; diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 31aae28dd61..9ff73767b4c 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -904,6 +904,13 @@ static int view3d_camera_active_poll(bContext *C) return 0; } +static int viewrotate_cancel(bContext *C, wmOperator *op) +{ + viewops_data_free(C, op); + + return OPERATOR_CANCELLED; +} + void VIEW3D_OT_rotate(wmOperatorType *ot) { @@ -916,6 +923,7 @@ void VIEW3D_OT_rotate(wmOperatorType *ot) ot->invoke= viewrotate_invoke; ot->modal= viewrotate_modal; ot->poll= ED_operator_region_view3d_active; + ot->cancel= viewrotate_cancel; /* flags */ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; @@ -1058,6 +1066,13 @@ static int viewmove_invoke(bContext *C, wmOperator *op, wmEvent *event) } } +static int viewmove_cancel(bContext *C, wmOperator *op) +{ + viewops_data_free(C, op); + + return OPERATOR_CANCELLED; +} + void VIEW3D_OT_move(wmOperatorType *ot) { @@ -1070,6 +1085,7 @@ void VIEW3D_OT_move(wmOperatorType *ot) ot->invoke= viewmove_invoke; ot->modal= viewmove_modal; ot->poll= ED_operator_view3d_active; + ot->cancel= viewmove_cancel; /* flags */ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; @@ -1414,6 +1430,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_FINISHED; } +static int viewzoom_cancel(bContext *C, wmOperator *op) +{ + viewops_data_free(C, op); + + return OPERATOR_CANCELLED; +} void VIEW3D_OT_zoom(wmOperatorType *ot) { @@ -1427,6 +1449,7 @@ void VIEW3D_OT_zoom(wmOperatorType *ot) ot->exec= viewzoom_exec; ot->modal= viewzoom_modal; ot->poll= ED_operator_region_view3d_active; + ot->cancel= viewzoom_cancel; /* flags */ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; @@ -1641,6 +1664,13 @@ static int viewdolly_poll(bContext *C) return 0; } +static int viewdolly_cancel(bContext *C, wmOperator *op) +{ + viewops_data_free(C, op); + + return OPERATOR_CANCELLED; +} + void VIEW3D_OT_dolly(wmOperatorType *ot) { /* identifiers */ @@ -1653,6 +1683,7 @@ void VIEW3D_OT_dolly(wmOperatorType *ot) ot->exec= viewdolly_exec; ot->modal= viewdolly_modal; ot->poll= viewdolly_poll; + ot->cancel= viewdolly_cancel; /* flags */ ot->flag= OPTYPE_BLOCKING|OPTYPE_GRAB_POINTER; @@ -2046,6 +2077,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) ot->invoke= WM_border_select_invoke; ot->exec= render_border_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= view3d_camera_active_poll; @@ -2201,6 +2233,7 @@ void VIEW3D_OT_zoom_border(wmOperatorType *ot) ot->invoke= view3d_zoom_border_invoke; ot->exec= view3d_zoom_border_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_region_view3d_active; @@ -2839,6 +2872,7 @@ void VIEW3D_OT_clip_border(wmOperatorType *ot) ot->invoke= view3d_clipping_invoke; ot->exec= view3d_clipping_exec; ot->modal= WM_border_select_modal; + ot->cancel= WM_border_select_cancel; ot->poll= ED_operator_region_view3d_active; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index fb3c0a63b7d..6391db7ae5e 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -875,6 +875,7 @@ void VIEW3D_OT_select_lasso(wmOperatorType *ot) ot->modal= WM_gesture_lasso_modal; ot->exec= view3d_lasso_select_exec; ot->poll= view3d_selectable_data; + ot->cancel= WM_gesture_lasso_cancel; /* flags */ ot->flag= OPTYPE_UNDO; @@ -1829,6 +1830,7 @@ void VIEW3D_OT_select_border(wmOperatorType *ot) ot->exec= view3d_borderselect_exec; ot->modal= WM_border_select_modal; ot->poll= view3d_selectable_data; + ot->cancel= WM_border_select_cancel; /* flags */ ot->flag= OPTYPE_UNDO; @@ -2308,6 +2310,7 @@ void VIEW3D_OT_select_circle(wmOperatorType *ot) ot->modal= WM_gesture_circle_modal; ot->exec= view3d_circle_select_exec; ot->poll= view3d_selectable_data; + ot->cancel= WM_gesture_circle_cancel; /* flags */ ot->flag= OPTYPE_UNDO; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 27ca345e132..181fb0f0aac 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -4858,8 +4858,8 @@ void initEdgeSlide(TransInfo *t) t->idx_max = 0; t->num.idx_max = 0; t->snap[0] = 0.0f; - t->snap[1] = (float)((5.0/180)*M_PI); - t->snap[2] = t->snap[1] * 0.2f; + t->snap[1] = 0.1f; + t->snap[2] = t->snap[1] * 0.1f; t->num.increment = t->snap[1]; @@ -4985,6 +4985,9 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2])) snapGrid(t, &final); + /* only do this so out of range values are not displayed */ + CLAMP(final, -1.0f, 1.0f); + if (hasNumInput(&t->num)) { char c[20]; @@ -4992,10 +4995,10 @@ int EdgeSlide(TransInfo *t, const int UNUSED(mval[2])) outputNumInput(&(t->num), c); - sprintf(str, "Edge Slide Percent: %s", &c[0]); + sprintf(str, "Edge Slide: %s", &c[0]); } else { - sprintf(str, "Edge Slide Percent: %.2f", final); + sprintf(str, "Edge Slide: %.2f", final); } CLAMP(final, -1.0f, 1.0f); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index c7699f7249c..68aa27a7b62 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4016,6 +4016,7 @@ static void freeSeqData(TransInfo *t) } if(overlap) { + int has_effect= 0; for(seq= seqbasep->first; seq; seq= seq->next) seq->tmp= NULL; @@ -4024,12 +4025,47 @@ static void freeSeqData(TransInfo *t) for(a=0; a<t->total; a++, td++) { seq= ((TransDataSeq *)td->extra)->seq; if ((seq != seq_prev)) { - /* Tag seq with a non zero value, used by shuffle_seq_time to identify the ones to shuffle */ - seq->tmp= (void*)1; + /* check effects strips, we cant change their time */ + if((seq->type & SEQ_EFFECT) && seq->seq1) { + has_effect= TRUE; + } + else { + /* Tag seq with a non zero value, used by shuffle_seq_time to identify the ones to shuffle */ + seq->tmp= (void*)1; + } } } shuffle_seq_time(seqbasep, t->scene); + + if(has_effect) { + /* update effects strips based on strips just moved in time */ + td= t->data; + seq_prev= NULL; + for(a=0; a<t->total; a++, td++) { + seq= ((TransDataSeq *)td->extra)->seq; + if ((seq != seq_prev)) { + if((seq->type & SEQ_EFFECT) && seq->seq1) { + calc_sequence(t->scene, seq); + } + } + } + + /* now if any effects _still_ overlap, we need to move them up */ + td= t->data; + seq_prev= NULL; + for(a=0; a<t->total; a++, td++) { + seq= ((TransDataSeq *)td->extra)->seq; + if ((seq != seq_prev)) { + if((seq->type & SEQ_EFFECT) && seq->seq1) { + if(seq_test_overlap(seqbasep, seq)) { + shuffle_seq(seqbasep, seq, t->scene); + } + } + } + } + /* done with effects */ + } } } #endif diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c index 692a19a7198..24a868891de 100644 --- a/source/blender/editors/util/undo.c +++ b/source/blender/editors/util/undo.c @@ -307,6 +307,8 @@ void ED_OT_undo_push(wmOperatorType *ot) /* api callbacks */ ot->exec= ed_undo_push_exec; + ot->flag= OPTYPE_INTERNAL; + RNA_def_string(ot->srna, "message", "Add an undo step *function may be moved*", MAXUNDONAME, "Undo Message", ""); } diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 66b1e7d412b..c09f8cff02d 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -2221,6 +2221,7 @@ static void UV_OT_select_border(wmOperatorType *ot) ot->exec= border_select_exec; ot->modal= WM_border_select_modal; ot->poll= ED_operator_image_active; /* requires space image */; + ot->cancel= WM_border_select_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; @@ -2310,6 +2311,7 @@ static void UV_OT_circle_select(wmOperatorType *ot) ot->modal= WM_gesture_circle_modal; ot->exec= circle_select_exec; ot->poll= ED_operator_image_active; /* requires space image */; + ot->cancel= WM_gesture_circle_cancel; /* flags */ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO; |