diff options
author | Ove Murberg Henriksen <sorayasilvermoon@hotmail.com> | 2012-05-18 03:34:54 +0400 |
---|---|---|
committer | Ove Murberg Henriksen <sorayasilvermoon@hotmail.com> | 2012-05-18 03:34:54 +0400 |
commit | 74a889d8b1a8e9f83214fa885f530b7b167b4a32 (patch) | |
tree | eb85f3c045b69b919b9d2b0b79f1e626ff4f2647 /source/blender/editors | |
parent | 8521ca69fac26ebfa14910566f2271562e1ff0b5 (diff) | |
parent | 7862b2fa13c0437d9c17eae78e7b79a421dacf05 (diff) |
svn merge ^/trunk/blender -r46644:HEAD
Diffstat (limited to 'source/blender/editors')
46 files changed, 1590 insertions, 534 deletions
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 2729396cb4a..160e6957513 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -379,7 +379,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) /* ... standard sub-channel filtering can go on here now ... */ #define END_ANIMFILTER_SUBCHANNELS \ filter_mode = _filter; \ - } + } (void)0 /* ............................... */ @@ -447,7 +447,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) } \ } \ } \ - } + } (void)0 /* ............................... */ @@ -467,7 +467,7 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) items ++; \ ale_statement \ } \ - } + } (void)0 #define ANIMCHANNEL_NEW_CHANNEL(channel_data, channel_type, owner_id) \ ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, {}) @@ -2223,7 +2223,7 @@ static size_t animdata_filter_remove_duplis(ListBase *anim_data) /* build new hashtable to efficiently store and retrieve which entries have been * encountered already while searching */ - gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "animdata_filter_duplis_remove gh"); + gh = BLI_ghash_ptr_new("animdata_filter_duplis_remove gh"); /* loop through items, removing them from the list if a similar item occurs already */ for (ale = anim_data->first; ale; ale = next) { diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 8e2dfb72703..7ce2988b067 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -5945,7 +5945,7 @@ void generateSkeletonFromReebGraph(Scene *scene, ReebGraph *rg) ED_armature_to_edit(obedit); - arcBoneMap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "SkeletonFromReebGraph gh"); + arcBoneMap = BLI_ghash_ptr_new("SkeletonFromReebGraph gh"); BLI_markdownSymmetry((BGraph *)rg, rg->nodes.first, scene->toolsettings->skgen_symmetry_limit); diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index 566dbc901b8..80f8c61694c 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -298,8 +298,8 @@ static RigGraph *newRigGraph(void) rg->head = NULL; - rg->bones_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "newRigGraph bones gh"); - rg->controls_map = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "newRigGraph cont gh"); + rg->bones_map = BLI_ghash_str_new("newRigGraph bones gh"); + rg->controls_map = BLI_ghash_str_new("newRigGraph cont gh"); rg->free_arc = RIG_freeRigArc; rg->free_node = NULL; @@ -532,7 +532,7 @@ static RigGraph *cloneRigGraph(RigGraph *src, ListBase *editbones, Object *ob, c RigControl *ctrl; RigGraph *rg; - ptr_hash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "cloneRigGraph gh"); + ptr_hash = BLI_ghash_ptr_new("cloneRigGraph gh"); rg = newRigGraph(); diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 2201bcf7224..06ecf76ba3e 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -165,7 +165,7 @@ void BIF_makeListTemplates(const bContext *C) BLI_ghash_free(TEMPLATES_HASH, NULL, NULL); } - TEMPLATES_HASH = BLI_ghash_new(BLI_ghashutil_inthash, BLI_ghashutil_intcmp, "makeListTemplates gh"); + TEMPLATES_HASH = BLI_ghash_int_new("makeListTemplates gh"); TEMPLATES_CURRENT = 0; for (base = FIRSTBASE; base; base = base->next) { diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c index 2564683ddd2..316c4699c0b 100644 --- a/source/blender/editors/armature/reeb.c +++ b/source/blender/editors/armature/reeb.c @@ -354,7 +354,7 @@ static ReebArc *copyArc(ReebGraph *rg, ReebArc *arc) memcpy(cp_arc->buckets, arc->buckets, sizeof(EmbedBucket) * cp_arc->bcount); /* copy faces map */ - cp_arc->faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "copyArc gh"); + cp_arc->faces = BLI_ghash_ptr_new("copyArc gh"); mergeArcFaces(rg, cp_arc, arc); /* find corresponding head and tail */ @@ -2295,7 +2295,7 @@ static ReebEdge *createArc(ReebGraph *rg, ReebNode *node1, ReebNode *node2) arc->flag = 0; // clear flag on init arc->symmetry_level = 0; - arc->faces = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "createArc gh"); + arc->faces = BLI_ghash_ptr_new("createArc gh"); if (node1->weight <= node2->weight) { v1 = node1; diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index e2824ee35cc..7afba049232 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -311,7 +311,7 @@ static void init_editNurb_keyIndex(EditNurb *editnurb, ListBase *origBase) if (editnurb->keyindex) return; - gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "editNurb keyIndex"); + gh = BLI_ghash_ptr_new("editNurb keyIndex"); while (orignu) { if (orignu->bezt) { @@ -667,7 +667,7 @@ static GHash *dupli_keyIndexHash(GHash *keyindex) GHash *gh; GHashIterator *hashIter; - gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "dupli_keyIndex gh"); + gh = BLI_ghash_ptr_new("dupli_keyIndex gh"); for (hashIter = BLI_ghashIterator_new(keyindex); !BLI_ghashIterator_isDone(hashIter); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 71d37d5c6ea..7e84962b154 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -267,6 +267,18 @@ void ED_mesh_mirrtopo_init(struct Mesh *me, const int ob_mode, MirrTopoStore_t * const short skip_em_vert_array_init); void ED_mesh_mirrtopo_free(MirrTopoStore_t *mesh_topo_store); +/* mesh backup */ +typedef struct BMBackup { + struct BMesh *bmcopy; +} BMBackup; + +/* save a copy of the bmesh for restoring later */ +struct BMBackup EDBM_redo_state_store(struct BMEditMesh *em); +/* restore a bmesh from backup */ +void EDBM_redo_state_restore(struct BMBackup, struct BMEditMesh *em, int recalctess); +/* delete the backup, optionally flushing it to an editmesh */ +void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalctess); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_transform.h b/source/blender/editors/include/ED_transform.h index 30d49748626..1cc82f19515 100644 --- a/source/blender/editors/include/ED_transform.h +++ b/source/blender/editors/include/ED_transform.h @@ -100,7 +100,7 @@ enum { * returns 1 if successful, 0 otherwise (usually means there's no selection) * (if 0 is returns, *vec is unmodified) * */ -int calculateTransformCenter(struct bContext *C, int centerMode, float *vec); +int calculateTransformCenter(struct bContext *C, int centerMode, float *cent3d, int *cent2d); struct TransInfo; struct ScrArea; diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 8c5913e23fb..2f9e763a7d0 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -252,7 +252,8 @@ void uiDrawBoxShade(int mode, float minx, float miny, float maxx, float maxy, fl /* linear vertical shade within button or in outline */ /* view2d scrollers use it */ -void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy, float rad, float shadeLeft, float shadeRight) +void uiDrawBoxVerticalShade(int mode, float minx, float miny, float maxx, float maxy, + float rad, float shadeLeft, float shadeRight) { float vec[7][2] = {{0.195, 0.02}, {0.383, 0.067}, {0.55, 0.169}, {0.707, 0.293}, {0.831, 0.45}, {0.924, 0.617}, {0.98, 0.805}}; @@ -656,7 +657,8 @@ static void draw_scope_end(rctf *rect, GLint *scissor) uiDrawBox(GL_LINE_LOOP, rect->xmin - 1, rect->ymin, rect->xmax + 1, rect->ymax + 1, 3.0f); } -static void histogram_draw_one(float r, float g, float b, float alpha, float x, float y, float w, float h, float *data, int res) +static void histogram_draw_one(float r, float g, float b, float alpha, + float x, float y, float w, float h, float *data, int res) { int i; @@ -716,7 +718,10 @@ void ui_draw_but_HISTOGRAM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol) /* need scissor test, histogram can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); + glScissor(ar->winrct.xmin + (rect.xmin - 1), + ar->winrct.ymin + (rect.ymin - 1), + (rect.xmax + 1) - (rect.xmin - 1), + (rect.ymax + 1) - (rect.ymin - 1)); glColor4f(1.f, 1.f, 1.f, 0.08f); /* draw grid lines here */ @@ -786,7 +791,10 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), /* need scissor test, waveform can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); + glScissor(ar->winrct.xmin + (rect.xmin - 1), + ar->winrct.ymin + (rect.ymin - 1), + (rect.xmax + 1) - (rect.xmin - 1), + (rect.ymax + 1) - (rect.ymin - 1)); glColor4f(1.f, 1.f, 1.f, 0.08f); /* draw grid lines here */ @@ -851,7 +859,12 @@ void ui_draw_but_WAVEFORM(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wcol), } /* RGB / YCC (3 channels) */ - else if (ELEM4(scopes->wavefrm_mode, SCOPES_WAVEFRM_RGB, SCOPES_WAVEFRM_YCC_601, SCOPES_WAVEFRM_YCC_709, SCOPES_WAVEFRM_YCC_JPEG)) { + else if (ELEM4(scopes->wavefrm_mode, + SCOPES_WAVEFRM_RGB, + SCOPES_WAVEFRM_YCC_601, + SCOPES_WAVEFRM_YCC_709, + SCOPES_WAVEFRM_YCC_JPEG)) + { int rgb = (scopes->wavefrm_mode == SCOPES_WAVEFRM_RGB); glBlendFunc(GL_ONE, GL_ONE); @@ -996,7 +1009,10 @@ void ui_draw_but_VECTORSCOPE(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wco /* need scissor test, hvectorscope can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); + glScissor(ar->winrct.xmin + (rect.xmin - 1), + ar->winrct.ymin + (rect.ymin - 1), + (rect.xmax + 1) - (rect.xmin - 1), + (rect.ymax + 1) - (rect.ymin - 1)); glColor4f(1.f, 1.f, 1.f, 0.08f); /* draw grid elements */ @@ -1507,7 +1523,10 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc /* need scissor test, preview image can draw outside of boundary */ glGetIntegerv(GL_VIEWPORT, scissor); - glScissor(ar->winrct.xmin + (rect.xmin - 1), ar->winrct.ymin + (rect.ymin - 1), (rect.xmax + 1) - (rect.xmin - 1), (rect.ymax + 1) - (rect.ymin - 1)); + glScissor(ar->winrct.xmin + (rect.xmin - 1), + ar->winrct.ymin + (rect.ymin - 1), + (rect.xmax + 1) - (rect.xmin - 1), + (rect.ymax + 1) - (rect.ymin - 1)); if (scopes->track_disabled) { glColor4f(0.7f, 0.3f, 0.3f, 0.3f); @@ -1550,7 +1569,10 @@ void ui_draw_but_TRACKPREVIEW(ARegion *ar, uiBut *but, uiWidgetColors *UNUSED(wc /* draw cross for pizel position */ glTranslatef(off_x + rect.xmin + track_pos[0] * zoomx, off_y + rect.ymin + track_pos[1] * zoomy, 0.f); - glScissor(ar->winrct.xmin + rect.xmin, ar->winrct.ymin + rect.ymin, rect.xmax - rect.xmin, rect.ymax - rect.ymin); + glScissor(ar->winrct.xmin + rect.xmin, + ar->winrct.ymin + rect.ymin, + rect.xmax - rect.xmin, + rect.ymax - rect.ymin); for (a = 0; a < 2; a++) { if (a == 1) { diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 94ebdb7c0b9..8b0c3ecfcf3 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -286,7 +286,9 @@ static void ui_apply_but_func(bContext *C, uiBut *but) * handling is done, i.e. menus are closed, in order to avoid conflicts * with these functions removing the buttons we are working with */ - if (but->func || but->funcN || block->handle_func || but->rename_func || (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop) { + if (but->func || but->funcN || block->handle_func || but->rename_func || + (but->type == BUTM && block->butm_func) || but->optype || but->rnaprop) + { after = MEM_callocN(sizeof(uiAfterFunc), "uiAfterFunc"); if (but->func && ELEM(but, but->func_arg1, but->func_arg2)) { @@ -4553,7 +4555,8 @@ static int ui_but_menu(bContext *C, uiBut *but) PointerRNA ptr_props; if (but->rnapoin.data && but->rnaprop) { - BLI_snprintf(buf, sizeof(buf), "%s.%s", RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop)); + BLI_snprintf(buf, sizeof(buf), "%s.%s", + RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop)); WM_operator_properties_create(&ptr_props, "WM_OT_doc_view"); RNA_string_set(&ptr_props, "doc_id", buf); @@ -5128,8 +5131,10 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s WM_event_add_ui_handler(C, &data->window->modalhandlers, ui_handler_region_menu, NULL, data); } else { - if (button_modal_state(data->state)) - WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, 1); /* 1 = postpone free */ + if (button_modal_state(data->state)) { + /* TRUE = postpone free */ + WM_event_remove_ui_handler(&data->window->modalhandlers, ui_handler_region_menu, NULL, data, TRUE); + } } } @@ -6548,7 +6553,7 @@ static void ui_handler_remove_popup(bContext *C, void *userdata) void UI_add_region_handlers(ListBase *handlers) { - WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL, 0); + WM_event_remove_ui_handler(handlers, ui_handler_region, ui_handler_remove_region, NULL, FALSE); WM_event_add_ui_handler(NULL, handlers, ui_handler_region, ui_handler_remove_region, NULL); } @@ -6559,7 +6564,7 @@ void UI_add_popup_handlers(bContext *C, ListBase *handlers, uiPopupBlockHandle * void UI_remove_popup_handlers(ListBase *handlers, uiPopupBlockHandle *popup) { - WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup, 0); + WM_event_remove_ui_handler(handlers, ui_handler_popup, ui_handler_remove_popup, popup, FALSE); } diff --git a/source/blender/editors/interface/interface_icons.c b/source/blender/editors/interface/interface_icons.c index e9186aff666..385f74acbd2 100644 --- a/source/blender/editors/interface/interface_icons.c +++ b/source/blender/editors/interface/interface_icons.c @@ -533,7 +533,8 @@ static void init_internal_icons(void) } } if (bbuf == NULL) - bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons_png, datatoc_blender_icons_png_size, IB_rect, "<blender icons>"); + bbuf = IMB_ibImageFromMemory((unsigned char *)datatoc_blender_icons_png, + datatoc_blender_icons_png_size, IB_rect, "<blender icons>"); if (bbuf) { /* free existing texture if any */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 9e073055fc3..2c4ec9ac482 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -428,7 +428,8 @@ void ui_but_search_test(uiBut *but); typedef uiBlock * (*uiBlockHandleCreateFunc)(struct bContext *C, struct uiPopupBlockHandle *handle, void *arg1); uiPopupBlockHandle *ui_popup_block_create(struct bContext *C, struct ARegion *butregion, uiBut *but, - uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func, void *arg); + uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func, + void *arg); uiPopupBlockHandle *ui_popup_menu_create(struct bContext *C, struct ARegion *butregion, uiBut *but, uiMenuCreateFunc create_func, void *arg, char *str); diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 6d2ac388374..f2a43580fd8 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -589,9 +589,7 @@ static void ui_editsource_active_but_set(uiBut *but) ui_editsource_info = MEM_callocN(sizeof(uiEditSourceStore), __func__); memcpy(&ui_editsource_info->but_orig, but, sizeof(uiBut)); - ui_editsource_info->hash = BLI_ghash_new(BLI_ghashutil_ptrhash, - BLI_ghashutil_ptrcmp, - __func__); + ui_editsource_info->hash = BLI_ghash_ptr_new(__func__); } static void ui_editsource_active_but_clear(void) diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c index 0be1761eaf5..dc2c3b4eea9 100644 --- a/source/blender/editors/interface/interface_panel.c +++ b/source/blender/editors/interface/interface_panel.c @@ -1253,7 +1253,8 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat if (data && data->state != PANEL_STATE_ANIMATION) { /* XXX: * - the panel tabbing function call below (test_add_new_tabs()) has been commented out - * "It is too easy to do by accident when reordering panels, is very hard to control and use, and has no real benefit." - BillRey + * "It is too easy to do by accident when reordering panels, + * is very hard to control and use, and has no real benefit." - BillRey * Aligorith, 2009Sep */ //test_add_new_tabs(ar); // also copies locations of tabs in dragged panel @@ -1274,7 +1275,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat MEM_freeN(data); pa->activedata = NULL; - WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, 0); + WM_event_remove_ui_handler(&win->modalhandlers, ui_handler_panel, ui_handler_remove_panel, pa, FALSE); } else { if (!data) { diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 9bcda7d86ed..a36b2dd2c45 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -429,7 +429,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* create tooltip data */ data = MEM_callocN(sizeof(uiTooltipData), "uiTooltipData"); - /* special case, enum rna buttons only have enum item description, use general enum description too before the specific one */ + /* special case, enum rna buttons only have enum item description, + * use general enum description too before the specific one */ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { const char *descr = RNA_property_description(but->rnaprop); if (descr && descr[0]) { @@ -448,7 +449,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) for (i = 0; i < totitem; i++) { if (item[i].identifier[0] && item[i].value == value) { if (item[i].description && item[i].description[0]) { - BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "%s: %s", item[i].name, item[i].description); + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), "%s: %s", + item[i].name, item[i].description); data->color_id[data->totline] = UI_TIP_LC_SUBMENU; data->totline++; } @@ -496,7 +498,9 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) if (unit_type == PROP_UNIT_ROTATION) { if (RNA_property_type(but->rnaprop) == PROP_FLOAT) { - float value = RNA_property_array_check(but->rnaprop) ? RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex) : RNA_property_float_get(&but->rnapoin, but->rnaprop); + float value = RNA_property_array_check(but->rnaprop) ? + RNA_property_float_get_index(&but->rnapoin, but->rnaprop, but->rnaindex) : + RNA_property_float_get(&but->rnapoin, but->rnaprop); BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Radians: %f"), value); data->color_id[data->totline] = UI_TIP_LC_NORMAL; data->totline++; @@ -514,7 +518,8 @@ ARegion *ui_tooltip_create(bContext *C, ARegion *butregion, uiBut *but) /* rna info */ if ((U.flag & USER_TOOLTIPS_PYTHON) == 0) { - BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s.%s"), RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop)); + BLI_snprintf(data->lines[data->totline], sizeof(data->lines[0]), TIP_("Python: %s.%s"), + RNA_struct_identifier(but->rnapoin.type), RNA_property_identifier(but->rnaprop)); data->color_id[data->totline] = UI_TIP_LC_PYTHON; data->totline++; } @@ -1553,7 +1558,9 @@ void ui_popup_block_scrolltest(uiBlock *block) } } -uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but, uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func, void *arg) +uiPopupBlockHandle *ui_popup_block_create(bContext *C, ARegion *butregion, uiBut *but, + uiBlockCreateFunc create_func, uiBlockHandleCreateFunc handle_create_func, + void *arg) { wmWindow *window = CTX_wm_window(C); static ARegionType type; @@ -1881,7 +1888,8 @@ static void ui_update_block_buts_rgb(uiBlock *block, const float rgb[3]) if (rgb_gamma[1] > 1.0f) rgb_gamma[1] = modf(rgb_gamma[1], &intpart); if (rgb_gamma[2] > 1.0f) rgb_gamma[2] = modf(rgb_gamma[2], &intpart); - BLI_snprintf(col, sizeof(col), "%02X%02X%02X", FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2])); + BLI_snprintf(col, sizeof(col), "%02X%02X%02X", + FTOCHAR(rgb_gamma[0]), FTOCHAR(rgb_gamma[1]), FTOCHAR(rgb_gamma[2])); strcpy(bt->poin, col); } @@ -2382,7 +2390,8 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi return pup->block; } -uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut *but, uiMenuCreateFunc menu_func, void *arg, char *str) +uiPopupBlockHandle *ui_popup_menu_create(bContext *C, ARegion *butregion, uiBut *but, + uiMenuCreateFunc menu_func, void *arg, char *str) { wmWindow *window = CTX_wm_window(C); uiStyle *style = UI_GetStyle(); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index d49b77c7005..a9ec893adb7 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -2829,9 +2829,9 @@ static int knifetool_init(bContext *C, wmOperator *op, int UNUSED(do_cut)) kcd->kverts = BLI_mempool_create(sizeof(KnifeVert), 1, 512, BLI_MEMPOOL_ALLOW_ITER); kcd->kedges = BLI_mempool_create(sizeof(KnifeEdge), 1, 512, BLI_MEMPOOL_ALLOW_ITER); - kcd->origedgemap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "knife origedgemap"); - kcd->origvertmap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "knife origvertmap"); - kcd->kedgefacemap = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "knife origvertmap"); + kcd->origedgemap = BLI_ghash_ptr_new("knife origedgemap"); + kcd->origvertmap = BLI_ghash_ptr_new("knife origvertmap"); + kcd->kedgefacemap = BLI_ghash_ptr_new("knife origvertmap"); /* cut all the way through the mesh if use_occlude_geometry button not pushed */ kcd->cut_through = !RNA_boolean_get(op->ptr, "use_occlude_geometry"); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index f1393e4def1..2df89a3df6c 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -834,7 +834,12 @@ static int edbm_select_similar_exec(bContext *C, wmOperator *op) static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { - Object *obedit = CTX_data_edit_object(C); + Object *obedit; + + if (!C) /* needed for docs and i18n tools */ + return prop_similar_types; + + obedit = CTX_data_edit_object(C); if (obedit && obedit->type == OB_MESH) { EnumPropertyItem *item = NULL; @@ -862,7 +867,7 @@ static EnumPropertyItem *select_similar_type_itemf(bContext *C, PointerRNA *UNUS return item; } - + return NULL; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 9be71218da0..57f663aa571 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1344,7 +1344,8 @@ void MESH_OT_flip_normals(wmOperatorType *ot) static const EnumPropertyItem direction_items[] = { {DIRECTION_CW, "CW", 0, "Clockwise", ""}, {DIRECTION_CCW, "CCW", 0, "Counter Clockwise", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} +}; /* only accepts 1 selected edge, or 2 selected faces */ static int edbm_edge_rotate_selected_exec(bContext *C, wmOperator *op) @@ -1957,7 +1958,8 @@ static EnumPropertyItem merge_type_items[] = { {3, "CENTER", 0, "At Center", ""}, {4, "CURSOR", 0, "At Cursor", ""}, {5, "COLLAPSE", 0, "Collapse", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} +}; static EnumPropertyItem *merge_type_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { @@ -2377,13 +2379,15 @@ void MESH_OT_select_axis(wmOperatorType *ot) {0, "POSITIVE", 0, "Positive Axis", ""}, {1, "NEGATIVE", 0, "Negative Axis", ""}, {-1, "ALIGNED", 0, "Aligned Axis", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; static EnumPropertyItem axis_items_xyz[] = { {0, "X_AXIS", 0, "X Axis", ""}, {1, "Y_AXIS", 0, "Y Axis", ""}, {2, "Z_AXIS", 0, "Z Axis", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Select Axis"; @@ -2685,7 +2689,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) } /* get the cut curve */ - RNA_BEGIN (op->ptr, itemptr, "path") + RNA_BEGIN(op->ptr, itemptr, "path") { RNA_float_get_array(&itemptr, "loc", (float *)&curve[len]); len++; @@ -2700,7 +2704,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) } /* the floating point coordinates of verts in screen space will be stored in a hash table according to the vertices pointer */ - gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "knife cut exec"); + gh = BLI_ghash_ptr_new("knife cut exec"); for (bv = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); bv; bv = BM_iter_step(&iter)) { scr = MEM_mallocN(sizeof(float) * 2, "Vertex Screen Coordinates"); copy_v3_v3(co, bv->co); @@ -3566,7 +3570,8 @@ void MESH_OT_select_by_number_vertices(wmOperatorType *ot) {1, "EQUAL", 0, "Equal To", ""}, {2, "GREATER", 0, "Greater Than", ""}, {3, "NOTEQUAL", 0, "Not Equal To", ""}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; /* identifiers */ ot->name = "Select by Number of Vertices"; @@ -3889,12 +3894,12 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const mp = map[0] = MEM_callocN(sizeof(int) * totelem[0], "sort_bmelem vert map"); BM_ITER_MESH_INDEX (ve, &iter, em->bm, BM_VERTS_OF_MESH, i) { - if (BM_elem_flag_test(ve, flag)) { - mp[affected[0]++] = i; - } - else { - *tb = i; - tb++; + if (BM_elem_flag_test(ve, flag)) { + mp[affected[0]++] = i; + } + else { + *tb = i; + tb++; } } } @@ -3904,12 +3909,12 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const mp = map[1] = MEM_callocN(sizeof(int) * totelem[1], "sort_bmelem edge map"); BM_ITER_MESH_INDEX (ed, &iter, em->bm, BM_EDGES_OF_MESH, i) { - if (BM_elem_flag_test(ed, flag)) { - mp[affected[1]++] = i; - } - else { - *tb = i; - tb++; + if (BM_elem_flag_test(ed, flag)) { + mp[affected[1]++] = i; + } + else { + *tb = i; + tb++; } } } @@ -3919,17 +3924,17 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const mp = map[2] = MEM_callocN(sizeof(int) * totelem[2], "sort_bmelem face map"); BM_ITER_MESH_INDEX (fa, &iter, em->bm, BM_FACES_OF_MESH, i) { - if (BM_elem_flag_test(fa, flag)) { - mp[affected[2]++] = i; - } - else { - *tb = i; - tb++; + if (BM_elem_flag_test(fa, flag)) { + mp[affected[2]++] = i; + } + else { + *tb = i; + tb++; } } } - for (j = 3; j--;) { + for (j = 3; j--; ) { int tot = totelem[j]; int aff = affected[j]; tb = tbuf[j]; @@ -4069,7 +4074,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const /* printf("%d edges: %d to be affected…\n", totelem[1], affected[1]);*/ /* printf("%d faces: %d to be affected…\n", totelem[2], affected[2]);*/ if (affected[0] == 0 && affected[1] == 0 && affected[2] == 0) { - for (j = 3; j--;) { + for (j = 3; j--; ) { if (pblock[j]) MEM_freeN(pblock[j]); if (sblock[j]) @@ -4081,7 +4086,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const } /* Sort affected elements, and populate mapping arrays, if needed. */ - for (j = 3; j--;) { + for (j = 3; j--; ) { pb = pblock[j]; sb = sblock[j]; if (pb && sb && !map[j]) { @@ -4114,7 +4119,7 @@ static void sort_bmelem_flag(bContext *C, const int types, const int flag, const BM_mesh_remap(em->bm, map[0], map[1], map[2]); /* DAG_id_tag_update(ob->data, 0);*/ - for (j = 3; j--;) { + for (j = 3; j--; ) { if (map[j]) MEM_freeN(map[j]); } @@ -4303,21 +4308,79 @@ void MESH_OT_noise(wmOperatorType *ot) RNA_def_float(ot->srna, "factor", 0.1f, -FLT_MAX, FLT_MAX, "Factor", "", 0.0f, 1.0f); } -/* bevel! yay!!*/ -static int edbm_bevel_exec(bContext *C, wmOperator *op) +typedef struct { + BMEditMesh *em; + BMBackup mesh_backup; + float *weights; + int li; + int mcenter[2]; + float initial_length; + int is_modal; +} BevelData; + +#define HEADER_LENGTH 180 + +static void edbm_bevel_update_header(wmOperator *op, bContext *C) +{ + static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), factor: %f, , Use Dist (D): %s: Use Even (E): %s"; + + char msg[HEADER_LENGTH]; + ScrArea *sa = CTX_wm_area(C); + + if (sa) { + BLI_snprintf(msg, HEADER_LENGTH, str, + RNA_float_get(op->ptr, "percent"), + RNA_boolean_get(op->ptr, "use_dist") ? "On" : "Off", + RNA_boolean_get(op->ptr, "use_even") ? "On" : "Off" + ); + + ED_area_headerprint(sa, msg); + } +} + +static void edbm_bevel_recalc_weights(wmOperator *op) +{ + float df, s, ftot; + int i; + int recursion = 1; /* RNA_int_get(op->ptr, "recursion"); */ /* temp removed, see comment below */ + BevelData *opdata = op->customdata; + + if (opdata->weights) { + /* TODO should change to free only when new recursion is greater than old */ + MEM_freeN(opdata->weights); + } + opdata->weights = MEM_mallocN(sizeof(float) * recursion, "bevel weights"); + + /* ugh, stupid math depends somewhat on angles!*/ + /* dfac = 1.0/(float)(recursion + 1); */ /* UNUSED */ + df = 1.0; + for (i = 0, ftot = 0.0f; i < recursion; i++) { + s = powf(df, 1.25f); + + opdata->weights[i] = s; + ftot += s; + + df *= 2.0f; + } + + mul_vn_fl(opdata->weights, recursion, 1.0f / (float)ftot); +} + +static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BMEdit_FromObject(obedit); BMIter iter; BMEdge *eed; - BMOperator bmop; - float factor = RNA_float_get(op->ptr, "percent") /*, dfac */ /* UNUSED */, df, s; - int i, recursion = 1; /* RNA_int_get(op->ptr, "recursion"); */ /* temp removed, see comment below */ - const int use_even = RNA_boolean_get(op->ptr, "use_even"); - const int use_dist = RNA_boolean_get(op->ptr, "use_dist"); - float *w = NULL, ftot; + BevelData *opdata; int li; + if (em == NULL) { + return 0; + } + + op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator"); + BM_data_layer_add(em->bm, &em->bm->edata, CD_PROP_FLT); li = CustomData_number_of_layers(&em->bm->edata, CD_PROP_FLT) - 1; @@ -4328,52 +4391,201 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op) *dv = d; } - if (em == NULL) { - return OPERATOR_CANCELLED; - } + opdata->em = em; + opdata->li = li; + opdata->weights = NULL; + opdata->is_modal = is_modal; - w = MEM_mallocN(sizeof(float) * recursion, "bevel weights"); + /* avoid the cost of allocating a bm copy */ + if (is_modal) + opdata->mesh_backup = EDBM_redo_state_store(em); + edbm_bevel_recalc_weights(op); - /* ugh, stupid math depends somewhat on angles!*/ - /* dfac = 1.0/(float)(recursion + 1); */ /* UNUSED */ - df = 1.0; - for (i = 0, ftot = 0.0f; i < recursion; i++) { - s = powf(df, 1.25f); + return 1; +} - w[i] = s; - ftot += s; +static int edbm_bevel_calc(bContext *C, wmOperator *op) +{ + BevelData *opdata = op->customdata; + BMEditMesh *em = opdata->em; + BMOperator bmop; + int i; - df *= 2.0f; - } + float factor = RNA_float_get(op->ptr, "percent") /*, dfac */ /* UNUSED */; + int recursion = 1; /* RNA_int_get(op->ptr, "recursion"); */ /* temp removed, see comment below */ + const int use_even = RNA_boolean_get(op->ptr, "use_even"); + const int use_dist = RNA_boolean_get(op->ptr, "use_dist"); - mul_vn_fl(w, recursion, 1.0f / (float)ftot); + /* revert to original mesh */ + if (opdata->is_modal) { + EDBM_redo_state_restore(opdata->mesh_backup, em, FALSE); + } for (i = 0; i < recursion; i++) { - float fac = w[recursion - i - 1] * factor; + float fac = opdata->weights[recursion - i - 1] * factor; + if (!EDBM_op_init(em, &bmop, op, "bevel geom=%hev percent=%f lengthlayer=%i use_lengths=%b use_even=%b use_dist=%b", - BM_ELEM_SELECT, fac, li, TRUE, use_even, use_dist)) + BM_ELEM_SELECT, fac, opdata->li, TRUE, use_even, use_dist)) { - return OPERATOR_CANCELLED; + return 0; } BMO_op_exec(em->bm, &bmop); if (!EDBM_op_finish(em, &bmop, op, TRUE)) - return OPERATOR_CANCELLED; + return 0; } - BM_data_layer_free_n(em->bm, &em->bm->edata, CD_PROP_FLT, li); + EDBM_mesh_normals_update(opdata->em); - MEM_freeN(w); + EDBM_update_generic(C, opdata->em, TRUE); - EDBM_mesh_normals_update(em); + return 1; +} - EDBM_update_generic(C, em, TRUE); +static void edbm_bevel_exit(bContext *C, wmOperator *op) +{ + BevelData *opdata = op->customdata; + + ScrArea *sa = CTX_wm_area(C); + + if (sa) { + ED_area_headerprint(sa, NULL); + } + BM_data_layer_free_n(opdata->em->bm, &opdata->em->bm->edata, CD_PROP_FLT, opdata->li); + + if (opdata->weights) + MEM_freeN(opdata->weights); + if (opdata->is_modal) { + EDBM_redo_state_free(&opdata->mesh_backup, NULL, FALSE); + } + MEM_freeN(opdata); + op->customdata = NULL; +} + +static int edbm_bevel_cancel(bContext *C, wmOperator *op) +{ + BevelData *opdata = op->customdata; + if (opdata->is_modal) { + EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, TRUE); + EDBM_update_generic(C, opdata->em, FALSE); + } + + edbm_bevel_exit(C, op); + + /* need to force redisplay or we may still view the modified result */ + ED_region_tag_redraw(CTX_wm_region(C)); + return OPERATOR_CANCELLED; +} + +/* bevel! yay!!*/ +static int edbm_bevel_exec(bContext *C, wmOperator *op) +{ + if (!edbm_bevel_init(C, op, FALSE)) { + edbm_bevel_exit(C, op); + return OPERATOR_CANCELLED; + } + + if (!edbm_bevel_calc(C, op)) { + edbm_bevel_cancel(C, op); + return OPERATOR_CANCELLED; + } + + edbm_bevel_exit(C, op); return OPERATOR_FINISHED; } +static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + /* TODO make modal keymap (see fly mode) */ + BevelData *opdata; + float mlen[2]; + + if (!edbm_bevel_init(C, op, TRUE)) + return OPERATOR_CANCELLED; + + /* initialize mouse values */ + opdata = op->customdata; + + calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter); + mlen[0] = opdata->mcenter[0] - event->mval[0]; + mlen[1] = opdata->mcenter[1] - event->mval[1]; + opdata->initial_length = len_v2(mlen); + + edbm_bevel_update_header(op, C); + + if (!edbm_bevel_calc(C, op)) { + edbm_bevel_cancel(C, op); + return OPERATOR_CANCELLED; + } + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + BevelData *opdata = op->customdata; +// Scene *scene = CTX_data_scene(C); + + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + edbm_bevel_cancel(C, op); + return OPERATOR_CANCELLED; + + case MOUSEMOVE: + { + float factor; + float mdiff[2]; + + mdiff[0] = opdata->mcenter[0] - event->mval[0]; + mdiff[1] = opdata->mcenter[1] - event->mval[1]; + + factor = len_v2(mdiff) / opdata->initial_length; + factor = MAX2(1.0 - factor, 0.0); + + RNA_float_set(op->ptr, "percent", factor); + + edbm_bevel_calc(C, op); + edbm_bevel_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } + + case LEFTMOUSE: + case PADENTER: + case RETKEY: + edbm_bevel_calc(C, op); + edbm_bevel_exit(C, op); + return OPERATOR_FINISHED; + + case EKEY: + if (event->val == KM_PRESS) { + int use_even = RNA_boolean_get(op->ptr, "use_even"); + RNA_boolean_set(op->ptr, "use_even", !use_even); + + edbm_bevel_calc(C, op); + edbm_bevel_update_header(op, C); + } + return OPERATOR_RUNNING_MODAL; + + case DKEY: + if (event->val == KM_PRESS) { + int use_dist = RNA_boolean_get(op->ptr, "use_dist"); + RNA_boolean_set(op->ptr, "use_dist", !use_dist); + + edbm_bevel_calc(C, op); + edbm_bevel_update_header(op, C); + } + return OPERATOR_RUNNING_MODAL; + } + + return OPERATOR_RUNNING_MODAL; +} + void MESH_OT_bevel(wmOperatorType *ot) { /* identifiers */ @@ -4383,12 +4595,15 @@ void MESH_OT_bevel(wmOperatorType *ot) /* api callbacks */ ot->exec = edbm_bevel_exec; + ot->invoke = edbm_bevel_invoke; + ot->modal = edbm_bevel_modal; + ot->cancel = edbm_bevel_cancel; ot->poll = ED_operator_editmesh; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_float(ot->srna, "percent", 0.5f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f); + RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f); // XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users. // RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8); @@ -4427,20 +4642,112 @@ void MESH_OT_bridge_edge_loops(wmOperatorType *ot) RNA_def_boolean(ot->srna, "inside", 0, "Inside", ""); } +typedef struct { + float old_thickness; + float old_depth; + int mcenter[2]; + int modify_depth; + int is_modal; + float initial_length; + BMBackup backup; + BMEditMesh *em; +} InsetData; +static void edbm_inset_update_header(wmOperator *op, bContext *C) +{ + InsetData *opdata = op->customdata; -static int edbm_inset_exec(bContext *C, wmOperator *op) + static char str[] = "Confirm: Enter/LClick, Cancel: (Esc/RClick), thickness: %f, depth (Ctrl to tweak): %f (%s), Outset (O): (%s)"; + + char msg[HEADER_LENGTH]; + ScrArea *sa = CTX_wm_area(C); + + if (sa) { + BLI_snprintf(msg, HEADER_LENGTH, str, + RNA_float_get(op->ptr, "thickness"), + RNA_float_get(op->ptr, "depth"), + opdata->modify_depth ? "On" : "Off", + RNA_boolean_get(op->ptr, "use_outset") ? "On" : "Off" + ); + + ED_area_headerprint(sa, msg); + } +} + + +static int edbm_inset_init(bContext *C, wmOperator *op, int is_modal) { + InsetData *opdata; Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BMEdit_FromObject(obedit); + + op->customdata = opdata = MEM_mallocN(sizeof(InsetData), "inset_operator_data"); + + opdata->old_thickness = 0.01; + opdata->old_depth = 0.0; + opdata->modify_depth = FALSE; + opdata->is_modal = is_modal; + opdata->em = em; + + if (is_modal) + opdata->backup = EDBM_redo_state_store(em); + + return 1; +} + +static void edbm_inset_exit(bContext *C, wmOperator *op) +{ + InsetData *opdata; + ScrArea *sa = CTX_wm_area(C); + + opdata = op->customdata; + + if (opdata->is_modal) + EDBM_redo_state_free(&opdata->backup, NULL, FALSE); + + if (sa) { + ED_area_headerprint(sa, NULL); + } + MEM_freeN(op->customdata); +} + +static int edbm_inset_cancel(bContext *C, wmOperator *op) +{ + InsetData *opdata; + + opdata = op->customdata; + if (opdata->is_modal) { + EDBM_redo_state_free(&opdata->backup, opdata->em, TRUE); + EDBM_update_generic(C, opdata->em, FALSE); + } + + edbm_inset_exit(C, op); + + /* need to force redisplay or we may still view the modified result */ + ED_region_tag_redraw(CTX_wm_region(C)); + return OPERATOR_CANCELLED; +} + +static int edbm_inset_calc(bContext *C, wmOperator *op) +{ + InsetData *opdata; + BMEditMesh *em; BMOperator bmop; - const int use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); - const int use_even_offset = RNA_boolean_get(op->ptr, "use_even_offset"); - const int use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset"); - const float thickness = RNA_float_get(op->ptr, "thickness"); - const float depth = RNA_float_get(op->ptr, "depth"); - const int use_outset = RNA_boolean_get(op->ptr, "use_outset"); - const int use_select_inset = RNA_boolean_get(op->ptr, "use_select_inset"); /* not passed onto the BMO */ + + int use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); + int use_even_offset = RNA_boolean_get(op->ptr, "use_even_offset"); + int use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset"); + float thickness = RNA_float_get(op->ptr, "thickness"); + float depth = RNA_float_get(op->ptr, "depth"); + int use_outset = RNA_boolean_get(op->ptr, "use_outset"); + int use_select_inset = RNA_boolean_get(op->ptr, "use_select_inset"); /* not passed onto the BMO */ + + opdata = op->customdata; + em = opdata->em; + + if (opdata->is_modal) { + EDBM_redo_state_restore(opdata->backup, em, FALSE); + } EDBM_op_init(em, &bmop, op, "inset faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b " @@ -4463,14 +4770,142 @@ static int edbm_inset_exec(bContext *C, wmOperator *op) } if (!EDBM_op_finish(em, &bmop, op, TRUE)) { - return OPERATOR_CANCELLED; + return 0; } else { EDBM_update_generic(C, em, TRUE); - return OPERATOR_FINISHED; + return 1; + } +} + +static int edbm_inset_exec(bContext *C, wmOperator *op) +{ + edbm_inset_init(C, op, FALSE); + + if (!edbm_inset_calc(C, op)) { + edbm_inset_exit(C, op); + return OPERATOR_CANCELLED; } + + edbm_inset_exit(C, op); + return OPERATOR_FINISHED; } +static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + InsetData *opdata; + float mlen[2]; + + edbm_inset_init(C, op, TRUE); + + opdata = op->customdata; + + calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter); + /* initialize mouse values */ + mlen[0] = opdata->mcenter[0] - event->mval[0]; + mlen[1] = opdata->mcenter[1] - event->mval[1]; + opdata->initial_length = len_v2(mlen); + + edbm_inset_calc(C, op); + + edbm_inset_update_header(op, C); + + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; +} + +static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) +{ + InsetData *opdata; + + opdata = op->customdata; + + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + + case MOUSEMOVE: + { + float mdiff[2]; + float amount; + + mdiff[0] = opdata->mcenter[0] - event->mval[0]; + mdiff[1] = opdata->mcenter[1] - event->mval[1]; + + if (opdata->modify_depth) { + amount = opdata->old_depth + (len_v2(mdiff) + - opdata->initial_length) / opdata->initial_length; + RNA_float_set(op->ptr, "depth", amount); + } + else { + amount = opdata->old_thickness - (len_v2(mdiff) + - opdata->initial_length) / opdata->initial_length; + amount = MAX2(amount, 0.0); + + RNA_float_set(op->ptr, "thickness", amount); + } + + if (edbm_inset_calc(C, op)) { + edbm_inset_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } + else { + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + + case LEFTMOUSE: + case PADENTER: + case RETKEY: + edbm_inset_calc(C, op); + edbm_inset_exit(C, op); + return OPERATOR_FINISHED; + + + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + { + float mlen[2]; + + mlen[0] = opdata->mcenter[0] - event->mval[0]; + mlen[1] = opdata->mcenter[1] - event->mval[1]; + + if (event->val == KM_PRESS) { + opdata->old_thickness = RNA_float_get(op->ptr, "thickness"); + opdata->modify_depth = TRUE; + } + else { + opdata->old_depth = RNA_float_get(op->ptr, "depth"); + opdata->modify_depth = FALSE; + } + opdata->initial_length = len_v2(mlen); + + edbm_inset_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } + + case OKEY: + if (event->val == KM_PRESS) { + int use_outset = RNA_boolean_get(op->ptr, "use_outset"); + RNA_boolean_set(op->ptr, "use_outset", !use_outset); + if (edbm_inset_calc(C, op)) { + edbm_inset_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } + else { + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + } + + return OPERATOR_RUNNING_MODAL; +} + + void MESH_OT_inset(wmOperatorType *ot) { PropertyRNA *prop; @@ -4481,7 +4916,10 @@ void MESH_OT_inset(wmOperatorType *ot) ot->description = "Inset new faces into selected faces"; /* api callbacks */ + ot->invoke = edbm_inset_invoke; + ot->modal = edbm_inset_modal; ot->exec = edbm_inset_exec; + ot->cancel = edbm_inset_cancel; ot->poll = ED_operator_editmesh; /* flags */ @@ -4578,9 +5016,9 @@ static int edbm_convex_hull_exec(bContext *C, wmOperator *op) BMOperator bmop; EDBM_op_init(em, &bmop, op, "convex_hull input=%hvef " - "use_existing_faces=%b", - BM_ELEM_SELECT, - RNA_boolean_get(op->ptr, "use_existing_faces")); + "use_existing_faces=%b", + BM_ELEM_SELECT, + RNA_boolean_get(op->ptr, "use_existing_faces")); BMO_op_exec(em->bm, &bmop); /* Hull fails if input is coplanar */ @@ -4647,20 +5085,20 @@ void MESH_OT_convex_hull(wmOperatorType *ot) /* props */ RNA_def_boolean(ot->srna, "delete_unused", TRUE, - "Delete Unused", - "Delete selected elements that are not used by the hull"); + "Delete Unused", + "Delete selected elements that are not used by the hull"); RNA_def_boolean(ot->srna, "use_existing_faces", TRUE, - "Use Existing Faces", - "Skip hull triangles that are covered by a pre-existing face"); + "Use Existing Faces", + "Skip hull triangles that are covered by a pre-existing face"); RNA_def_boolean(ot->srna, "make_holes", FALSE, - "Make Holes", - "Delete selected faces that are used by the hull"); + "Make Holes", + "Delete selected faces that are used by the hull"); RNA_def_boolean(ot->srna, "join_triangles", TRUE, - "Join Triangles", - "Merge adjacent triangles into quads"); + "Join Triangles", + "Merge adjacent triangles into quads"); join_triangle_props(ot); } diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 533ead1ff29..c3fbb2e8c16 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -58,6 +58,52 @@ #include "mesh_intern.h" +/* mesh backup implementation. This would greatly benefit from some sort of binary diffing + * just as the undo stack would. So leaving this as an interface for further work */ + +BMBackup EDBM_redo_state_store(BMEditMesh *em) +{ + BMBackup backup; + backup.bmcopy = BM_mesh_copy(em->bm); + return backup; +} + +void EDBM_redo_state_restore(BMBackup backup, BMEditMesh *em, int recalctess) +{ + BMesh *tmpbm; + if (!em || !backup.bmcopy) + return; + + BM_mesh_data_free(em->bm); + tmpbm = BM_mesh_copy(backup.bmcopy); + *em->bm = *tmpbm; + MEM_freeN(tmpbm); + tmpbm = NULL; + + if (recalctess) + BMEdit_RecalcTessellation(em); +} + +void EDBM_redo_state_free(BMBackup *backup, BMEditMesh *em, int recalctess) +{ + if (em && backup->bmcopy) { + BM_mesh_data_free(em->bm); + *em->bm = *backup->bmcopy; + } + else if (backup->bmcopy) { + BM_mesh_data_free(backup->bmcopy); + } + + if (backup->bmcopy) + MEM_freeN(backup->bmcopy); + backup->bmcopy = NULL; + + if (recalctess && em) + BMEdit_RecalcTessellation(em); +} + + + void EDBM_mesh_normals_update(BMEditMesh *em) { BM_mesh_normals_update(em->bm, TRUE); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 98dce10779f..a77a6f4b430 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -255,6 +255,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) keymap->poll = ED_operator_editmesh; WM_keymap_add_item(keymap, "MESH_OT_loopcut_slide", RKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MESH_OT_bevel", BKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "MESH_OT_inset", IKEY, KM_PRESS, 0, 0); /* selecting */ /* standard mouse selection goes via space_view3d */ diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 466338a736f..69aae5c4f06 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1067,8 +1067,8 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base, lb = object_duplilist(scene, base->object); if (use_hierarchy || use_base_parent) { - dupli_gh = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, "make_object_duplilist_real dupli_gh"); - parent_gh = BLI_ghash_new(BLI_ghashutil_pairhash, BLI_ghashutil_paircmp, "make_object_duplilist_real parent_gh"); + dupli_gh = BLI_ghash_ptr_new("make_object_duplilist_real dupli_gh"); + parent_gh = BLI_ghash_pair_new("make_object_duplilist_real parent_gh"); } for (dob = lb->first; dob; dob = dob->next) { diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index d73b53deecc..7cc11fa0209 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -356,8 +356,15 @@ static void test_constraints(Object *owner, bPoseChannel *pchan) bActionConstraint *data = curcon->data; /* validate action */ - if (data->act == NULL) + if (data->act == NULL) { + /* must have action */ curcon->flag |= CONSTRAINT_DISABLE; + } + else if (data->act->idroot != ID_OB) { + /* only object-rooted actions can be used */ + data->act = NULL; + curcon->flag |= CONSTRAINT_DISABLE; + } } else if (curcon->type == CONSTRAINT_TYPE_FOLLOWPATH) { bFollowPathConstraint *data = curcon->data; @@ -409,12 +416,12 @@ static void test_constraints(Object *owner, bPoseChannel *pchan) if (data->clip != NULL && data->track[0]) { MovieTracking *tracking = &data->clip->tracking; MovieTrackingObject *tracking_object; - + if (data->object[0]) tracking_object = BKE_tracking_named_object(tracking, data->object); else tracking_object = BKE_tracking_get_camera_object(tracking); - + if (!tracking_object) { curcon->flag |= CONSTRAINT_DISABLE; } @@ -428,14 +435,14 @@ static void test_constraints(Object *owner, bPoseChannel *pchan) } else if (curcon->type == CONSTRAINT_TYPE_CAMERASOLVER) { bCameraSolverConstraint *data = curcon->data; - - if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && data->clip == NULL) + + if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && (data->clip == NULL)) curcon->flag |= CONSTRAINT_DISABLE; } else if (curcon->type == CONSTRAINT_TYPE_OBJECTSOLVER) { bObjectSolverConstraint *data = curcon->data; - - if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && data->clip == NULL) + + if ((data->flag & CAMERASOLVER_ACTIVECLIP) == 0 && (data->clip == NULL)) curcon->flag |= CONSTRAINT_DISABLE; } diff --git a/source/blender/editors/object/object_select.c b/source/blender/editors/object/object_select.c index 86823be09a4..3a932b58fd9 100644 --- a/source/blender/editors/object/object_select.c +++ b/source/blender/editors/object/object_select.c @@ -79,8 +79,8 @@ /************************ Exported **************************/ /* simple API for object selection, rather than just using the flag -* this takes into account the 'restrict selection in 3d view' flag. -* deselect works always, the restriction just prevents selection */ + * this takes into account the 'restrict selection in 3d view' flag. + * deselect works always, the restriction just prevents selection */ /* Note: send a NC_SCENE|ND_OB_SELECT notifier yourself! (or * or a NC_SCENE|ND_OB_VISIBLE in case of visibility toggling */ diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 16f62f56505..2e21fe9cdfe 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -361,7 +361,7 @@ void OBJECT_OT_origin_clear(wmOperatorType *ot) /*************************** Apply Transformation ****************************/ /* use this when the loc/size/rot of the parent has changed but the children -* should stay in the same place, e.g. for apply-size-rot or object center */ + * should stay in the same place, e.g. for apply-size-rot or object center */ static void ignore_parent_tx(Main *bmain, Scene *scene, Object *ob) { Object workob; diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 48c35873304..08ccf37265b 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -127,7 +127,7 @@ void ED_render_engine_area_exit(ScrArea *sa) for (ar = sa->regionbase.first; ar; ar = ar->next) { RegionView3D *rv3d; - if (ar->regiontype != RGN_TYPE_WINDOW) + if (ar->regiontype != RGN_TYPE_WINDOW || !(ar->regiondata)) continue; rv3d = ar->regiondata; diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 52e1f90606f..0d5aceb9870 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2301,7 +2301,7 @@ static int area_join_modal(bContext *C, wmOperator *op, wmEvent *event) } else { /* we are back in the area previously selected for keeping - * we swap the areas if possible to allow user to choose */ + * we swap the areas if possible to allow user to choose */ if (jd->sa2 != NULL) { if (jd->sa1) jd->sa1->flag &= ~AREA_FLAG_DRAWJOINFROM; if (jd->sa2) jd->sa2->flag &= ~AREA_FLAG_DRAWJOINTO; diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index c681f8ddb75..ebc255f4e43 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -86,7 +86,7 @@ static int same_snap(Snapshot *snap, Brush *brush, ViewContext *vc) mtex->rot == snap->rot) && /* make brush smaller shouldn't cause a resample */ - ((mtex->brush_map_mode == MTEX_MAP_MODE_FIXED && + ((mtex->brush_map_mode == MTEX_MAP_MODE_VIEW && (BKE_brush_size_get(vc->scene, brush) <= snap->BKE_brush_size_get)) || (BKE_brush_size_get(vc->scene, brush) == snap->BKE_brush_size_get)) && @@ -154,7 +154,7 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc) make_snap(&snap, br, vc); - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) { int s = BKE_brush_size_get(vc->scene, br); int r = 1; @@ -239,7 +239,7 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc) avg += br->texture_sample_bias; - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) avg *= BKE_brush_curve_strength(br, len, 1); /* Falloff curve */ buffer[index] = 255 - (GLubyte)(255 * avg); @@ -278,7 +278,7 @@ static int load_tex(Sculpt *sd, Brush *br, ViewContext *vc) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); } @@ -376,7 +376,7 @@ static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush, /* check for overlay mode */ if (!(brush->flag & BRUSH_TEXTURE_OVERLAY) || - !(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_FIXED, MTEX_MAP_MODE_TILED))) + !(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED))) { return; } @@ -405,7 +405,7 @@ static void paint_draw_alpha_overlay(Sculpt *sd, Brush *brush, glPushMatrix(); glLoadIdentity(); - if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) { + if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) { /* brush rotation */ glTranslatef(0.5, 0.5, 0); glRotatef((double)RAD2DEGF((brush->flag & BRUSH_RAKE) ? diff --git a/source/blender/editors/sculpt_paint/paint_hide.c b/source/blender/editors/sculpt_paint/paint_hide.c index 87bc89f810c..cd8b9164862 100644 --- a/source/blender/editors/sculpt_paint/paint_hide.c +++ b/source/blender/editors/sculpt_paint/paint_hide.c @@ -90,7 +90,7 @@ static int is_effected(PartialVisArea area, if (area == PARTIALVIS_ALL) return 1; else if (area == PARTIALVIS_MASKED) { - return mask > 0.5; + return mask > 0.5f; } else { int inside = planes_contain_v3(planes, 4, co); diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index ead85486ec0..9effba5b433 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -114,24 +114,24 @@ (c)[0]= FTOCHAR((f)[0]); \ (c)[1]= FTOCHAR((f)[1]); \ (c)[2]= FTOCHAR((f)[2]); \ -} +} (void)0 #define IMAPAINT_FLOAT_RGBA_TO_CHAR(c, f) { \ (c)[0]= FTOCHAR((f)[0]); \ (c)[1]= FTOCHAR((f)[1]); \ (c)[2]= FTOCHAR((f)[2]); \ (c)[3]= FTOCHAR((f)[3]); \ -} +} (void)0 #define IMAPAINT_CHAR_RGB_TO_FLOAT(f, c) { \ (f)[0]= IMAPAINT_CHAR_TO_FLOAT((c)[0]); \ (f)[1]= IMAPAINT_CHAR_TO_FLOAT((c)[1]); \ (f)[2]= IMAPAINT_CHAR_TO_FLOAT((c)[2]); \ -} +} (void)0 #define IMAPAINT_CHAR_RGBA_TO_FLOAT(f, c) { \ (f)[0]= IMAPAINT_CHAR_TO_FLOAT((c)[0]); \ (f)[1]= IMAPAINT_CHAR_TO_FLOAT((c)[1]); \ (f)[2]= IMAPAINT_CHAR_TO_FLOAT((c)[2]); \ (f)[3]= IMAPAINT_CHAR_TO_FLOAT((c)[3]); \ -} +} (void)0 #define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b) @@ -1547,7 +1547,7 @@ static ProjPixel *project_paint_uvpixel_init( if (ibuf_other->rect_float) { /* float to char */ float rgba[4]; project_face_pixel(tf_other, ibuf_other, w, side, NULL, rgba); - IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba) + IMAPAINT_FLOAT_RGBA_TO_CHAR(((ProjPixelClone *)projPixel)->clonepx.ch, rgba); } else { /* char to char */ project_face_pixel(tf_other, ibuf_other, w, side, ((ProjPixelClone *)projPixel)->clonepx.ch, NULL); @@ -4206,7 +4206,7 @@ static void imapaint_ibuf_rgb_get(ImBuf *ibuf, int x, int y, const short is_toru } else { char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4; - IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb) + IMAPAINT_CHAR_RGB_TO_FLOAT(r_rgb, rrgb); } } static void imapaint_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_torus, const float rgb[3]) @@ -4224,7 +4224,7 @@ static void imapaint_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const short is_toru } else { char *rrgb = (char *)ibuf->rect + (ibuf->x * y + x) * 4; - IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb) + IMAPAINT_FLOAT_RGB_TO_CHAR(rrgb, rgb); } } @@ -4237,7 +4237,9 @@ static int imapaint_ibuf_add_if(ImBuf *ibuf, unsigned int x, unsigned int y, flo if (torus) imapaint_ibuf_rgb_get(ibuf, x, y, 1, inrgb); else return 0; } - else imapaint_ibuf_rgb_get(ibuf, x, y, 0, inrgb); + else { + imapaint_ibuf_rgb_get(ibuf, x, y, 0, inrgb); + } outrgb[0] += inrgb[0]; outrgb[1] += inrgb[1]; diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index f8ed20430e7..368729723eb 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -238,7 +238,7 @@ static Brush *brush_tool_toggle(Main *bmain, Brush *brush_orig, const int tool, if (!brush_orig || brush_tool(brush_orig, tool_offset) != tool) { Brush *br; /* if the current brush is not using the desired tool, look - for one that is */ + * for one that is */ br = brush_tool_cycle(bmain, brush_orig, tool, tool_offset, ob_mode); /* store the previously-selected brush */ if (br) @@ -250,8 +250,8 @@ static Brush *brush_tool_toggle(Main *bmain, Brush *brush_orig, const int tool, BLI_findindex(bmain->brush.first, brush_orig->toggle_brush) != -1) { /* if current brush is using the desired tool, try to toggle - back to the previously selected brush (if it was set, and - if it still exists) */ + * back to the previously selected brush (if it was set, and + * if it still exists) */ return brush_orig->toggle_brush; } else diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 3b74ae54810..d544183ced8 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -2079,7 +2079,7 @@ static char *wpaint_make_validmap(Object *ob) return NULL; } - gh = BLI_ghash_new(BLI_ghashutil_strhash, BLI_ghashutil_strcmp, "wpaint_make_validmap gh"); + gh = BLI_ghash_str_new("wpaint_make_validmap gh"); /* add all names to a hash table */ for (dg = ob->defbase.first; dg; dg = dg->next) { diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 02c0acfc367..7e766ea3388 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -247,7 +247,17 @@ typedef struct StrokeCache { int mirror_symmetry_pass; /* the symmetry pass we are currently on between 0 and 7*/ float true_view_normal[3]; float view_normal[3]; - float last_area_normal[3]; + + /* sculpt_normal gets calculated by calc_sculpt_normal(), then the + * sculpt_normal_symm gets updated quickly with the usual symmetry + * transforms */ + float sculpt_normal[3]; + float sculpt_normal_symm[3]; + + /* Used for wrap texture mode, local_mat gets calculated by + * calc_brush_local_mat() and used in tex_strength(). */ + float brush_local_mat[4][4]; + float last_center[3]; int radial_symmetry_pass; float symm_rot_mat[4][4]; @@ -537,7 +547,7 @@ static float integrate_overlap(Brush *br) } /* Uses symm to selectively flip any axis of a coordinate. */ -static void flip_coord(float out[3], float in[3], const char symm) +static void flip_v3_v3(float out[3], const float in[3], const char symm) { if (symm & SCULPT_SYMM_X) out[0] = -in[0]; @@ -553,13 +563,18 @@ static void flip_coord(float out[3], float in[3], const char symm) out[2] = in[2]; } +static void flip_v3(float v[3], const char symm) +{ + flip_v3_v3(v, v, symm); +} + static float calc_overlap(StrokeCache *cache, const char symm, const char axis, const float angle) { float mirror[3]; float distsq; - /* flip_coord(mirror, cache->traced_location, symm); */ - flip_coord(mirror, cache->true_location, symm); + /* flip_v3_v3(mirror, cache->traced_location, symm); */ + flip_v3_v3(mirror, cache->true_location, symm); if (axis != 0) { float mat[4][4] = MAT4_UNITY; @@ -745,15 +760,16 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3], * position in order to project it. This insures that the * brush texture will be oriented correctly. */ - flip_coord(symm_point, point, ss->cache->mirror_symmetry_pass); + flip_v3_v3(symm_point, point, ss->cache->mirror_symmetry_pass); if (ss->cache->radial_symmetry_pass) mul_m4_v3(ss->cache->symm_rot_mat_inv, symm_point); ED_view3d_project_float_v2(ss->cache->vc->ar, symm_point, point_2d, ss->cache->projection_mat); - /* if fixed mode, keep coordinates relative to mouse */ - if (mtex->brush_map_mode == MTEX_MAP_MODE_FIXED) { + if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { + /* keep coordinates relative to mouse */ + rotation += ss->cache->special_rotation; point_2d[0] -= ss->cache->tex_mouse[0]; @@ -765,8 +781,8 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3], x = point_2d[0] + ss->cache->vc->ar->winrct.xmin; y = point_2d[1] + ss->cache->vc->ar->winrct.ymin; } - else { /* else (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) */ - /* leave the coordinates relative to the screen */ + else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) { + /* leave the coordinates relative to the screen */ /* use unadjusted size for tiled mode */ radius = BKE_brush_size_get(ss->cache->vc->scene, br); @@ -774,17 +790,31 @@ static float tex_strength(SculptSession *ss, Brush *br, float point[3], x = point_2d[0]; y = point_2d[1]; } + else if (mtex->brush_map_mode == MTEX_MAP_MODE_AREA) { + /* Similar to fixed mode, but projects from brush angle + * rather than view direction */ + + /* Rotation is handled by the brush_local_mat */ + rotation = 0; - x /= ss->cache->vc->ar->winx; - y /= ss->cache->vc->ar->winy; + mul_m4_v3(ss->cache->brush_local_mat, symm_point); - if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) { - x -= 0.5f; - y -= 0.5f; + x = symm_point[0]; + y = symm_point[1]; } + + if (mtex->brush_map_mode != MTEX_MAP_MODE_AREA) { + x /= ss->cache->vc->ar->winx; + y /= ss->cache->vc->ar->winy; + + if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) { + x -= 0.5f; + y -= 0.5f; + } - x *= ss->cache->vc->ar->winx / radius; - y *= ss->cache->vc->ar->winy / radius; + x *= ss->cache->vc->ar->winx / radius; + y *= ss->cache->vc->ar->winy / radius; + } /* it is probably worth optimizing for those cases where * the texture is not rotated by skipping the calls to @@ -882,9 +912,13 @@ static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], floa static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; - int n; - float out_flip[3] = {0.0f, 0.0f, 0.0f}; + int n, original; + + /* Grab brush requires to test on original data (see r33888 and + * bug #25371) */ + original = (paint_brush(&sd->paint)->sculpt_tool == SCULPT_TOOL_GRAB ? + TRUE : ss->cache->original); (void)sd; /* unused w/o openmp */ @@ -901,7 +935,7 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod unode = sculpt_undo_push_node(ob, nodes[n], SCULPT_UNDO_COORDS); sculpt_brush_test_init(ss, &test); - if (ss->cache->original) { + if (original) { BLI_pbvh_vertex_iter_begin(ss->pbvh, nodes[n], vd, PBVH_ITER_UNIQUE) { if (sculpt_brush_test_fast(&test, unode->co[vd.i])) { @@ -944,56 +978,161 @@ static void calc_area_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nod normalize_v3(an); } -/* This initializes the faces to be moved for this sculpt for draw/layer/flatten; then it - * finds average normal for all active vertices - note that this is called once for each mirroring direction */ -static void calc_sculpt_normal(Sculpt *sd, Object *ob, float an[3], PBVHNode **nodes, int totnode) +/* Calculate primary direction of movement for many brushes */ +static void calc_sculpt_normal(Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode, + float an[3]) { - SculptSession *ss = ob->sculpt; - Brush *brush = paint_brush(&sd->paint); - - if (ss->cache->mirror_symmetry_pass == 0 && - ss->cache->radial_symmetry_pass == 0 && - (ss->cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) - { - switch (brush->sculpt_plane) { - case SCULPT_DISP_DIR_VIEW: - ED_view3d_global_to_vector(ss->cache->vc->rv3d, ss->cache->vc->rv3d->twmat[3], an); - break; + const Brush *brush = paint_brush(&sd->paint); + const SculptSession *ss = ob->sculpt; + + switch (brush->sculpt_plane) { + case SCULPT_DISP_DIR_VIEW: + ED_view3d_global_to_vector(ss->cache->vc->rv3d, + ss->cache->vc->rv3d->twmat[3], + an); + break; - case SCULPT_DISP_DIR_X: - an[1] = 0.0; - an[2] = 0.0; - an[0] = 1.0; - break; + case SCULPT_DISP_DIR_X: + an[1] = 0.0; + an[2] = 0.0; + an[0] = 1.0; + break; - case SCULPT_DISP_DIR_Y: - an[0] = 0.0; - an[2] = 0.0; - an[1] = 1.0; - break; + case SCULPT_DISP_DIR_Y: + an[0] = 0.0; + an[2] = 0.0; + an[1] = 1.0; + break; - case SCULPT_DISP_DIR_Z: - an[0] = 0.0; - an[1] = 0.0; - an[2] = 1.0; - break; + case SCULPT_DISP_DIR_Z: + an[0] = 0.0; + an[1] = 0.0; + an[2] = 1.0; + break; - case SCULPT_DISP_DIR_AREA: - calc_area_normal(sd, ob, an, nodes, totnode); + case SCULPT_DISP_DIR_AREA: + calc_area_normal(sd, ob, an, nodes, totnode); - default: - break; - } + default: + break; + } +} - copy_v3_v3(ss->cache->last_area_normal, an); +static void update_sculpt_normal(Sculpt *sd, Object *ob, + PBVHNode **nodes, int totnode) +{ + const Brush *brush = paint_brush(&sd->paint); + StrokeCache *cache = ob->sculpt->cache; + + if (cache->mirror_symmetry_pass == 0 && + cache->radial_symmetry_pass == 0 && + (cache->first_time || !(brush->flag & BRUSH_ORIGINAL_NORMAL))) + { + calc_sculpt_normal(sd, ob, nodes, totnode, cache->sculpt_normal); + copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal); } else { - copy_v3_v3(an, ss->cache->last_area_normal); - flip_coord(an, an, ss->cache->mirror_symmetry_pass); - mul_m4_v3(ss->cache->symm_rot_mat, an); + copy_v3_v3(cache->sculpt_normal_symm, cache->sculpt_normal); + flip_v3(cache->sculpt_normal_symm, cache->mirror_symmetry_pass); + mul_m4_v3(cache->symm_rot_mat, cache->sculpt_normal_symm); + } +} + +static void calc_local_y(ViewContext *vc, const float center[3], float y[3]) +{ + Object *ob = vc->obact; + float loc[3], mval_f[2] = {0.0f, 1.0f}; + + mul_v3_m4v3(loc, ob->imat, center); + initgrabz(vc->rv3d, loc[0], loc[1], loc[2]); + + ED_view3d_win_to_delta(vc->ar, mval_f, y); + normalize_v3(y); + + add_v3_v3(y, ob->loc); + mul_m4_v3(ob->imat, y); +} + +static void calc_brush_local_mat(const Brush *brush, Object *ob, + float local_mat[4][4]) +{ + const StrokeCache *cache = ob->sculpt->cache; + float tmat[4][4]; + float mat[4][4]; + float scale[4][4]; + float angle, v[3]; + float up[3]; + + /* Ensure ob->imat is up to date */ + invert_m4_m4(ob->imat, ob->obmat); + + /* Initialize last column of matrix */ + mat[0][3] = 0; + mat[1][3] = 0; + mat[2][3] = 0; + mat[3][3] = 1; + + /* Get view's up vector in object-space */ + calc_local_y(cache->vc, cache->location, up); + + /* Calculate the X axis of the local matrix */ + cross_v3_v3v3(v, up, cache->sculpt_normal); + /* Apply rotation (user angle, rake, etc.) to X axis */ + angle = brush->mtex.rot - cache->special_rotation; + rotate_v3_v3v3fl(mat[0], v, cache->sculpt_normal, angle); + + /* Get other axes */ + cross_v3_v3v3(mat[1], cache->sculpt_normal, mat[0]); + copy_v3_v3(mat[2], cache->sculpt_normal); + + /* Set location */ + copy_v3_v3(mat[3], cache->location); + + /* Scale by brush radius */ + normalize_m4(mat); + scale_m4_fl(scale, cache->radius); + mult_m4_m4m4(tmat, mat, scale); + + /* Return inverse (for converting from modelspace coords to local + * area coords) */ + invert_m4_m4(local_mat, tmat); +} + +static void update_brush_local_mat(Sculpt *sd, Object *ob) +{ + StrokeCache *cache = ob->sculpt->cache; + + if (cache->mirror_symmetry_pass == 0 && + cache->radial_symmetry_pass == 0) + { + calc_brush_local_mat(paint_brush(&sd->paint), ob, + cache->brush_local_mat); } } +/* Test whether the StrokeCache.sculpt_normal needs update in + * do_brush_action() */ +static int brush_needs_sculpt_normal(const Brush *brush) +{ + return ((ELEM(brush->sculpt_tool, + SCULPT_TOOL_GRAB, + SCULPT_TOOL_SNAKE_HOOK) && + ((brush->normal_weight > 0) || + (brush->flag & BRUSH_FRONTFACE))) || + + ELEM7(brush->sculpt_tool, + SCULPT_TOOL_BLOB, + SCULPT_TOOL_CREASE, + SCULPT_TOOL_DRAW, + SCULPT_TOOL_LAYER, + SCULPT_TOOL_NUDGE, + SCULPT_TOOL_ROTATE, + SCULPT_TOOL_THUMB) || + + (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA)); +} + /* For the smooth brush, uses the neighboring vertices around vert to calculate * a smoothed location for vert. Skips corner vertices (used by only one * polygon.) */ @@ -1037,8 +1176,8 @@ static void neighbor_average(SculptSession *ss, float avg[3], unsigned vert) } /* Similar to neighbor_average(), but returns an averaged mask value - instead of coordinate. Also does not restrict based on border or - corner vertices. */ + * instead of coordinate. Also does not restrict based on border or + * corner vertices. */ static float neighbor_average_mask(SculptSession *ss, unsigned vert) { const float *vmask = ss->vmask; @@ -1356,14 +1495,12 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { SculptSession *ss = ob->sculpt; Brush *brush = paint_brush(&sd->paint); - float offset[3], area_normal[3]; + float offset[3]; float bstrength = ss->cache->bstrength; int n; - calc_sculpt_normal(sd, ob, area_normal, nodes, totnode); - /* offset with as much as possible factored in already */ - mul_v3_v3fl(offset, area_normal, ss->cache->radius); + mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius); mul_v3_v3(offset, ss->cache->scale); mul_v3_fl(offset, bstrength); @@ -1383,7 +1520,8 @@ static void do_draw_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) if (sculpt_brush_test(&test, vd.co)) { /* offset vertex */ float fade = tex_strength(ss, brush, vd.co, test.dist, - area_normal, vd.no, vd.fno, *vd.mask); + ss->cache->sculpt_normal_symm, vd.no, + vd.fno, *vd.mask); mul_v3_v3fl(proxy[vd.i], offset, fade); @@ -1400,16 +1538,14 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod SculptSession *ss = ob->sculpt; const Scene *scene = ss->cache->vc->scene; Brush *brush = paint_brush(&sd->paint); - float offset[3], area_normal[3]; + float offset[3]; float bstrength = ss->cache->bstrength; float flippedbstrength, crease_correction; float brush_alpha; int n; - calc_sculpt_normal(sd, ob, area_normal, nodes, totnode); - /* offset with as much as possible factored in already */ - mul_v3_v3fl(offset, area_normal, ss->cache->radius); + mul_v3_v3fl(offset, ss->cache->sculpt_normal_symm, ss->cache->radius); mul_v3_v3(offset, ss->cache->scale); mul_v3_fl(offset, bstrength); @@ -1440,7 +1576,8 @@ static void do_crease_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod if (sculpt_brush_test(&test, vd.co)) { /* offset vertex */ const float fade = tex_strength(ss, brush, vd.co, test.dist, - area_normal, vd.no, vd.fno, *vd.mask); + ss->cache->sculpt_normal_symm, + vd.no, vd.fno, *vd.mask); float val1[3]; float val2[3]; @@ -1502,26 +1639,18 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) SculptSession *ss = ob->sculpt; Brush *brush = paint_brush(&sd->paint); float bstrength = ss->cache->bstrength; - float grab_delta[3], an[3]; + float grab_delta[3]; int n; float len; - if (brush->normal_weight > 0 || brush->flag & BRUSH_FRONTFACE) { - int cache = 1; - /* grab brush requires to test on original data */ - SWAP(int, ss->cache->original, cache); - calc_sculpt_normal(sd, ob, an, nodes, totnode); - SWAP(int, ss->cache->original, cache); - } - copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); len = len_v3(grab_delta); if (brush->normal_weight > 0) { - mul_v3_fl(an, len * brush->normal_weight); + mul_v3_fl(ss->cache->sculpt_normal_symm, len * brush->normal_weight); mul_v3_fl(grab_delta, 1.0f - brush->normal_weight); - add_v3_v3(grab_delta, an); + add_v3_v3(grab_delta, ss->cache->sculpt_normal_symm); } #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) @@ -1545,7 +1674,7 @@ static void do_grab_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode) { if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist, - an, origno[vd.i], NULL, *vd.mask); + ss->cache->sculpt_normal_symm, origno[vd.i], NULL, *vd.mask); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1563,16 +1692,13 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode Brush *brush = paint_brush(&sd->paint); float bstrength = ss->cache->bstrength; float grab_delta[3]; - int n; - float an[3]; float tmp[3], cono[3]; + int n; copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); - calc_sculpt_normal(sd, ob, an, nodes, totnode); - - cross_v3_v3v3(tmp, an, grab_delta); - cross_v3_v3v3(cono, tmp, an); + cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta); + cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm); #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) for (n = 0; n < totnode; n++) { @@ -1588,7 +1714,8 @@ static void do_nudge_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode { if (sculpt_brush_test(&test, vd.co)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, - an, vd.no, vd.fno, *vd.mask); + ss->cache->sculpt_normal_symm, + vd.no, vd.fno, *vd.mask); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1605,13 +1732,10 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to SculptSession *ss = ob->sculpt; Brush *brush = paint_brush(&sd->paint); float bstrength = ss->cache->bstrength; - float grab_delta[3], an[3]; + float grab_delta[3]; int n; float len; - if (brush->normal_weight > 0 || brush->flag & BRUSH_FRONTFACE) - calc_sculpt_normal(sd, ob, an, nodes, totnode); - copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); len = len_v3(grab_delta); @@ -1620,9 +1744,9 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to negate_v3(grab_delta); if (brush->normal_weight > 0) { - mul_v3_fl(an, len * brush->normal_weight); + mul_v3_fl(ss->cache->sculpt_normal_symm, len * brush->normal_weight); mul_v3_fl(grab_delta, 1.0f - brush->normal_weight); - add_v3_v3(grab_delta, an); + add_v3_v3(grab_delta, ss->cache->sculpt_normal_symm); } #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) @@ -1639,7 +1763,8 @@ static void do_snake_hook_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int to { if (sculpt_brush_test(&test, vd.co)) { const float fade = bstrength * tex_strength(ss, brush, vd.co, test.dist, - an, vd.no, vd.fno, *vd.mask); + ss->cache->sculpt_normal_symm, + vd.no, vd.fno, *vd.mask); mul_v3_v3fl(proxy[vd.i], grab_delta, fade); @@ -1657,16 +1782,13 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode Brush *brush = paint_brush(&sd->paint); float bstrength = ss->cache->bstrength; float grab_delta[3]; - int n; - float an[3]; float tmp[3], cono[3]; + int n; copy_v3_v3(grab_delta, ss->cache->grab_delta_symmetry); - calc_sculpt_normal(sd, ob, an, nodes, totnode); - - cross_v3_v3v3(tmp, an, grab_delta); - cross_v3_v3v3(cono, tmp, an); + cross_v3_v3v3(tmp, ss->cache->sculpt_normal_symm, grab_delta); + cross_v3_v3v3(cono, tmp, ss->cache->sculpt_normal_symm); #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) for (n = 0; n < totnode; n++) { @@ -1689,7 +1811,8 @@ static void do_thumb_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode { if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist, - an, origno[vd.i], NULL, *vd.mask); + ss->cache->sculpt_normal_symm, + origno[vd.i], NULL, *vd.mask); mul_v3_v3fl(proxy[vd.i], cono, fade); @@ -1706,20 +1829,17 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod SculptSession *ss = ob->sculpt; Brush *brush = paint_brush(&sd->paint); float bstrength = ss->cache->bstrength; - float an[3]; int n; float m[4][4], rot[4][4], lmat[4][4], ilmat[4][4]; static const int flip[8] = { 1, -1, -1, 1, -1, 1, 1, -1 }; float angle = ss->cache->vertex_rotation * flip[ss->cache->mirror_symmetry_pass]; - calc_sculpt_normal(sd, ob, an, nodes, totnode); - unit_m4(m); unit_m4(lmat); copy_v3_v3(lmat[3], ss->cache->location); invert_m4_m4(ilmat, lmat); - axis_angle_to_mat4(rot, an, angle); + axis_angle_to_mat4(rot, ss->cache->sculpt_normal_symm, angle); mul_serie_m4(m, lmat, rot, ilmat, NULL, NULL, NULL, NULL, NULL); @@ -1744,7 +1864,8 @@ static void do_rotate_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnod { if (sculpt_brush_test(&test, origco[vd.i])) { const float fade = bstrength * tex_strength(ss, brush, origco[vd.i], test.dist, - an, origno[vd.i], NULL, *vd.mask); + ss->cache->sculpt_normal_symm, + origno[vd.i], NULL, *vd.mask); mul_v3_m4v3(proxy[vd.i], m, origco[vd.i]); sub_v3_v3(proxy[vd.i], origco[vd.i]); @@ -1770,8 +1891,6 @@ static void do_layer_brush(Sculpt *sd, Object *ob, PBVHNode **nodes, int totnode if (bstrength < 0) lim = -lim; - calc_sculpt_normal(sd, ob, area_normal, nodes, totnode); - mul_v3_v3v3(offset, ss->cache->scale, area_normal); #pragma omp parallel for schedule(guided) if (sd->flags & SCULPT_USE_OPENMP) @@ -2069,23 +2188,23 @@ static void calc_sculpt_plane(Sculpt *sd, Object *ob, PBVHNode **nodes, int totn calc_flatten_center(sd, ob, nodes, totnode, fc); /* for area normal */ - copy_v3_v3(ss->cache->last_area_normal, an); + copy_v3_v3(ss->cache->sculpt_normal, an); /* for flatten center */ copy_v3_v3(ss->cache->last_center, fc); } else { /* for area normal */ - copy_v3_v3(an, ss->cache->last_area_normal); + copy_v3_v3(an, ss->cache->sculpt_normal); /* for flatten center */ copy_v3_v3(fc, ss->cache->last_center); /* for area normal */ - flip_coord(an, an, ss->cache->mirror_symmetry_pass); + flip_v3(an, ss->cache->mirror_symmetry_pass); /* for flatten center */ - flip_coord(fc, fc, ss->cache->mirror_symmetry_pass); + flip_v3(fc, ss->cache->mirror_symmetry_pass); /* for area normal */ mul_m4_v3(ss->cache->symm_rot_mat, an); @@ -2591,6 +2710,12 @@ static void do_brush_action(Sculpt *sd, Object *ob, Brush *brush) BLI_pbvh_node_mark_update(nodes[n]); } + if (brush_needs_sculpt_normal(brush)) + update_sculpt_normal(sd, ob, nodes, totnode); + + if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_AREA) + update_brush_local_mat(sd, ob); + /* Apply one type of brush action */ switch (brush->sculpt_tool) { case SCULPT_TOOL_DRAW: @@ -2816,9 +2941,9 @@ static void calc_brushdata_symm(Sculpt *sd, StrokeCache *cache, const char symm, { (void)sd; /* unused */ - flip_coord(cache->location, cache->true_location, symm); - flip_coord(cache->grab_delta_symmetry, cache->grab_delta, symm); - flip_coord(cache->view_normal, cache->true_view_normal, symm); + flip_v3_v3(cache->location, cache->true_location, symm); + flip_v3_v3(cache->grab_delta_symmetry, cache->grab_delta, symm); + flip_v3_v3(cache->view_normal, cache->true_view_normal, symm); /* XXX This reduces the length of the grab delta if it approaches the line of symmetry * XXX However, a different approach appears to be needed */ @@ -3364,7 +3489,7 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, { copy_v2_v2(cache->tex_mouse, cache->mouse); - if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_FIXED) && + if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) && (brush->flag & BRUSH_RANDOM_ROTATION) && !(brush->flag & BRUSH_RAKE)) { @@ -3909,7 +4034,7 @@ void ED_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd) paint_mask = CustomData_get_layer(&me->vdata, CD_PAINT_MASK); /* if multires is active, create a grid paint mask layer if there - isn't one already */ + * isn't one already */ if (mmd && !CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) { GridPaintMask *gmask; int level = MAX2(1, mmd->sculptlvl); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index ed9265deeb2..a477a7435fd 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -142,7 +142,7 @@ void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *c if (sc->clip && sc->clip->id.us == 0) sc->clip->id.us = 1; - if (screen) { + if (screen && sc->view == SC_VIEW_CLIP) { ScrArea *area; SpaceLink *sl; @@ -151,7 +151,7 @@ void ED_space_clip_set(bContext *C, bScreen *screen, SpaceClip *sc, MovieClip *c if (sl->spacetype == SPACE_CLIP) { SpaceClip *cur_sc = (SpaceClip *) sl; - if (cur_sc != sc) { + if (cur_sc != sc && cur_sc->view != SC_VIEW_CLIP) { if (cur_sc->clip == old_clip || cur_sc->clip == NULL) { cur_sc->clip = clip; } diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index f340c53f528..3ff9c3c0520 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -1099,7 +1099,11 @@ static void file_expand_directory(bContext *C) SpaceFile *sfile= CTX_wm_space_file(C); if (sfile->params) { - if ( sfile->params->dir[0] == '~' ) { + /* TODO, what about // when relbase isn't valid? */ + if (G.relbase_valid && strncmp(sfile->params->dir, "//", 2) == 0) { + BLI_path_abs(sfile->params->dir, G.main->name); + } + else if (sfile->params->dir[0] == '~') { char tmpstr[sizeof(sfile->params->dir)-1]; BLI_strncpy(tmpstr, sfile->params->dir+1, sizeof(tmpstr)); BLI_join_dirfile(sfile->params->dir, sizeof(sfile->params->dir), BLI_getDefaultDocumentFolder(), tmpstr); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 58fbceb999d..e2ab5ea64e4 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -2210,7 +2210,7 @@ static int image_record_composite_apply(bContext *C, wmOperator *op) BKE_image_all_free_anim_ibufs(scene->r.cfra); ntreeCompositTagAnimated(scene->nodetree); - ntreeCompositExecTree(scene->nodetree, &scene->r, scene->r.cfra != rcd->old_cfra); /* 1 is no previews */ + ntreeCompositExecTree(scene->nodetree, &scene->r, 0, scene->r.cfra != rcd->old_cfra); /* 1 is no previews */ ED_area_tag_redraw(CTX_wm_area(C)); diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 205202a0658..d9fc793adb3 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -1967,6 +1967,256 @@ static void node_composit_buts_moviedistortion(uiLayout *layout, bContext *C, Po uiItemR(layout, ptr, "distortion_type", 0, "", 0); } +static void node_composit_buts_colorcorrection(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *row; + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "red", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "green", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE); + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "midtones_start", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_end", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "master_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + row = uiLayoutRow(layout, 0); + uiItemL(row, "Saturation", 0); + uiItemL(row, "Contrast", 0); + uiItemL(row, "Gamma", 0); + uiItemL(row, "Gain", 0); + uiItemL(row, "Lift", 0); + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); +} +static void node_composit_buts_colorcorrection_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) { + uiLayout *row; + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "red", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "green", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "blue", 0, NULL, ICON_NONE); + row = layout; + uiItemL(row, "Saturation", 0); + uiItemR(row, ptr, "master_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_saturation", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + uiItemL(row, "Contrast", 0); + uiItemR(row, ptr, "master_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_contrast", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + uiItemL(row, "Gamma", 0); + uiItemR(row, ptr, "master_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_gamma", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + uiItemL(row, "Gain", 0); + uiItemR(row, ptr, "master_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_gain", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + uiItemL(row, "Lift", 0); + uiItemR(row, ptr, "master_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "highlights_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "shadows_lift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + row = uiLayoutRow(layout, 0); + uiItemR(row, ptr, "midtones_start", 0, NULL, ICON_NONE); + uiItemR(row, ptr, "midtones_end", 0, NULL, ICON_NONE); +} + +static void node_composit_buts_switch(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "check", 0, NULL, ICON_NONE); +} + +static void node_composit_buts_boxmask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *row; + + row= uiLayoutRow(layout, 1); + uiItemR(row, ptr, "x", 0, "X", ICON_NONE); + uiItemR(row, ptr, "y", 0, "Y", ICON_NONE); + + row= uiLayoutRow(layout, 1); + uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + uiItemR(layout, ptr, "rotation", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "mask_type", 0, NULL, ICON_NONE); +} + +static void node_composit_buts_bokehimage(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiItemR(layout, ptr, "flaps", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "angle", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "rounding", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(layout, ptr, "catadioptric", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(layout, ptr, "shift", UI_ITEM_R_SLIDER, NULL, ICON_NONE); +} + +void node_composit_backdrop_viewer(SpaceNode* snode, ImBuf* backdrop, bNode* node, int x, int y) +{ +// node_composit_backdrop_canvas(snode, backdrop, node, x, y); + if (node->custom1 == 0) { /// @todo: why did we need this one? + const float backdropWidth = backdrop->x; + const float backdropHeight = backdrop->y; + const float cx = x+snode->zoom*backdropWidth*node->custom3; + const float cy = y+snode->zoom*backdropHeight*node->custom4; + + glColor3f(1.0, 1.0, 1.0); + + glBegin(GL_LINES); + glVertex2f(cx-25, cy-25); + glVertex2f(cx+25, cy+25); + glVertex2f(cx+25, cy-25); + glVertex2f(cx-25, cy+25); + glEnd(); + } +} + +void node_composit_backdrop_boxmask(SpaceNode* snode, ImBuf* backdrop, bNode* node, int x, int y) +{ + NodeBoxMask * boxmask = node->storage; + const float backdropWidth = backdrop->x; + const float backdropHeight = backdrop->y; + const float aspect = backdropWidth/backdropHeight; + const float rad = DEG2RAD(-boxmask->rotation); + const float cosine = cos(rad); + const float sine = sin(rad); + const float halveBoxWidth = backdropWidth*(boxmask->width/2.0f); + const float halveBoxHeight = backdropHeight*(boxmask->height/2.0f)*aspect; + + float cx, cy, x1, x2, x3, x4; + float y1, y2, y3, y4; + + + /* keep this, saves us from a version patch */ + if(snode->zoom==0.0f) snode->zoom= 1.0f; + + glColor3f(1.0, 1.0, 1.0); + + cx = x+snode->zoom*backdropWidth*boxmask->x; + cy = y+snode->zoom*backdropHeight*boxmask->y; + + x1 = cx - (cosine*halveBoxWidth+sine*halveBoxHeight)*snode->zoom; + x2 = cx - (cosine*-halveBoxWidth+sine*halveBoxHeight)*snode->zoom; + x3 = cx - (cosine*-halveBoxWidth+sine*-halveBoxHeight)*snode->zoom; + x4 = cx - (cosine*halveBoxWidth+sine*-halveBoxHeight)*snode->zoom; + y1 = cy - (-sine*halveBoxWidth + cosine*halveBoxHeight)*snode->zoom; + y2 = cy - (-sine*-halveBoxWidth + cosine*halveBoxHeight)*snode->zoom; + y3 = cy - (-sine*-halveBoxWidth + cosine*-halveBoxHeight)*snode->zoom; + y4 = cy - (-sine*halveBoxWidth + cosine*-halveBoxHeight)*snode->zoom; + + glBegin(GL_LINE_LOOP); + glVertex2f(x1, y1); + glVertex2f(x2, y2); + glVertex2f(x3, y3); + glVertex2f(x4, y4); + glEnd(); +} + +void node_composit_backdrop_ellipsemask(SpaceNode* snode, ImBuf* backdrop, bNode* node, int x, int y) +{ + NodeEllipseMask * ellipsemask = node->storage; + const float backdropWidth = backdrop->x; + const float backdropHeight = backdrop->y; + const float aspect = backdropWidth/backdropHeight; + const float rad = DEG2RAD(-ellipsemask->rotation); + const float cosine = cos(rad); + const float sine = sin(rad); + const float halveBoxWidth = backdropWidth*(ellipsemask->width/2.0f); + const float halveBoxHeight = backdropHeight*(ellipsemask->height/2.0f)*aspect; + + float cx, cy, x1, x2, x3, x4; + float y1, y2, y3, y4; + + + /* keep this, saves us from a version patch */ + if(snode->zoom==0.0f) snode->zoom= 1.0f; + + glColor3f(1.0, 1.0, 1.0); + + cx = x+snode->zoom*backdropWidth*ellipsemask->x; + cy = y+snode->zoom*backdropHeight*ellipsemask->y; + + x1 = cx - (cosine*halveBoxWidth+sine*halveBoxHeight)*snode->zoom; + x2 = cx - (cosine*-halveBoxWidth+sine*halveBoxHeight)*snode->zoom; + x3 = cx - (cosine*-halveBoxWidth+sine*-halveBoxHeight)*snode->zoom; + x4 = cx - (cosine*halveBoxWidth+sine*-halveBoxHeight)*snode->zoom; + y1 = cy - (-sine*halveBoxWidth + cosine*halveBoxHeight)*snode->zoom; + y2 = cy - (-sine*-halveBoxWidth + cosine*halveBoxHeight)*snode->zoom; + y3 = cy - (-sine*-halveBoxWidth + cosine*-halveBoxHeight)*snode->zoom; + y4 = cy - (-sine*halveBoxWidth + cosine*-halveBoxHeight)*snode->zoom; + + glBegin(GL_LINE_LOOP); + + glVertex2f(x1, y1); + glVertex2f(x2, y2); + glVertex2f(x3, y3); + glVertex2f(x4, y4); + glEnd(); +} + +static void node_composit_buts_ellipsemask(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *row; + row= uiLayoutRow(layout, 1); + uiItemR(row, ptr, "x", 0, "X", ICON_NONE); + uiItemR(row, ptr, "y", 0, "Y", ICON_NONE); + row= uiLayoutRow(layout, 1); + uiItemR(row, ptr, "width", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + uiItemR(row, ptr, "height", UI_ITEM_R_SLIDER, NULL, ICON_NONE); + + uiItemR(layout, ptr, "rotation", 0, NULL, ICON_NONE); + uiItemR(layout, ptr, "mask_type", 0, NULL, ICON_NONE); +} + +static void node_composit_buts_viewer_but(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr) +{ + uiLayout *col; + + uiItemR(layout, ptr, "tile_order", 0, NULL, ICON_NONE); + if (RNA_enum_get(ptr, "tile_order")==0) { + col= uiLayoutColumn(layout, 1); + uiItemR(col, ptr, "center_x", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "center_y", 0, NULL, ICON_NONE); + } +} + /* only once called */ static void node_composit_set_butfunc(bNodeType *ntype) { @@ -2134,6 +2384,30 @@ static void node_composit_set_butfunc(bNodeType *ntype) case CMP_NODE_MOVIEDISTORTION: ntype->uifunc= node_composit_buts_moviedistortion; break; + case CMP_NODE_COLORCORRECTION: + ntype->uifunc=node_composit_buts_colorcorrection; + ntype->uifuncbut=node_composit_buts_colorcorrection_but; + break; + case CMP_NODE_SWITCH: + ntype->uifunc= node_composit_buts_switch; + break; + case CMP_NODE_MASK_BOX: + ntype->uifunc= node_composit_buts_boxmask; + ntype->uibackdropfunc = node_composit_backdrop_boxmask; + break; + case CMP_NODE_MASK_ELLIPSE: + ntype->uifunc= node_composit_buts_ellipsemask; + ntype->uibackdropfunc = node_composit_backdrop_ellipsemask; + break; + case CMP_NODE_BOKEHIMAGE: + ntype->uifunc= node_composit_buts_bokehimage; + break; + case CMP_NODE_VIEWER: + ntype->uifunc = NULL; + ntype->uifuncbut= node_composit_buts_viewer_but; + ntype->uibackdropfunc = node_composit_backdrop_viewer; + break; + default: ntype->uifunc= NULL; } @@ -2432,6 +2706,19 @@ void draw_nodespace_back_pix(ARegion *ar, SpaceNode *snode, int color_manage) glPixelZoom(1.0f, 1.0f); } } + + /// @note draw selected info on backdrop + if (snode->edittree) { + bNode *node = snode->edittree->nodes.first; + while (node) { + if (node->flag & NODE_SELECT) { + if (node->typeinfo->uibackdropfunc) { + node->typeinfo->uibackdropfunc(snode, ibuf, node, x, y); + } + } + node = node->next; + } + } glMatrixMode(GL_PROJECTION); glPopMatrix(); diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c index 3a920e16f8a..d93b1b1fcc8 100644 --- a/source/blender/editors/space_node/node_draw.c +++ b/source/blender/editors/space_node/node_draw.c @@ -914,6 +914,7 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) Scene *scene= CTX_data_scene(C); int color_manage = scene->r.color_mgt_flag & R_COLOR_MANAGEMENT; bNodeLinkDrag *nldrag; + LinkData *linkdata; UI_ThemeClearColor(TH_BACK); glClear(GL_COLOR_BUFFER_BIT); @@ -965,8 +966,10 @@ void drawnodespace(const bContext *C, ARegion *ar, View2D *v2d) /* temporary links */ glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); - for (nldrag= snode->linkdrag.first; nldrag; nldrag= nldrag->next) - node_draw_link(&ar->v2d, snode, nldrag->link); + for (nldrag= snode->linkdrag.first; nldrag; nldrag= nldrag->next) { + for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) + node_draw_link(&ar->v2d, snode, (bNodeLink *)linkdata->data); + } glDisable(GL_LINE_SMOOTH); glDisable(GL_BLEND); diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index ae6c09b0339..f71ce3f960c 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -185,8 +185,8 @@ static void compo_startjob(void *cjv, short *stop, short *do_update, float *prog // XXX BIF_store_spare(); - ntreeCompositExecTree(ntree, &cj->scene->r, 1); /* 1 is do_previews */ - + ntreeCompositExecTree(ntree, &cj->scene->r, 0, 1); /* 1 is do_previews */ + ntree->test_break= NULL; ntree->stats_draw= NULL; ntree->progress= NULL; @@ -405,6 +405,10 @@ void ED_node_composit_default(Scene *sce) } sce->nodetree= ntreeAddTree("Compositing Nodetree", NTREE_COMPOSIT, 0); + + sce->nodetree->chunksize = 256; + sce->nodetree->edit_quality = NTREE_QUALITY_HIGH; + sce->nodetree->render_quality = NTREE_QUALITY_HIGH; ntemp.type = CMP_NODE_COMPOSITE; out= nodeAddNode(sce->nodetree, &ntemp); @@ -2324,15 +2328,13 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) SpaceNode *snode= CTX_wm_space_node(C); ARegion *ar= CTX_wm_region(C); bNodeLinkDrag *nldrag= op->customdata; - bNode *tnode, *node; - bNodeSocket *tsock= NULL, *sock; + bNode *tnode; + bNodeSocket *tsock= NULL; bNodeLink *link; + LinkData *linkdata; int in_out; - in_out= nldrag->in_out; - node= nldrag->node; - sock= nldrag->sock; - link= nldrag->link; + in_out = nldrag->in_out; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->mx, &snode->my); @@ -2342,57 +2344,86 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) if (in_out==SOCK_OUT) { if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_IN)) { - if (nodeFindLink(snode->edittree, sock, tsock)==NULL) { - if ( link->tosock!= tsock && (!tnode || (tnode!=node && link->tonode!=tnode)) ) { - link->tonode= tnode; - link->tosock= tsock; - if (link->prev==NULL && link->next==NULL) { - BLI_addtail(&snode->edittree->links, link); - } - - snode->edittree->update |= NTREE_UPDATE_LINKS; - ntreeUpdateTree(snode->edittree); - } + for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) { + link = linkdata->data; + + /* skip if this is already the target socket */ + if (link->tosock == tsock) + continue; + /* skip if socket is on the same node as the fromsock */ + if (tnode && link->fromnode == tnode) + continue; + + /* attach links to the socket */ + link->tonode = tnode; + link->tosock = tsock; + /* add it to the node tree temporarily */ + if (link->prev==NULL && link->next==NULL) + BLI_addtail(&snode->edittree->links, link); + + snode->edittree->update |= NTREE_UPDATE_LINKS; } + ntreeUpdateTree(snode->edittree); } else { - if (link->tonode || link->tosock) { - BLI_remlink(&snode->edittree->links, link); - link->prev = link->next = NULL; - link->tonode= NULL; - link->tosock= NULL; + int do_update = 0; + for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) { + link = linkdata->data; - snode->edittree->update |= NTREE_UPDATE_LINKS; - ntreeUpdateTree(snode->edittree); + if (link->tonode || link->tosock) { + BLI_remlink(&snode->edittree->links, link); + link->prev = link->next = NULL; + link->tonode= NULL; + link->tosock= NULL; + + snode->edittree->update |= NTREE_UPDATE_LINKS; + do_update = 1; + } } + if (do_update) + ntreeUpdateTree(snode->edittree); } } else { if (node_find_indicated_socket(snode, &tnode, &tsock, SOCK_OUT)) { - if (nodeFindLink(snode->edittree, sock, tsock)==NULL) { - if (nodeCountSocketLinks(snode->edittree, tsock) < tsock->limit) { - if ( link->fromsock!= tsock && (!tnode || (tnode!=node && link->fromnode!=tnode)) ) { - link->fromnode= tnode; - link->fromsock= tsock; - if (link->prev==NULL && link->next==NULL) { - BLI_addtail(&snode->edittree->links, link); - } - - snode->edittree->update |= NTREE_UPDATE_LINKS; - ntreeUpdateTree(snode->edittree); - } - } + for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) { + link = linkdata->data; + + /* skip if this is already the target socket */ + if (link->fromsock == tsock) + continue; + /* skip if socket is on the same node as the fromsock */ + if (tnode && link->tonode == tnode) + continue; + + /* attach links to the socket */ + link->fromnode = tnode; + link->fromsock = tsock; + /* add it to the node tree temporarily */ + if (link->prev==NULL && link->next==NULL) + BLI_addtail(&snode->edittree->links, link); + + snode->edittree->update |= NTREE_UPDATE_LINKS; } + ntreeUpdateTree(snode->edittree); } else { - if (link->tonode || link->tosock) { - BLI_remlink(&snode->edittree->links, link); - link->prev = link->next = NULL; - link->fromnode= NULL; - link->fromsock= NULL; - snode->edittree->update |= NTREE_UPDATE_LINKS; - ntreeUpdateTree(snode->edittree); + int do_update = 0; + for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) { + link = linkdata->data; + + if (link->fromnode || link->fromsock) { + BLI_remlink(&snode->edittree->links, link); + link->prev = link->next = NULL; + link->fromnode= NULL; + link->fromsock= NULL; + + snode->edittree->update |= NTREE_UPDATE_LINKS; + do_update = 1; + } } + if (do_update) + ntreeUpdateTree(snode->edittree); } } @@ -2401,139 +2432,161 @@ static int node_link_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case RIGHTMOUSE: - case MIDDLEMOUSE: - if (link->tosock && link->fromsock) { - /* send changed events for original tonode and new */ - snode_update(snode, link->tonode); + case MIDDLEMOUSE: { + for (linkdata=nldrag->links.first; linkdata; linkdata=linkdata->next) { + link = linkdata->data; - /* we might need to remove a link */ - if (in_out==SOCK_OUT) - node_remove_extra_links(snode, link->tosock, link); - - /* when linking to group outputs, update the socket type */ - /* XXX this should all be part of a generic update system */ - if (!link->tonode) { - if(link->tosock->type != link->fromsock->type) - nodeSocketSetType(link->tosock, link->fromsock->type); - } - } - else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) { - /* automatically add new group socket */ - if (link->tonode && link->tosock) { - link->fromsock = node_group_expose_socket(snode->edittree, link->tosock, SOCK_IN); - link->fromnode = NULL; - if (link->prev==NULL && link->next==NULL) { - BLI_addtail(&snode->edittree->links, link); + if (link->tosock && link->fromsock) { + /* send changed events for original tonode and new */ + if (link->tonode) + snode_update(snode, link->tonode); + + /* we might need to remove a link */ + if (in_out==SOCK_OUT) + node_remove_extra_links(snode, link->tosock, link); + + /* when linking to group outputs, update the socket type */ + /* XXX this should all be part of a generic update system */ + if (!link->tonode) { + if(link->tosock->type != link->fromsock->type) + nodeSocketSetType(link->tosock, link->fromsock->type); } - snode->edittree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS; } - else if (link->fromnode && link->fromsock) { - link->tosock = node_group_expose_socket(snode->edittree, link->fromsock, SOCK_OUT); - link->tonode = NULL; - if (link->prev==NULL && link->next==NULL) { - BLI_addtail(&snode->edittree->links, link); + else if (outside_group_rect(snode) && (link->tonode || link->fromnode)) { + /* automatically add new group socket */ + if (link->tonode && link->tosock) { + link->fromsock = node_group_expose_socket(snode->edittree, link->tosock, SOCK_IN); + link->fromnode = NULL; + if (link->prev==NULL && link->next==NULL) + BLI_addtail(&snode->edittree->links, link); + + snode->edittree->update |= NTREE_UPDATE_GROUP_IN | NTREE_UPDATE_LINKS; + } + else if (link->fromnode && link->fromsock) { + link->tosock = node_group_expose_socket(snode->edittree, link->fromsock, SOCK_OUT); + link->tonode = NULL; + if (link->prev==NULL && link->next==NULL) + BLI_addtail(&snode->edittree->links, link); + + snode->edittree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS; } - snode->edittree->update |= NTREE_UPDATE_GROUP_OUT | NTREE_UPDATE_LINKS; } + else + nodeRemLink(snode->edittree, link); } - else - nodeRemLink(snode->edittree, link); ntreeUpdateTree(snode->edittree); snode_notify(C, snode); snode_dag_update(C, snode); BLI_remlink(&snode->linkdrag, nldrag); + /* links->data pointers are either held by the tree or freed already */ + BLI_freelistN(&nldrag->links); MEM_freeN(nldrag); return OPERATOR_FINISHED; + } } return OPERATOR_RUNNING_MODAL; } /* return 1 when socket clicked */ -static int node_link_init(SpaceNode *snode, bNodeLinkDrag *nldrag) +static bNodeLinkDrag *node_link_init(SpaceNode *snode, int detach) { - bNodeLink *link; - int in_out = 0; - + bNode *node; + bNodeSocket *sock; + bNodeLink *link, *link_next, *oplink; + bNodeLinkDrag *nldrag = NULL; + LinkData *linkdata; + int num_links; + /* output indicated? */ - if (node_find_indicated_socket(snode, &nldrag->node, &nldrag->sock, SOCK_OUT)) { - if (nodeCountSocketLinks(snode->edittree, nldrag->sock) < nldrag->sock->limit) - in_out = SOCK_OUT; - else { - /* find if we break a link */ - for (link= snode->edittree->links.first; link; link= link->next) { - if (link->fromsock==nldrag->sock) - break; - } - if (link) { - nldrag->node= link->tonode; - nldrag->sock= link->tosock; - nodeRemLink(snode->edittree, link); - in_out = SOCK_IN; + if (node_find_indicated_socket(snode, &node, &sock, SOCK_OUT)) { + nldrag= MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata"); + + num_links = nodeCountSocketLinks(snode->edittree, sock); + if (num_links > 0 && (num_links >= sock->limit || detach)) { + /* dragged links are fixed on input side */ + nldrag->in_out = SOCK_IN; + /* detach current links and store them in the operator data */ + for (link= snode->edittree->links.first; link; link= link_next) { + link_next = link->next; + if (link->fromsock==sock) { + linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); + linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); + *oplink = *link; + BLI_addtail(&nldrag->links, linkdata); + nodeRemLink(snode->edittree, link); + } } } + else { + /* dragged links are fixed on output side */ + nldrag->in_out = SOCK_OUT; + /* create a new link */ + linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); + linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); + oplink->fromnode = node; + oplink->fromsock = sock; + BLI_addtail(&nldrag->links, linkdata); + } } /* or an input? */ - else if (node_find_indicated_socket(snode, &nldrag->node, &nldrag->sock, SOCK_IN)) { - if (nodeCountSocketLinks(snode->edittree, nldrag->sock) < nldrag->sock->limit) - in_out = SOCK_IN; - else { - /* find if we break a link */ - for (link= snode->edittree->links.first; link; link= link->next) { - if (link->tosock==nldrag->sock) - break; - } - if (link) { - /* send changed event to original tonode */ - if (link->tonode) - snode_update(snode, link->tonode); - - nldrag->node= link->fromnode; - nldrag->sock= link->fromsock; - nodeRemLink(snode->edittree, link); - in_out = SOCK_OUT; + else if (node_find_indicated_socket(snode, &node, &sock, SOCK_IN)) { + nldrag= MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata"); + + num_links = nodeCountSocketLinks(snode->edittree, sock); + if (num_links > 0 && (num_links >= sock->limit || detach)) { + /* dragged links are fixed on output side */ + nldrag->in_out = SOCK_OUT; + /* detach current links and store them in the operator data */ + for (link= snode->edittree->links.first; link; link= link_next) { + link_next = link->next; + if (link->tosock==sock) { + linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); + linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); + *oplink = *link; + BLI_addtail(&nldrag->links, linkdata); + nodeRemLink(snode->edittree, link); + + /* send changed event to original link->tonode */ + if (node) + snode_update(snode, node); + } } } + else { + /* dragged links are fixed on input side */ + nldrag->in_out = SOCK_IN; + /* create a new link */ + linkdata = MEM_callocN(sizeof(LinkData), "drag link op link data"); + linkdata->data = oplink = MEM_callocN(sizeof(bNodeLink), "drag link op link"); + oplink->tonode = node; + oplink->tosock = sock; + BLI_addtail(&nldrag->links, linkdata); + } } - return in_out; + return nldrag; } static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event) { SpaceNode *snode= CTX_wm_space_node(C); ARegion *ar= CTX_wm_region(C); - bNodeLinkDrag *nldrag= MEM_callocN(sizeof(bNodeLinkDrag), "drag link op customdata"); - + bNodeLinkDrag *nldrag; + int detach = RNA_boolean_get(op->ptr, "detach"); UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &snode->mx, &snode->my); ED_preview_kill_jobs(C); - nldrag->in_out= node_link_init(snode, nldrag); + nldrag = node_link_init(snode, detach); - if (nldrag->in_out) { + if (nldrag) { op->customdata= nldrag; - - /* we make a temporal link */ - if (nldrag->in_out==SOCK_OUT) { - nldrag->link= MEM_callocN(sizeof(bNodeLink), "link"); - nldrag->link->fromnode= nldrag->node; - nldrag->link->fromsock= nldrag->sock; - nldrag->link->tonode= NULL; - nldrag->link->tosock= NULL; - } - else { - nldrag->link= MEM_callocN(sizeof(bNodeLink), "link"); - nldrag->link->fromnode= NULL; - nldrag->link->fromsock= NULL; - nldrag->link->tonode= nldrag->node; - nldrag->link->tosock= nldrag->sock; - } BLI_addtail(&snode->linkdrag, nldrag); /* add modal handler */ @@ -2541,21 +2594,20 @@ static int node_link_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } - else { - MEM_freeN(nldrag); + else return OPERATOR_CANCELLED|OPERATOR_PASS_THROUGH; - } } 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); + + BLI_freelistN(&nldrag->links); MEM_freeN(nldrag); - + return OPERATOR_CANCELLED; } @@ -2575,6 +2627,8 @@ void NODE_OT_link(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING; + + RNA_def_boolean(ot->srna, "detach", FALSE, "Detach", "Detach and redirect existing links"); } /* ********************** Make Link operator ***************** */ diff --git a/source/blender/editors/space_node/node_intern.h b/source/blender/editors/space_node/node_intern.h index 17078443987..802c471c7aa 100644 --- a/source/blender/editors/space_node/node_intern.h +++ b/source/blender/editors/space_node/node_intern.h @@ -52,9 +52,11 @@ typedef struct bNodeLinkDrag { struct bNodeLinkDrag *next, *prev; - struct bNode *node; - struct bNodeSocket *sock; - struct bNodeLink *link; + /* List of links dragged by the operator. + * Note: This is a list of LinkData structs on top of the actual bNodeLinks. + * This way the links can be added to the node tree while being stored in this list. + */ + ListBase links; int in_out; } bNodeLinkDrag; diff --git a/source/blender/editors/space_node/node_ops.c b/source/blender/editors/space_node/node_ops.c index 7d9d7d736f6..5d586f08eb0 100644 --- a/source/blender/editors/space_node/node_ops.c +++ b/source/blender/editors/space_node/node_ops.c @@ -171,6 +171,8 @@ void node_keymap(struct wmKeyConfig *keyconf) /* each of these falls through if not handled... */ WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, 0, 0); + kmi = WM_keymap_add_item(keymap, "NODE_OT_link", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "detach", TRUE); WM_keymap_add_item(keymap, "NODE_OT_resize", LEFTMOUSE, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "NODE_OT_links_cut", LEFTMOUSE, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 3d6fbb53e37..1590d08b4a1 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -1323,7 +1323,7 @@ void SEQUENCER_OT_reload(struct wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; /* no undo, the data changed is stored outside 'main' */ prop = RNA_def_boolean(ot->srna, "adjust_length", 0, "Adjust Length", - "Adjust lenght of strips to their data lenght"); + "Adjust length of strips to their data length"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 5413aa88ab6..00622f368f0 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2987,7 +2987,7 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS interp_v3_v3v3(fvec, vmid, v2, 0.8f); } else { - angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->v->co); + angle = angle_v3v3v3(loop->prev->v->co, loop->v->co, loop->next->v->co); interp_v3_v3v3(fvec, vmid, loop->v->co, 0.8f); } @@ -3586,7 +3586,7 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } else { /* ob->bb was set by derived mesh system, do NULL check just to be sure */ - if (me->totpoly <= 4 || (ob->bb && ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb))) { + if (me->totpoly <= 4 || (!ob->bb || ED_view3d_boundbox_clip(rv3d, ob->obmat, ob->bb))) { glsl = draw_glsl_material(scene, ob, v3d, dt); check_alpha = check_alpha_pass(base); @@ -3603,19 +3603,21 @@ static int draw_mesh_object(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D } } - /* GPU_begin_object_materials checked if this is needed */ - if (do_alpha_after) { - if (ob->dtx & OB_DRAWXRAY) { - add_view3d_after(&v3d->afterdraw_xraytransp, base, flag); - } - else { - add_view3d_after(&v3d->afterdraw_transp, base, flag); + if ((flag & DRAW_PICKING) == 0 && (base->flag & OB_FROMDUPLI) == 0) { + /* GPU_begin_object_materials checked if this is needed */ + if (do_alpha_after) { + if (ob->dtx & OB_DRAWXRAY) { + add_view3d_after(&v3d->afterdraw_xraytransp, base, flag); + } + else { + add_view3d_after(&v3d->afterdraw_transp, base, flag); + } } - } - else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { - /* special case xray+transp when alpha is 1.0, without this the object vanishes */ - if (v3d->xray == 0 && v3d->transp == 0) { - add_view3d_after(&v3d->afterdraw_xray, base, flag); + else if (ob->dtx & OB_DRAWXRAY && ob->dtx & OB_DRAWTRANSP) { + /* special case xray+transp when alpha is 1.0, without this the object vanishes */ + if (v3d->xray == 0 && v3d->transp == 0) { + add_view3d_after(&v3d->afterdraw_xray, base, flag); + } } } diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 682d8950440..fe142ced7fa 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1715,6 +1715,7 @@ typedef struct View3DAfter { void add_view3d_after(ListBase *lb, Base *base, int flag) { View3DAfter *v3da = MEM_callocN(sizeof(View3DAfter), "View 3d after"); + BLI_assert((base->flag & OB_FROMDUPLI) == 0); BLI_addtail(lb, v3da); v3da->base = base; v3da->flag = flag; @@ -1815,7 +1816,7 @@ static void draw_dupli_objects_color(Scene *scene, ARegion *ar, View3D *v3d, Bas RegionView3D *rv3d = ar->regiondata; ListBase *lb; DupliObject *dob_prev = NULL, *dob, *dob_next = NULL; - Base tbase; + Base tbase = {NULL}; BoundBox bb, *bb_tmp; /* use a copy because draw_object, calls clear_mesh_caches */ GLuint displist = 0; short transflag, use_displist = -1; /* -1 is initialize */ diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index e35c0e1c654..4bfb6dd9fd6 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -431,7 +431,7 @@ static void viewops_data_create(bContext *C, wmOperator *op, wmEvent *event) if (vod->use_dyn_ofs) { /* If there's no selection, lastofs is unmodified and last value since static */ - calculateTransformCenter(C, V3D_CENTROID, lastofs); + calculateTransformCenter(C, V3D_CENTROID, lastofs, NULL); negate_v3_v3(vod->dyn_ofs, lastofs); } else if (U.uiflag & USER_ORBIT_ZBUF) { @@ -1423,7 +1423,8 @@ void viewzoom_modal_keymap(wmKeyConfig *keyconf) {VIEWROT_MODAL_SWITCH_ROTATE, "SWITCH_TO_ROTATE", 0, "Switch to Rotate"}, {VIEWROT_MODAL_SWITCH_MOVE, "SWITCH_TO_MOVE", 0, "Switch to Move"}, - {0, NULL, 0, NULL, NULL}}; + {0, NULL, 0, NULL, NULL} + }; wmKeyMap *keymap = WM_modalkeymap_get(keyconf, "View3D Zoom Modal"); diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 5c605e02fd1..d07ae468f35 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -606,6 +606,72 @@ wmKeyMap* transform_modal_keymap(wmKeyConfig *keyconf) return keymap; } +static void transform_event_xyz_constraint(TransInfo *t, short key_type, char cmode) +{ + if (!(t->flag & T_NO_CONSTRAINT)) { + int constraint_axis, constraint_plane; + int edit_2d = (t->flag & T_2D_EDIT); + char msg1[] = "along _"; + char msg2[] = "along %s _"; + char msg3[] = "locking %s _"; + char axis; + + /* Initialize */ + switch(key_type) { + case XKEY: + axis = 'X'; + constraint_axis = CON_AXIS0; + break; + case YKEY: + axis = 'Y'; + constraint_axis = CON_AXIS1; + break; + case ZKEY: + axis = 'Z'; + constraint_axis = CON_AXIS2; + break; + default: + /* Invalid key */ + return; + } + msg1[sizeof(msg1) - 2] = axis; + msg2[sizeof(msg2) - 2] = axis; + msg3[sizeof(msg3) - 2] = axis; + constraint_plane = ((CON_AXIS0 | CON_AXIS1 | CON_AXIS2) & + (~constraint_axis)); + + if (edit_2d && (key_type != ZKEY)) { + if (cmode == axis) { + stopConstraint(t); + } + else { + setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg1); + } + } + else if (!edit_2d) { + if (cmode == axis) { + if (t->con.orientation != V3D_MANIP_GLOBAL) { + stopConstraint(t); + } + else { + short orientation = (t->current_orientation != V3D_MANIP_GLOBAL ? + t->current_orientation : V3D_MANIP_LOCAL); + if (!(t->modifiers & MOD_CONSTRAINT_PLANE)) + setUserConstraint(t, orientation, constraint_axis, msg2); + else if (t->modifiers & MOD_CONSTRAINT_PLANE) + setUserConstraint(t, orientation, constraint_plane, msg3); + } + } + else { + if (!(t->modifiers & MOD_CONSTRAINT_PLANE)) + setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_axis, msg2); + else if (t->modifiers & MOD_CONSTRAINT_PLANE) + setUserConstraint(t, V3D_MANIP_GLOBAL, constraint_plane, msg3); + } + } + t->redraw |= TREDRAW_HARD; + } +} int transformEvent(TransInfo *t, wmEvent *event) { @@ -950,93 +1016,9 @@ int transformEvent(TransInfo *t, wmEvent *event) } break; case XKEY: - if ((t->flag & T_NO_CONSTRAINT)==0) { - if (t->flag & T_2D_EDIT) { - if (cmode == 'X') { - stopConstraint(t); - } - else { - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), "along X"); - } - } - else { - if (cmode == 'X') { - if (t->con.orientation != V3D_MANIP_GLOBAL) { - stopConstraint(t); - } - else { - short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; - if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, orientation, (CON_AXIS0), "along %s X"); - else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, orientation, (CON_AXIS1|CON_AXIS2), "locking %s X"); - } - } - else { - if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0), "along %s X"); - else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1|CON_AXIS2), "locking %s X"); - } - } - t->redraw |= TREDRAW_HARD; - } - break; case YKEY: - if ((t->flag & T_NO_CONSTRAINT)==0) { - if (t->flag & T_2D_EDIT) { - if (cmode == 'Y') { - stopConstraint(t); - } - else { - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), "along Y"); - } - } - else { - if (cmode == 'Y') { - if (t->con.orientation != V3D_MANIP_GLOBAL) { - stopConstraint(t); - } - else { - short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; - if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, orientation, (CON_AXIS1), "along %s Y"); - else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS2), "locking %s Y"); - } - } - else { - if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS1), "along %s Y"); - else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0|CON_AXIS2), "locking %s Y"); - } - } - t->redraw |= TREDRAW_HARD; - } - break; case ZKEY: - if ((t->flag & (T_NO_CONSTRAINT|T_2D_EDIT))==0) { - if (cmode == 'Z') { - if (t->con.orientation != V3D_MANIP_GLOBAL) { - stopConstraint(t); - } - else { - short orientation = t->current_orientation != V3D_MANIP_GLOBAL ? t->current_orientation : V3D_MANIP_LOCAL; - if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, orientation, (CON_AXIS2), "along %s Z"); - else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, orientation, (CON_AXIS0|CON_AXIS1), "locking %s Z"); - } - } - else { - if ((t->modifiers & MOD_CONSTRAINT_PLANE) == 0) - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS2), "along %s Z"); - else if (t->modifiers & MOD_CONSTRAINT_PLANE) - setUserConstraint(t, V3D_MANIP_GLOBAL, (CON_AXIS0|CON_AXIS1), "locking %s Z"); - } - t->redraw |= TREDRAW_HARD; - } + transform_event_xyz_constraint(t, event->type, cmode); break; case OKEY: if (t->flag & T_PROP_EDIT && event->shift) { @@ -1134,7 +1116,7 @@ int transformEvent(TransInfo *t, wmEvent *event) return OPERATOR_PASS_THROUGH; } -int calculateTransformCenter(bContext *C, int centerMode, float *vec) +int calculateTransformCenter(bContext *C, int centerMode, float *cent3d, int *cent2d) { TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data"); int success = 1; @@ -1159,8 +1141,12 @@ int calculateTransformCenter(bContext *C, int centerMode, float *vec) calculateCenter(t); - // Copy center from constraint center. Transform center can be local - copy_v3_v3(vec, t->con.center); + if(cent2d) + copy_v2_v2_int(cent2d, t->center2d); + if(cent3d) { + // Copy center from constraint center. Transform center can be local + copy_v3_v3(cent3d, t->con.center); + } } diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index c4db85420ca..c9eb975cb77 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -4054,7 +4054,47 @@ static void freeSeqData(TransInfo *t) } } +#if 1 /* (mango hack! - for Ian) this is truely bad - should _never_ be in a release :| */ + if (CTX_wm_window(t->context)->eventstate->alt) { + int minframe = MAXFRAME; + td= t->data; + seq_prev= NULL; + for (a=0; a<t->total; a++, td++) { + seq= ((TransDataSeq *)td->extra)->seq; + if ((seq != seq_prev)) { + minframe = MIN2(minframe, seq->startdisp); + } + } + + + for (seq= seqbasep->first; seq; seq= seq->next) { + if (!(seq->flag & SELECT)) { + if (seq->startdisp >= minframe) { + seq->machine += MAXSEQ * 2; + } + } + } + + shuffle_seq_time(seqbasep, t->scene); + + for (seq= seqbasep->first; seq; seq= seq->next) { + if (seq->machine >= MAXSEQ * 2) { + seq->machine -= MAXSEQ * 2; + seq->tmp= (void*)1; + } + else { + seq->tmp= NULL; + } + } + + shuffle_seq_time(seqbasep, t->scene); + } + else { + shuffle_seq_time(seqbasep, t->scene); + } +#else shuffle_seq_time(seqbasep, t->scene); +#endif if (has_effect) { /* update effects strips based on strips just moved in time */ |