From 15016873ab74634cf0a1cde0adab8f981ce9e117 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 11:26:11 +0000 Subject: [PATCH 01/24] dont use 'if(${WITH_STATIC_LIBS})', no need to expend the variable. --- CMakeLists.txt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 16d00dd4b54..e2dda8553d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -562,12 +562,12 @@ set(PLATFORM_LINKFLAGS_DEBUG "") if(UNIX AND NOT APPLE) macro(find_package_wrapper) string(TOUPPER ${ARGV0} _NAME_UPPER) - if(${WITH_STATIC_LIBS}) + if(WITH_STATIC_LIBS) set(_cmake_find_library_suffixes_back ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) endif() find_package(${ARGV}) - if(${WITH_STATIC_LIBS}) + if(WITH_STATIC_LIBS) set(CMAKE_FIND_LIBRARY_SUFFIXES ${_cmake_find_library_suffixes_back}) unset(_cmake_find_library_suffixes_back) endif() @@ -707,7 +707,7 @@ if(UNIX AND NOT APPLE) if(WITH_BOOST) # uses in build instructions to override include and library variables if(NOT BOOST_CUSTOM) - if(${WITH_STATIC_LIBS}) + if(WITH_STATIC_LIBS) set(Boost_USE_STATIC_LIBS ON) endif() set(Boost_USE_MULTITHREADED ON) From 9d4cc7885dce3237b98e282d79a589f288c6310c Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 11:53:48 +0000 Subject: [PATCH 02/24] fix for filesel autocomplete, it had the annoying behavior if you entered in a non-existing name, of executing it and then asking to add the dir. --- source/blender/editors/include/UI_interface.h | 4 +-- source/blender/editors/interface/interface.c | 11 +++++--- .../editors/interface/interface_handlers.c | 9 +++---- .../editors/interface/interface_intern.h | 2 +- .../editors/interface/interface_regions.c | 6 +++-- .../blender/editors/space_file/file_intern.h | 4 +-- source/blender/editors/space_file/filesel.c | 25 ++++++++++++------- 7 files changed, 37 insertions(+), 24 deletions(-) diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index cb2f3e3286e..86e51b201d9 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -304,7 +304,7 @@ typedef struct uiSearchItems uiSearchItems; typedef void (*uiButHandleFunc)(struct bContext *C, void *arg1, void *arg2); typedef void (*uiButHandleRenameFunc)(struct bContext *C, void *arg, char *origstr); typedef void (*uiButHandleNFunc)(struct bContext *C, void *argN, void *arg2); -typedef void (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); +typedef bool (*uiButCompleteFunc)(struct bContext *C, char *str, void *arg); typedef void (*uiButSearchFunc)(const struct bContext *C, void *arg, const char *str, uiSearchItems *items); typedef void (*uiBlockHandleFunc)(struct bContext *C, void *arg, int event); @@ -644,7 +644,7 @@ typedef struct AutoComplete AutoComplete; AutoComplete *autocomplete_begin(const char *startname, size_t maxlen); void autocomplete_do_name(AutoComplete *autocpl, const char *name); -void autocomplete_end(AutoComplete *autocpl, char *autoname); +bool autocomplete_end(AutoComplete *autocpl, char *autoname); /* Panels * diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 5a1ba8f31f0..834458a3226 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -3086,16 +3086,21 @@ void autocomplete_do_name(AutoComplete *autocpl, const char *name) } } -void autocomplete_end(AutoComplete *autocpl, char *autoname) +bool autocomplete_end(AutoComplete *autocpl, char *autoname) { - if (autocpl->truncate[0]) + bool change = false; + if (autocpl->truncate[0]) { BLI_strncpy(autoname, autocpl->truncate, autocpl->maxlen); + change = true; + } else { - if (autoname != autocpl->startname) /* don't copy a string over its self */ + if (autoname != autocpl->startname) { /* don't copy a string over its self */ BLI_strncpy(autoname, autocpl->startname, autocpl->maxlen); + } } MEM_freeN(autocpl->truncate); MEM_freeN(autocpl); + return change; } static void ui_check_but_and_iconize(uiBut *but, int icon) diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 85a23a9da22..7aee228ddaa 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -1828,20 +1828,19 @@ static bool ui_textedit_delete(uiBut *but, uiHandleButtonData *data, int directi static bool ui_textedit_autocomplete(bContext *C, uiBut *but, uiHandleButtonData *data) { char *str; - /* TODO, should return false if it cant autocomp. */ - bool changed = true; + bool change = true; str = data->str; if (data->searchbox) - ui_searchbox_autocomplete(C, data->searchbox, but, data->str); + change = ui_searchbox_autocomplete(C, data->searchbox, but, data->str); else - but->autocomplete_func(C, str, but->autofunc_arg); + change = but->autocomplete_func(C, str, but->autofunc_arg); but->pos = strlen(str); but->selsta = but->selend = but->pos; - return changed; + return change; } /* mode for ui_textedit_copypaste() */ diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h index 9de608f2730..a6076b8df78 100644 --- a/source/blender/editors/interface/interface_intern.h +++ b/source/blender/editors/interface/interface_intern.h @@ -471,7 +471,7 @@ ARegion *ui_searchbox_create(struct bContext *C, struct ARegion *butregion, uiBu bool ui_searchbox_inside(struct ARegion *ar, int x, int y); int ui_searchbox_find_index(struct ARegion *ar, const char *name); void ui_searchbox_update(struct bContext *C, struct ARegion *ar, uiBut *but, const bool reset); -void ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str); +bool ui_searchbox_autocomplete(struct bContext *C, struct ARegion *ar, uiBut *but, char *str); void ui_searchbox_event(struct bContext *C, struct ARegion *ar, uiBut *but, const struct wmEvent *event); bool ui_searchbox_apply(uiBut *but, struct ARegion *ar); void ui_searchbox_free(struct bContext *C, struct ARegion *ar); diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index b764c70b111..1ff46004bdf 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -1039,18 +1039,20 @@ void ui_searchbox_update(bContext *C, ARegion *ar, uiBut *but, const bool reset) ED_region_tag_redraw(ar); } -void ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) +bool ui_searchbox_autocomplete(bContext *C, ARegion *ar, uiBut *but, char *str) { uiSearchboxData *data = ar->regiondata; + bool changed = false; if (str[0]) { data->items.autocpl = autocomplete_begin(str, ui_get_but_string_max_length(but)); but->search_func(C, but->search_arg, but->editstr, &data->items); - autocomplete_end(data->items.autocpl, str); + changed = autocomplete_end(data->items.autocpl, str); data->items.autocpl = NULL; } + return changed; } static void ui_searchbox_region_draw_cb(const bContext *UNUSED(C), ARegion *ar) diff --git a/source/blender/editors/space_file/file_intern.h b/source/blender/editors/space_file/file_intern.h index e5c6a839380..240106d37d5 100644 --- a/source/blender/editors/space_file/file_intern.h +++ b/source/blender/editors/space_file/file_intern.h @@ -105,8 +105,8 @@ float file_string_width(const char *str); float file_font_pointsize(void); void file_change_dir(bContext *C, int checkdir); int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matched_file); -void autocomplete_directory(struct bContext *C, char *str, void *arg_v); -void autocomplete_file(struct bContext *C, char *str, void *arg_v); +bool autocomplete_directory(struct bContext *C, char *str, void *arg_v); +bool autocomplete_file(struct bContext *C, char *str, void *arg_v); /* file_panels.c */ void file_panels_register(struct ARegionType *art); diff --git a/source/blender/editors/space_file/filesel.c b/source/blender/editors/space_file/filesel.c index 59801796f8c..a31af851575 100644 --- a/source/blender/editors/space_file/filesel.c +++ b/source/blender/editors/space_file/filesel.c @@ -638,9 +638,10 @@ int file_select_match(struct SpaceFile *sfile, const char *pattern, char *matche return match; } -void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) +bool autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); + bool change = false; /* search if str matches the beginning of name */ if (str[0] && sfile->files) { @@ -675,20 +676,25 @@ void autocomplete_directory(struct bContext *C, char *str, void *UNUSED(arg_v)) } closedir(dir); - autocomplete_end(autocpl, str); - if (BLI_exists(str)) { - BLI_add_slash(str); - } - else { - BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir)); + change = autocomplete_end(autocpl, str); + if (change) { + if (BLI_exists(str)) { + BLI_add_slash(str); + } + else { + BLI_strncpy(sfile->params->dir, str, sizeof(sfile->params->dir)); + } } } } + + return change; } -void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) +bool autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) { SpaceFile *sfile = CTX_wm_space_file(C); + bool change = false; /* search if str matches the beginning of name */ if (str[0] && sfile->files) { @@ -702,8 +708,9 @@ void autocomplete_file(struct bContext *C, char *str, void *UNUSED(arg_v)) autocomplete_do_name(autocpl, file->relname); } } - autocomplete_end(autocpl, str); + change = autocomplete_end(autocpl, str); } + return change; } void ED_fileselect_clear(struct wmWindowManager *wm, struct SpaceFile *sfile) From 5e9e906bd3eb4c1a84156ee13bf8fbdb97f8d704 Mon Sep 17 00:00:00 2001 From: Gaia Clary Date: Wed, 19 Jun 2013 12:16:50 +0000 Subject: [PATCH 03/24] Take precision into account for calculating display of small numbers --- source/blender/editors/interface/interface.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 834458a3226..8a5f2877f34 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -453,7 +453,7 @@ static int ui_but_float_precision(uiBut *but, double value) * the number, this is so 0.00001 is not displayed as 0.00, * _but_, this is only for small values si 10.0001 will not get * the same treatment */ - if (value != 0.0 && (value = ABS(value)) < 0.1) { + if (value != 0.0 && (value = ABS(value)) < pow(10, -prec)) { int value_i = (int)((value * PRECISION_FLOAT_MAX_POW) + 0.5); if (value_i != 0) { const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */ From a8d5a22f7fb2587ade3460df9af6441093f3c4a7 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 14:08:27 +0000 Subject: [PATCH 04/24] ui precision drawing - avoid calling pow(10, -prec) since the range is small use a fixed array. --- source/blender/editors/interface/interface.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 8a5f2877f34..19eb978a01e 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -443,17 +443,24 @@ void uiExplicitBoundsBlock(uiBlock *block, int minx, int miny, int maxx, int max static int ui_but_float_precision(uiBut *but, double value) { int prec; + const double pow10_neg[PRECISION_FLOAT_MAX + 1] = {1.0, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001}; /* first check if prec is 0 and fallback to a simple default */ if ((prec = (int)but->a2) == -1) { prec = (but->hardmax < 10.001f) ? 3 : 2; } + BLI_assert(prec <= PRECISION_FLOAT_MAX); + BLI_assert(pow10_neg[prec] == pow(10, -prec)); + /* check on the number of decimal places need to display * the number, this is so 0.00001 is not displayed as 0.00, * _but_, this is only for small values si 10.0001 will not get * the same treatment */ - if (value != 0.0 && (value = ABS(value)) < pow(10, -prec)) { + value = ABS(value); + if ((value < pow10_neg[prec]) && + (value > (1.0 / PRECISION_FLOAT_MAX_POW))) + { int value_i = (int)((value * PRECISION_FLOAT_MAX_POW) + 0.5); if (value_i != 0) { const int prec_span = 3; /* show: 0.01001, 5 would allow 0.0100001 for eg. */ From 5a4e36c05184271194bd7fbf5afc49224c40fa45 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 15:05:02 +0000 Subject: [PATCH 05/24] fix own regression with normal recalculation updates --- source/blender/blenkernel/intern/DerivedMesh.c | 2 +- source/blender/blenkernel/intern/displist.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index c9c33014aa5..96ccc5be8e0 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2085,7 +2085,7 @@ static void editbmesh_calc_modifiers(Scene *scene, Object *ob, BMEditMesh *em, D if (mti->applyModifierEM) ndm = modwrap_applyModifierEM(md, ob, em, dm, MOD_APPLY_USECACHE); else - ndm = mti->applyModifier(md, ob, dm, MOD_APPLY_USECACHE); + ndm = modwrap_applyModifier(md, ob, dm, MOD_APPLY_USECACHE); if (ndm) { if (dm && dm != ndm) diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index ed8d7bd3d2f..e1ecf00104a 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1178,7 +1178,7 @@ static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFina if (!orcodm) orcodm = create_orco_dm(scene, ob); - ndm = mti->applyModifier(md, ob, orcodm, app_flag); + ndm = modwrap_applyModifier(md, ob, orcodm, app_flag); if (ndm) { /* if the modifier returned a new dm, release the old one */ From 30a108ddad253c58b87615d3106bd9bfeecb1775 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 19 Jun 2013 15:08:07 +0000 Subject: [PATCH 06/24] Fix for expanded enums with icon_only enabled, name of each item was still used to compute its button's size! --- source/blender/editors/interface/interface_layout.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index b6575f4eca0..ef839f1d143 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -525,7 +525,7 @@ static void ui_item_enum_expand(uiLayout *layout, uiBlock *block, PointerRNA *pt name = (!uiname || uiname[0]) ? item->name : ""; icon = item->icon; value = item->value; - itemw = ui_text_icon_width(block->curlayout, name, icon, 0); + itemw = ui_text_icon_width(block->curlayout, icon_only ? "" : name, icon, 0); if (icon && name[0] && !icon_only) but = uiDefIconTextButR_prop(block, ROW, 0, icon, name, 0, 0, itemw, h, ptr, prop, -1, 0, value, -1, -1, NULL); From 033089d28678f78fc76b3f3ca6fe2022cd3493e7 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Wed, 19 Jun 2013 15:20:50 +0000 Subject: [PATCH 07/24] Usability: For users without middle-mouse buttons, they can now use Circle and Border deselect by holding SHIFT. Middle mouse still works too. --- .../windowmanager/intern/wm_operators.c | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index cd0042731c1..e71be6052d0 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -4210,13 +4210,12 @@ static void gesture_circle_modal_keymap(wmKeyConfig *keyconf) WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_SELECT); -#if 0 /* Durien guys like this :S */ + /* left mouse shift for deselect too */ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_DESELECT); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_NOP); -#else + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_DESELECT); // default 2.4x WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP); // default 2.4x -#endif WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_NOP); @@ -4284,21 +4283,22 @@ static void gesture_border_modal_keymap(wmKeyConfig *keyconf) /* items for modal map */ WM_modalkeymap_add_item(keymap, ESCKEY, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); + /* Note: cancel only on press otherwise you cannot map this to RMB-gesture */ WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_PRESS, KM_ANY, 0, GESTURE_MODAL_CANCEL); - - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); - WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT); WM_modalkeymap_add_item(keymap, RIGHTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT); -#if 0 /* Durian guys like this */ + /* allow shift leftclick for deselect too */ WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, KM_SHIFT, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_SHIFT, 0, GESTURE_MODAL_DESELECT); -#else + + /* any unhandled leftclick release handles select */ + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); + WM_modalkeymap_add_item(keymap, LEFTMOUSE, KM_RELEASE, KM_ANY, 0, GESTURE_MODAL_SELECT); + WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_PRESS, 0, 0, GESTURE_MODAL_BEGIN); WM_modalkeymap_add_item(keymap, MIDDLEMOUSE, KM_RELEASE, 0, 0, GESTURE_MODAL_DESELECT); -#endif - + /* assign map to operators */ WM_modalkeymap_assign(keymap, "ACTION_OT_select_border"); WM_modalkeymap_assign(keymap, "ANIM_OT_channels_select_border"); From a7416641e6cb634e4ac5fd3ad14be57e308b52fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=BCrgen=20Herrmann?= Date: Wed, 19 Jun 2013 17:17:51 +0000 Subject: [PATCH 08/24] Fix for Debug build on MSVC2008 and MSVC2012 after Cycles Kernel optimization: Compiler optimization was accidentally set to /Ox for debug build too. Changed this to be /Od in Debug and /Ox in Release mode. --- intern/cycles/CMakeLists.txt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index a8293ac683c..06f780eb86f 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -13,10 +13,11 @@ if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD) endif() if(WIN32 AND MSVC) - set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /GS-") + set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /GS-") # there is no /arch:SSE3, but intrinsics are available anyway - set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /GS-") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /EHsc /Ox /GS-") + set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /GS-") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /EHsc /GS-") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") elseif(CMAKE_COMPILER_IS_GNUCC) set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse") set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse") From 16204bd64759fddc940800f39fc91461ee340424 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 19 Jun 2013 17:54:23 +0000 Subject: [PATCH 09/24] Cycles: prepare to make CUDA 5.0 the official version we use * Add CUDA compiler version detection to cmake/scons/runtime * Remove noinline in kernel_shader.h and reenable --use_fast_math if CUDA 5.x is used, these were workarounds for CUDA 4.2 bugs * Change max number of registers to 32 for sm 2.x (based on performance tests from Martijn Berger and confirmed here), and also for NVidia OpenCL. Overall it seems that with these changes and the latest CUDA 5.0 download, that performance is as good as or better than the 2.67b release with the scenes and graphics cards I tested. --- intern/cycles/device/device_cuda.cpp | 50 ++++++++++++++++++++-- intern/cycles/device/device_opencl.cpp | 2 +- intern/cycles/kernel/CMakeLists.txt | 54 ++++++++++++++++++++---- intern/cycles/kernel/SConscript | 41 ++++++++++++++++-- intern/cycles/kernel/kernel_jitter.h | 4 +- intern/cycles/kernel/kernel_shader.h | 21 ++++++++-- intern/cycles/util/util_cuda.cpp | 58 +++++++++++++++++++++++++- intern/cycles/util/util_cuda.h | 1 + 8 files changed, 209 insertions(+), 22 deletions(-) diff --git a/intern/cycles/device/device_cuda.cpp b/intern/cycles/device/device_cuda.cpp index f32c6dde639..1f96ed0ae83 100644 --- a/intern/cycles/device/device_cuda.cpp +++ b/intern/cycles/device/device_cuda.cpp @@ -271,11 +271,53 @@ public: return ""; } + int cuda_version = cuCompilerVersion(); + + if(cuda_version == 0) { + cuda_error_message("CUDA nvcc compiler version could not be parsed."); + return ""; + } + + if(cuda_version != 50) + printf("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported.\n", cuda_version/10, cuda_version%10); + /* compile */ string kernel = path_join(kernel_path, "kernel.cu"); string include = kernel_path; const int machine = system_cpu_bits(); - const int maxreg = 24; + string arch_flags; + + /* build flags depending on CUDA version and arch */ + if(cuda_version < 50) { + /* CUDA 4.x */ + if(major == 1) { + /* sm_1x */ + arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0"; + } + else if(major == 2) { + /* sm_2x */ + arch_flags = "--maxrregcount=24"; + } + else { + /* sm_3x */ + arch_flags = "--maxrregcount=32"; + } + } + else { + /* CUDA 4.x */ + if(major == 1) { + /* sm_1x */ + arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math"; + } + else if(major == 2) { + /* sm_2x */ + arch_flags = "--maxrregcount=32 --use_fast_math"; + } + else { + /* sm_3x */ + arch_flags = "--maxrregcount=32 --use_fast_math"; + } + } double starttime = time_dt(); printf("Compiling CUDA kernel ...\n"); @@ -283,8 +325,10 @@ public: path_create_directories(cubin); string command = string_printf("\"%s\" -arch=sm_%d%d -m%d --cubin \"%s\" " - "-o \"%s\" --ptxas-options=\"-v\" --maxrregcount=%d --opencc-options -OPT:Olimit=0 -I\"%s\" -DNVCC", - nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), maxreg, include.c_str()); + "-o \"%s\" --ptxas-options=\"-v\" %s -I\"%s\" -DNVCC -D__KERNEL_CUDA_VERSION__=%d", + nvcc.c_str(), major, minor, machine, kernel.c_str(), cubin.c_str(), arch_flags.c_str(), include.c_str(), cuda_version); + + printf("%s\n", command.c_str()); if(system(command.c_str()) == -1) { cuda_error_message("Failed to execute compilation command, see console for details."); diff --git a/intern/cycles/device/device_opencl.cpp b/intern/cycles/device/device_opencl.cpp index 0fb5c7abafb..2ee4ffaca17 100644 --- a/intern/cycles/device/device_opencl.cpp +++ b/intern/cycles/device/device_opencl.cpp @@ -85,7 +85,7 @@ static string opencl_kernel_build_options(const string& platform, const string * string build_options = " -cl-fast-relaxed-math "; if(platform == "NVIDIA CUDA") - build_options += "-D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=24 -cl-nv-verbose "; + build_options += "-D__KERNEL_OPENCL_NVIDIA__ -cl-nv-maxrregcount=32 -cl-nv-verbose "; else if(platform == "Apple") build_options += "-D__KERNEL_OPENCL_APPLE__ -Wno-missing-prototypes "; diff --git a/intern/cycles/kernel/CMakeLists.txt b/intern/cycles/kernel/CMakeLists.txt index 8b4466863e0..5e9dd15b812 100644 --- a/intern/cycles/kernel/CMakeLists.txt +++ b/intern/cycles/kernel/CMakeLists.txt @@ -117,32 +117,68 @@ set(SRC_UTIL_HEADERS # CUDA module if(WITH_CYCLES_CUDA_BINARIES) + # 32 bit or 64 bit if("${CMAKE_SIZEOF_VOID_P}" EQUAL "8") set(CUDA_BITS 64) else() set(CUDA_BITS 32) endif() + # CUDA version + execute_process (COMMAND ${CUDA_NVCC_EXECUTABLE} "--version" OUTPUT_VARIABLE NVCC_OUT) + string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\1" CUDA_VERSION_MAJOR ${NVCC_OUT}) + string(REGEX REPLACE ".*release ([0-9]+)\\.([0-9]+).*" "\\2" CUDA_VERSION_MINOR ${NVCC_OUT}) + set(CUDA_VERSION "${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}") + + # build for each arch set(cuda_sources kernel.cu ${SRC_HEADERS} ${SRC_SVM_HEADERS} ${SRC_CLOSURE_HEADERS} ${SRC_UTIL_HEADERS}) set(cuda_cubins) foreach(arch ${CYCLES_CUDA_BINARIES_ARCH}) set(cuda_cubin kernel_${arch}.cubin) - if(${arch} MATCHES "sm_1[0-9]") - # sm_1x - set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0") - elseif(${arch} MATCHES "sm_2[0-9]") - # sm_2x - set(cuda_arch_flags "--maxrregcount=24") + set(cuda_version_flags "-D__KERNEL_CUDA_VERSION__=${CUDA_VERSION}") + + # warn for other versions + if(CUDA_VERSION MATCHES "50") else() - # sm_3x - set(cuda_arch_flags "--maxrregcount=32") + message(STATUS "CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, build may succeed but only CUDA 5.0 is officially supported") + endif() + + # build flags depending on CUDA version and arch + if(CUDA_VERSION LESS 50) + # CUDA 4.x + if(${arch} MATCHES "sm_1[0-9]") + # sm_1x + set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0") + elseif(${arch} MATCHES "sm_2[0-9]") + # sm_2x + set(cuda_arch_flags "--maxrregcount=24") + else() + # sm_3x + set(cuda_arch_flags "--maxrregcount=32") + endif() + + set(cuda_math_flags "") + else() + # CUDA 5.x + if(${arch} MATCHES "sm_1[0-9]") + # sm_1x + set(cuda_arch_flags "--maxrregcount=24 --opencc-options -OPT:Olimit=0") + elseif(${arch} MATCHES "sm_2[0-9]") + # sm_2x + set(cuda_arch_flags "--maxrregcount=32") + else() + # sm_3x + set(cuda_arch_flags "--maxrregcount=32") + endif() + + set(cuda_math_flags "--use_fast_math") endif() add_custom_command( OUTPUT ${cuda_cubin} - COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC + COMMAND ${CUDA_NVCC_EXECUTABLE} -arch=${arch} -m${CUDA_BITS} --cubin ${CMAKE_CURRENT_SOURCE_DIR}/kernel.cu -o ${CMAKE_CURRENT_BINARY_DIR}/${cuda_cubin} --ptxas-options="-v" ${cuda_arch_flags} ${cuda_version_flags} ${cuda_math_flags} -I${CMAKE_CURRENT_SOURCE_DIR}/../util -I${CMAKE_CURRENT_SOURCE_DIR}/svm -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC DEPENDS ${cuda_sources}) delayed_install("${CMAKE_CURRENT_BINARY_DIR}" "${cuda_cubin}" ${CYCLES_INSTALL_PATH}/lib) diff --git a/intern/cycles/kernel/SConscript b/intern/cycles/kernel/SConscript index 3a46d10dee1..353ec1ce9d8 100644 --- a/intern/cycles/kernel/SConscript +++ b/intern/cycles/kernel/SConscript @@ -25,6 +25,8 @@ # # ***** END GPL LICENSE BLOCK ***** +import re +import subprocess import sys import os import Blender as B @@ -60,10 +62,19 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']: svm_dir = os.path.join(source_dir, "../svm") closure_dir = os.path.join(source_dir, "../closure") + # get CUDA version + nvcc_pipe = subprocess.Popen([nvcc, "--version"],stdout=subprocess.PIPE,stderr=subprocess.PIPE) + output, erroroutput = nvcc_pipe.communicate() + cuda_major_minor = re.findall(r'release (\d+).(\d+)', output)[0] + cuda_version = int(cuda_major_minor[0])*10 + int(cuda_major_minor[1]) + + if cuda_version != 50: + print("CUDA version %d.%d detected, build may succeed but only CUDA 5.0 is officially supported." % (cuda_version/10, cuda_version%10)) + # nvcc flags nvcc_flags = "-m%s" % (bits) - nvcc_flags += " --cubin --ptxas-options=\"-v\" --maxrregcount=24" - nvcc_flags += " --opencc-options -OPT:Olimit=0" + nvcc_flags += " --cubin --ptxas-options=\"-v\"" + nvcc_flags += " -D__KERNEL_CUDA_VERSION__=%d" % (cuda_version) nvcc_flags += " -DCCL_NAMESPACE_BEGIN= -DCCL_NAMESPACE_END= -DNVCC" nvcc_flags += " -I \"%s\" -I \"%s\" -I \"%s\"" % (util_dir, svm_dir, closure_dir) @@ -75,7 +86,31 @@ if env['WITH_BF_CYCLES_CUDA_BINARIES']: for arch in cuda_archs: cubin_file = os.path.join(build_dir, "kernel_%s.cubin" % arch) - command = "\"%s\" -arch=%s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, kernel_file, cubin_file) + # build flags depending on CUDA version and arch + if cuda_version < 50: + # CUDA 4.x + if arch.startswith("sm_1"): + # sm_1x + cuda_arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0" + elif arch.startswith("sm_2"): + # sm_2x + cuda_arch_flags = "--maxrregcount=24" + else: + # sm_3x + cuda_arch_flags = "--maxrregcount=32" + else: + # CUDA 5.x + if arch.startswith("sm_1"): + # sm_1x + cuda_arch_flags = "--maxrregcount=24 --opencc-options -OPT:Olimit=0 --use_fast_math" + elif arch.startswith("sm_2"): + # sm_2x + cuda_arch_flags = "--maxrregcount=32 --use_fast_math" + else: + # sm_3x + cuda_arch_flags = "--maxrregcount=32 --use_fast_math" + + command = "\"%s\" -arch=%s %s %s \"%s\" -o \"%s\"" % (nvcc, arch, nvcc_flags, cuda_arch_flags, kernel_file, cubin_file) kernel.Command(cubin_file, 'kernel.cu', command) kernel.Depends(cubin_file, dependencies) diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h index 17704b48cee..3e1a18ab469 100644 --- a/intern/cycles/kernel/kernel_jitter.h +++ b/intern/cycles/kernel/kernel_jitter.h @@ -137,7 +137,7 @@ __device_inline float cmj_randfloat(uint i, uint p) } #ifdef __CMJ__ -__device_noinline float cmj_sample_1D(int s, int N, int p) +__device float cmj_sample_1D(int s, int N, int p) { uint x = cmj_permute(s, N, p * 0x68bc21eb); float jx = cmj_randfloat(s, p * 0x967a889b); @@ -146,7 +146,7 @@ __device_noinline float cmj_sample_1D(int s, int N, int p) return (x + jx)*invN; } -__device_noinline void cmj_sample_2D(int s, int N, int p, float *fx, float *fy) +__device void cmj_sample_2D(int s, int N, int p, float *fx, float *fy) { int m = float_to_int(sqrtf(N)); int n = (N + m - 1)/m; diff --git a/intern/cycles/kernel/kernel_shader.h b/intern/cycles/kernel/kernel_shader.h index 7e41ee35ae0..039981a031a 100644 --- a/intern/cycles/kernel/kernel_shader.h +++ b/intern/cycles/kernel/kernel_shader.h @@ -38,7 +38,12 @@ CCL_NAMESPACE_BEGIN /* ShaderData setup from incoming ray */ #ifdef __OBJECT_MOTION__ -__device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time) +#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42 +__device_noinline +#else +__device +#endif +void shader_setup_object_transforms(KernelGlobals *kg, ShaderData *sd, float time) { /* note that this is a separate non-inlined function to work around crash * on CUDA sm 2.0, otherwise kernel execution crashes (compiler bug?) */ @@ -53,7 +58,12 @@ __device_noinline void shader_setup_object_transforms(KernelGlobals *kg, ShaderD } #endif -__device_noinline void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, +#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42 +__device_noinline +#else +__device +#endif +void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd, const Intersection *isect, const Ray *ray) { #ifdef __INSTANCING__ @@ -260,7 +270,12 @@ __device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderData /* ShaderData setup from position sampled on mesh */ -__device_noinline void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, +#if defined(__KERNEL_CUDA_VERSION__) && __KERNEL_CUDA_VERSION__ <= 42 +__device_noinline +#else +__device +#endif +void shader_setup_from_sample(KernelGlobals *kg, ShaderData *sd, const float3 P, const float3 Ng, const float3 I, int shader, int object, int prim, float u, float v, float t, float time, int segment) { diff --git a/intern/cycles/util/util_cuda.cpp b/intern/cycles/util/util_cuda.cpp index 6c9ee7c548f..42ffb04a793 100644 --- a/intern/cycles/util/util_cuda.cpp +++ b/intern/cycles/util/util_cuda.cpp @@ -16,6 +16,8 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +#include + #include #include @@ -25,6 +27,11 @@ #include "util_path.h" #include "util_string.h" +#ifdef _WIN32 +#define popen _popen +#define pclose _pclose +#endif + /* function defininitions */ tcuInit *cuInit; @@ -399,7 +406,15 @@ string cuCompilerPath() const char *defaultpaths[] = {"C:/CUDA/bin", NULL}; const char *executable = "nvcc.exe"; #else - const char *defaultpaths[] = {"/Developer/NVIDIA/CUDA-4.2/bin", "/usr/local/cuda-4.2/bin", "/usr/local/cuda/bin", NULL}; + const char *defaultpaths[] = { + "/Developer/NVIDIA/CUDA-5.0/bin", + "/usr/local/cuda-5.0/bin", + "/usr/local/cuda/bin", + "/Developer/NVIDIA/CUDA-4.2/bin", + "/usr/local/cuda-4.2/bin", + "/Developer/NVIDIA/CUDA-5.5/bin", + "/usr/local/cuda-5.5/bin", + NULL}; const char *executable = "nvcc"; #endif @@ -437,5 +452,46 @@ string cuCompilerPath() return ""; } +int cuCompilerVersion() +{ + string path = cuCompilerPath(); + if(path == "") + return 0; + + /* get --version output */ + FILE *pipe = popen((path + " --version").c_str(), "r"); + if(!pipe) { + fprintf(stderr, "CUDA: failed to run compiler to retrieve version"); + return 0; + } + + char buf[128]; + string output = ""; + + while(!feof(pipe)) + if(fgets(buf, 128, pipe) != NULL) + output += buf; + + pclose(pipe); + + /* parse version number */ + string marker = "Cuda compilation tools, release "; + size_t offset = output.find(marker); + if(offset == string::npos) { + fprintf(stderr, "CUDA: failed to find version number in:\n\n%s\n", output.c_str()); + return 0; + } + + string versionstr = output.substr(offset + marker.size(), string::npos); + int major, minor; + + if(sscanf(versionstr.c_str(), "%d.%d", &major, &minor) < 2) { + fprintf(stderr, "CUDA: failed to parse version number from:\n\n%s\n", output.c_str()); + return 0; + } + + return 10*major + minor; +} + CCL_NAMESPACE_END diff --git a/intern/cycles/util/util_cuda.h b/intern/cycles/util/util_cuda.h index 55feb3f84cb..ba4df0de90a 100644 --- a/intern/cycles/util/util_cuda.h +++ b/intern/cycles/util/util_cuda.h @@ -32,6 +32,7 @@ CCL_NAMESPACE_BEGIN bool cuLibraryInit(); bool cuHavePrecompiledKernels(); string cuCompilerPath(); +int cuCompilerVersion(); CCL_NAMESPACE_END From f811e6e3ae79be46144d33baf11dbfb618fd4315 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 19 Jun 2013 17:54:26 +0000 Subject: [PATCH 10/24] Cycles: optimized SSE BVH traversal now also works with SSE2 CPUs, so all the way back to Pentium 4, using a slightly less efficient instruction. Also ensure /Ox is used for Visual Studio for RelWithDebInfo builds. --- intern/cycles/CMakeLists.txt | 9 ++-- intern/cycles/SConscript | 8 +-- intern/cycles/kernel/kernel_bvh_traversal.h | 54 +++++++++++---------- intern/cycles/util/util_types.h | 51 +++++++++++++++++-- 4 files changed, 85 insertions(+), 37 deletions(-) diff --git a/intern/cycles/CMakeLists.txt b/intern/cycles/CMakeLists.txt index 06f780eb86f..cc132a2c3b2 100644 --- a/intern/cycles/CMakeLists.txt +++ b/intern/cycles/CMakeLists.txt @@ -13,11 +13,14 @@ if(WITH_RAYOPTIMIZATION AND SUPPORT_SSE_BUILD) endif() if(WIN32 AND MSVC) - set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /GS-") # there is no /arch:SSE3, but intrinsics are available anyway - set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /GS-") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /EHsc /GS-") + set(CYCLES_SSE2_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-") + set(CYCLES_SSE3_KERNEL_FLAGS "/arch:SSE2 /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-") + + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:fast -D_CRT_SECURE_NO_WARNINGS /Gs-") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /Ox") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELEASE} /Ox") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_RELEASE} /Ox") elseif(CMAKE_COMPILER_IS_GNUCC) set(CYCLES_SSE2_KERNEL_FLAGS "-ffast-math -msse -msse2 -mfpmath=sse") set(CYCLES_SSE3_KERNEL_FLAGS "-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse") diff --git a/intern/cycles/SConscript b/intern/cycles/SConscript index 57f44ae9d52..d1f1b287e00 100644 --- a/intern/cycles/SConscript +++ b/intern/cycles/SConscript @@ -79,12 +79,12 @@ if env['WITH_BF_RAYOPTIMIZATION']: sse3_cxxflags = Split(env['CXXFLAGS']) if env['OURPLATFORM'] == 'win32-vc': - sse2_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /Gs-'.split()) # there is no /arch:SSE3, but intrinsics are available anyway - sse3_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /Gs-'.split()) + sse2_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split()) + sse3_cxxflags.append('/arch:SSE /arch:SSE2 -D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split()) elif env['OURPLATFORM'] == 'win64-vc': - sse2_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /Gs-'.split()) - sse3_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /EHsc /Ox /Gs-'.split()) + sse2_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split()) + sse3_cxxflags.append('-D_CRT_SECURE_NO_WARNINGS /fp:fast /Ox /Gs-'.split()) else: sse2_cxxflags.append('-ffast-math -msse -msse2 -mfpmath=sse'.split()) sse3_cxxflags.append('-ffast-math -msse -msse2 -msse3 -mssse3 -mfpmath=sse'.split()) diff --git a/intern/cycles/kernel/kernel_bvh_traversal.h b/intern/cycles/kernel/kernel_bvh_traversal.h index 900aa7e75fb..8d423b7e7ce 100644 --- a/intern/cycles/kernel/kernel_bvh_traversal.h +++ b/intern/cycles/kernel/kernel_bvh_traversal.h @@ -80,10 +80,10 @@ __device bool BVH_FUNCTION_NAME isect->u = 0.0f; isect->v = 0.0f; -#if defined(__KERNEL_SSSE3__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) - const __m128i shuffle_identity = _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); - const __m128i shuffle_swap = _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); - +#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) + const shuffle_swap_t shuf_identity = shuffle_swap_identity(); + const shuffle_swap_t shuf_swap = shuffle_swap_swap(); + const __m128i pn = _mm_set_epi32(0x80000000, 0x80000000, 0x00000000, 0x00000000); __m128 Psplat[3], idirsplat[3]; @@ -97,9 +97,9 @@ __device bool BVH_FUNCTION_NAME __m128 tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f); - __m128i shufflex = (idir.x >= 0)? shuffle_identity: shuffle_swap; - __m128i shuffley = (idir.y >= 0)? shuffle_identity: shuffle_swap; - __m128i shufflez = (idir.z >= 0)? shuffle_identity: shuffle_swap; + shuffle_swap_t shufflex = (idir.x >= 0)? shuf_identity: shuf_swap; + shuffle_swap_t shuffley = (idir.y >= 0)? shuf_identity: shuf_swap; + shuffle_swap_t shufflez = (idir.z >= 0)? shuf_identity: shuf_swap; #endif /* traversal loop */ @@ -112,7 +112,7 @@ __device bool BVH_FUNCTION_NAME bool traverseChild0, traverseChild1; int nodeAddrChild1; -#if !defined(__KERNEL_SSSE3__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if !defined(__KERNEL_SSE2__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH) /* Intersect two child bounding boxes, non-SSE version */ float t = isect->t; @@ -166,20 +166,20 @@ __device bool BVH_FUNCTION_NAME traverseChild1 = (c1max >= c1min); #endif -#else // __KERNEL_SSSE3__ - /* Intersect two child bounding boxes, SSSE3 version adapted from Embree */ +#else // __KERNEL_SSE2__ + /* Intersect two child bounding boxes, SSE3 version adapted from Embree */ /* fetch node data */ __m128 *bvh_nodes = (__m128*)kg->__bvh_nodes.data + nodeAddr*BVH_NODE_SIZE; float4 cnodes = ((float4*)bvh_nodes)[3]; /* intersect ray against child nodes */ - const __m128 tminmaxx = _mm_mul_ps(_mm_sub_ps(shuffle8(bvh_nodes[0], shufflex), Psplat[0]), idirsplat[0]); - const __m128 tminmaxy = _mm_mul_ps(_mm_sub_ps(shuffle8(bvh_nodes[1], shuffley), Psplat[1]), idirsplat[1]); - const __m128 tminmaxz = _mm_mul_ps(_mm_sub_ps(shuffle8(bvh_nodes[2], shufflez), Psplat[2]), idirsplat[2]); + const __m128 tminmaxx = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[0], shufflex), Psplat[0]), idirsplat[0]); + const __m128 tminmaxy = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[1], shuffley), Psplat[1]), idirsplat[1]); + const __m128 tminmaxz = _mm_mul_ps(_mm_sub_ps(shuffle_swap(bvh_nodes[2], shufflez), Psplat[2]), idirsplat[2]); const __m128 tminmax = _mm_xor_ps(_mm_max_ps(_mm_max_ps(tminmaxx, tminmaxy), _mm_max_ps(tminmaxz, tsplat)), _mm_castsi128_ps(pn)); - const __m128 lrhit = _mm_cmple_ps(tminmax, shuffle8(tminmax, shuffle_swap)); + const __m128 lrhit = _mm_cmple_ps(tminmax, shuffle_swap(tminmax, shuf_swap)); /* decide which nodes to traverse next */ #ifdef __VISIBILITY_FLAG__ @@ -190,14 +190,14 @@ __device bool BVH_FUNCTION_NAME traverseChild0 = (_mm_movemask_ps(lrhit) & 1); traverseChild1 = (_mm_movemask_ps(lrhit) & 2); #endif -#endif // __KERNEL_SSSE3__ +#endif // __KERNEL_SSE2__ nodeAddr = __float_as_int(cnodes.x); nodeAddrChild1 = __float_as_int(cnodes.y); if(traverseChild0 && traverseChild1) { /* both children were intersected, push the farther one */ -#if !defined(__KERNEL_SSSE3__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if !defined(__KERNEL_SSE2__) || FEATURE(BVH_HAIR_MINIMUM_WIDTH) bool closestChild1 = (c1min < c0min); #else union { __m128 m128; float v[4]; } uminmax; @@ -244,6 +244,7 @@ __device bool BVH_FUNCTION_NAME /* primitive intersection */ while(primAddr < primAddr2) { bool hit; + #if FEATURE(BVH_SUBSURFACE) /* only primitives from the same object */ uint tri_object = (object == ~0)? kernel_tex_fetch(__prim_object, primAddr): object; @@ -275,14 +276,17 @@ __device bool BVH_FUNCTION_NAME #if FEATURE(BVH_HAIR) if(segment == ~0) #endif + { hit = bvh_triangle_intersect_subsurface(kg, isect, P, idir, object, primAddr, tmax, &num_hits, subsurface_random); + (void)hit; + } } #else hit = bvh_triangle_intersect(kg, isect, P, idir, visibility, object, primAddr); /* shadow ray early termination */ -#if defined(__KERNEL_SSSE3__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) if(hit) { if(visibility == PATH_RAY_SHADOW_OPAQUE) return true; @@ -315,7 +319,7 @@ __device bool BVH_FUNCTION_NAME bvh_instance_push(kg, object, ray, &P, &idir, &isect->t, tmax); #endif -#if defined(__KERNEL_SSSE3__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) Psplat[0] = _mm_set_ps1(P.x); Psplat[1] = _mm_set_ps1(P.y); Psplat[2] = _mm_set_ps1(P.z); @@ -326,9 +330,9 @@ __device bool BVH_FUNCTION_NAME tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f); - shufflex = (idir.x >= 0)? shuffle_identity: shuffle_swap; - shuffley = (idir.y >= 0)? shuffle_identity: shuffle_swap; - shufflez = (idir.z >= 0)? shuffle_identity: shuffle_swap; + shufflex = (idir.x >= 0)? shuf_identity: shuf_swap; + shuffley = (idir.y >= 0)? shuf_identity: shuf_swap; + shufflez = (idir.z >= 0)? shuf_identity: shuf_swap; #endif ++stackPtr; @@ -359,7 +363,7 @@ __device bool BVH_FUNCTION_NAME bvh_instance_pop(kg, object, ray, &P, &idir, &isect->t, tmax); #endif -#if defined(__KERNEL_SSSE3__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) +#if defined(__KERNEL_SSE2__) && !FEATURE(BVH_HAIR_MINIMUM_WIDTH) Psplat[0] = _mm_set_ps1(P.x); Psplat[1] = _mm_set_ps1(P.y); Psplat[2] = _mm_set_ps1(P.z); @@ -370,9 +374,9 @@ __device bool BVH_FUNCTION_NAME tsplat = _mm_set_ps(-isect->t, -isect->t, 0.0f, 0.0f); - shufflex = (idir.x >= 0)? shuffle_identity: shuffle_swap; - shuffley = (idir.y >= 0)? shuffle_identity: shuffle_swap; - shufflez = (idir.z >= 0)? shuffle_identity: shuffle_swap; + shufflex = (idir.x >= 0)? shuf_identity: shuf_swap; + shuffley = (idir.y >= 0)? shuf_identity: shuf_swap; + shufflez = (idir.z >= 0)? shuf_identity: shuf_swap; #endif object = ~0; diff --git a/intern/cycles/util/util_types.h b/intern/cycles/util/util_types.h index d0116186ee8..4fd1e9d8807 100644 --- a/intern/cycles/util/util_types.h +++ b/intern/cycles/util/util_types.h @@ -76,8 +76,8 @@ #define __KERNEL_SSE2__ #endif -#ifndef __KERNEL_SSSE3__ -#define __KERNEL_SSSE3__ +#ifndef __KERNEL_SSE3__ +#define __KERNEL_SSE3__ #endif #ifndef __KERNEL_SSSE3__ @@ -100,7 +100,7 @@ #include /* SSE 1 */ #include /* SSE 2 */ -#ifdef __KERNEL_SSSE3__ +#ifdef __KERNEL_SSE3__ #include /* SSE 3 */ #endif #ifdef __KERNEL_SSSE3__ @@ -491,15 +491,56 @@ __device_inline int4 make_int4(const float3& f) #endif -#ifdef __KERNEL_SSSE3__ +#ifdef __KERNEL_SSE2__ /* SSE shuffle utility functions */ -__device_inline const __m128 shuffle8(const __m128& a, const __m128i& shuf) +#ifdef __KERNEL_SSSE3__ + +/* faster version for SSSE3 */ +typedef __m128i shuffle_swap_t; + +__device_inline const shuffle_swap_t shuffle_swap_identity(void) +{ + return _mm_set_epi8(15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0); +} + +__device_inline const shuffle_swap_t shuffle_swap_swap(void) +{ + return _mm_set_epi8(7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8); +} + +__device_inline const __m128 shuffle_swap(const __m128& a, const shuffle_swap_t& shuf) { return _mm_castsi128_ps(_mm_shuffle_epi8(_mm_castps_si128(a), shuf)); } +#else + +/* somewhat slower version for SSE3 */ +typedef int shuffle_swap_t; + +__device_inline const shuffle_swap_t shuffle_swap_identity(void) +{ + return 0; +} + +__device_inline const shuffle_swap_t shuffle_swap_swap(void) +{ + return 1; +} + +__device_inline const __m128 shuffle_swap(const __m128& a, shuffle_swap_t shuf) +{ + /* shuffle value must be a constant, so we need to branch */ + if(shuf) + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + else + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 1, 0)); +} + +#endif + template __device_inline const __m128 shuffle(const __m128& a, const __m128& b) { return _mm_shuffle_ps(a, b, _MM_SHUFFLE(i3, i2, i1, i0)); From 06e1bc6178fc22178b79763d392c8d58d06285fe Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 18:22:00 +0000 Subject: [PATCH 11/24] internal editmesh api: add an extended version of EDBM_verts_mirror_cache_begin which takes arguments to give some more control. --- source/blender/editors/include/ED_mesh.h | 2 + source/blender/editors/mesh/editmesh_utils.c | 76 +++++++++++++------- 2 files changed, 53 insertions(+), 25 deletions(-) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 097ea477501..f35edb70251 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -76,6 +76,8 @@ struct MeshStatVis; /* editmesh_utils.c */ +void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em, const bool use_self, const bool use_select, + const bool is_topo, float maxdist, int *r_index); void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const bool use_self, const bool use_select); void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to); struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index fa857edb6fc..ae2b25084bd 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1144,46 +1144,58 @@ static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index) * preference */ #define BM_SEARCH_MAXDIST_MIRR 0.00002f #define BM_CD_LAYER_ID "__mirror_index" -void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select) +/** + * \param em Editmesh. + * \param use_self Allow a vertex to point to its self (middle verts). + * \param use_select Restrict to selected verts. + * \param is_topo Use topology mirror. + * \param maxdist Distance for close point test. + * \param r_index Optional array to write into, as an alternative to a customdata layer (length of total verts). + */ +void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const bool use_select, + /* extra args */ + const bool is_topo, float maxdist, int *r_index) { Mesh *me = (Mesh *)em->ob->data; BMesh *bm = em->bm; BMIter iter; BMVert *v; - bool topo = false; int cd_vmirr_offset; + int i; /* one or the other is used depending if topo is enabled */ struct BMBVHTree *tree = NULL; MirrTopoStore_t mesh_topo_store = {NULL, -1, -1, -1}; - if (me && (me->editflag & ME_EDIT_MIRROR_TOPO)) { - topo = 1; - } - EDBM_index_arrays_ensure(em, BM_VERT); - em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); - if (em->mirror_cdlayer == -1) { - BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); - em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, BM_CD_LAYER_ID); + if (r_index == NULL) { + const char *layer_id = BM_CD_LAYER_ID; + em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id); + if (em->mirror_cdlayer == -1) { + BM_data_layer_add_named(bm, &bm->vdata, CD_PROP_INT, layer_id); + em->mirror_cdlayer = CustomData_get_named_layer_index(&bm->vdata, CD_PROP_INT, layer_id); + } + + cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT, + em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT)); + + bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY; } - cd_vmirr_offset = CustomData_get_n_offset(&bm->vdata, CD_PROP_INT, - em->mirror_cdlayer - CustomData_get_layer_index(&bm->vdata, CD_PROP_INT)); - - bm->vdata.layers[em->mirror_cdlayer].flag |= CD_FLAG_TEMPORARY; - BM_mesh_elem_index_ensure(bm, BM_VERT); - if (topo) { + if (is_topo) { ED_mesh_mirrtopo_init(me, -1, &mesh_topo_store, true); } else { tree = BKE_bmbvh_new(em, 0, NULL, false); } - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { +#define VERT_INTPTR(_v, _i) r_index ? &r_index[_i] : BM_ELEM_CD_GET_VOID_P(_v, cd_vmirr_offset); + + BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { + BLI_assert(BM_elem_index_get(v) == i); /* temporary for testing, check for selection */ if (use_select && !BM_elem_flag_test(v, BM_ELEM_SELECT)) { @@ -1191,20 +1203,21 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } else { BMVert *v_mirr; - int *idx = BM_ELEM_CD_GET_VOID_P(v, cd_vmirr_offset); + int *idx = VERT_INTPTR(v, i); - if (topo) { - v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, BM_elem_index_get(v)); + if (is_topo) { + v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i); } else { float co[3] = {-v->co[0], v->co[1], v->co[2]}; - v_mirr = BKE_bmbvh_find_vert_closest(tree, co, BM_SEARCH_MAXDIST_MIRR); + v_mirr = BKE_bmbvh_find_vert_closest(tree, co, maxdist); } if (v_mirr && (use_self || (v_mirr != v))) { - *idx = BM_elem_index_get(v_mirr); - idx = BM_ELEM_CD_GET_VOID_P(v_mirr, cd_vmirr_offset); - *idx = BM_elem_index_get(v); + const int i_mirr = BM_elem_index_get(v_mirr); + *idx = i_mirr; + idx = VERT_INTPTR(v_mirr, i_mirr); + *idx = i; } else { *idx = -1; @@ -1213,8 +1226,9 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } +#undef VERT_INTPTR - if (topo) { + if (is_topo) { ED_mesh_mirrtopo_free(&mesh_topo_store); } else { @@ -1222,6 +1236,18 @@ void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bo } } +void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select) +{ + Mesh *me = (Mesh *)em->ob->data; + bool is_topo; + + is_topo = (me && (me->editflag & ME_EDIT_MIRROR_TOPO)); + + EDBM_verts_mirror_cache_begin_ex(em, use_self, use_select, + /* extra args */ + is_topo, BM_SEARCH_MAXDIST_MIRR, NULL); +} + BMVert *EDBM_verts_mirror_get(BMEditMesh *em, BMVert *v) { int *mirr = CustomData_bmesh_get_layer_n(&em->bm->vdata, v->head.data, em->mirror_cdlayer); From d54d00ef845a7bb4f0d8e08133b2489983dbe907 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 18:59:54 +0000 Subject: [PATCH 12/24] Remove paranoid null checks for editmesh EDBM_vert_at_index and friends (use asserts instead). temp set BM_OMP_LIMIT to zero for better testing before release. --- source/blender/bmesh/bmesh_class.h | 2 +- source/blender/bmesh/intern/bmesh_marking.c | 6 ++++++ source/blender/bmesh/intern/bmesh_mesh.c | 2 ++ source/blender/editors/mesh/editmesh_utils.c | 9 ++++++--- source/blender/editors/space_view3d/view3d_iterators.c | 2 +- 5 files changed, 16 insertions(+), 5 deletions(-) diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h index 8d95ab85df8..c92b049eafb 100644 --- a/source/blender/bmesh/bmesh_class.h +++ b/source/blender/bmesh/bmesh_class.h @@ -290,6 +290,6 @@ extern void bpy_bm_generic_invalidate(struct BPy_BMGeneric *self); * but should not error on valid cases */ #define BM_LOOP_RADIAL_MAX 10000 #define BM_NGON_MAX 100000 -#define BM_OMP_LIMIT 10000 /* setting zero so we can catch bugs in OpenMP/BMesh */ +#define BM_OMP_LIMIT 0 /* 10000 */ /* setting zero so we can catch bugs in OpenMP/BMesh */ #endif /* __BMESH_CLASS_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_marking.c b/source/blender/bmesh/intern/bmesh_marking.c index 2608a79d455..313d76721fa 100644 --- a/source/blender/bmesh/intern/bmesh_marking.c +++ b/source/blender/bmesh/intern/bmesh_marking.c @@ -498,6 +498,8 @@ static int bm_mesh_flag_count(BMesh *bm, const char htype, const char hflag, BMIter iter; int tot = 0; + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + if (htype & BM_VERT) { for (ele = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL); ele; ele = BM_iter_step(&iter)) { if (respecthide && BM_elem_flag_test(ele, BM_ELEM_HIDDEN)) continue; @@ -803,6 +805,8 @@ void BM_mesh_elem_hflag_disable_test(BMesh *bm, const char htype, const char hfl int i; + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + if (hflag & BM_ELEM_SELECT) { BM_select_history_clear(bm); } @@ -872,6 +876,8 @@ void BM_mesh_elem_hflag_enable_test(BMesh *bm, const char htype, const char hfla BMElem *ele; int i; + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + if (hflag & BM_ELEM_SELECT) { BM_select_history_clear(bm); } diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 79dacaad2fa..4027d4b2c19 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -628,6 +628,8 @@ void BM_mesh_elem_index_validate(BMesh *bm, const char *location, const char *fu */ int BM_mesh_elem_count(BMesh *bm, const char htype) { + BLI_assert((htype & ~BM_ALL_NOLOOP) == 0); + switch (htype) { case BM_VERT: return bm->totvert; case BM_EDGE: return bm->totedge; diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index ae2b25084bd..963b9cf134b 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -507,17 +507,20 @@ bool EDBM_index_arrays_check(BMEditMesh *em) BMVert *EDBM_vert_at_index(BMEditMesh *em, int index) { - return em->vert_index && index < em->bm->totvert ? em->vert_index[index] : NULL; + BLI_assert((index >= 0) && (index < em->bm->totvert)); + return em->vert_index[index]; } BMEdge *EDBM_edge_at_index(BMEditMesh *em, int index) { - return em->edge_index && index < em->bm->totedge ? em->edge_index[index] : NULL; + BLI_assert((index >= 0) && (index < em->bm->totedge)); + return em->edge_index[index]; } BMFace *EDBM_face_at_index(BMEditMesh *em, int index) { - return (em->face_index && index < em->bm->totface && index >= 0) ? em->face_index[index] : NULL; + BLI_assert((index >= 0) && (index < em->bm->totface)); + return em->face_index[index]; } void EDBM_selectmode_flush_ex(BMEditMesh *em, const short selectmode) diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 9e310c84bd0..180686b4b82 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -237,7 +237,7 @@ static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const flo foreachScreenFace_userData *data = userData; BMFace *efa = EDBM_face_at_index(data->vc.em, index); - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { float screen_co[2]; if (ED_view3d_project_float_object(data->vc.ar, cent, screen_co, data->clip_flag) == V3D_PROJ_RET_OK) { data->func(data->userData, efa, screen_co, index); From 881dbac5d93cffd2f6a9f5c3896d1c84ebfd0ce5 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 19 Jun 2013 19:37:17 +0000 Subject: [PATCH 13/24] This commit tackles the "context" buttons in Properties header, which were still using "ugly" old UI code. It removes buttons_header.c file, adds a (small) space_properties.py one, with a PROPERTIES_HT_header class, which simply uses the RNA enum to draw the context buttons. It also fixes that enum, btw, it always featured all contexts, which means you could (try to!) set through RNA invalid contexts... Thanks to brecht and dingto for the reviews. --- release/scripts/startup/bl_ui/__init__.py | 1 + .../scripts/startup/bl_ui/space_properties.py | 46 ++++++ .../editors/space_buttons/CMakeLists.txt | 1 - .../editors/space_buttons/buttons_header.c | 140 ------------------ .../editors/space_buttons/buttons_intern.h | 3 - .../editors/space_buttons/space_buttons.c | 19 +-- source/blender/makesrna/intern/rna_space.c | 109 +++++++++++--- 7 files changed, 144 insertions(+), 175 deletions(-) create mode 100644 release/scripts/startup/bl_ui/space_properties.py delete mode 100644 source/blender/editors/space_buttons/buttons_header.c diff --git a/release/scripts/startup/bl_ui/__init__.py b/release/scripts/startup/bl_ui/__init__.py index 868fa2a311c..594f724c6e3 100644 --- a/release/scripts/startup/bl_ui/__init__.py +++ b/release/scripts/startup/bl_ui/__init__.py @@ -68,6 +68,7 @@ _modules = [ "space_nla", "space_node", "space_outliner", + "space_properties", "space_sequencer", "space_text", "space_time", diff --git a/release/scripts/startup/bl_ui/space_properties.py b/release/scripts/startup/bl_ui/space_properties.py new file mode 100644 index 00000000000..758713b5cc4 --- /dev/null +++ b/release/scripts/startup/bl_ui/space_properties.py @@ -0,0 +1,46 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +# +import bpy +from bpy.types import Header + + +class PROPERTIES_HT_header(Header): + bl_space_type = 'PROPERTIES' + + def draw(self, context): + layout = self.layout + + view = context.space_data + + row = layout.row() + row.template_header(menus=False) + row.prop(view, "context", expand=True, icon_only=True) + + +def register(): + bpy.utils.register_module(__name__) + + +def unregister(): + bpy.utils.unregister_module(__name__) + + +if __name__ == "__main__": + register() diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index b20301cfc3b..9e045a39a0c 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -35,7 +35,6 @@ set(INC_SYS set(SRC buttons_context.c - buttons_header.c buttons_ops.c buttons_texture.c space_buttons.c diff --git a/source/blender/editors/space_buttons/buttons_header.c b/source/blender/editors/space_buttons/buttons_header.c deleted file mode 100644 index 44c76d7a9a2..00000000000 --- a/source/blender/editors/space_buttons/buttons_header.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * ***** BEGIN GPL LICENSE BLOCK ***** - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - * - * The Original Code is Copyright (C) 2008 Blender Foundation. - * All rights reserved. - * - * - * Contributor(s): Blender Foundation - * - * ***** END GPL LICENSE BLOCK ***** - */ - -/** \file blender/editors/space_buttons/buttons_header.c - * \ingroup spbuttons - */ - - -#include -#include - -#include "BLI_blenlib.h" -#include "BLI_utildefines.h" - -#include "BLF_translation.h" - -#include "BKE_context.h" -#include "BKE_modifier.h" -#include "BKE_paint.h" -#include "BKE_scene.h" - -#include "ED_buttons.h" -#include "ED_screen.h" -#include "ED_types.h" - -#include "DNA_brush_types.h" -#include "DNA_object_force.h" -#include "DNA_object_types.h" - -#include "UI_interface.h" -#include "UI_resources.h" -#include "UI_view2d.h" - -#include "buttons_intern.h" - - -#define B_CONTEXT_SWITCH 101 - -static void do_buttons_buttons(bContext *C, void *UNUSED(arg), int event) -{ - SpaceButs *sbuts = CTX_wm_space_buts(C); - - if (!sbuts) /* editor type switch */ - return; - - switch (event) { - case B_CONTEXT_SWITCH: - ED_area_tag_redraw(CTX_wm_area(C)); - - sbuts->preview = 1; - break; - } - - sbuts->mainbuser = sbuts->mainb; -} - -#define BUT_UNIT_X (UI_UNIT_X + 2 * U.pixelsize) - -void buttons_header_buttons(const bContext *C, ARegion *ar) -{ - SpaceButs *sbuts = CTX_wm_space_buts(C); - uiBlock *block; - uiBut *but; - int headery = ED_area_headersize(); - int xco, yco = 0.5f * (headery - UI_UNIT_Y); - - buttons_context_compute(C, sbuts); - - block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); - uiBlockSetHandleFunc(block, do_buttons_buttons, NULL); - - xco = ED_area_header_switchbutton(C, block, yco); - - uiBlockSetEmboss(block, UI_EMBOSS); - - xco -= UI_UNIT_X; - - /* Default panels */ - - uiBlockBeginAlign(block); - -#define BUTTON_HEADER_CTX(_ctx, _icon, _tip) \ - if (sbuts->pathflag & (1 << _ctx)) { \ - but = uiDefIconButS(block, ROW, B_CONTEXT_SWITCH, _icon, xco += BUT_UNIT_X, yco, BUT_UNIT_X, UI_UNIT_Y, \ - &(sbuts->mainb), 0.0, (float)_ctx, 0, 0, TIP_(_tip)); \ - uiButClearFlag(but, UI_BUT_UNDO); \ - } (void)0 - - BUTTON_HEADER_CTX(BCONTEXT_RENDER, ICON_SCENE, N_("Render")); - BUTTON_HEADER_CTX(BCONTEXT_RENDER_LAYER, ICON_RENDERLAYERS, N_("Render Layers")); - BUTTON_HEADER_CTX(BCONTEXT_SCENE, ICON_SCENE_DATA, N_("Scene")); - BUTTON_HEADER_CTX(BCONTEXT_WORLD, ICON_WORLD, N_("World")); - BUTTON_HEADER_CTX(BCONTEXT_OBJECT, ICON_OBJECT_DATA, N_("Object")); - BUTTON_HEADER_CTX(BCONTEXT_CONSTRAINT, ICON_CONSTRAINT, N_("Object Constraints")); - BUTTON_HEADER_CTX(BCONTEXT_MODIFIER, ICON_MODIFIER, N_("Object Modifiers")); - BUTTON_HEADER_CTX(BCONTEXT_DATA, sbuts->dataicon, N_("Object Data")); - BUTTON_HEADER_CTX(BCONTEXT_BONE, ICON_BONE_DATA, N_("Bone")); - BUTTON_HEADER_CTX(BCONTEXT_BONE_CONSTRAINT, ICON_CONSTRAINT_BONE, N_("Bone Constraints")); - BUTTON_HEADER_CTX(BCONTEXT_MATERIAL, ICON_MATERIAL, N_("Material")); - BUTTON_HEADER_CTX(BCONTEXT_TEXTURE, ICON_TEXTURE, N_("Textures")); - BUTTON_HEADER_CTX(BCONTEXT_PARTICLE, ICON_PARTICLES, N_("Particles")); - BUTTON_HEADER_CTX(BCONTEXT_PHYSICS, ICON_PHYSICS, N_("Physics")); - -#undef BUTTON_HEADER_CTX - - xco += BUT_UNIT_X; - - uiBlockEndAlign(block); - - /* always as last */ - UI_view2d_totRect_set(&ar->v2d, xco + (UI_UNIT_X / 2), BLI_rctf_size_y(&ar->v2d.tot)); - - uiEndBlock(C, block); - uiDrawBlock(C, block); -} - - diff --git a/source/blender/editors/space_buttons/buttons_intern.h b/source/blender/editors/space_buttons/buttons_intern.h index 5700d361e15..f294729ae97 100644 --- a/source/blender/editors/space_buttons/buttons_intern.h +++ b/source/blender/editors/space_buttons/buttons_intern.h @@ -97,9 +97,6 @@ typedef struct ButsContextTexture { /* internal exports only */ -/* buttons_header.c */ -void buttons_header_buttons(const struct bContext *C, struct ARegion *ar); - /* buttons_context.c */ void buttons_context_compute(const struct bContext *C, struct SpaceButs *sbuts); int buttons_context(const struct bContext *C, const char *member, struct bContextDataResult *result); diff --git a/source/blender/editors/space_buttons/space_buttons.c b/source/blender/editors/space_buttons/space_buttons.c index 02b06e08eed..e6c6df416bf 100644 --- a/source/blender/editors/space_buttons/space_buttons.c +++ b/source/blender/editors/space_buttons/space_buttons.c @@ -87,7 +87,7 @@ static SpaceLink *buttons_new(const bContext *UNUSED(C)) BLI_addtail(&sbuts->regionbase, ar); ar->regiontype = RGN_TYPE_WINDOW; - + return (SpaceLink *)sbuts; } @@ -200,22 +200,17 @@ static void buttons_keymap(struct wmKeyConfig *keyconf) /* add handlers, stuff you only do once or on area/region changes */ static void buttons_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar) { - UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_HEADER, ar->winx, ar->winy); + ED_region_header_init(ar); } static void buttons_header_area_draw(const bContext *C, ARegion *ar) { - /* clear */ - UI_ThemeClearColor(ED_screen_area_active(C) ? TH_HEADER : TH_HEADERDESEL); - glClear(GL_COLOR_BUFFER_BIT); - - /* set view2d view matrix for scrolling (without scrollers) */ - UI_view2d_view_ortho(&ar->v2d); - - buttons_header_buttons(C, ar); + SpaceButs *sbuts = CTX_wm_space_buts(C); - /* restore view matrix? */ - UI_view2d_view_restore(C); + /* Needed for RNA to get the good values! */ + buttons_context_compute(C, sbuts); + + ED_region_header(C, ar); } /* draw a certain button set only if properties area is currently diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index 36da4e3508c..4513694e59d 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -137,6 +137,25 @@ EnumPropertyItem clip_editor_mode_items[] = { {0, NULL, 0, NULL, NULL} }; +/* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */ +static EnumPropertyItem buttons_context_items[] = { + {BCONTEXT_SCENE, "SCENE", ICON_SCENE_DATA, "Scene", "Scene"}, + {BCONTEXT_RENDER, "RENDER", ICON_SCENE, "Render", "Render"}, + {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render layers"}, + {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"}, + {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"}, + {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Object constraints"}, + {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Object modifiers"}, + {BCONTEXT_DATA, "DATA", ICON_NONE, "Data", "Object data"}, + {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"}, + {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone constraints"}, + {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"}, + {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"}, + {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"}, + {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"}, + {0, NULL, 0, NULL, NULL} +}; + /* Actually populated dynamically trough a function, but helps for context-less access (e.g. doc, i18n...). */ static EnumPropertyItem buttons_texture_context_items[] = { {SB_TEXC_MATERIAL, "MATERIAL", ICON_MATERIAL, "", "Show material textures"}, @@ -831,6 +850,76 @@ static void rna_SpaceProperties_context_set(PointerRNA *ptr, int value) sbuts->mainbuser = value; } +static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *C, PointerRNA *ptr, + PropertyRNA *UNUSED(prop), int *free) +{ + SpaceButs *sbuts = (SpaceButs *)(ptr->data); + EnumPropertyItem *item = NULL; + int totitem = 0; + + if (sbuts->pathflag & (1 << BCONTEXT_RENDER)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER); + } + + if (sbuts->pathflag & (1 << BCONTEXT_RENDER_LAYER)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_RENDER_LAYER); + } + + if (sbuts->pathflag & (1 << BCONTEXT_SCENE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_SCENE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_WORLD)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_WORLD); + } + + if (sbuts->pathflag & (1 << BCONTEXT_OBJECT)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_OBJECT); + } + + if (sbuts->pathflag & (1 << BCONTEXT_CONSTRAINT)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_CONSTRAINT); + } + + if (sbuts->pathflag & (1 << BCONTEXT_MODIFIER)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MODIFIER); + } + + if (sbuts->pathflag & (1 << BCONTEXT_DATA)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_DATA); + (item + totitem - 1)->icon = sbuts->dataicon; + } + + if (sbuts->pathflag & (1 << BCONTEXT_BONE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_BONE_CONSTRAINT)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_BONE_CONSTRAINT); + } + + if (sbuts->pathflag & (1 << BCONTEXT_MATERIAL)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_MATERIAL); + } + + if (sbuts->pathflag & (1 << BCONTEXT_TEXTURE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_TEXTURE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_PARTICLE)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PARTICLE); + } + + if (sbuts->pathflag & (1 << BCONTEXT_PHYSICS)) { + RNA_enum_items_add_value(&item, &totitem, buttons_context_items, BCONTEXT_PHYSICS); + } + + RNA_enum_item_end(&item, &totitem); + *free = 1; + + return item; +} + static void rna_SpaceProperties_align_set(PointerRNA *ptr, int value) { SpaceButs *sbuts = (SpaceButs *)(ptr->data); @@ -2068,24 +2157,6 @@ static void rna_def_space_buttons(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; - static EnumPropertyItem buttons_context_items[] = { - {BCONTEXT_SCENE, "SCENE", ICON_SCENE, "Scene", "Scene"}, - {BCONTEXT_RENDER, "RENDER", ICON_SCENE_DATA, "Render", "Render"}, - {BCONTEXT_RENDER_LAYER, "RENDER_LAYER", ICON_RENDERLAYERS, "Render Layers", "Render Layers"}, - {BCONTEXT_WORLD, "WORLD", ICON_WORLD, "World", "World"}, - {BCONTEXT_OBJECT, "OBJECT", ICON_OBJECT_DATA, "Object", "Object"}, - {BCONTEXT_CONSTRAINT, "CONSTRAINT", ICON_CONSTRAINT, "Constraints", "Constraints"}, - {BCONTEXT_MODIFIER, "MODIFIER", ICON_MODIFIER, "Modifiers", "Modifiers"}, - {BCONTEXT_DATA, "DATA", 0, "Data", "Data"}, - {BCONTEXT_BONE, "BONE", ICON_BONE_DATA, "Bone", "Bone"}, - {BCONTEXT_BONE_CONSTRAINT, "BONE_CONSTRAINT", ICON_CONSTRAINT, "Bone Constraints", "Bone Constraints"}, - {BCONTEXT_MATERIAL, "MATERIAL", ICON_MATERIAL, "Material", "Material"}, - {BCONTEXT_TEXTURE, "TEXTURE", ICON_TEXTURE, "Texture", "Texture"}, - {BCONTEXT_PARTICLE, "PARTICLES", ICON_PARTICLES, "Particles", "Particle"}, - {BCONTEXT_PHYSICS, "PHYSICS", ICON_PHYSICS, "Physics", "Physics"}, - {0, NULL, 0, NULL, NULL} - }; - static EnumPropertyItem align_items[] = { {BUT_HORIZONTAL, "HORIZONTAL", 0, "Horizontal", ""}, {BUT_VERTICAL, "VERTICAL", 0, "Vertical", ""}, @@ -2099,7 +2170,7 @@ static void rna_def_space_buttons(BlenderRNA *brna) prop = RNA_def_property(srna, "context", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "mainb"); RNA_def_property_enum_items(prop, buttons_context_items); - RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", NULL); + RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", "rna_SpaceProperties_context_itemf"); RNA_def_property_ui_text(prop, "Context", "Type of active data to display and edit"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, NULL); From 998101763aae5b0d25f6fa0f1a3227e45bb03b1e Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 19:59:49 +0000 Subject: [PATCH 14/24] correct for own regressions when refactoring select-path, was using heap popmin incorrectly. --- source/blender/blenlib/intern/BLI_heap.c | 3 +++ source/blender/bmesh/tools/bmesh_path.c | 9 ++++++--- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index a8fdcd56abb..2da36377e55 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -30,6 +30,7 @@ * \ingroup bli */ +#include #include #include "MEM_guardedalloc.h" @@ -207,6 +208,8 @@ void *BLI_heap_popmin(Heap *heap) { void *ptr = heap->tree[0]->ptr; + BLI_assert(heap->size == 0); + heap->tree[0]->ptr = heap->freenodes; heap->freenodes = heap->tree[0]; diff --git a/source/blender/bmesh/tools/bmesh_path.c b/source/blender/bmesh/tools/bmesh_path.c index eda252f18f5..9fc1996e51a 100644 --- a/source/blender/bmesh/tools/bmesh_path.c +++ b/source/blender/bmesh/tools/bmesh_path.c @@ -144,7 +144,8 @@ LinkNode *BM_mesh_calc_path_vert( BLI_heap_insert(heap, 0.0f, v_src); cost[BM_elem_index_get(v_src)] = 0.0f; - while ((v = BLI_heap_popmin(heap))) { + while (!BLI_heap_is_empty(heap)) { + v = BLI_heap_popmin(heap); if (v == v_dst) break; @@ -261,7 +262,8 @@ LinkNode *BM_mesh_calc_path_edge( BLI_heap_insert(heap, 0.0f, e_src); cost[BM_elem_index_get(e_src)] = 0.0f; - while ((e = BLI_heap_popmin(heap))) { + while (!BLI_heap_is_empty(heap)) { + e = BLI_heap_popmin(heap); if (e == e_dst) break; @@ -386,7 +388,8 @@ LinkNode *BM_mesh_calc_path_face( BLI_heap_insert(heap, 0.0f, f_src); cost[BM_elem_index_get(f_src)] = 0.0f; - while ((f = BLI_heap_popmin(heap))) { + while (!BLI_heap_is_empty(heap)) { + f = BLI_heap_popmin(heap); if (f == f_dst) break; From 93af050824170913d716e42e918ab58c224ed7f1 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 20:11:28 +0000 Subject: [PATCH 15/24] correct editmesh BKE_bmbvh_find_vert_closest(), distances are expected to be squared. --- source/blender/blenkernel/intern/editmesh_bvh.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c index 979a38f0346..160972889fd 100644 --- a/source/blender/blenkernel/intern/editmesh_bvh.c +++ b/source/blender/blenkernel/intern/editmesh_bvh.c @@ -382,7 +382,7 @@ static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float *U bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage); for (i = 0; i < 3; i++) { - dist = len_v3v3(hit->co, tri_cos[i]); + dist = len_squared_v3v3(hit->co, tri_cos[i]); if (dist < hit->dist && dist < maxdist) { copy_v3_v3(hit->co, tri_cos[i]); /* XXX, normal ignores cage */ @@ -398,17 +398,17 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const { BVHTreeNearest hit; struct VertSearchUserData bmcb_data; + const float maxdist_sq = maxdist * maxdist; if (bmtree->cos_cage) BLI_assert(!(bmtree->em->bm->elem_index_dirty & BM_VERT)); copy_v3_v3(hit.co, co); - /* XXX, why x5, scampbell */ - hit.dist = maxdist * 5; + hit.dist = maxdist_sq; hit.index = -1; bmcb_data.looptris = (const BMLoop *(*)[3])bmtree->em->looptris; bmcb_data.cos_cage = (const float (*)[3])bmtree->cos_cage; - bmcb_data.maxdist = maxdist; + bmcb_data.maxdist = maxdist_sq; BLI_bvhtree_find_nearest(bmtree->tree, co, &hit, bmbvh_find_vert_closest_cb, &bmcb_data); if (hit.dist != FLT_MAX && hit.index != -1) { From c33093ac085c117a0c3004c42def280c8c977ce3 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 20:43:38 +0000 Subject: [PATCH 16/24] BKE_bmbvh_find_vert_closest: very stupid & old bug, it was comparing hit locations incorrectly so that only the first hit was valid. This isn't noticeable for small distances, otherwise it gives bad results. --- source/blender/blenkernel/intern/editmesh_bvh.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/source/blender/blenkernel/intern/editmesh_bvh.c b/source/blender/blenkernel/intern/editmesh_bvh.c index 160972889fd..fced3472566 100644 --- a/source/blender/blenkernel/intern/editmesh_bvh.c +++ b/source/blender/blenkernel/intern/editmesh_bvh.c @@ -369,7 +369,7 @@ struct VertSearchUserData { int index_tri; }; -static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float *UNUSED(co), BVHTreeNearest *hit) +static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float co[3], BVHTreeNearest *hit) { struct VertSearchUserData *bmcb_data = userdata; const BMLoop **ltri = bmcb_data->looptris[index]; @@ -382,7 +382,7 @@ static void bmbvh_find_vert_closest_cb(void *userdata, int index, const float *U bmbvh_tri_from_face(tri_cos, ltri, bmcb_data->cos_cage); for (i = 0; i < 3; i++) { - dist = len_squared_v3v3(hit->co, tri_cos[i]); + dist = len_squared_v3v3(co, tri_cos[i]); if (dist < hit->dist && dist < maxdist) { copy_v3_v3(hit->co, tri_cos[i]); /* XXX, normal ignores cage */ @@ -402,7 +402,6 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const if (bmtree->cos_cage) BLI_assert(!(bmtree->em->bm->elem_index_dirty & BM_VERT)); - copy_v3_v3(hit.co, co); hit.dist = maxdist_sq; hit.index = -1; @@ -411,7 +410,7 @@ BMVert *BKE_bmbvh_find_vert_closest(BMBVHTree *bmtree, const float co[3], const bmcb_data.maxdist = maxdist_sq; BLI_bvhtree_find_nearest(bmtree->tree, co, &hit, bmbvh_find_vert_closest_cb, &bmcb_data); - if (hit.dist != FLT_MAX && hit.index != -1) { + if (hit.index != -1) { BMLoop **ltri = bmtree->em->looptris[hit.index]; return ltri[bmcb_data.index_tri]->v; } From 1ed8343d6da17076e43c06cce272c4b1d93f89a8 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 21:23:00 +0000 Subject: [PATCH 17/24] add axis option to EDBM_verts_mirror_cache_begin --- source/blender/editors/include/ED_mesh.h | 6 ++++-- source/blender/editors/mesh/editmesh_select.c | 2 +- source/blender/editors/mesh/editmesh_tools.c | 4 ++-- source/blender/editors/mesh/editmesh_utils.c | 12 ++++++++---- source/blender/editors/object/object_vgroup.c | 2 +- .../editors/transform/transform_conversions.c | 2 +- 6 files changed, 17 insertions(+), 11 deletions(-) diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index f35edb70251..0b25c494ba9 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -76,9 +76,11 @@ struct MeshStatVis; /* editmesh_utils.c */ -void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em, const bool use_self, const bool use_select, +void EDBM_verts_mirror_cache_begin_ex(struct BMEditMesh *em, const int axis, + const bool use_self, const bool use_select, const bool is_topo, float maxdist, int *r_index); -void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const bool use_self, const bool use_select); +void EDBM_verts_mirror_cache_begin(struct BMEditMesh *em, const int axis, + const bool use_self, const bool use_select); void EDBM_verts_mirror_apply(struct BMEditMesh *em, const int sel_from, const int sel_to); struct BMVert *EDBM_verts_mirror_get(struct BMEditMesh *em, struct BMVert *v); void EDBM_verts_mirror_cache_clear(struct BMEditMesh *em, struct BMVert *v); diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index e14dd484ad3..77b91365535 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -92,7 +92,7 @@ void EDBM_select_mirrored(BMEditMesh *em, bool extend, } } - EDBM_verts_mirror_cache_begin(em, true, true); + EDBM_verts_mirror_cache_begin(em, 0, true, true); if (!extend) EDBM_flag_disable_all(em, BM_ELEM_SELECT); diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 3581902e29e..56f70b73a16 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -1121,7 +1121,7 @@ static int edbm_do_smooth_vertex_exec(bContext *C, wmOperator *op) /* mirror before smooth */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - EDBM_verts_mirror_cache_begin(em, false, true); + EDBM_verts_mirror_cache_begin(em, 0, false, true); } /* if there is a mirror modifier with clipping, flag the verts that @@ -1212,7 +1212,7 @@ static int edbm_do_smooth_laplacian_vertex_exec(bContext *C, wmOperator *op) /* mirror before smooth */ if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - EDBM_verts_mirror_cache_begin(em, false, true); + EDBM_verts_mirror_cache_begin(em, 0, false, true); } repeat = RNA_int_get(op->ptr, "repeat"); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index 963b9cf134b..f3540fe62b7 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -1155,7 +1155,7 @@ static BMVert *cache_mirr_intptr_as_bmvert(intptr_t *index_lookup, int index) * \param maxdist Distance for close point test. * \param r_index Optional array to write into, as an alternative to a customdata layer (length of total verts). */ -void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const bool use_select, +void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const int axis, const bool use_self, const bool use_select, /* extra args */ const bool is_topo, float maxdist, int *r_index) { @@ -1212,7 +1212,9 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const v_mirr = cache_mirr_intptr_as_bmvert(mesh_topo_store.index_lookup, i); } else { - float co[3] = {-v->co[0], v->co[1], v->co[2]}; + float co[3]; + copy_v3_v3(co, v->co); + co[axis] *= -1.0f; v_mirr = BKE_bmbvh_find_vert_closest(tree, co, maxdist); } @@ -1239,14 +1241,16 @@ void EDBM_verts_mirror_cache_begin_ex(BMEditMesh *em, const bool use_self, const } } -void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const bool use_self, const bool use_select) +void EDBM_verts_mirror_cache_begin(BMEditMesh *em, const int axis, + const bool use_self, const bool use_select) { Mesh *me = (Mesh *)em->ob->data; bool is_topo; is_topo = (me && (me->editflag & ME_EDIT_MIRROR_TOPO)); - EDBM_verts_mirror_cache_begin_ex(em, use_self, use_select, + EDBM_verts_mirror_cache_begin_ex(em, axis, + use_self, use_select, /* extra args */ is_topo, BM_SEARCH_MAXDIST_MIRR, NULL); } diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 8da953c4f84..d38f4048572 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -2170,7 +2170,7 @@ void ED_vgroup_mirror(Object *ob, goto cleanup; } - EDBM_verts_mirror_cache_begin(em, true, false); + EDBM_verts_mirror_cache_begin(em, 0, true, false); /* Go through the list of editverts and assign them */ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index ac5727a116c..d1b57e2e402 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2020,7 +2020,7 @@ static void createTransEditVerts(TransInfo *t) int cd_vert_bweight_offset = -1; if (t->flag & T_MIRROR) { - EDBM_verts_mirror_cache_begin(em, false, true); + EDBM_verts_mirror_cache_begin(em, 0, false, true); mirror = 1; } From c00b4080526c2442cf56484d47aaa1f02b13cd44 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Wed, 19 Jun 2013 21:35:06 +0000 Subject: [PATCH 18/24] Snap to Symmetry (editmesh tool) Update from a script I had in 2.4x, useful if you have mesh data which is _almost_ symmetrical, there was no good way to automatically make the minor adjustments to make the mesh fully symmetrical. Options for... - symmetry-axis. - blending between the +/- side. - center mid verts. Access from Mesh menu. --- release/scripts/startup/bl_ui/space_view3d.py | 2 + source/blender/editors/mesh/editmesh_tools.c | 126 ++++++++++++++++++ source/blender/editors/mesh/mesh_intern.h | 1 + source/blender/editors/mesh/mesh_ops.c | 1 + 4 files changed, 130 insertions(+) diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e0449931fc9..cfd8fd2080f 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1801,6 +1801,8 @@ class VIEW3D_MT_edit_mesh(Menu): layout.separator() layout.operator("mesh.symmetrize") + layout.operator("mesh.symmetry_snap") + layout.separator() layout.operator("mesh.duplicate_move") layout.menu("VIEW3D_MT_edit_mesh_extrude") layout.menu("VIEW3D_MT_edit_mesh_delete") diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index 56f70b73a16..bab9a2d8f5a 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -4258,6 +4258,132 @@ void MESH_OT_symmetrize(struct wmOperatorType *ot) "Direction", "Which sides to copy from and to"); } +static int mesh_symmetry_snap_exec(bContext *C, wmOperator *op) +{ + const float eps = 0.00001f; + const float eps_sq = eps * eps; + + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BKE_editmesh_from_object(obedit); + BMesh *bm = em->bm; + int *index = MEM_mallocN(bm->totvert * sizeof(*index), __func__); + const bool is_topo = false; + + const float thresh = RNA_float_get(op->ptr, "threshold"); + const float fac = RNA_float_get(op->ptr, "factor"); + const bool use_center = RNA_boolean_get(op->ptr, "use_center"); + + /* stats */ + int totmirr = 0, totfail = 0, totfound = 0; + + /* axix */ + const int axis_dir = RNA_enum_get(op->ptr, "direction"); + int axis = axis_dir % 3; + bool axis_sign = axis != axis_dir; + + /* vertex iter */ + BMIter iter; + BMVert *v; + int i; + + EDBM_verts_mirror_cache_begin_ex(em, axis, true, true, is_topo, thresh, index); + + EDBM_index_arrays_ensure(em, BM_VERT); + + BM_mesh_elem_hflag_disable_all(bm, BM_VERT, BM_ELEM_TAG, false); + + + BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) { + if ((BM_elem_flag_test(v, BM_ELEM_SELECT) != false) && + (BM_elem_flag_test(v, BM_ELEM_TAG) == false)) + { + int i_mirr = index[i]; + if (i_mirr != -1) { + + BMVert *v_mirr = EDBM_vert_at_index(em, index[i]); + + if (v != v_mirr) { + float co[3], co_mirr[3]; + + if ((v->co[axis] > v->co[axis]) == axis_sign) { + SWAP(BMVert *, v, v_mirr); + } + + copy_v3_v3(co_mirr, v_mirr->co); + co_mirr[axis] *= -1.0f; + + if (len_squared_v3v3(v->co, co_mirr) > eps_sq) { + totmirr++; + } + + interp_v3_v3v3(co, v->co, co_mirr, fac); + + copy_v3_v3(v->co, co); + + co[axis] *= -1.0f; + copy_v3_v3(v_mirr->co, co); + + BM_elem_flag_enable(v, BM_ELEM_TAG); + BM_elem_flag_enable(v_mirr, BM_ELEM_TAG); + totfound++; + } + else { + if (use_center) { + + if (fabsf(v->co[axis]) > eps) { + totmirr++; + } + + v->co[axis] = 0.0f; + } + BM_elem_flag_enable(v, BM_ELEM_TAG); + totfound++; + } + } + else { + totfail++; + } + } + } + + + if (totfail) { + BKE_reportf(op->reports, RPT_WARNING, "%d already symmetrical, %d pairs mirrored, %d failed", + totfound - totmirr, totmirr, totfail); + } + else { + BKE_reportf(op->reports, RPT_INFO, "%d already symmetrical, %d pairs mirrored", + totfound - totmirr, totmirr); + } + + /* no need to end cache, just free the array */ + MEM_freeN(index); + + return OPERATOR_FINISHED; +} + +void MESH_OT_symmetry_snap(struct wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Snap to Symmetry"; + ot->description = "Snap vertex pairs to their mirrored locations"; + ot->idname = "MESH_OT_symmetry_snap"; + + /* api callbacks */ + ot->exec = mesh_symmetry_snap_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "direction", symmetrize_direction_items, + BMO_SYMMETRIZE_NEGATIVE_X, + "Direction", "Which sides to copy from and to"); + RNA_def_float(ot->srna, "threshold", 0.05, 0.0, 10.0, "Threshold", "", 0.0001, 1.0); + RNA_def_float(ot->srna, "factor", 0.5f, 0.0, 1.0, "Factor", "", 0.0, 1.0); + RNA_def_boolean(ot->srna, "use_center", true, "Center", "Snap mid verts to the axis center"); +} + #ifdef WITH_FREESTYLE static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op) diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index bc74f4a8bf5..e086e11e3bf 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -170,6 +170,7 @@ void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot); void MESH_OT_wireframe(struct wmOperatorType *ot); void MESH_OT_convex_hull(struct wmOperatorType *ot); void MESH_OT_symmetrize(struct wmOperatorType *ot); +void MESH_OT_symmetry_snap(struct wmOperatorType *ot); void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot); void MESH_OT_blend_from_shape(struct wmOperatorType *ot); void MESH_OT_sort_elements(struct wmOperatorType *ot); diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 966d5ecb00e..7fe0c3b0344 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -172,6 +172,7 @@ void ED_operatortypes_mesh(void) #endif WM_operatortype_append(MESH_OT_symmetrize); + WM_operatortype_append(MESH_OT_symmetry_snap); #ifdef WITH_GAMEENGINE WM_operatortype_append(MESH_OT_navmesh_make); From 4eded6dbdcb3c0d451a0d5d5f0147be73b10f8af Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Thu, 20 Jun 2013 03:22:55 +0000 Subject: [PATCH 19/24] BGE: Fix for [#35479] "OSKEY (Command Key on Mac) not working" reported by Mike Pan (mpan3). The OSKEY was never added to the game engine, so it didn't recognize it. --- source/gameengine/Converter/BL_BlenderDataConversion.cpp | 5 +++-- source/gameengine/GameLogic/SCA_IInputDevice.h | 2 ++ source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp | 2 ++ source/gameengine/Ketsji/KX_PythonInit.cpp | 2 ++ 4 files changed, 9 insertions(+), 2 deletions(-) diff --git a/source/gameengine/Converter/BL_BlenderDataConversion.cpp b/source/gameengine/Converter/BL_BlenderDataConversion.cpp index 2fb83d4c1fd..ad16c96dc70 100644 --- a/source/gameengine/Converter/BL_BlenderDataConversion.cpp +++ b/source/gameengine/Converter/BL_BlenderDataConversion.cpp @@ -358,8 +358,9 @@ static std::map create_translate_table() m[F17KEY ] = SCA_IInputDevice::KX_F17KEY; m[F18KEY ] = SCA_IInputDevice::KX_F18KEY; m[F19KEY ] = SCA_IInputDevice::KX_F19KEY; - - + + m[OSKEY ] = SCA_IInputDevice::KX_OSKEY; + m[PAUSEKEY ] = SCA_IInputDevice::KX_PAUSEKEY; m[INSERTKEY ] = SCA_IInputDevice::KX_INSERTKEY; m[HOMEKEY ] = SCA_IInputDevice::KX_HOMEKEY; diff --git a/source/gameengine/GameLogic/SCA_IInputDevice.h b/source/gameengine/GameLogic/SCA_IInputDevice.h index ceb9c1e1d4f..47fdd45c78b 100644 --- a/source/gameengine/GameLogic/SCA_IInputDevice.h +++ b/source/gameengine/GameLogic/SCA_IInputDevice.h @@ -238,6 +238,8 @@ public: KX_F17KEY, KX_F18KEY, KX_F19KEY, + + KX_OSKEY, KX_PAUSEKEY, KX_INSERTKEY, diff --git a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp index e8d3441e4ce..53d03c6f479 100644 --- a/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp +++ b/source/gameengine/GamePlayer/ghost/GPG_KeyboardDevice.cpp @@ -147,6 +147,8 @@ GPG_KeyboardDevice::GPG_KeyboardDevice(void) m_reverseKeyTranslateTable[GHOST_kKeyLeftBracket ] = KX_LEFTBRACKETKEY ; m_reverseKeyTranslateTable[GHOST_kKeyRightBracket ] = KX_RIGHTBRACKETKEY ; + m_reverseKeyTranslateTable[GHOST_kKeyOS ] = KX_OSKEY ; + // Modifier keys. m_reverseKeyTranslateTable[GHOST_kKeyLeftControl ] = KX_LEFTCTRLKEY ; m_reverseKeyTranslateTable[GHOST_kKeyRightControl ] = KX_RIGHTCTRLKEY ; diff --git a/source/gameengine/Ketsji/KX_PythonInit.cpp b/source/gameengine/Ketsji/KX_PythonInit.cpp index 69b37ceae7a..58996f7b86f 100644 --- a/source/gameengine/Ketsji/KX_PythonInit.cpp +++ b/source/gameengine/Ketsji/KX_PythonInit.cpp @@ -2415,6 +2415,8 @@ PyObject *initGameKeys() KX_MACRO_addTypesToDict(d, F17KEY, SCA_IInputDevice::KX_F17KEY); KX_MACRO_addTypesToDict(d, F18KEY, SCA_IInputDevice::KX_F18KEY); KX_MACRO_addTypesToDict(d, F19KEY, SCA_IInputDevice::KX_F19KEY); + + KX_MACRO_addTypesToDict(d, OSKEY, SCA_IInputDevice::KX_OSKEY); KX_MACRO_addTypesToDict(d, PAUSEKEY, SCA_IInputDevice::KX_PAUSEKEY); KX_MACRO_addTypesToDict(d, INSERTKEY, SCA_IInputDevice::KX_INSERTKEY); From 1e64732d5264edef5af455febdf8567fc3472a05 Mon Sep 17 00:00:00 2001 From: Mitchell Stokes Date: Thu, 20 Jun 2013 03:50:02 +0000 Subject: [PATCH 20/24] BGE: Fix for [#34781] "bge.texture.ImageRender does not show Font object" reported by Monster. This fix is mostly based off of HG1's patch from the bug report, which had ImageRender::Render() call KX_KetsjiEngine::RenderFonts(). However, I have moved RenderFonts() from KX_KetsjiEngine to KX_Scene where all of the other font and rendering functions are. The real fix for this mess would be to not have ImageRender::Render() have so much duplicate code from KX_KetsjiEngine::Render(), but that's a code cleanup problem for another day. --- source/gameengine/Ketsji/KX_KetsjiEngine.cpp | 18 +++--------------- source/gameengine/Ketsji/KX_KetsjiEngine.h | 1 - source/gameengine/Ketsji/KX_Scene.cpp | 15 ++++++++++----- source/gameengine/Ketsji/KX_Scene.h | 8 ++++---- source/gameengine/VideoTexture/ImageRender.cpp | 2 ++ 5 files changed, 19 insertions(+), 25 deletions(-) diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp index f02e842ad2e..1061e9fd571 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.cpp +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.cpp @@ -54,7 +54,6 @@ #include "MT_Transform.h" #include "SCA_IInputDevice.h" #include "KX_Camera.h" -#include "KX_FontObject.h" #include "KX_Dome.h" #include "KX_Light.h" #include "KX_PythonInit.h" @@ -340,7 +339,7 @@ void KX_KetsjiEngine::RenderDome() // do the rendering m_dome->RenderDomeFrame(scene,cam, i); //render all the font objects for this scene - RenderFonts(scene); + scene->RenderFonts(); } list* cameras = scene->GetCameras(); @@ -358,7 +357,7 @@ void KX_KetsjiEngine::RenderDome() // do the rendering m_dome->RenderDomeFrame(scene, (*it),i); //render all the font objects for this scene - RenderFonts(scene); + scene->RenderFonts(); } it++; @@ -1339,23 +1338,12 @@ void KX_KetsjiEngine::RenderFrame(KX_Scene* scene, KX_Camera* cam) scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); //render all the font objects for this scene - RenderFonts(scene); + scene->RenderFonts(); if (scene->GetPhysicsEnvironment()) scene->GetPhysicsEnvironment()->debugDrawWorld(); } -void KX_KetsjiEngine::RenderFonts(KX_Scene* scene) -{ - list* fonts = scene->GetFonts(); - - list::iterator it = fonts->begin(); - while (it != fonts->end()) { - (*it)->DrawText(); - ++it; - } -} - /* * To run once per scene */ diff --git a/source/gameengine/Ketsji/KX_KetsjiEngine.h b/source/gameengine/Ketsji/KX_KetsjiEngine.h index 3cba3558db3..4e69c7d35f7 100644 --- a/source/gameengine/Ketsji/KX_KetsjiEngine.h +++ b/source/gameengine/Ketsji/KX_KetsjiEngine.h @@ -205,7 +205,6 @@ private: void RenderDebugProperties(); void RenderShadowBuffers(KX_Scene *scene); void SetBackGround(KX_WorldInfo* worldinfo); - void RenderFonts(KX_Scene* scene); public: KX_KetsjiEngine(class KX_ISystem* system); diff --git a/source/gameengine/Ketsji/KX_Scene.cpp b/source/gameengine/Ketsji/KX_Scene.cpp index 8bb9eaeef10..13fb168221d 100644 --- a/source/gameengine/Ketsji/KX_Scene.cpp +++ b/source/gameengine/Ketsji/KX_Scene.cpp @@ -40,6 +40,7 @@ #include "MT_assert.h" #include "KX_KetsjiEngine.h" #include "KX_BlenderMaterial.h" +#include "KX_FontObject.h" #include "RAS_IPolygonMaterial.h" #include "ListValue.h" #include "SCA_LogicManager.h" @@ -352,11 +353,6 @@ list* KX_Scene::GetCameras() return &m_cameras; } -list* KX_Scene::GetFonts() -{ - return &m_fonts; -} - void KX_Scene::SetFramingType(RAS_FrameSettings & frame_settings) { m_frame_settings = frame_settings; @@ -1639,6 +1635,15 @@ void KX_Scene::RenderBuckets(const MT_Transform & cameratransform, KX_BlenderMaterial::EndFrame(); } +void KX_Scene::RenderFonts() +{ + list::iterator it = m_fonts.begin(); + while (it != m_fonts.end()) { + (*it)->DrawText(); + ++it; + } +} + void KX_Scene::UpdateObjectActivity(void) { if (m_activity_culling) { diff --git a/source/gameengine/Ketsji/KX_Scene.h b/source/gameengine/Ketsji/KX_Scene.h index 632e1bf9b50..7c3ea946044 100644 --- a/source/gameengine/Ketsji/KX_Scene.h +++ b/source/gameengine/Ketsji/KX_Scene.h @@ -381,10 +381,6 @@ public: ); /** Font Routines */ - - std::list* - GetFonts( - ); /** Find a font in the scene by pointer. */ KX_FontObject* @@ -398,6 +394,10 @@ public: KX_FontObject* ); + /** Render the fonts in this scene. */ + void + RenderFonts( + ); /** Camera Routines */ diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index d251f4f7bcb..f184ab9bd1d 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -275,6 +275,8 @@ void ImageRender::Render() m_scene->RenderBuckets(camtrans, m_rasterizer, m_rendertools); + m_scene->RenderFonts(); + // restore the canvas area now that the render is completed m_canvas->GetWindowArea() = area; } From 62c6ee2c558eb33813dc41326f4f14ce046c477a Mon Sep 17 00:00:00 2001 From: Daniel Stokes Date: Thu, 20 Jun 2013 06:17:28 +0000 Subject: [PATCH 21/24] BGE: fix [#35447] LibLoad Meshes and Scenes causes crash of blender KX_BlenderSceneConverter's destructor freed the contents of several std::vectors without removing those contents from the vectors. Later these vectors are iterated through. Making sure the vectors get cleared solves this problem. --- source/gameengine/Converter/KX_BlenderSceneConverter.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp index 8703a545a4f..19287c1fd62 100644 --- a/source/gameengine/Converter/KX_BlenderSceneConverter.cpp +++ b/source/gameengine/Converter/KX_BlenderSceneConverter.cpp @@ -170,6 +170,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itw).second; itw++; } + m_worldinfos.clear(); vector >::iterator itp = m_polymaterials.begin(); while (itp != m_polymaterials.end()) { @@ -177,6 +178,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itp).second; itp++; } + m_polymaterials.clear(); // delete after RAS_IPolyMaterial vector >::iterator itmat = m_materials.begin(); @@ -185,6 +187,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itmat).second; itmat++; } + m_materials.clear(); vector >::iterator itm = m_meshobjects.begin(); @@ -192,6 +195,7 @@ KX_BlenderSceneConverter::~KX_BlenderSceneConverter() delete (*itm).second; itm++; } + m_meshobjects.clear(); #ifdef WITH_BULLET KX_ClearBulletSharedShapes(); From 972c01ac0cfa90d3414625a6ef248c3ab66d1842 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 20 Jun 2013 07:00:57 +0000 Subject: [PATCH 22/24] remove NULL checks for return values from EDBM_***_at_index calls. --- source/blender/editors/object/object_vgroup.c | 8 +- .../blender/editors/space_view3d/drawmesh.c | 2 +- .../blender/editors/space_view3d/drawobject.c | 75 ++++++++++--------- source/blender/editors/transform/transform.c | 11 --- source/blender/editors/transform/transform.h | 1 - .../editors/transform/transform_snap.c | 11 ++- 6 files changed, 48 insertions(+), 60 deletions(-) diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index d38f4048572..80ca0b38f8c 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -976,11 +976,11 @@ static float get_vert_def_nr(Object *ob, const int def_nr, const int vertnum) BMEditMesh *em = me->edit_btmesh; const int cd_dvert_offset = CustomData_get_offset(&em->bm->vdata, CD_MDEFORMVERT); /* warning, this lookup is _not_ fast */ - BMVert *eve; - EDBM_index_arrays_ensure(em, BM_VERT); - - if ((cd_dvert_offset != -1) && (eve = EDBM_vert_at_index(em, vertnum))) { + if (cd_dvert_offset != -1) { + BMVert *eve; + EDBM_index_arrays_ensure(em, BM_VERT); + eve = EDBM_vert_at_index(em, vertnum); dv = BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset); } else { diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index ade38a4288b..d0a34f20c77 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -567,7 +567,7 @@ static DMDrawOption draw_em_tf_mapped__set_draw(void *userData, int index) BMEditMesh *em = data->em; BMFace *efa = EDBM_face_at_index(em, index); - if (efa == NULL || BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { return DM_DRAW_OPTION_SKIP; } else { diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index ac0ecaf58dd..ac5deb057b5 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2060,7 +2060,9 @@ static void draw_dm_face_centers__mapFunc(void *userData, int index, const float BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); const char sel = *(((char **)userData)[1]); - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && BM_elem_flag_test(efa, BM_ELEM_SELECT) == sel) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN) && + (BM_elem_flag_test(efa, BM_ELEM_SELECT) == sel)) + { bglVertex3fv(cent); } } @@ -2326,9 +2328,6 @@ static DMDrawOption draw_dm_edges_freestyle__setDrawOptions(void *userData, int { BMEdge *eed = EDBM_edge_at_index(userData, index); - if (!eed) - return DM_DRAW_OPTION_SKIP; - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && draw_dm_test_freestyle_edge_mark(userData, eed)) return DM_DRAW_OPTION_NORMAL; else @@ -2358,9 +2357,6 @@ static DMDrawOption draw_dm_faces_sel__setDrawOptions(void *userData, int index) BMFace *efa = EDBM_face_at_index(data->em, index); unsigned char *col; - if (!efa) - return DM_DRAW_OPTION_SKIP; - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (efa == data->efa_act) { glColor4ubv(data->cols[2]); @@ -2385,6 +2381,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int { drawDMFacesSel_userData *data = userData; + int i; BMFace *efa; BMFace *next_efa; @@ -2393,8 +2390,13 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int if (!data->orig_index_mf_to_mpoly) return 0; - efa = EDBM_face_at_index(data->em, DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, index)); - next_efa = EDBM_face_at_index(data->em, DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, next_index)); + i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, index); + efa = (i != ORIGINDEX_NONE) ? EDBM_face_at_index(data->em, i) : NULL; + i = DM_origindex_mface_mpoly(data->orig_index_mf_to_mpoly, data->orig_index_mp_to_orig, next_index); + next_efa = (i != ORIGINDEX_NONE) ? EDBM_face_at_index(data->em, i) : NULL; + + if (ELEM(NULL, efa, next_efa)) + return 0; if (efa == next_efa) return 1; @@ -2473,32 +2475,27 @@ static DMDrawOption draw_dm_bweights__setDrawOptions(void *userData, int index) { BMEditMesh *em = userData; BMEdge *eed = EDBM_edge_at_index(userData, index); - float *bweight = (float *)CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT); - - if (!bweight) - return DM_DRAW_OPTION_SKIP; - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN) && *bweight != 0.0f) { - UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, *bweight); - return DM_DRAW_OPTION_NORMAL; - } - else { - return DM_DRAW_OPTION_SKIP; + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + const float *bweight = (float *)CustomData_bmesh_get(&em->bm->edata, eed->head.data, CD_BWEIGHT); + if (*bweight != 0.0f) { + UI_ThemeColorBlend(TH_WIRE_EDIT, TH_EDGE_SELECT, *bweight); + return DM_DRAW_OPTION_NORMAL; + } } + return DM_DRAW_OPTION_SKIP; } static void draw_dm_bweights__mapFunc(void *userData, int index, const float co[3], const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) { BMEditMesh *em = userData; BMVert *eve = EDBM_vert_at_index(userData, index); - float *bweight = (float *)CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_BWEIGHT); - - if (!bweight) - return; - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN) && *bweight != 0.0f) { - UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, *bweight); - bglVertex3fv(co); + + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + const float *bweight = (float *)CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_BWEIGHT); + if (*bweight != 0.0f) { + UI_ThemeColorBlend(TH_VERTEX, TH_VERTEX_SELECT, *bweight); + bglVertex3fv(co); + } } } static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) @@ -2506,15 +2503,19 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) ToolSettings *ts = scene->toolsettings; if (ts->selectmode & SCE_SELECT_VERTEX) { - glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2); - bglBegin(GL_POINTS); - dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, em); - bglEnd(); + if (CustomData_has_layer(&em->bm->vdata, CD_BWEIGHT)) { + glPointSize(UI_GetThemeValuef(TH_VERTEX_SIZE) + 2); + bglBegin(GL_POINTS); + dm->foreachMappedVert(dm, draw_dm_bweights__mapFunc, em); + bglEnd(); + } } else { - glLineWidth(3.0); - dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, em); - glLineWidth(1.0); + if (CustomData_has_layer(&em->bm->edata, CD_BWEIGHT)) { + glLineWidth(3.0); + dm->drawMappedEdges(dm, draw_dm_bweights__setDrawOptions, em); + glLineWidth(1.0); + } } } @@ -2958,7 +2959,7 @@ static DMDrawOption draw_em_fancy__setFaceOpts(void *userData, int index) { BMFace *efa = EDBM_face_at_index(userData, index); - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { GPU_enable_material(efa->mat_nr + 1, NULL); return DM_DRAW_OPTION_NORMAL; } @@ -7274,7 +7275,7 @@ static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int inde { BMFace *efa = EDBM_face_at_index(((void **)userData)[0], index); - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { if (((void **)userData)[1]) { WM_framebuffer_index_set(index + 1); } diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index 68b93fe6560..7a8d4c6750e 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -2181,17 +2181,6 @@ int transformEnd(bContext *C, TransInfo *t) /* send events out for redraws */ viewRedrawPost(C, t); - /* Undo as last, certainly after special_trans_update! */ - - if (t->state == TRANS_CANCEL) { -// if (t->undostr) ED_undo_push(C, t->undostr); - } - else { -// if (t->undostr) ED_undo_push(C, t->undostr); -// else ED_undo_push(C, transform_to_undostr(t)); - } - t->undostr = NULL; - viewRedrawForce(C, t); } diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 987180d4efd..2cef3209b4e 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -319,7 +319,6 @@ typedef struct TransInfo { float vec[3]; /* translation, to show for widget */ float mat[3][3]; /* rot/rescale, to show for widget */ - char *undostr; /* if set, uses this string for undo */ float spacemtx[3][3]; /* orientation matrix of the current space */ char spacename[64]; /* name of the current space, MAX_NAME */ diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 6b529e13aec..4ab2269ff01 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -1475,7 +1475,6 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes } for (i = 0; i < totedge; i++) { - BMEdge *eed = NULL; MEdge *e = edges + i; test = 1; /* reset for every vert */ @@ -1492,11 +1491,11 @@ static bool snapDerivedMesh(short snap_mode, ARegion *ar, Object *ob, DerivedMes test = 0; } else { - eed = EDBM_edge_at_index(em, index); - - if (eed && (BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || - BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || - BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) + BMEdge *eed = EDBM_edge_at_index(em, index); + + if ((BM_elem_flag_test(eed, BM_ELEM_HIDDEN) || + BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || + BM_elem_flag_test(eed->v2, BM_ELEM_SELECT))) { test = 0; } From e5944d23edd3efc88d1f60e4cee40eff8e21abfd Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Thu, 20 Jun 2013 07:46:40 +0000 Subject: [PATCH 23/24] Fix for [#35230] CPU freeze at playback after cutting/deleting/duplicating audio strip --- intern/audaspace/intern/AUD_Sequencer.cpp | 2 +- intern/audaspace/intern/AUD_SequencerReader.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/intern/audaspace/intern/AUD_Sequencer.cpp b/intern/audaspace/intern/AUD_Sequencer.cpp index 58e8f682714..c59c56a4479 100644 --- a/intern/audaspace/intern/AUD_Sequencer.cpp +++ b/intern/audaspace/intern/AUD_Sequencer.cpp @@ -161,7 +161,7 @@ boost::shared_ptr AUD_Sequencer::add(boost::shared_ptr entry = boost::shared_ptr(new AUD_SequencerEntry(sound, begin, end, skip, m_id++)); - m_entries.push_front(entry); + m_entries.push_back(entry); m_entry_status++; return entry; diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp index d5e14590df5..aef93cd3896 100644 --- a/intern/audaspace/intern/AUD_SequencerReader.cpp +++ b/intern/audaspace/intern/AUD_SequencerReader.cpp @@ -112,7 +112,7 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer) try { handle = boost::shared_ptr(new AUD_SequencerHandle(entry, m_device)); - handles.push_front(handle); + handles.push_back(handle); } catch(AUD_Exception&) { @@ -143,7 +143,7 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer) try { handle = boost::shared_ptr(new AUD_SequencerHandle(*eit, m_device)); - handles.push_front(handle); + handles.push_back(handle); } catch(AUD_Exception&) { From b843bebb15a5d626e3367823f5071fff8518fcaf Mon Sep 17 00:00:00 2001 From: Sergey Sharybin Date: Thu, 20 Jun 2013 11:00:35 +0000 Subject: [PATCH 24/24] Fix crash in when dding subsurf modifier to curves Issue was caused by svn rev57566 which didn't take into account the fact that curves could have dm of type CCGDM and in this case CDDM_calc_normals_mapping_ex would fail dramatically. Added a check around normals update call bout whether DM is CDDM or not. The same happens in mesh's modifier stack. --- source/blender/blenkernel/intern/displist.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index e1ecf00104a..38a0b848339 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -1040,7 +1040,9 @@ static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispba DM_update_tessface_data(dm); } - CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true); + if (dm->type == DM_TYPE_CDDM) { + CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true); + } } (*derivedFinal) = dm; }