diff options
author | Daniel Genrich <daniel.genrich@gmx.net> | 2012-10-10 15:32:27 +0400 |
---|---|---|
committer | Daniel Genrich <daniel.genrich@gmx.net> | 2012-10-10 15:32:27 +0400 |
commit | 7b6eefea41e2bf9ba8162c7666d56157bea1b34e (patch) | |
tree | 9b834f67ae71f8b87e0f8236108c359e494b1427 | |
parent | a355ff367b24552c7f1a9c288d62ba5ebfc2e1a4 (diff) |
Merge from trunk r51234-r51251soc-2012-fried_chicken
43 files changed, 1096 insertions, 824 deletions
diff --git a/release/scripts/presets/keyconfig/maya.py b/release/scripts/presets/keyconfig/maya.py index fe011a51e22..b5df519cf59 100644 --- a/release/scripts/presets/keyconfig/maya.py +++ b/release/scripts/presets/keyconfig/maya.py @@ -133,42 +133,42 @@ kmi = km.keymap_items.new('wm.context_toggle_enum', 'Z', 'PRESS', alt=True) kmi.properties.data_path = 'space_data.viewport_shade' kmi.properties.value_1 = 'TEXTURED' kmi.properties.value_2 = 'SOLID' -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS') +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE') kmi.properties.extend = False kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True) kmi.properties.extend = True kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True) kmi.properties.extend = False kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', alt=True) kmi.properties.extend = False kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True) kmi.properties.extend = True kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = False -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', ctrl=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', ctrl=True, alt=True) kmi.properties.extend = False kmi.properties.center = True kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, alt=True) kmi.properties.extend = True kmi.properties.center = False kmi.properties.object = False kmi.properties.enumerate = True -kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'PRESS', shift=True, ctrl=True, alt=True) +kmi = km.keymap_items.new('view3d.select', 'SELECTMOUSE', 'RELEASE', shift=True, ctrl=True, alt=True) kmi.properties.extend = True kmi.properties.center = True kmi.properties.object = False diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index eac90a8b091..af33f80bdf8 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -1668,7 +1668,7 @@ class WM_OT_theme_install(Operator): class WM_OT_addon_install(Operator): "Install an addon" bl_idname = "wm.addon_install" - bl_label = "Install Addon..." + bl_label = "Install from File..." overwrite = BoolProperty( name="Overwrite", diff --git a/release/scripts/startup/bl_ui/space_dopesheet.py b/release/scripts/startup/bl_ui/space_dopesheet.py index 8e955338480..8a47a631e82 100644 --- a/release/scripts/startup/bl_ui/space_dopesheet.py +++ b/release/scripts/startup/bl_ui/space_dopesheet.py @@ -29,6 +29,7 @@ from bpy.types import Header, Menu def dopesheet_filter(layout, context, genericFiltersOnly=False): dopesheet = context.space_data.dopesheet is_nla = context.area.type == 'NLA_EDITOR' + is_drivers = (context.area.type == 'GRAPH_EDITOR' and context.space_data.mode == 'DRIVERS') row = layout.row(align=True) row.prop(dopesheet, "show_only_selected", text="") @@ -37,6 +38,9 @@ def dopesheet_filter(layout, context, genericFiltersOnly=False): if is_nla: row.prop(dopesheet, "show_missing_nla", text="") + if is_drivers: + row.prop(dopesheet, "show_only_errors", text="") + if not genericFiltersOnly: if bpy.data.groups: row = layout.row(align=True) diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index df30c3ee9ae..39e2cf40569 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -92,7 +92,7 @@ class USERPREF_HT_header(Header): layout.operator("wm.keyconfig_import") layout.operator("wm.keyconfig_export") elif userpref.active_section == 'ADDONS': - layout.operator("wm.addon_install") + layout.operator("wm.addon_install", icon="FILESEL") layout.menu("USERPREF_MT_addons_dev_guides") elif userpref.active_section == 'THEMES': layout.operator("ui.reset_default_theme") diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index d5648a6d3a2..606b14d4221 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -1247,6 +1247,7 @@ class VIEW3D_MT_paint_weight(Menu): layout.operator("object.vertex_group_clean", text="Clean") layout.operator("object.vertex_group_levels", text="Levels") layout.operator("object.vertex_group_blend", text="Blend") + layout.operator("object.vertex_group_transfer_weight", text="Transfer Weights") layout.operator("object.vertex_group_limit_total", text="Limit Total") layout.operator("object.vertex_group_fix", text="Fix Deforms") diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index b0b8401fe02..d162a97d32c 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -967,7 +967,7 @@ class VIEW3D_PT_tools_weightpaint(View3DPanel, Panel): col.operator("object.vertex_group_clean", text="Clean") col.operator("object.vertex_group_levels", text="Levels") col.operator("object.vertex_group_blend", text="Blend") - col.operator("object.vertex_group_transfer_weight", text="Transfer weight") + col.operator("object.vertex_group_transfer_weight", text="Transfer Weights") col.operator("object.vertex_group_limit_total", text="Limit Total") col.operator("object.vertex_group_fix", text="Fix Deforms") diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index 7709e51ab9e..83b07bae53f 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -140,12 +140,16 @@ MINLINE void star_m3_v3(float rmat[3][3], float a[3]); MINLINE float len_squared_v2(const float v[2]); MINLINE float len_squared_v3(const float v[3]); +MINLINE float len_manhattan_v2(const float v[2]); +MINLINE float len_manhattan_v3(const float v[3]); MINLINE float len_v2(const float a[2]); MINLINE float len_v2v2(const float a[2], const float b[2]); MINLINE float len_squared_v2v2(const float a[2], const float b[2]); +MINLINE float len_squared_v3v3(const float a[3], const float b[3]); +MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]); +MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]); MINLINE float len_v3(const float a[3]); MINLINE float len_v3v3(const float a[3], const float b[3]); -MINLINE float len_squared_v3v3(const float a[3], const float b[3]); MINLINE float normalize_v2(float r[2]); MINLINE float normalize_v2_v2(float r[2], const float a[2]); diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h index de4c2cf3a86..f84820e94f3 100644 --- a/source/blender/blenlib/BLI_rect.h +++ b/source/blender/blenlib/BLI_rect.h @@ -66,9 +66,7 @@ int BLI_rcti_isect_pt_v(const struct rcti *rect, const int xy[2]); int BLI_rctf_isect_pt(const struct rctf *rect, const float x, const float y); int BLI_rctf_isect_pt_v(const struct rctf *rect, const float xy[2]); int BLI_rcti_isect_segment(const struct rcti *rect, const int s1[2], const int s2[2]); -#if 0 /* NOT NEEDED YET */ -int BLI_rctf_isect_segment(struct rcti *rect, int s1[2], int s2[2]); -#endif +int BLI_rctf_isect_segment(const struct rctf *rect, const float s1[2], const float s2[2]); void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2); void BLI_rcti_union(struct rcti *rcti1, const struct rcti *rcti2); void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src); diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 666c74ca36f..943597b6688 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -74,7 +74,7 @@ __attribute__((nonnull)) * \param str2 second string for append * \retval Returns dst */ -char *BLI_strdupcat(const char *str1, const char *str2) +char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -91,7 +91,7 @@ __attribute__((nonnull)) * the size of dst) * \retval Returns dst */ -char *BLI_strncpy(char *dst, const char *src, const size_t maxncpy) +char *BLI_strncpy(char *__restrict dst, const char *__restrict src, const size_t maxncpy) #ifdef __GNUC__ __attribute__((nonnull)) #endif @@ -107,7 +107,7 @@ __attribute__((nonnull)) * Assume that the strings returned must be freed afterwards, and that the inputs will contain * data we want... */ -char *BLI_str_quoted_substrN(const char *str, const char *prefix) +char *BLI_str_quoted_substrN(const char *__restrict str, const char *__restrict prefix) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -124,7 +124,7 @@ __attribute__((nonnull)) * \param newText The text in the string to find and replace * \retval Returns the duplicated string */ -char *BLI_replacestr(char *str, const char *oldText, const char *newText) +char *BLI_replacestr(char *__restrict str, const char *__restrict oldText, const char *__restrict newText) #ifdef __GNUC__ __attribute__((warn_unused_result)) __attribute__((nonnull)) @@ -134,7 +134,7 @@ __attribute__((nonnull)) /* * Replacement for snprintf */ -size_t BLI_snprintf(char *buffer, size_t len, const char *format, ...) +size_t BLI_snprintf(char *__restrict buffer, size_t len, const char *__restrict format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 4))) __attribute__((nonnull)) @@ -144,7 +144,7 @@ __attribute__((nonnull)) /* * Replacement for vsnprintf */ -size_t BLI_vsnprintf(char *buffer, size_t count, const char *format, va_list arg) +size_t BLI_vsnprintf(char *__restrict buffer, size_t count, const char *__restrict format, va_list arg) #ifdef __GNUC__ __attribute__ ((format(printf, 3, 0))) #endif @@ -154,7 +154,7 @@ __attribute__ ((format(printf, 3, 0))) * Print formatted string into a newly mallocN'd string * and return it. */ -char *BLI_sprintfN(const char *format, ...) +char *BLI_sprintfN(const char *__restrict format, ...) #ifdef __GNUC__ __attribute__ ((format(printf, 1, 2))) __attribute__((warn_unused_result)) @@ -162,7 +162,7 @@ __attribute__((nonnull)) #endif ; -size_t BLI_strescape(char *dst, const char *src, const size_t maxlen) +size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const size_t maxlen) #ifdef __GNUC__ __attribute__((nonnull)) #endif @@ -216,12 +216,12 @@ __attribute__((nonnull)) #endif ; /* time var is global */ -void BLI_ascii_strtolower(char *str, int len) +void BLI_ascii_strtolower(char *str, const size_t len) #ifdef __GNUC__ __attribute__((nonnull)) #endif ; -void BLI_ascii_strtoupper(char *str, int len) +void BLI_ascii_strtoupper(char *str, const size_t len) #ifdef __GNUC__ __attribute__((nonnull)) #endif diff --git a/source/blender/blenlib/BLI_string_utf8.h b/source/blender/blenlib/BLI_string_utf8.h index 56ed4beba53..47980d104fe 100644 --- a/source/blender/blenlib/BLI_string_utf8.h +++ b/source/blender/blenlib/BLI_string_utf8.h @@ -31,16 +31,16 @@ extern "C" { #endif -char *BLI_strncpy_utf8(char *dst, const char *src, size_t maxncpy); -char *BLI_strncat_utf8(char *dst, const char *src, size_t maxncpy); +char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy); +char *BLI_strncat_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy); int BLI_utf8_invalid_byte(const char *str, int length); int BLI_utf8_invalid_strip(char *str, int length); int BLI_str_utf8_size(const char *p); /* warning, can return -1 on bad chars */ /* copied from glib */ unsigned int BLI_str_utf8_as_unicode(const char *p); -unsigned int BLI_str_utf8_as_unicode_and_size(const char *p, size_t *index); -unsigned int BLI_str_utf8_as_unicode_step(const char *p, size_t *index); +unsigned int BLI_str_utf8_as_unicode_and_size(const char *__restrict p, size_t *__restrict index); +unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index); size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf); char *BLI_str_find_prev_char_utf8(const char *str, const char *p); @@ -50,8 +50,8 @@ char *BLI_str_prev_char_utf8(const char *p); /* wchar_t functions, copied from blenders own font.c originally */ size_t BLI_wstrlen_utf8(const wchar_t *src); size_t BLI_strlen_utf8(const char *strc); -size_t BLI_strncpy_wchar_as_utf8(char *dst, const wchar_t *src, const size_t maxcpy); -size_t BLI_strncpy_wchar_from_utf8(wchar_t *dst, const char *src, const size_t maxcpy); +size_t BLI_strncpy_wchar_as_utf8(char *__restrict dst, const wchar_t *__restrict src, const size_t maxcpy); +size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst, const char *__restrict src, const size_t maxcpy); #define BLI_UTF8_MAX 6 #define BLI_UTF8_ERR ((unsigned int)-1) diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 17b616e9954..191b0e16025 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -568,6 +568,16 @@ MINLINE float len_squared_v3(const float v[3]) return v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; } +MINLINE float len_manhattan_v2(const float v[2]) +{ + return fabsf(v[0]) + fabsf(v[1]); +} + +MINLINE float len_manhattan_v3(const float v[3]) +{ + return fabsf(v[0]) + fabsf(v[1]) + fabsf(v[2]); +} + MINLINE float len_v2(const float v[2]) { return sqrtf(v[0] * v[0] + v[1] * v[1]); @@ -595,20 +605,36 @@ MINLINE float len_squared_v2v2(const float a[2], const float b[2]) return dot_v2v2(d, d); } -MINLINE float len_v3v3(const float a[3], const float b[3]) +MINLINE float len_squared_v3v3(const float a[3], const float b[3]) { float d[3]; sub_v3_v3v3(d, b, a); - return len_v3(d); + return dot_v3v3(d, d); } -MINLINE float len_squared_v3v3(const float a[3], const float b[3]) +MINLINE float len_manhattan_v2v2(const float a[2], const float b[2]) +{ + float d[2]; + + sub_v2_v2v2(d, b, a); + return len_manhattan_v2(d); +} + +MINLINE float len_manhattan_v3v3(const float a[3], const float b[3]) { float d[3]; sub_v3_v3v3(d, b, a); - return dot_v3v3(d, d); + return len_manhattan_v3(d); +} + +MINLINE float len_v3v3(const float a[3], const float b[3]) +{ + float d[3]; + + sub_v3_v3v3(d, b, a); + return len_v3(d); } MINLINE float normalize_v2_v2(float r[2], const float a[2]) diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c index cab383b60f3..2e2619df24e 100644 --- a/source/blender/blenlib/intern/rct.c +++ b/source/blender/blenlib/intern/rct.c @@ -102,7 +102,19 @@ int BLI_rctf_isect_pt_v(const rctf *rect, const float xy[2]) } /* based closely on 'isect_line_line_v2_int', but in modified so corner cases are treated as intersections */ -static int isect_segments(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) +static int isect_segments_i(const int v1[2], const int v2[2], const int v3[2], const int v4[2]) +{ + const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); + if (div == 0.0f) { + return 1; /* co-linear */ + } + else { + const double labda = (double)((v1[1] - v3[1]) * (v4[0] - v3[0]) - (v1[0] - v3[0]) * (v4[1] - v3[1])) / div; + const double mu = (double)((v1[1] - v3[1]) * (v2[0] - v1[0]) - (v1[0] - v3[0]) * (v2[1] - v1[1])) / div; + return (labda >= 0.0f && labda <= 1.0f && mu >= 0.0f && mu <= 1.0f); + } +} +static int isect_segments_fl(const float v1[2], const float v2[2], const float v3[2], const float v4[2]) { const double div = (double)((v2[0] - v1[0]) * (v4[1] - v3[1]) - (v2[1] - v1[1]) * (v4[0] - v3[0])); if (div == 0.0f) { @@ -134,14 +146,49 @@ int BLI_rcti_isect_segment(const rcti *rect, const int s1[2], const int s2[2]) /* diagonal: [/] */ tvec1[0] = rect->xmin; tvec1[1] = rect->ymin; tvec2[0] = rect->xmin; tvec2[1] = rect->ymax; - if (isect_segments(s1, s2, tvec1, tvec2)) { + if (isect_segments_i(s1, s2, tvec1, tvec2)) { + return 1; + } + + /* diagonal: [\] */ + tvec1[0] = rect->xmin; tvec1[1] = rect->ymax; + tvec2[0] = rect->xmax; tvec2[1] = rect->ymin; + if (isect_segments_i(s1, s2, tvec1, tvec2)) { + return 1; + } + + /* no intersection */ + return 0; + } +} + +int BLI_rctf_isect_segment(const rctf *rect, const float s1[2], const float s2[2]) +{ + /* first do outside-bounds check for both points of the segment */ + if (s1[0] < rect->xmin && s2[0] < rect->xmin) return 0; + if (s1[0] > rect->xmax && s2[0] > rect->xmax) return 0; + if (s1[1] < rect->ymin && s2[1] < rect->ymin) return 0; + if (s1[1] > rect->ymax && s2[1] > rect->ymax) return 0; + + /* if either points intersect then we definetly intersect */ + if (BLI_rctf_isect_pt_v(rect, s1) || BLI_rctf_isect_pt_v(rect, s2)) { + return 1; + } + else { + /* both points are outside but may insersect the rect */ + float tvec1[2]; + float tvec2[2]; + /* diagonal: [/] */ + tvec1[0] = rect->xmin; tvec1[1] = rect->ymin; + tvec2[0] = rect->xmin; tvec2[1] = rect->ymax; + if (isect_segments_fl(s1, s2, tvec1, tvec2)) { return 1; } /* diagonal: [\] */ tvec1[0] = rect->xmin; tvec1[1] = rect->ymax; tvec2[0] = rect->xmax; tvec2[1] = rect->ymin; - if (isect_segments(s1, s2, tvec1, tvec2)) { + if (isect_segments_fl(s1, s2, tvec1, tvec2)) { return 1; } diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 8501db7c8b8..4b64a650b52 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -296,11 +296,12 @@ char *BLI_strcasestr(const char *s, const char *find) int BLI_strcasecmp(const char *s1, const char *s2) { - int i; + register int i; + register char c1, c2; for (i = 0;; i++) { - char c1 = tolower(s1[i]); - char c2 = tolower(s2[i]); + c1 = tolower(s1[i]); + c2 = tolower(s2[i]); if (c1 < c2) { return -1; @@ -318,11 +319,12 @@ int BLI_strcasecmp(const char *s1, const char *s2) int BLI_strncasecmp(const char *s1, const char *s2, size_t len) { - int i; + register size_t i; + register char c1, c2; for (i = 0; i < len; i++) { - char c1 = tolower(s1[i]); - char c2 = tolower(s2[i]); + c1 = tolower(s1[i]); + c2 = tolower(s2[i]); if (c1 < c2) { return -1; @@ -341,15 +343,16 @@ int BLI_strncasecmp(const char *s1, const char *s2, size_t len) /* natural string compare, keeping numbers in order */ int BLI_natstrcmp(const char *s1, const char *s2) { - int d1 = 0, d2 = 0; + register int d1 = 0, d2 = 0; + register char c1, c2; /* if both chars are numeric, to a strtol(). * then increase string deltas as long they are * numeric, else do a tolower and char compare */ while (1) { - char c1 = tolower(s1[d1]); - char c2 = tolower(s2[d2]); + c1 = tolower(s1[d1]); + c2 = tolower(s2[d2]); if (isdigit(c1) && isdigit(c2) ) { int val1, val2; @@ -419,18 +422,18 @@ size_t BLI_strnlen(const char *str, size_t maxlen) return end ? (size_t) (end - str) : maxlen; } -void BLI_ascii_strtolower(char *str, int len) +void BLI_ascii_strtolower(char *str, const size_t len) { - int i; + size_t i; for (i = 0; i < len; i++) if (str[i] >= 'A' && str[i] <= 'Z') str[i] += 'a' - 'A'; } -void BLI_ascii_strtoupper(char *str, int len) +void BLI_ascii_strtoupper(char *str, const size_t len) { - int i; + size_t i; for (i = 0; i < len; i++) if (str[i] >= 'a' && str[i] <= 'z') diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 8b0593d48ac..d913779a883 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -980,6 +980,27 @@ static short skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, ID *owner_id) return 1; } +/* Check if F-Curve has errors and/or is disabled + * > returns: (bool) True if F-Curve has errors/is disabled + */ +static short fcurve_has_errors(FCurve *fcu) +{ + /* F-Curve disabled - path eval error */ + if (fcu->flag & FCURVE_DISABLED) { + return 1; + } + + /* driver? */ + if (fcu->driver) { + /* for now, just check if the entire thing got disabled... */ + if (fcu->driver->flag & DRIVER_FLAG_INVALID) + return 1; + } + + /* no errors found */ + return 0; +} + /* find the next F-Curve that is usable for inclusion */ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGroup *grp, int filter_mode, ID *owner_id) { @@ -1018,6 +1039,13 @@ static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, bActionGro continue; } + /* error-based filtering... */ + if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) { + /* skip if no errors... */ + if (fcurve_has_errors(fcu) == 0) + continue; + } + /* this F-Curve can be used, so return it */ return fcu; } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index d22b9f2abfb..42b42a594ce 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -3226,12 +3226,12 @@ void CURVE_OT_subdivide(wmOperatorType *ot) /******************** find nearest ************************/ -static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { - struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } *data = userData; + struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } *data = userData; short flag; - short temp; + float dist_test; if (bp) { flag = bp->f1; @@ -3248,12 +3248,12 @@ static void findnearestNurbvert__doClosest(void *userData, Nurb *nu, BPoint *bp, } } - temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); - if ((flag & 1) == data->select) temp += 5; - if (bezt && beztindex == 1) temp += 3; /* middle points get a small disadvantage */ + dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); + if ((flag & SELECT) == data->select) dist_test += 5.0f; + if (bezt && beztindex == 1) dist_test += 3.0f; /* middle points get a small disadvantage */ - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->bp = bp; data->bezt = bezt; @@ -3267,16 +3267,16 @@ static short findnearestNurbvert(ViewContext *vc, short sel, const int mval[2], /* (sel == 1): selected gets a disadvantage */ /* in nurb and bezt or bp the nearest is written */ /* return 0 1 2: handlepunt */ - struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; int dist, hpoint, select, mval[2]; } data = {NULL}; + struct { BPoint *bp; BezTriple *bezt; Nurb *nurb; float dist; int hpoint, select; float mval_fl[2]; } data = {NULL}; data.dist = 100; data.hpoint = 0; data.select = sel; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; + data.mval_fl[0] = mval[0]; + data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data); + nurbs_foreachScreenVert(vc, findnearestNurbvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); *nurb = data.nurb; *bezt = data.bezt; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index c07f0db7114..d0b48772d85 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -787,11 +787,16 @@ static short gp_stroke_eraser_strokeinside(const int mval[], const int UNUSED(mv int rad, int x0, int y0, int x1, int y1) { /* simple within-radius check for now */ - if (edge_inside_circle(mval[0], mval[1], rad, x0, y0, x1, y1)) - return 1; + const float mval_fl[2] = {mval[0], mval[1]}; + const float screen_co_a[2] = {x0, y0}; + const float screen_co_b[2] = {x1, y1}; + + if (edge_inside_circle(mval_fl, rad, screen_co_a, screen_co_b)) { + return TRUE; + } /* not inside */ - return 0; + return FALSE; } static void gp_point_to_xy(ARegion *ar, View2D *v2d, rctf *subrect, bGPDstroke *gps, bGPDspoint *pt, diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index 093872c79f6..f55f7755668 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -142,9 +142,9 @@ int EDBM_backbuf_border_mask_init(struct ViewContext *vc, const int mcords[][2] short xmin, short ymin, short xmax, short ymax); int EDBM_backbuf_circle_init(struct ViewContext *vc, short xs, short ys, short rads); -struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, int *dist, short sel, short strict); -struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, int *dist); -struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, int *dist); +struct BMVert *EDBM_vert_find_nearest(struct ViewContext *vc, float *r_dist, const short sel, const short strict); +struct BMEdge *EDBM_edge_find_nearest(struct ViewContext *vc, float *r_dist); +struct BMFace *EDBM_face_find_nearest(struct ViewContext *vc, float *r_dist); int EDBM_select_pick(struct bContext *C, const int mval[2], short extend, short deselect, short toggle); diff --git a/source/blender/editors/include/ED_object.h b/source/blender/editors/include/ED_object.h index 9836d690e53..f792d8b1a87 100644 --- a/source/blender/editors/include/ED_object.h +++ b/source/blender/editors/include/ED_object.h @@ -35,22 +35,31 @@ extern "C" { #endif +struct BMEdge; +struct BMFace; +struct BMVert; +struct BPoint; struct Base; -struct bConstraint; -struct bContext; -struct bPoseChannel; +struct BezTriple; struct Curve; +struct EditBone; struct EnumPropertyItem; struct ID; struct KeyBlock; struct Lattice; struct Main; struct Mesh; +struct MetaElem; struct ModifierData; +struct Nurb; struct Object; struct ReportList; struct Scene; struct View3D; +struct ViewContext; +struct bConstraint; +struct bContext; +struct bPoseChannel; struct wmEvent; struct wmKeyConfig; struct wmKeyMap; @@ -82,8 +91,10 @@ typedef enum eParentType { PAR_TRIA } eParentType; +#ifdef __RNA_TYPES_H__ extern struct EnumPropertyItem prop_clear_parent_types[]; extern struct EnumPropertyItem prop_make_parent_types[]; +#endif int ED_object_parent_set(struct ReportList *reports, struct Main *bmain, struct Scene *scene, struct Object *ob, struct Object *par, int partype, int xmirror, int keep_transform); @@ -183,9 +194,53 @@ int ED_object_iter_other(struct Main *bmain, struct Object *orig_ob, int include int ED_object_multires_update_totlevels_cb(struct Object *ob, void *totlevel_v); -/* ibject_select.c */ +/* object_select.c */ void ED_object_select_linked_by_id(struct bContext *C, struct ID *id); + +/* object_iterators.c */ + +#include "ED_view3d.h" /* XXX, needed for eV3DProjTest */ + +/* foreach iterators */ +void mesh_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct BMVert *eve, const float screen_co[2], int index), + void *userData, const eV3DProjTest clip_flag); +void mesh_foreachScreenEdge( + struct ViewContext *vc, + void (*func)(void *userData, struct BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], + int index), + void *userData, const eV3DProjTest clip_flag); +void mesh_foreachScreenFace( + struct ViewContext *vc, + void (*func)(void *userData, struct BMFace *efa, const float screen_co[2], int index), + void *userData, const eV3DProjTest clip_flag); +void nurbs_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, + int beztindex, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void mball_foreachScreenElem( + struct ViewContext *vc, + void (*func)(void *userData, struct MetaElem *ml, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void lattice_foreachScreenVert( + struct ViewContext *vc, + void (*func)(void *userData, struct BPoint *bp, + const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag); +void armature_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct EditBone *ebone, + const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag); +void pose_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct bPoseChannel *pchan, + const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag); + #ifdef __cplusplus } #endif diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index f71133d3118..d0243527b83 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -50,6 +50,8 @@ struct Nurb; struct Object; struct RegionView3D; struct Scene; +struct bScreen; +struct ScrArea; struct View3D; struct ViewContext; struct bContext; @@ -80,13 +82,6 @@ typedef struct ViewDepths { char damaged; } ViewDepths; -/* enum for passing to foreach functions to test RV3D_CLIPPING */ -typedef enum eV3DClipTest { - V3D_CLIP_TEST_OFF = 0, /* clipping is off */ - V3D_CLIP_TEST_RV3D_CLIPPING = 1, /* clip single points */ - V3D_CLIP_TEST_REGION = 2 /* use for edges to check if both verts are in the view, but not RV3D_CLIPPING */ -} eV3DClipTest; - float *give_cursor(struct Scene *scene, struct View3D *v3d); int initgrabz(struct RegionView3D *rv3d, float x, float y, float z); @@ -133,24 +128,27 @@ typedef enum { V3D_PROJ_TEST_CLIP_WIN = (1 << 1), } eV3DProjTest; +#define V3D_PROJ_TEST_CLIP_DEFAULT (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) +#define V3D_PROJ_TEST_ALL (V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) + /* *** short *** */ eV3DProjStatus ED_view3d_project_short_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], short r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag); + const float co[3], short r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_short_global(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_short_object(struct ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag); /* *** int *** */ eV3DProjStatus ED_view3d_project_int_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], int r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag); + const float co[3], int r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_int_global(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_int_object(struct ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag); /* *** float *** */ eV3DProjStatus ED_view3d_project_float_ex(struct ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], float r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag); -eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag); + const float co[3], float r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_float_global(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag); +eV3DProjStatus ED_view3d_project_float_object(struct ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag); void ED_view3d_project_float_v2_m4(const struct ARegion *a, const float co[3], float r_co[2], float mat[4][4]); void ED_view3d_project_float_v3_m4(struct ARegion *a, const float co[3], float r_co[3], float mat[4][4]); @@ -166,17 +164,6 @@ void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, f void ED_view3d_calc_camera_border(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, struct rctf *viewborder_r, short no_shift); void ED_view3d_calc_camera_border_size(struct Scene *scene, struct ARegion *ar, struct View3D *v3d, struct RegionView3D *rv3d, float size_r[2]); -/* drawobject.c iterators */ -void mesh_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BMVert *eve, int x, int y, int index), void *userData, eV3DClipTest clipVerts); -void mesh_foreachScreenEdge(struct ViewContext *vc, void (*func)(void *userData, struct BMEdge *eed, int x0, int y0, int x1, int y1, int index), void *userData, eV3DClipTest clipVerts); -void mesh_foreachScreenFace(struct ViewContext *vc, void (*func)(void *userData, struct BMFace *efa, int x, int y, int index), void *userData); -void nurbs_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct Nurb *nu, struct BPoint *bp, struct BezTriple *bezt, int beztindex, int x, int y), void *userData); -void mball_foreachScreenElem(struct ViewContext *vc, void (*func)(void *userData, struct MetaElem *ml, int x, int y), void *userData); -void lattice_foreachScreenVert(struct ViewContext *vc, void (*func)(void *userData, struct BPoint *bp, int x, int y), void *userData); -void armature_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), void *userData); -void pose_foreachScreenBone(struct ViewContext *vc, void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), void *userData); - - void ED_view3d_clipping_calc(struct BoundBox *bb, float planes[4][4], struct bglMats *mats, const struct rcti *rect); void ED_view3d_clipping_local(struct RegionView3D *rv3d, float mat[][4]); int ED_view3d_clipping_test(struct RegionView3D *rv3d, const float vec[3], const int is_local); @@ -191,7 +178,8 @@ void drawcircball(int mode, const float cent[3], float rad, float tmat[][4]); /* backbuffer select and draw support */ void view3d_validate_backbuf(struct ViewContext *vc); struct ImBuf *view3d_read_backbuf(struct ViewContext *vc, short xmin, short ymin, short xmax, short ymax); -unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size, unsigned int min, unsigned int max, int *dist, short strict, +unsigned int view3d_sample_backbuf_rect(struct ViewContext *vc, const int mval[2], int size, + unsigned int min, unsigned int max, float *dist, short strict, void *handle, unsigned int (*indextest)(void *handle, unsigned int index)); unsigned int view3d_sample_backbuf(struct ViewContext *vc, int x, int y); @@ -215,7 +203,7 @@ int view3d_get_view_aligned_coordinate(struct ViewContext *vc, float fp[3], cons void view3d_get_transformation(const struct ARegion *ar, struct RegionView3D *rv3d, struct Object *ob, struct bglMats *mats); /* XXX should move to BLI_math */ -int edge_inside_circle(int centx, int centy, int rad, int x1, int y1, int x2, int y2); +int edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]); /* get 3d region from context, also if mouse is in header or toolbar */ struct RegionView3D *ED_view3d_context_rv3d(struct bContext *C); diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 4f4fc27582c..1d19d35ca34 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -1418,7 +1418,7 @@ static void knife_input_ray_cast(KnifeTool_OpData *kcd, const int mval_i[2], static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd, float co[3], float cageco[3], int *is_space) { BMFace *f; - int dist = KMAXDIST; + float dist = KMAXDIST; float origin[3]; float ray[3]; diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index c0a36e24015..98fae2cc701 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -416,7 +416,7 @@ static int ringcut_invoke(bContext *C, wmOperator *op, wmEvent *evt) Object *obedit = CTX_data_edit_object(C); RingSelOpData *lcd; BMEdge *edge; - int dist = 75; + float dist = 75.0f; if (modifiers_isDeformedByLattice(obedit) || modifiers_isDeformedByArmature(obedit)) BKE_report(op->reports, RPT_WARNING, "Loop cut doesn't work well on deformed edit mesh display"); @@ -513,7 +513,7 @@ static int loopcut_modal(bContext *C, wmOperator *op, wmEvent *event) ED_region_tag_redraw(lcd->ar); break; case MOUSEMOVE: { /* mouse moved somewhere to select another loop */ - int dist = 75; + float dist = 75.0f; BMEdge *edge; lcd->vc.mval[0] = event->mval[0]; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 680d15ec51e..32643cb20cd 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -57,6 +57,7 @@ #include "ED_mesh.h" #include "ED_screen.h" #include "ED_uvedit.h" +#include "ED_object.h" #include "ED_view3d.h" #include "BIF_gl.h" @@ -330,9 +331,9 @@ int EDBM_backbuf_circle_init(ViewContext *vc, short xs, short ys, short rads) } -static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y, int index) +static void findnearestvert__doClosest(void *userData, BMVert *eve, const float screen_co[2], int index) { - struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } *data = userData; + struct { float mval_fl[2], pass, select, strict; float dist, lastIndex, closestIndex; BMVert *closest; } *data = userData; if (data->pass == 0) { if (index <= data->lastIndex) @@ -344,18 +345,18 @@ static void findnearestvert__doClosest(void *userData, BMVert *eve, int x, int y } if (data->dist > 3) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); if (BM_elem_flag_test(eve, BM_ELEM_SELECT) == data->select) { if (data->strict == 1) { return; } else { - temp += 5; + dist_test += 5; } } - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->closest = eve; data->closestIndex = index; } @@ -382,10 +383,10 @@ static unsigned int findnearestvert__backbufIndextest(void *handle, unsigned int * if 0, unselected vertice are given the bias * strict: if 1, the vertice corresponding to the sel parameter are ignored and not just biased */ -BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short strict) +BMVert *EDBM_vert_find_nearest(ViewContext *vc, float *r_dist, const short sel, const short strict) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { - int distance; + float distance; unsigned int index; BMVert *eve; @@ -400,8 +401,8 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri eve = BM_vert_at_index(vc->em->bm, index - 1); - if (eve && distance < *dist) { - *dist = distance; + if (eve && distance < *r_dist) { + *r_dist = distance; return eve; } else { @@ -410,7 +411,7 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri } else { - struct { short mval[2], pass, select, strict; int dist, lastIndex, closestIndex; BMVert *closest; } data; + struct { float mval_fl[2], pass, select, strict; float dist, lastIndex, closestIndex; BMVert *closest; } data; static int lastSelectedIndex = 0; static BMVert *lastSelected = NULL; @@ -420,10 +421,10 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri } data.lastIndex = lastSelectedIndex; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; data.select = sel; - data.dist = *dist; + data.dist = *r_dist; data.strict = strict; data.closest = NULL; data.closestIndex = 0; @@ -432,14 +433,14 @@ BMVert *EDBM_vert_find_nearest(ViewContext *vc, int *dist, short sel, short stri ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.dist > 3) { data.pass = 1; - mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, findnearestvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } - *dist = data.dist; + *r_dist = data.dist; lastSelected = data.closest; lastSelectedIndex = data.closestIndex; @@ -462,18 +463,12 @@ float labda_PdistVL2Dfl(const float v1[2], const float v2[2], const float v3[2]) } /* note; uses v3d, so needs active 3d window */ -static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index)) +static void findnearestedge__doClosest(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index)) { - struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } *data = userData; - float v1[2], v2[2]; + struct { ViewContext vc; float mval_fl[2]; float dist; BMEdge *closest; } *data = userData; int distance; - - v1[0] = x0; - v1[1] = y0; - v2[0] = x1; - v2[1] = y1; - - distance = dist_to_line_segment_v2(data->mval, v1, v2); + + distance = dist_to_line_segment_v2(data->mval_fl, screen_co_a, screen_co_b); if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { distance += 5; @@ -481,7 +476,7 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int if (distance < data->dist) { if (data->vc.rv3d->rflag & RV3D_CLIPPING) { - float labda = labda_PdistVL2Dfl(data->mval, v1, v2); + float labda = labda_PdistVL2Dfl(data->mval_fl, screen_co_a, screen_co_b); float vec[3]; vec[0] = eed->v1->co[0] + labda * (eed->v2->co[0] - eed->v1->co[0]); @@ -499,11 +494,11 @@ static void findnearestedge__doClosest(void *userData, BMEdge *eed, int x0, int } } } -BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) +BMEdge *EDBM_edge_find_nearest(ViewContext *vc, float *r_dist) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { - int distance; + float distance; unsigned int index; BMEdge *eed; @@ -512,8 +507,8 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) index = view3d_sample_backbuf_rect(vc, vc->mval, 50, bm_solidoffs, bm_wireoffs, &distance, 0, NULL, NULL); eed = BM_edge_at_index(vc->em->bm, index - 1); - if (eed && distance < *dist) { - *dist = distance; + if (eed && distance < *r_dist) { + *r_dist = distance; return eed; } else { @@ -521,36 +516,37 @@ BMEdge *EDBM_edge_find_nearest(ViewContext *vc, int *dist) } } else { - struct { ViewContext vc; float mval[2]; int dist; BMEdge *closest; } data; + struct { ViewContext vc; float mval_fl[2]; float dist; BMEdge *closest; } data; data.vc = *vc; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; - data.dist = *dist; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; + data.dist = *r_dist; data.closest = NULL; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_CLIP_TEST_REGION); + mesh_foreachScreenEdge(vc, findnearestedge__doClosest, &data, V3D_PROJ_TEST_CLIP_WIN); - *dist = data.dist; + *r_dist = data.dist; return data.closest; } } -static void findnearestface__getDistance(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void findnearestface__getDistance(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { - struct { short mval[2]; int dist; BMFace *toFace; } *data = userData; + struct { float mval_fl[2]; float dist; BMFace *toFace; } *data = userData; if (efa == data->toFace) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if (temp < data->dist) - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; + } } } -static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y, int index) +static void findnearestface__doClosest(void *userData, BMFace *efa, const float screen_co[2], int index) { - struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } *data = userData; + struct { float mval_fl[2], pass; float dist, lastIndex, closestIndex; BMFace *closest; } *data = userData; if (data->pass == 0) { if (index <= data->lastIndex) @@ -562,17 +558,17 @@ static void findnearestface__doClosest(void *userData, BMFace *efa, int x, int y } if (data->dist > 3) { - int temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + const float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->closest = efa; data->closestIndex = index; } } } -BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) +BMFace *EDBM_face_find_nearest(ViewContext *vc, float *r_dist) { if (vc->v3d->drawtype > OB_WIRE && (vc->v3d->flag & V3D_ZBUF_SELECT)) { @@ -585,17 +581,17 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) efa = BM_face_at_index(vc->em->bm, index - 1); if (efa) { - struct { short mval[2]; int dist; BMFace *toFace; } data; + struct { float mval_fl[2]; float dist; BMFace *toFace; } data; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; data.dist = 0x7FFF; /* largest short */ data.toFace = efa; - mesh_foreachScreenFace(vc, findnearestface__getDistance, &data); + mesh_foreachScreenFace(vc, findnearestface__getDistance, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if (vc->em->selectmode == SCE_SELECT_FACE || data.dist < *dist) { /* only faces, no dist check */ - *dist = data.dist; + if ((vc->em->selectmode == SCE_SELECT_FACE) || (data.dist < *r_dist)) { /* only faces, no dist check */ + *r_dist = data.dist; return efa; } } @@ -603,7 +599,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) return NULL; } else { - struct { short mval[2], pass; int dist, lastIndex, closestIndex; BMFace *closest; } data; + struct { float mval_fl[2], pass; float dist, lastIndex, closestIndex; BMFace *closest; } data; static int lastSelectedIndex = 0; static BMFace *lastSelected = NULL; @@ -613,23 +609,23 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) } data.lastIndex = lastSelectedIndex; - data.mval[0] = vc->mval[0]; - data.mval[1] = vc->mval[1]; - data.dist = *dist; + data.mval_fl[0] = vc->mval[0]; + data.mval_fl[1] = vc->mval[1]; + data.dist = *r_dist; data.closest = NULL; data.closestIndex = 0; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); data.pass = 0; - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); + mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); - if (data.dist > 3) { + if (data.dist > 3.0f) { data.pass = 1; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mesh_foreachScreenFace(vc, findnearestface__doClosest, &data); + mesh_foreachScreenFace(vc, findnearestface__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } - *dist = data.dist; + *r_dist = data.dist; lastSelected = data.closest; lastSelectedIndex = data.closestIndex; @@ -645,7 +641,7 @@ BMFace *EDBM_face_find_nearest(ViewContext *vc, int *dist) static int unified_findnearest(ViewContext *vc, BMVert **r_eve, BMEdge **r_eed, BMFace **r_efa) { BMEditMesh *em = vc->em; - int dist = 75; + float dist = 75.0f; *r_eve = NULL; *r_eed = NULL; @@ -1004,7 +1000,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) BMEditMesh *em; BMEdge *eed; int select = TRUE; - int dist = 50; + float dist = 50.0f; float mvalf[2]; em_setup_viewcontext(C, &vc); @@ -1392,7 +1388,7 @@ static int mouse_mesh_shortest_path(bContext *C, int mval[2]) ViewContext vc; BMEditMesh *em; BMEdge *e; - int dist = 50; + float dist = 75.0f; em_setup_viewcontext(C, &vc); vc.mval[0] = mval[0]; diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index eaf0c14a0a8..a0cf5efabd9 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -409,7 +409,8 @@ static void vtx_slide_find_edge(VertexSlideOp *vso, wmEvent *event) /* Nearest edge */ BMEdge *nst_edge = NULL; - const float mval_float[] = { (float)event->mval[0], (float)event->mval[1]}; + const float mval_float[2] = {(float)event->mval[0], + (float)event->mval[1]}; /* Set mouse coords */ copy_v2_v2_int(vso->view_context->mval, event->mval); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index f265113708a..b5521a5ecea 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -1192,7 +1192,7 @@ int ED_mesh_pick_face(bContext *C, Mesh *me, const int mval[2], unsigned int *in /* sample rect to increase chances of selecting, so that when clicking * on an edge in the backbuf, we can still select a face */ - int dummy_dist; + float dummy_dist; *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totpoly + 1, &dummy_dist, 0, NULL, NULL); } else { @@ -1277,7 +1277,7 @@ int ED_mesh_pick_vert(bContext *C, Mesh *me, const int mval[2], unsigned int *in /* sample rect to increase chances of selecting, so that when clicking * on an face in the backbuf, we can still select a vert */ - int dummy_dist; + float dummy_dist; *index = view3d_sample_backbuf_rect(&vc, mval, size, 1, me->totvert + 1, &dummy_dist, 0, NULL, NULL); } else { diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 05c042a4182..a6745f95ea0 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -46,6 +46,7 @@ set(SRC object_edit.c object_group.c object_hook.c + object_iterators.c object_lattice.c object_modifier.c object_ops.c diff --git a/source/blender/editors/object/object_iterators.c b/source/blender/editors/object/object_iterators.c new file mode 100644 index 00000000000..1d38db9d59b --- /dev/null +++ b/source/blender/editors/object/object_iterators.c @@ -0,0 +1,417 @@ +/* + * ***** 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. + * + * Contributor(s): Blender Foundation, full recode and added functions + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/object/object_iterators.c + * \ingroup edobj + */ + +#include "DNA_curve_types.h" +#include "DNA_lattice_types.h" +#include "DNA_meta_types.h" +#include "DNA_armature_types.h" +#include "DNA_object_types.h" + +#include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_rect.h" + +#include "BKE_armature.h" +#include "BKE_curve.h" +#include "BKE_DerivedMesh.h" +#include "BKE_displist.h" + +#include "bmesh.h" + +#include "ED_mesh.h" +#include "ED_screen.h" +#include "ED_armature.h" +#include "ED_object.h" +#include "ED_view3d.h" + + +typedef struct foreachScreenVert_userData { + void (*func)(void *userData, BMVert *eve, const float screen_co_b[2], int index); + void *userData; + ViewContext vc; + eV3DProjTest clip_flag; +} foreachScreenVert_userData; + +/* user data structures for derived mesh callbacks */ +typedef struct foreachScreenEdge_userData { + void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index); + void *userData; + ViewContext vc; + rctf win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ + eV3DProjTest clip_flag; +} foreachScreenEdge_userData; + +typedef struct foreachScreenFace_userData { + void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index); + void *userData; + ViewContext vc; + eV3DProjTest clip_flag; +} foreachScreenFace_userData; + + +/* Note! - foreach funcs should be called while drawing or directly after + * if not, ED_view3d_init_mats_rv3d() can be used for selection tools + * but would not give correct results with dupli's for eg. which don't + * use the object matrix in the usual way */ + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3], + const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) +{ + foreachScreenVert_userData *data = userData; + BMVert *eve = EDBM_vert_at_index(data->vc.em, index); + + if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { + float screen_co[2]; + + if (ED_view3d_project_float_object(data->vc.ar, co, screen_co, data->clip_flag) != V3D_PROJ_RET_OK) { + return; + } + + data->func(data->userData, eve, screen_co, index); + } +} + +void mesh_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, BMVert *eve, const float screen_co[2], int index), + void *userData, eV3DProjTest clip_flag) +{ + foreachScreenVert_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + data.func = func; + data.userData = userData; + data.clip_flag = clip_flag; + + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } + + EDBM_index_arrays_init(vc->em, 1, 0, 0); + dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3]) +{ + foreachScreenEdge_userData *data = userData; + BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); + + if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { + float screen_co_a[2]; + float screen_co_b[2]; + + if (ED_view3d_project_float_object(data->vc.ar, v0co, screen_co_a, data->clip_flag) != V3D_PROJ_RET_OK) { + return; + } + if (ED_view3d_project_float_object(data->vc.ar, v1co, screen_co_b, data->clip_flag) != V3D_PROJ_RET_OK) { + return; + } + + if (data->clip_flag & V3D_PROJ_TEST_CLIP_WIN) { + if (!BLI_rctf_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { + return; + } + } + + data->func(data->userData, eed, screen_co_a, screen_co_b, index); + } +} + +void mesh_foreachScreenEdge( + ViewContext *vc, + void (*func)(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index), + void *userData, eV3DProjTest clip_flag) +{ + foreachScreenEdge_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + + data.win_rect.xmin = 0; + data.win_rect.ymin = 0; + data.win_rect.xmax = vc->ar->winx; + data.win_rect.ymax = vc->ar->winy; + + data.func = func; + data.userData = userData; + data.clip_flag = clip_flag; + + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } + + EDBM_index_arrays_init(vc->em, 0, 1, 0); + dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) +{ + foreachScreenFace_userData *data = userData; + BMFace *efa = EDBM_face_at_index(data->vc.em, index); + + if (efa && !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); + } + } +} + +void mesh_foreachScreenFace( + ViewContext *vc, + void (*func)(void *userData, BMFace *efa, const float screen_co_b[2], int index), + void *userData, const eV3DProjTest clip_flag) +{ + foreachScreenFace_userData data; + DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); + + data.vc = *vc; + data.func = func; + data.userData = userData; + data.clip_flag = clip_flag; + + ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); + + EDBM_index_arrays_init(vc->em, 0, 0, 1); + dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); + EDBM_index_arrays_free(vc->em); + + dm->release(dm); +} + +/* ------------------------------------------------------------------------ */ + +void nurbs_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag) +{ + Curve *cu = vc->obedit->data; + Nurb *nu; + int i; + ListBase *nurbs = BKE_curve_editNurbs_get(cu); + + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ + } + + for (nu = nurbs->first; nu; nu = nu->next) { + if (nu->type == CU_BEZIER) { + for (i = 0; i < nu->pntsu; i++) { + BezTriple *bezt = &nu->bezt[i]; + + if (bezt->hide == 0) { + float screen_co[2]; + + if (cu->drawflag & CU_HIDE_HANDLES) { + if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 1, screen_co); + } + } + else { + if (ED_view3d_project_float_object(vc->ar, bezt->vec[0], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 0, screen_co); + } + if (ED_view3d_project_float_object(vc->ar, bezt->vec[1], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 1, screen_co); + } + if (ED_view3d_project_float_object(vc->ar, bezt->vec[2], screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, NULL, bezt, 2, screen_co); + } + } + } + } + } + else { + for (i = 0; i < nu->pntsu * nu->pntsv; i++) { + BPoint *bp = &nu->bp[i]; + + if (bp->hide == 0) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, bp->vec, screen_co, + V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) + { + func(userData, nu, bp, NULL, -1, screen_co); + } + } + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +void mball_foreachScreenElem( + struct ViewContext *vc, + void (*func)(void *userData, struct MetaElem *ml, const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag) +{ + MetaBall *mb = (MetaBall *)vc->obedit->data; + MetaElem *ml; + + for (ml = mb->editelems->first; ml; ml = ml->next) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, &ml->x, screen_co, clip_flag) == V3D_PROJ_RET_OK) + { + func(userData, ml, screen_co); + } + } +} + +/* ------------------------------------------------------------------------ */ + +void lattice_foreachScreenVert( + ViewContext *vc, + void (*func)(void *userData, BPoint *bp, const float screen_co[2]), + void *userData, const eV3DProjTest clip_flag) +{ + Object *obedit = vc->obedit; + Lattice *lt = obedit->data; + BPoint *bp = lt->editlatt->latt->def; + DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); + float *co = dl ? dl->verts : NULL; + int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; + + if (clip_flag & V3D_PROJ_TEST_CLIP_BB) { + ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ + } + + for (i = 0; i < N; i++, bp++, co += 3) { + if (bp->hide == 0) { + float screen_co[2]; + if (ED_view3d_project_float_object(vc->ar, dl ? co : bp->vec, screen_co, clip_flag) == V3D_PROJ_RET_OK) { + func(userData, bp, screen_co); + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +void armature_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag) +{ + bArmature *arm = vc->obedit->data; + EditBone *ebone; + + for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { + if (EBONE_VISIBLE(arm, ebone)) { + float screen_co_a[2], screen_co_b[2]; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, ebone->head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) { + points_proj_tot++; + } + else { + screen_co_a[0] = IS_CLIPPED; /* weak */ + /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ + } + + /* project tail location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, ebone->tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) { + points_proj_tot++; + } + else { + screen_co_b[0] = IS_CLIPPED; /* weak */ + /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ + } + + if (points_proj_tot) { /* at least one point's projection worked */ + func(userData, ebone, screen_co_a, screen_co_b); + } + } + } +} + +/* ------------------------------------------------------------------------ */ + +/* ED_view3d_init_mats_rv3d must be called first */ +/* almost _exact_ copy of #armature_foreachScreenBone */ +void pose_foreachScreenBone( + struct ViewContext *vc, + void (*func)(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]), + void *userData, const eV3DProjTest clip_flag) +{ + bArmature *arm = vc->obact->data; + bPose *pose = vc->obact->pose; + bPoseChannel *pchan; + + for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { + if (PBONE_VISIBLE(arm, pchan->bone)) { + float screen_co_a[2], screen_co_b[2]; + int points_proj_tot = 0; + + /* project head location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, pchan->pose_head, screen_co_a, clip_flag) == V3D_PROJ_RET_OK) { + points_proj_tot++; + } + else { + screen_co_a[0] = IS_CLIPPED; /* weak */ + /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ + } + + /* project tail location to screenspace */ + if (ED_view3d_project_float_object(vc->ar, pchan->pose_tail, screen_co_b, clip_flag) == V3D_PROJ_RET_OK) { + points_proj_tot++; + } + else { + screen_co_b[0] = IS_CLIPPED; /* weak */ + /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ + } + + if (points_proj_tot) { /* at least one point's projection worked */ + func(userData, pchan, screen_co_a, screen_co_b); + } + } + } +} diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 1f7be0bf9a6..d8974ea677c 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -302,16 +302,16 @@ void LATTICE_OT_make_regular(wmOperatorType *ot) /****************************** Mouse Selection *************************/ -static void findnearestLattvert__doClosest(void *userData, BPoint *bp, int x, int y) +static void findnearestLattvert__doClosest(void *userData, BPoint *bp, const float screen_co[2]) { - struct { BPoint *bp; short dist, select; int mval[2]; } *data = userData; - float temp = abs(data->mval[0] - x) + abs(data->mval[1] - y); + struct { BPoint *bp; float dist; int select; float mval_fl[2]; } *data = userData; + float dist_test = len_manhattan_v2v2(data->mval_fl, screen_co); - if ((bp->f1 & SELECT) == data->select) - temp += 5; + if ((bp->f1 & SELECT) && data->select) + dist_test += 5.0f; - if (temp < data->dist) { - data->dist = temp; + if (dist_test < data->dist) { + data->dist = dist_test; data->bp = bp; } @@ -322,15 +322,15 @@ static BPoint *findnearestLattvert(ViewContext *vc, const int mval[2], int sel) /* sel==1: selected gets a disadvantage */ /* in nurb and bezt or bp the nearest is written */ /* return 0 1 2: handlepunt */ - struct { BPoint *bp; short dist, select; int mval[2]; } data = {NULL}; + struct { BPoint *bp; float dist; int select; float mval_fl[2]; } data = {NULL}; data.dist = 100; data.select = sel; - data.mval[0] = mval[0]; - data.mval[1] = mval[1]; + data.mval_fl[0] = mval[0]; + data.mval_fl[1] = mval[1]; ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data); + lattice_foreachScreenVert(vc, findnearestLattvert__doClosest, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return data.bp; } @@ -341,7 +341,7 @@ int mouse_lattice(bContext *C, const int mval[2], int extend, int deselect, int BPoint *bp = NULL; view3d_set_viewcontext(C, &vc); - bp = findnearestLattvert(&vc, mval, 1); + bp = findnearestLattvert(&vc, mval, TRUE); if (bp) { if (extend) { diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index dea7eb984ad..b5643cdb9cb 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -406,7 +406,6 @@ typedef enum WT_Method { typedef enum WT_ReplaceMode { WT_REPLACE_ALL_WEIGHTS = 1, WT_REPLACE_EMPTY_WEIGHTS = 2, - WT_REPLACE_SELECTED_WEIGHTS = 3 } WT_ReplaceMode; static EnumPropertyItem WT_vertex_group_mode_item[] = { @@ -426,25 +425,21 @@ static EnumPropertyItem WT_method_item[] = { static EnumPropertyItem WT_replace_mode_item[] = { {WT_REPLACE_ALL_WEIGHTS, "WT_REPLACE_ALL_WEIGHTS", 1, "All", "Overwrites all weights."}, {WT_REPLACE_EMPTY_WEIGHTS, "WT_REPLACE_EMPTY_WEIGHTS", 1, "Empty", "Adds weights to vertices with no weight."}, - {WT_REPLACE_SELECTED_WEIGHTS, "WT_REPLACE_SELECTED_WEIGHTS", 1, "Selected", "Replace selected weights."}, {0, NULL, 0, NULL, NULL} }; /*copy weight*/ -static void vgroup_transfer_weight(MVert *mv_dst, float *weight_dst, float weight_src, WT_ReplaceMode replace_mode) +static void vgroup_transfer_weight(float *r_weight_dst, const float weight_src, const WT_ReplaceMode replace_mode) { switch (replace_mode) { - case WT_REPLACE_ALL_WEIGHTS: - *weight_dst = weight_src; + *r_weight_dst = weight_src; break; case WT_REPLACE_EMPTY_WEIGHTS: - if (*weight_dst == 0) *weight_dst = weight_src; - break; - - case WT_REPLACE_SELECTED_WEIGHTS: - if (mv_dst->flag & SELECT) *weight_dst = weight_src; + if (*r_weight_dst == 0.0f) { + *r_weight_dst = weight_src; + } break; default: @@ -469,9 +464,10 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou int dv_tot_src, dv_tot_dst, i, v_index, index_dst, index_src, index_nearest, index_nearest_vertex; unsigned int f_index; float weight, tmp_weight[4], tmp_co[3], normal[3], tmp_mat[4][4], dist_v1, dist_v2, dist_v3, dist_v4; + const int use_vert_sel = vertex_group_use_vert_sel(ob_dst); /* create new and overwrite vertex group on destination without data */ - if (!defgroup_find_name(ob_dst, dg_src->name) || replace_mode == WT_REPLACE_ALL_WEIGHTS) { + if (!defgroup_find_name(ob_dst, dg_src->name)) { ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); ED_vgroup_add_name(ob_dst, dg_src->name); } @@ -495,7 +491,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* get vertex group arrays */ ED_vgroup_give_parray(ob_src->data, &dv_array_src, &dv_tot_src, FALSE); - ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, FALSE); + ED_vgroup_give_parray(ob_dst->data, &dv_array_dst, &dv_tot_dst, use_vert_sel); /* get indexes of vertex groups */ index_src = BLI_findindex(&ob_src->defbase, dg_src); @@ -511,9 +507,13 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* clear weights */ if (replace_mode == WT_REPLACE_ALL_WEIGHTS) { - for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { - dw_dst = defvert_verify_index(*dv_dst, index_dst); - if (dw_dst) (*dw_dst).weight = 0; + for (i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++) { + + if (*dv_dst == NULL) continue; + + dw_dst = defvert_find_index(*dv_dst, index_dst); + /* remove vertex from group */ + if (dw_dst) defvert_remove_group(*dv_dst, dw_dst); } } @@ -533,13 +533,17 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou } /* loop through the vertices*/ - for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++) { + for(i = 0, dv_src = dv_array_src, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, dv_src++, mv_src++, mv_dst++) { + + if (*dv_dst == NULL) { + continue; + } /* copy weight */ dw_src = defvert_find_index(*dv_src, index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); } } break; @@ -551,9 +555,13 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* loop trough vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ + if (*dv_dst == NULL) { + continue; + } + /* reset nearest */ nearest.dist = FLT_MAX; - /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ nearest.index = -1; /* transform into target space */ @@ -567,7 +575,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou dw_src = defvert_find_index(dv_array_src[nearest.index], index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); } } @@ -586,9 +594,13 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++) { + if (*dv_dst == NULL) { + continue; + } + /* reset nearest */ nearest.dist = FLT_MAX; - /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ + /* with current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ nearest.index = -1; /* transform into target space */ @@ -623,7 +635,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ if (weight > 0) { dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, weight, replace_mode); + vgroup_transfer_weight(&dw_dst->weight, weight, replace_mode); } } @@ -642,6 +654,10 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou /* loop through the vertices */ for(i = 0, dv_dst = dv_array_dst; i < me_dst->totvert; i++, dv_dst++, mv_dst++){ + if (*dv_dst == NULL) { + continue; + } + /* reset nearest */ nearest.dist = FLT_MAX; /* With current binary tree its marginally faster to start searching at the top, as opposed to previous search. */ @@ -677,7 +693,7 @@ static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGrou dw_src = defvert_find_index(dv_array_src[index_nearest_vertex], index_src); if (dw_src && dw_src->weight) { dw_dst = defvert_verify_index(*dv_dst, index_dst); - vgroup_transfer_weight(mv_dst, &dw_dst->weight, dw_src->weight, replace_mode); + vgroup_transfer_weight(&dw_dst->weight, dw_src->weight, replace_mode); } } @@ -3316,7 +3332,7 @@ static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) { /* identifiers */ - ot->name = "Transfer weight"; + ot->name = "Transfer Weights"; ot->idname = "OBJECT_OT_vertex_group_transfer_weight"; ot->description = "Transfer weight paint to active from selected mesh"; diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 817067422af..96276d5eb1b 100644 --- a/source/blender/editors/render/render_preview.c +++ b/source/blender/editors/render/render_preview.c @@ -273,16 +273,7 @@ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPre /* exception: don't apply render part of display transform for texture previews or icons */ if ((id && sp->pr_method == PR_ICON_RENDER) || id_type == ID_TE) { - ColorManagedDisplaySettings *display_settings = &sce->display_settings; - ColorManagedViewSettings *view_settings = &sce->view_settings; - - const char *default_view_name = IMB_colormanagement_view_get_default_name(display_settings->display_device); - - view_settings->exposure = 0.0f; - view_settings->gamma = 1.0f; - view_settings->flag &= ~COLORMANAGE_VIEW_USE_CURVES; - - BLI_strncpy(view_settings->view_transform, default_view_name, sizeof(view_settings->view_transform)); + BKE_scene_disable_color_management(sce); } if ((id && sp->pr_method == PR_ICON_RENDER) && id_type != ID_WO) @@ -550,7 +541,7 @@ static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int * color managed as well? */ IMB_buffer_byte_from_float(rect_byte, rres.rectf, - 4, dither, IB_PROFILE_SRGB, IB_PROFILE_LINEAR_RGB, do_predivide, + 4, dither, IB_PROFILE_SRGB, IB_PROFILE_SRGB, do_predivide, rres.rectx, rres.recty, rres.rectx, rres.rectx); } diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index c64a4a37f3a..5eac841dec6 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2716,6 +2716,8 @@ static int region_quadview_exec(bContext *C, wmOperator *op) /* lock views and set them */ if (sa->spacetype == SPACE_VIEW3D) { + View3D *v3d = sa->spacedata.first; + /* run ED_view3d_lock() so the correct 'rv3d->viewquat' is set, * otherwise when restoring rv3d->localvd the 'viewquat' won't * match the 'view', set on entering localview See: [#26315], @@ -2743,7 +2745,15 @@ static int region_quadview_exec(bContext *C, wmOperator *op) ar = ar->next; rv3d = ar->regiondata; - rv3d->view = RV3D_VIEW_CAMERA; rv3d->persp = RV3D_CAMOB; + + /* check if we have a camera */ + if (v3d->camera) { + rv3d->view = RV3D_VIEW_CAMERA; rv3d->persp = RV3D_CAMOB; + } + else { + rv3d->view = RV3D_VIEW_PERSPORTHO; rv3d->persp = RV3D_PERSP; + } + ED_view3d_lock(rv3d); view3d_localview_update_rv3d(rv3d); } diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 04dfbf819f5..dd3c7408511 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -27,10 +27,6 @@ * \ingroup spview3d */ - -#include <string.h> -#include <math.h> - #include "MEM_guardedalloc.h" #include "DNA_camera_types.h" @@ -40,21 +36,14 @@ #include "DNA_lattice_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" -#include "DNA_meshdata_types.h" #include "DNA_meta_types.h" #include "DNA_scene_types.h" #include "DNA_smoke_types.h" -#include "DNA_speaker_types.h" #include "DNA_world_types.h" -#include "DNA_armature_types.h" #include "DNA_object_types.h" -#include "BLI_utildefines.h" #include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_edgehash.h" -#include "BLI_rand.h" -#include "BLI_utildefines.h" #include "BKE_anim.h" /* for the where_on_path function */ #include "BKE_armature.h" @@ -79,13 +68,10 @@ #include "BKE_pointcache.h" #include "BKE_scene.h" #include "BKE_unit.h" -#include "BKE_movieclip.h" #include "BKE_tracking.h" #include "BKE_tessmesh.h" -#include "smoke_API.h" - #include "IMB_imbuf.h" #include "IMB_imbuf_types.h" @@ -100,16 +86,13 @@ #include "ED_screen.h" #include "ED_sculpt.h" #include "ED_types.h" -#include "ED_curve.h" /* for curve_editnurbs */ -#include "ED_armature.h" #include "UI_resources.h" #include "WM_api.h" -#include "wm_subwindow.h" #include "BLF_api.h" -#include "view3d_intern.h" /* own include */ +#include "view3d_intern.h" /* bad level include */ typedef enum eWireDrawMode { OBDRAW_WIRE_OFF = 0, @@ -117,28 +100,6 @@ typedef enum eWireDrawMode { OBDRAW_WIRE_ON_DEPTH = 2 } eWireDrawMode; -/* user data structures for derived mesh callbacks */ -typedef struct foreachScreenVert_userData { - void (*func)(void *userData, BMVert *eve, int x, int y, int index); - void *userData; - ViewContext vc; - eV3DClipTest clipVerts; -} foreachScreenVert_userData; - -typedef struct foreachScreenEdge_userData { - void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index); - void *userData; - ViewContext vc; - rcti win_rect; /* copy of: vc.ar->winx/winy, use for faster tests, minx/y will always be 0 */ - eV3DClipTest clipVerts; -} foreachScreenEdge_userData; - -typedef struct foreachScreenFace_userData { - void (*func)(void *userData, BMFace *efa, int x, int y, int index); - void *userData; - ViewContext vc; -} foreachScreenFace_userData; - typedef struct drawDMVerts_userData { BMEditMesh *em; /* BMESH BRANCH ONLY */ @@ -1870,29 +1831,6 @@ static void lattice_draw_verts(Lattice *lt, DispList *dl, short sel) bglEnd(); } -void lattice_foreachScreenVert(ViewContext *vc, void (*func)(void *userData, BPoint *bp, int x, int y), void *userData) -{ - Object *obedit = vc->obedit; - Lattice *lt = obedit->data; - BPoint *bp = lt->editlatt->latt->def; - DispList *dl = BKE_displist_find(&obedit->disp, DL_VERTS); - float *co = dl ? dl->verts : NULL; - int i, N = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; - - ED_view3d_clipping_local(vc->rv3d, obedit->obmat); /* for local clipping lookups */ - - for (i = 0; i < N; i++, bp++, co += 3) { - if (bp->hide == 0) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, dl ? co : bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, bp, screen_co[0], screen_co[1]); - } - } - } -} - static void drawlattice__point(Lattice *lt, DispList *dl, int u, int v, int w, int use_wcol) { int index = ((w * lt->pntsv + v) * lt->pntsu) + u; @@ -1979,53 +1917,6 @@ static void drawlattice(Scene *scene, View3D *v3d, Object *ob) /* ***************** ******************** */ -/* Note! - foreach funcs should be called while drawing or directly after - * if not, ED_view3d_init_mats_rv3d() can be used for selection tools - * but would not give correct results with dupli's for eg. which don't - * use the object matrix in the usual way */ -static void mesh_foreachScreenVert__mapFunc(void *userData, int index, const float co[3], - const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) -{ - foreachScreenVert_userData *data = userData; - BMVert *eve = EDBM_vert_at_index(data->vc.em, index); - - if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_OFF) ? - V3D_PROJ_TEST_NOP : - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN; - int screen_co[2]; - - if (ED_view3d_project_int_object(data->vc.ar, co, screen_co, flag) != V3D_PROJ_RET_OK) { - return; - } - - data->func(data->userData, eve, screen_co[0], screen_co[1], index); - } -} - -void mesh_foreachScreenVert( - ViewContext *vc, - void (*func)(void *userData, BMVert *eve, int x, int y, int index), - void *userData, eV3DClipTest clipVerts) -{ - foreachScreenVert_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - data.func = func; - data.userData = userData; - data.clipVerts = clipVerts; - - if (clipVerts != V3D_CLIP_TEST_OFF) - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - EDBM_index_arrays_init(vc->em, 1, 0, 0); - dm->foreachMappedVert(dm, mesh_foreachScreenVert__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - /* draw callback */ static void drawSelectedVertices__mapFunc(void *userData, int index, const float co[3], const float UNUSED(no_f[3]), const short UNUSED(no_s[3])) @@ -2054,283 +1945,6 @@ static void drawSelectedVertices(DerivedMesh *dm, Mesh *me) glEnd(); } -static void mesh_foreachScreenEdge__mapFunc(void *userData, int index, const float v0co[3], const float v1co[3]) -{ - foreachScreenEdge_userData *data = userData; - BMEdge *eed = EDBM_edge_at_index(data->vc.em, index); - - if (!BM_elem_flag_test(eed, BM_ELEM_HIDDEN)) { - int screen_co_a[2]; - int screen_co_b[2]; - - const eV3DProjTest flag = (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) ? - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN : - V3D_PROJ_TEST_NOP; - - if (ED_view3d_project_int_object(data->vc.ar, v0co, screen_co_a, flag) != V3D_PROJ_RET_OK) { - return; - } - if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_OK) { - return; - } - - if (data->clipVerts == V3D_CLIP_TEST_RV3D_CLIPPING) { - /* pass */ - } - else { - if (data->clipVerts == V3D_CLIP_TEST_REGION) { - if (!BLI_rcti_isect_segment(&data->win_rect, screen_co_a, screen_co_b)) { - return; - } - } - } - - data->func(data->userData, eed, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1], index); - } -} - -void mesh_foreachScreenEdge( - ViewContext *vc, - void (*func)(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index), - void *userData, eV3DClipTest clipVerts) -{ - foreachScreenEdge_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - - data.win_rect.xmin = 0; - data.win_rect.ymin = 0; - data.win_rect.xmax = vc->ar->winx; - data.win_rect.ymax = vc->ar->winy; - - data.func = func; - data.userData = userData; - data.clipVerts = clipVerts; - - if (clipVerts != V3D_CLIP_TEST_OFF) - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - EDBM_index_arrays_init(vc->em, 0, 1, 0); - dm->foreachMappedEdge(dm, mesh_foreachScreenEdge__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - -static void mesh_foreachScreenFace__mapFunc(void *userData, int index, const float cent[3], const float UNUSED(no[3])) -{ - foreachScreenFace_userData *data = userData; - BMFace *efa = EDBM_face_at_index(data->vc.em, index); - - if (efa && !BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - int screen_co[2]; - if (ED_view3d_project_int_object(data->vc.ar, cent, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - data->func(data->userData, efa, screen_co[0], screen_co[1], index); - } - } -} - -void mesh_foreachScreenFace( - ViewContext *vc, - void (*func)(void *userData, BMFace *efa, int x, int y, int index), - void *userData) -{ - foreachScreenFace_userData data; - DerivedMesh *dm = editbmesh_get_derived_cage(vc->scene, vc->obedit, vc->em, CD_MASK_BAREMESH); - - data.vc = *vc; - data.func = func; - data.userData = userData; - - ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - - EDBM_index_arrays_init(vc->em, 0, 0, 1); - dm->foreachMappedFaceCenter(dm, mesh_foreachScreenFace__mapFunc, &data); - EDBM_index_arrays_free(vc->em); - - dm->release(dm); -} - -void nurbs_foreachScreenVert( - ViewContext *vc, - void (*func)(void *userData, Nurb *nu, BPoint *bp, BezTriple *bezt, int beztindex, int x, int y), - void *userData) -{ - Curve *cu = vc->obedit->data; - Nurb *nu; - int i; - ListBase *nurbs = BKE_curve_editNurbs_get(cu); - - ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */ - - for (nu = nurbs->first; nu; nu = nu->next) { - if (nu->type == CU_BEZIER) { - for (i = 0; i < nu->pntsu; i++) { - BezTriple *bezt = &nu->bezt[i]; - - if (bezt->hide == 0) { - int screen_co[2]; - - if (cu->drawflag & CU_HIDE_HANDLES) { - if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); - } - } - else { - if (ED_view3d_project_int_object(vc->ar, bezt->vec[0], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 0, screen_co[0], screen_co[1]); - } - if (ED_view3d_project_int_object(vc->ar, bezt->vec[1], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 1, screen_co[0], screen_co[1]); - } - if (ED_view3d_project_int_object(vc->ar, bezt->vec[2], screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, NULL, bezt, 2, screen_co[0], screen_co[1]); - } - } - } - } - } - else { - for (i = 0; i < nu->pntsu * nu->pntsv; i++) { - BPoint *bp = &nu->bp[i]; - - if (bp->hide == 0) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, bp->vec, screen_co, - V3D_PROJ_RET_CLIP_BB | V3D_PROJ_RET_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, nu, bp, NULL, -1, screen_co[0], screen_co[1]); - } - } - } - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -void mball_foreachScreenElem( - struct ViewContext *vc, - void (*func)(void *userData, struct MetaElem *ml, int x, int y), - void *userData) -{ - MetaBall *mb = (MetaBall *)vc->obedit->data; - MetaElem *ml; - - for (ml = mb->editelems->first; ml; ml = ml->next) { - int screen_co[2]; - if (ED_view3d_project_int_object(vc->ar, &ml->x, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - func(userData, ml, screen_co[0], screen_co[1]); - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -void armature_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1), - void *userData) -{ - bArmature *arm = vc->obedit->data; - EditBone *ebone; - - for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { - if (EBONE_VISIBLE(arm, ebone)) { - int screen_co_a[2], screen_co_b[2]; - int points_proj_tot = 0; - - /* project head location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, ebone->head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_a[0] = IS_CLIPPED; /* weak */ - /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ - } - - /* project tail location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, ebone->tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_b[0] = IS_CLIPPED; /* weak */ - /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ - } - - if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, ebone, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1]); - } - } - } -} - -/* ED_view3d_init_mats_rv3d must be called first */ -/* almost _exact_ copy of #armature_foreachScreenBone */ -void pose_foreachScreenBone( - struct ViewContext *vc, - void (*func)(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1), - void *userData) -{ - bArmature *arm = vc->obact->data; - bPose *pose = vc->obact->pose; - bPoseChannel *pchan; - - for (pchan = pose->chanbase.first; pchan; pchan = pchan->next) { - if (PBONE_VISIBLE(arm, pchan->bone)) { - int screen_co_a[2], screen_co_b[2]; - int points_proj_tot = 0; - - /* project head location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, pchan->pose_head, screen_co_a, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_a[0] = IS_CLIPPED; /* weak */ - /* screen_co_a[1]: intentionally dont set this so we get errors on misuse */ - } - - /* project tail location to screenspace */ - if (ED_view3d_project_int_object(vc->ar, pchan->pose_tail, screen_co_b, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) - { - points_proj_tot++; - } - else { - screen_co_b[0] = IS_CLIPPED; /* weak */ - /* screen_co_b[1]: intentionally dont set this so we get errors on misuse */ - } - - if (points_proj_tot) { /* at least one point's projection worked */ - func(userData, pchan, - screen_co_a[0], screen_co_a[1], - screen_co_b[0], screen_co_b[1]); - } - } - } -} - /* ************** DRAW MESH ****************** */ /* First section is all the "simple" draw routines, diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index c5246b1ad1f..88375c409b8 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1462,7 +1462,7 @@ ImBuf *view3d_read_backbuf(ViewContext *vc, short xmin, short ymin, short xmax, /* smart function to sample a rect spiralling outside, nice for backbuf selection */ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int size, - unsigned int min, unsigned int max, int *dist, short strict, + unsigned int min, unsigned int max, float *r_dist, short strict, void *handle, unsigned int (*indextest)(void *handle, unsigned int index)) { struct ImBuf *buf; @@ -1500,13 +1500,13 @@ unsigned int view3d_sample_backbuf_rect(ViewContext *vc, const int mval[2], int if (strict) { indexok = indextest(handle, *tbuf - min + 1); if (indexok) { - *dist = (short) sqrt( (float)distance); + *r_dist = sqrtf((float)distance); index = *tbuf - min + 1; goto exit; } } else { - *dist = (short) sqrt( (float)distance); /* XXX, this distance is wrong - */ + *r_dist = sqrtf((float)distance); /* XXX, this distance is wrong - */ index = *tbuf - min + 1; /* messy yah, but indices start at 1 */ goto exit; } diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 4e8981f16bd..2b2453d6dc2 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -2282,23 +2282,78 @@ void VIEW3D_OT_view_all(wmOperatorType *ot) RNA_def_boolean(ot->srna, "center", 0, "Center", ""); } +static void viewselected_rv3d_from_minmax(bContext *C, View3D *v3d, ARegion *ar, + const float min[3], const float max[3], + int ok_dist) +{ + RegionView3D *rv3d = ar->regiondata; + float afm[3]; + float size; + + /* SMOOTHVIEW */ + float new_ofs[3]; + float new_dist; + + sub_v3_v3v3(afm, max, min); + size = MAX3(afm[0], afm[1], afm[2]); + + if (ok_dist) { + /* fix up zoom distance if needed */ + + if (rv3d->is_persp) { + if (size <= v3d->near * 1.5f) { + /* do not zoom closer than the near clipping plane */ + size = v3d->near * 1.5f; + } + } + else { /* ortho */ + if (size < 0.0001f) { + /* bounding box was a single point so do not zoom */ + ok_dist = 0; + } + else { + /* adjust zoom so it looks nicer */ + size *= 0.7f; + } + } + } + + add_v3_v3v3(new_ofs, min, max); + mul_v3_fl(new_ofs, -0.5f); + + new_dist = size; + + /* correction for window aspect ratio */ + if (ar->winy > 2 && ar->winx > 2) { + size = (float)ar->winx / (float)ar->winy; + if (size < 1.0f) size = 1.0f / size; + new_dist *= size; + } + + if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) { + rv3d->persp = RV3D_PERSP; + view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + } + else { + view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + } + + /* smooth view does viewlock RV3D_BOXVIEW copy */ +} + /* like a localview without local!, was centerview() in 2.4x */ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); + RegionView3D *rv3d = ar->regiondata; Scene *scene = CTX_data_scene(C); Object *ob = OBACT; Object *obedit = CTX_data_edit_object(C); - float size, min[3], max[3], afm[3]; + float min[3], max[3]; int ok = 0, ok_dist = 1; const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); - /* SMOOTHVIEW */ - float new_ofs[3]; - float new_dist; - INIT_MINMAX(min, max); if (ob && (ob->mode & OB_MODE_WEIGHT_PAINT)) { @@ -2368,53 +2423,11 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) } } - if (ok == 0) return OPERATOR_FINISHED; - - sub_v3_v3v3(afm, max, min); - size = MAX3(afm[0], afm[1], afm[2]); - - if (ok_dist) { - /* fix up zoom distance if needed */ - - if (rv3d->is_persp) { - if (size <= v3d->near * 1.5f) { - /* do not zoom closer than the near clipping plane */ - size = v3d->near * 1.5f; - } - } - else { /* ortho */ - if (size < 0.0001f) { - /* bounding box was a single point so do not zoom */ - ok_dist = 0; - } - else { - /* adjust zoom so it looks nicer */ - size *= 0.7f; - } - } - } - - add_v3_v3v3(new_ofs, min, max); - mul_v3_fl(new_ofs, -0.5f); - - new_dist = size; - - /* correction for window aspect ratio */ - if (ar->winy > 2 && ar->winx > 2) { - size = (float)ar->winx / (float)ar->winy; - if (size < 1.0f) size = 1.0f / size; - new_dist *= size; - } - - if (rv3d->persp == RV3D_CAMOB && !ED_view3d_camera_lock_check(v3d, rv3d)) { - rv3d->persp = RV3D_PERSP; - view3d_smooth_view(C, v3d, ar, v3d->camera, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); - } - else { - view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + if (ok == 0) { + return OPERATOR_FINISHED; } - /* smooth view does viewlock RV3D_BOXVIEW copy */ + viewselected_rv3d_from_minmax(C, v3d, ar, min, max, ok_dist); // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); diff --git a/source/blender/editors/space_view3d/view3d_fly.c b/source/blender/editors/space_view3d/view3d_fly.c index c743b88e889..cd358dea869 100644 --- a/source/blender/editors/space_view3d/view3d_fly.c +++ b/source/blender/editors/space_view3d/view3d_fly.c @@ -284,6 +284,11 @@ static int initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event puts("\n-- fly begin --"); #endif + /* sanity check: for rare but possible case (if lib-linking the camera fails) */ + if ((fly->rv3d->persp == RV3D_CAMOB) && (fly->v3d->camera == NULL)) { + fly->rv3d->persp = RV3D_PERSP; + } + if (fly->rv3d->persp == RV3D_CAMOB && fly->v3d->camera->id.lib) { BKE_report(op->reports, RPT_ERROR, "Cannot fly a camera from an external library"); return FALSE; diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 5f0bb180711..dc3cfa41e37 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -258,6 +258,8 @@ static void edbm_backbuf_check_and_select_tfaces(Mesh *me, int select) typedef struct LassoSelectUserData { ViewContext *vc; const rcti *rect; + const rctf *rect_fl; + rctf _rect_fl; const int (*mcords)[2]; int moves; int select; @@ -273,7 +275,11 @@ static void view3d_userdata_lassoselect_init(LassoSelectUserData *r_data, const int moves, const int select) { r_data->vc = vc; + r_data->rect = rect; + r_data->rect_fl = &r_data->_rect_fl; + BLI_rctf_rcti_copy(&r_data->_rect_fl, rect); + r_data->mcords = mcords; r_data->moves = moves; r_data->select = select; @@ -314,29 +320,29 @@ static int view3d_selectable_data(bContext *C) /* helper also for borderselect */ -static int edge_fully_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) +static int edge_fully_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) { - return BLI_rcti_isect_pt(rect, x1, y1) && BLI_rcti_isect_pt(rect, x2, y2); + return BLI_rctf_isect_pt_v(rect, v1) && BLI_rctf_isect_pt_v(rect, v2); } -static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) +static int edge_inside_rect(const rctf *rect, const float v1[2], const float v2[2]) { int d1, d2, d3, d4; /* check points in rect */ - if (edge_fully_inside_rect(rect, x1, y1, x2, y2)) return 1; + if (edge_fully_inside_rect(rect, v1, v2)) return 1; /* check points completely out rect */ - if (x1 < rect->xmin && x2 < rect->xmin) return 0; - if (x1 > rect->xmax && x2 > rect->xmax) return 0; - if (y1 < rect->ymin && y2 < rect->ymin) return 0; - if (y1 > rect->ymax && y2 > rect->ymax) return 0; + if (v1[0] < rect->xmin && v2[0] < rect->xmin) return 0; + if (v1[0] > rect->xmax && v2[0] > rect->xmax) return 0; + if (v1[1] < rect->ymin && v2[1] < rect->ymin) return 0; + if (v1[1] > rect->ymax && v2[1] > rect->ymax) return 0; /* simple check lines intersecting. */ - d1 = (y1 - y2) * (x1 - rect->xmin) + (x2 - x1) * (y1 - rect->ymin); - d2 = (y1 - y2) * (x1 - rect->xmin) + (x2 - x1) * (y1 - rect->ymax); - d3 = (y1 - y2) * (x1 - rect->xmax) + (x2 - x1) * (y1 - rect->ymax); - d4 = (y1 - y2) * (x1 - rect->xmax) + (x2 - x1) * (y1 - rect->ymin); + d1 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymin); + d2 = (v1[1] - v2[1]) * (v1[0] - rect->xmin) + (v2[0] - v1[0]) * (v1[1] - rect->ymax); + d3 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymax); + d4 = (v1[1] - v2[1]) * (v1[0] - rect->xmax) + (v2[0] - v1[0]) * (v1[1] - rect->ymin); if (d1 < 0 && d2 < 0 && d3 < 0 && d4 < 0) return 0; if (d1 > 0 && d2 > 0 && d3 > 0 && d4 > 0) return 0; @@ -344,7 +350,7 @@ static int edge_inside_rect(const rcti *rect, int x1, int y1, int x2, int y2) return 1; } -static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) +static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]) { LassoSelectUserData *data = userData; bArmature *arm = data->vc->obact->data; @@ -353,6 +359,11 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann int is_point_done = FALSE; int points_proj_tot = 0; + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + /* project head location to screenspace */ if (x0 != IS_CLIPPED) { points_proj_tot++; @@ -387,6 +398,7 @@ static void do_lasso_select_pose__doSelectBone(void *userData, struct bPoseChann } static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[][2], short moves, short select) { + ViewContext vc_tmp; LassoSelectUserData data; rcti rect; @@ -394,13 +406,16 @@ static void do_lasso_select_pose(ViewContext *vc, Object *ob, const int mcords[] return; } + vc_tmp = *vc; + vc_tmp.obact = ob; + + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - - pose_foreachScreenBone(vc, do_lasso_select_pose__doSelectBone, &data); + pose_foreachScreenBone(&vc_tmp, do_lasso_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = ob->data; @@ -445,23 +460,28 @@ static void do_lasso_select_objects(ViewContext *vc, const int mcords[][2], cons } } -static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void do_lasso_select_mesh__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) +static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index) { LassoSelectUserData *data = userData; if (EDBM_backbuf_check(bm_solidoffs + index)) { + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + if (data->pass == 0) { - if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1) && + if (edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b) && BLI_lasso_is_point_inside(data->mcords, data->moves, x0, y0, IS_CLIPPED) && BLI_lasso_is_point_inside(data->mcords, data->moves, x1, y1, IS_CLIPPED)) { @@ -476,12 +496,12 @@ static void do_lasso_select_mesh__doSelectEdge(void *userData, BMEdge *eed, int } } } -static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void do_lasso_select_mesh__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { BM_face_select_set(data->vc->em->bm, efa, data->select); } @@ -494,11 +514,11 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m rcti rect; int bbsel; - BLI_lasso_boundbox(&rect, mcords, moves); - /* set editmesh */ vc->em = BMEdit_FromObject(vc->obedit); + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) @@ -515,17 +535,17 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, do_lasso_select_mesh__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP); if (data.is_done == 0) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_lasso_select_mesh__doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -534,7 +554,7 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data); + mesh_foreachScreenFace(vc, do_lasso_select_mesh__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -542,13 +562,13 @@ static void do_lasso_select_mesh(ViewContext *vc, const int mcords[][2], short m EDBM_selectmode_flush(vc->em); } -static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { LassoSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) { + if (BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; @@ -578,38 +598,45 @@ static void do_lasso_select_curve__doSelect(void *userData, Nurb *UNUSED(nu), BP static void do_lasso_select_curve(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; + rcti rect; - view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); + BLI_lasso_boundbox(&rect, mcords, moves); + + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) CU_deselect_all(vc->obedit); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data); + nurbs_foreachScreenVert(vc, do_lasso_select_curve__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } -static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, int x, int y) +static void do_lasso_select_lattice__doSelect(void *userData, BPoint *bp, const float screen_co[2]) { LassoSelectUserData *data = userData; - if (BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, IS_CLIPPED)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], IS_CLIPPED)) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } static void do_lasso_select_lattice(ViewContext *vc, const int mcords[][2], short moves, short extend, short select) { LassoSelectUserData data; + rcti rect; - view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); + BLI_lasso_boundbox(&rect, mcords, moves); + + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); if (extend == 0 && select) ED_setflagsLatt(vc->obedit, 0); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data); + lattice_foreachScreenVert(vc, do_lasso_select_lattice__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } -static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) +static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]) { LassoSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; @@ -618,6 +645,11 @@ static void do_lasso_select_armature__doSelectBone(void *userData, struct EditBo int is_point_done = FALSE; int points_proj_tot = 0; + const int x0 = screen_co_a[0]; + const int y0 = screen_co_a[1]; + const int x1 = screen_co_b[0]; + const int y1 = screen_co_b[1]; + /* project head location to screenspace */ if (x0 != IS_CLIPPED) { points_proj_tot++; @@ -660,16 +692,16 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho LassoSelectUserData data; rcti rect; + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - if (extend == 0 && select) ED_armature_deselect_all_visible(vc->obedit); - armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data); + armature_foreachScreenBone(vc, do_lasso_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = vc->obedit->data; @@ -679,12 +711,12 @@ static void do_lasso_select_armature(ViewContext *vc, const int mcords[][2], sho } } -static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +static void do_lasso_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2]) { LassoSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y) && - BLI_lasso_is_point_inside(data->mcords, data->moves, x, y, INT_MAX)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co) && + BLI_lasso_is_point_inside(data->mcords, data->moves, screen_co[0], screen_co[1], INT_MAX)) { if (data->select) ml->flag |= SELECT; else ml->flag &= ~SELECT; data->is_change = TRUE; @@ -700,13 +732,13 @@ static void do_lasso_select_meta(ViewContext *vc, const int mcords[][2], short m if (extend == 0 && select) BKE_mball_deselect_all(mb); + BLI_lasso_boundbox(&rect, mcords, moves); + view3d_userdata_lassoselect_init(&data, vc, &rect, mcords, moves, select); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - BLI_lasso_boundbox(&rect, mcords, moves); - - mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data); + mball_foreachScreenElem(vc, do_lasso_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } static int do_paintvert_box_select(ViewContext *vc, rcti *rect, int select, int extend) @@ -1387,9 +1419,12 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese View3D *v3d = CTX_wm_view3d(C); Scene *scene = CTX_data_scene(C); Base *base, *startbase = NULL, *basact = NULL, *oldbasact = NULL; - int temp, a, dist = 100; + int a; + float dist = 100.0f; int retval = 0; short hits; + const float mval_fl[2] = {(float)mval[0], (float)mval[1]}; + /* setup view context for argument to callbacks */ view3d_set_viewcontext(C, &vc); @@ -1410,13 +1445,16 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese base = startbase; while (base) { if (BASE_SELECTABLE(v3d, base)) { - ED_view3d_project_base(ar, base); - temp = abs(base->sx - mval[0]) + abs(base->sy - mval[1]); - if (base == BASACT) temp += 10; - if (temp < dist) { - - dist = temp; - basact = base; + float screen_co[2]; + if (ED_view3d_project_float_global(ar, base->object->obmat[3], screen_co, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) + { + float dist_temp = len_manhattan_v2v2(mval_fl, screen_co); + if (base == BASACT) dist_temp += 10.0f; + if (dist_temp < dist) { + dist = dist_temp; + basact = base; + } } } base = base->next; @@ -1583,6 +1621,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese typedef struct BoxSelectUserData { ViewContext *vc; const rcti *rect; + const rctf *rect_fl; + rctf _rect_fl; int select; /* runtime */ @@ -1595,7 +1635,11 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, ViewContext *vc, const rcti *rect, const int select) { r_data->vc = vc; + r_data->rect = rect; + r_data->rect_fl = &r_data->_rect_fl; + BLI_rctf_rcti_copy(&r_data->_rect_fl, rect); + r_data->select = select; /* runtime */ @@ -1604,23 +1648,20 @@ static void view3d_userdata_boxselect_init(BoxSelectUserData *r_data, r_data->is_change = FALSE; } -int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, int y2) +int edge_inside_circle(const float cent[2], float radius, const float screen_co_a[2], const float screen_co_b[2]) { int radius_squared = radius * radius; /* check points in circle itself */ - if ((x1 - centx) * (x1 - centx) + (y1 - centy) * (y1 - centy) <= radius_squared) { + if (len_squared_v2v2(cent, screen_co_a) <= radius_squared) { return TRUE; } - else if ((x2 - centx) * (x2 - centx) + (y2 - centy) * (y2 - centy) <= radius_squared) { + if (len_squared_v2v2(cent, screen_co_b) <= radius_squared) { return TRUE; } else { - const float cent[2] = {centx, centy}; - const float v1[2] = {x1, y1}; - const float v2[2] = {x2, y2}; /* pointdistline */ - if (dist_squared_to_line_segment_v2(cent, v1, v2) < (float)radius_squared) { + if (dist_squared_to_line_segment_v2(cent, screen_co_a, screen_co_b) < (float)radius_squared) { return TRUE; } } @@ -1628,13 +1669,13 @@ int edge_inside_circle(int centx, int centy, int radius, int x1, int y1, int x2, return FALSE; } -static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void do_nurbs_box_select__doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { BoxSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); if (bp == cu->lastsel && !(bp->f1 & SELECT)) cu->lastsel = NULL; @@ -1670,16 +1711,16 @@ static int do_nurbs_box_select(ViewContext *vc, rcti *rect, int select, int exte CU_deselect_all(vc->obedit); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data); + nurbs_foreachScreenVert(vc, do_nurbs_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return OPERATOR_FINISHED; } -static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, int x, int y) +static void do_lattice_box_select__doSelect(void *userData, BPoint *bp, const float screen_co[2]) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } @@ -1693,42 +1734,42 @@ static int do_lattice_box_select(ViewContext *vc, rcti *rect, int select, int ex ED_setflagsLatt(vc->obedit, 0); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data); + lattice_foreachScreenVert(vc, do_lattice_box_select__doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); return OPERATOR_FINISHED; } -static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void do_mesh_box_select__doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int index) +static void do_mesh_box_select__doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int index) { BoxSelectUserData *data = userData; if (EDBM_backbuf_check(bm_solidoffs + index)) { if (data->pass == 0) { - if (edge_fully_inside_rect(data->rect, x0, y0, x1, y1)) { + if (edge_fully_inside_rect(data->rect_fl, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); data->is_done = TRUE; } } else { - if (edge_inside_rect(data->rect, x0, y0, x1, y1)) { + if (edge_inside_rect(data->rect_fl, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); } } } } -static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void do_mesh_box_select__doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { BoxSelectUserData *data = userData; - if (BLI_rcti_isect_pt(data->rect, x, y)) { + if (BLI_rctf_isect_pt_v(data->rect_fl, screen_co)) { BM_face_select_set(data->vc->em->bm, efa, data->select); } } @@ -1754,18 +1795,18 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten edbm_backbuf_check_and_select_verts(vc->em, select); } else { - mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, do_mesh_box_select__doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } if (ts->selectmode & SCE_SELECT_EDGE) { /* Does both bbsel and non-bbsel versions (need screen cos for both) */ data.pass = 0; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP); if (data.is_done == 0) { data.pass = 1; - mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, do_mesh_box_select__doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -1774,7 +1815,7 @@ static int do_mesh_box_select(ViewContext *vc, rcti *rect, int select, int exten edbm_backbuf_check_and_select_faces(vc->em, select); } else { - mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data); + mesh_foreachScreenFace(vc, do_mesh_box_select__doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2216,7 +2257,8 @@ void VIEW3D_OT_select(wmOperatorType *ot) typedef struct CircleSelectUserData { ViewContext *vc; short select; - int mval[2]; + int mval[2]; + float mval_fl[2]; float radius; float radius_squared; @@ -2230,6 +2272,9 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, r_data->vc = vc; r_data->select = select; copy_v2_v2_int(r_data->mval, mval); + r_data->mval_fl[0] = mval[0]; + r_data->mval_fl[1] = mval[1]; + r_data->radius = rad; r_data->radius_squared = rad * rad; @@ -2237,31 +2282,27 @@ static void view3d_userdata_circleselect_init(CircleSelectUserData *r_data, r_data->is_change = FALSE; } -static void mesh_circle_doSelectVert(void *userData, BMVert *eve, int x, int y, int UNUSED(index)) +static void mesh_circle_doSelectVert(void *userData, BMVert *eve, const float screen_co[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { BM_vert_select_set(data->vc->em->bm, eve, data->select); } } -static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, int x0, int y0, int x1, int y1, int UNUSED(index)) +static void mesh_circle_doSelectEdge(void *userData, BMEdge *eed, const float screen_co_a[2], const float screen_co_b[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - if (edge_inside_circle(data->mval[0], data->mval[1], (int)data->radius, x0, y0, x1, y1)) { + if (edge_inside_circle(data->mval_fl, (int)data->radius, screen_co_a, screen_co_b)) { BM_edge_select_set(data->vc->em->bm, eed, data->select); } } -static void mesh_circle_doSelectFace(void *userData, BMFace *efa, int x, int y, int UNUSED(index)) +static void mesh_circle_doSelectFace(void *userData, BMFace *efa, const float screen_co[2], int UNUSED(index)) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { BM_face_select_set(data->vc->em->bm, efa, data->select); } } @@ -2284,7 +2325,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_verts(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_CLIP_TEST_RV3D_CLIPPING); + mesh_foreachScreenVert(vc, mesh_circle_doSelectVert, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2293,7 +2334,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_edges(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_CLIP_TEST_OFF); + mesh_foreachScreenEdge(vc, mesh_circle_doSelectEdge, &data, V3D_PROJ_TEST_NOP); } } @@ -2302,7 +2343,7 @@ static void mesh_circle_select(ViewContext *vc, int select, const int mval[2], f edbm_backbuf_check_and_select_faces(vc->em, select == LEFTMOUSE); } else { - mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data); + mesh_foreachScreenFace(vc, mesh_circle_doSelectFace, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } } @@ -2345,16 +2386,13 @@ static void paint_vertsel_circle_select(ViewContext *vc, int select, const int m } -static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, int x, int y) +static void nurbscurve_circle_doSelect(void *userData, Nurb *UNUSED(nu), BPoint *bp, BezTriple *bezt, int beztindex, const float screen_co[2]) { CircleSelectUserData *data = userData; Object *obedit = data->vc->obedit; Curve *cu = (Curve *)obedit->data; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (bp) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); @@ -2388,17 +2426,15 @@ static void nurbscurve_circle_select(ViewContext *vc, int select, const int mval view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data); + nurbs_foreachScreenVert(vc, nurbscurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } -static void latticecurve_circle_doSelect(void *userData, BPoint *bp, int x, int y) +static void latticecurve_circle_doSelect(void *userData, BPoint *bp, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { bp->f1 = data->select ? (bp->f1 | SELECT) : (bp->f1 & ~SELECT); } } @@ -2409,18 +2445,16 @@ static void lattice_circle_select(ViewContext *vc, int select, const int mval[2] view3d_userdata_circleselect_init(&data, vc, select, mval, rad); ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); /* for foreach's screen/vert projection */ - lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data); + lattice_foreachScreenVert(vc, latticecurve_circle_doSelect, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } /* NOTE: pose-bone case is copied from editbone case... */ -static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int x, int y) +static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (data->select) pchan->bone->flag |= BONE_SELECTED; else @@ -2429,7 +2463,7 @@ static short pchan_circle_doSelectJoint(void *userData, bPoseChannel *pchan, int } return 0; } -static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, int x0, int y0, int x1, int y1) +static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChannel *pchan, const float screen_co_a[2], const float screen_co_b[2]) { CircleSelectUserData *data = userData; bArmature *arm = data->vc->obact->data; @@ -2439,17 +2473,17 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan int points_proj_tot = 0; /* project head location to screenspace */ - if (x0 != IS_CLIPPED) { + if (screen_co_a[0] != IS_CLIPPED) { points_proj_tot++; - if (pchan_circle_doSelectJoint(data, pchan, x0, y0)) { + if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) { is_point_done = TRUE; } } /* project tail location to screenspace */ - if (x1 != IS_CLIPPED) { + if (screen_co_b[0] != IS_CLIPPED) { points_proj_tot++; - if (pchan_circle_doSelectJoint(data, pchan, x1, y1)) { + if (pchan_circle_doSelectJoint(data, pchan, screen_co_a)) { is_point_done = TRUE; } } @@ -2462,7 +2496,7 @@ static void do_circle_select_pose__doSelectBone(void *userData, struct bPoseChan * It works nicer to only do this if the head or tail are not in the circle, * otherwise there is no way to circle select joints alone */ if ((is_point_done == FALSE) && (points_proj_tot == 2) && - edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1)) + edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) { if (data->select) pchan->bone->flag |= BONE_SELECTED; else pchan->bone->flag &= ~BONE_SELECTED; @@ -2480,7 +2514,7 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f ED_view3d_init_mats_rv3d(vc->obact, vc->rv3d); /* for foreach's screen/vert projection */ - pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data); + pose_foreachScreenBone(vc, do_circle_select_pose__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { bArmature *arm = vc->obact->data; @@ -2494,13 +2528,11 @@ static void pose_circle_select(ViewContext *vc, int select, const int mval[2], f } } -static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int x, int y, short head) +static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, const float screen_co[2], short head) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - - if (len_squared_v2(delta) <= data->radius_squared) { + + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (head) { if (data->select) ebone->flag |= BONE_ROOTSEL; @@ -2517,7 +2549,7 @@ static short armature_circle_doSelectJoint(void *userData, EditBone *ebone, int } return 0; } -static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, int x0, int y0, int x1, int y1) +static void do_circle_select_armature__doSelectBone(void *userData, struct EditBone *ebone, const float screen_co_a[2], const float screen_co_b[2]) { CircleSelectUserData *data = userData; bArmature *arm = data->vc->obedit->data; @@ -2527,17 +2559,17 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB int points_proj_tot = 0; /* project head location to screenspace */ - if (x0 != IS_CLIPPED) { + if (screen_co_a[0] != IS_CLIPPED) { points_proj_tot++; - if (armature_circle_doSelectJoint(data, ebone, x0, y0, TRUE)) { + if (armature_circle_doSelectJoint(data, ebone, screen_co_a, TRUE)) { is_point_done = TRUE; } } /* project tail location to screenspace */ - if (x1 != IS_CLIPPED) { + if (screen_co_b[0] != IS_CLIPPED) { points_proj_tot++; - if (armature_circle_doSelectJoint(data, ebone, x1, y1, FALSE)) { + if (armature_circle_doSelectJoint(data, ebone, screen_co_b, FALSE)) { is_point_done = TRUE; } } @@ -2550,7 +2582,7 @@ static void do_circle_select_armature__doSelectBone(void *userData, struct EditB * It works nicer to only do this if the head or tail are not in the circle, * otherwise there is no way to circle select joints alone */ if ((is_point_done == FALSE) && (points_proj_tot == 2) && - edge_inside_circle(data->mval[0], data->mval[1], data->radius, x0, y0, x1, y1)) + edge_inside_circle(data->mval_fl, data->radius, screen_co_a, screen_co_b)) { if (data->select) ebone->flag |= (BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); else ebone->flag &= ~(BONE_SELECTED | BONE_TIPSEL | BONE_ROOTSEL); @@ -2569,7 +2601,7 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2 ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data); + armature_foreachScreenBone(vc, do_circle_select_armature__doSelectBone, &data, V3D_PROJ_TEST_CLIP_DEFAULT); if (data.is_change) { ED_armature_sync_selection(arm->edbo); @@ -2578,13 +2610,11 @@ static void armature_circle_select(ViewContext *vc, int select, const int mval[2 } } -static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, int x, int y) +static void do_circle_select_mball__doSelectElem(void *userData, struct MetaElem *ml, const float screen_co[2]) { CircleSelectUserData *data = userData; - const float delta[2] = {(float)(x - data->mval[0]), - (float)(y - data->mval[1])}; - if (len_squared_v2(delta) <= data->radius_squared) { + if (len_squared_v2v2(data->mval_fl, screen_co) <= data->radius_squared) { if (data->select) ml->flag |= SELECT; else ml->flag &= ~SELECT; data->is_change = TRUE; @@ -2598,7 +2628,7 @@ static void mball_circle_select(ViewContext *vc, int select, const int mval[2], ED_view3d_init_mats_rv3d(vc->obedit, vc->rv3d); - mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data); + mball_foreachScreenElem(vc, do_circle_select_mball__doSelectElem, &data, V3D_PROJ_TEST_CLIP_DEFAULT); } /** Callbacks for circle selection in Editmode */ @@ -2633,11 +2663,12 @@ static int object_circle_select(ViewContext *vc, int select, const int mval[2], const float radius_squared = rad * rad; const float mval_fl[2] = {mval[0], mval[1]}; int is_change = FALSE; + int select_flag = select ? SELECT : 0; Base *base; select = select ? BA_SELECT : BA_DESELECT; for (base = FIRSTBASE; base; base = base->next) { - if (((base->flag & SELECT) == 0) && BASE_SELECTABLE(vc->v3d, base)) { + if (BASE_SELECTABLE(vc->v3d, base) && ((base->flag & SELECT) != select_flag)) { float screen_co[2]; if (ED_view3d_project_float_global(vc->ar, base->object->obmat[3], screen_co, V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index e4a6d7e1b17..26242773e28 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -125,7 +125,7 @@ struct SmoothView3DStore { /* will start timer if appropriate */ /* the arguments are the desired situation */ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera, Object *camera, - float *ofs, float *quat, float *dist, float *lens) + float *ofs, float *quat, float *dist, float *lens) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); @@ -140,7 +140,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera copy_qt_qt(sms.new_quat, rv3d->viewquat); sms.new_dist = rv3d->dist; sms.new_lens = v3d->lens; - sms.to_camera = 0; + sms.to_camera = FALSE; /* note on camera locking, this is a little confusing but works ok. * we may be changing the view 'as if' there is no active camera, but in fact @@ -162,22 +162,22 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera if (camera) { ED_view3d_from_object(camera, sms.new_ofs, sms.new_quat, &sms.new_dist, &sms.new_lens); - sms.to_camera = 1; /* restore view3d values in end */ + sms.to_camera = TRUE; /* restore view3d values in end */ } if (C && U.smooth_viewtx) { - int changed = 0; /* zero means no difference */ + int changed = FALSE; /* zero means no difference */ if (oldcamera != camera) - changed = 1; + changed = TRUE; else if (sms.new_dist != rv3d->dist) - changed = 1; + changed = TRUE; else if (sms.new_lens != v3d->lens) - changed = 1; + changed = TRUE; else if (!equals_v3v3(sms.new_ofs, rv3d->ofs)) - changed = 1; + changed = TRUE; else if (!equals_v4v4(sms.new_quat, rv3d->viewquat)) - changed = 1; + changed = TRUE; /* The new view is different from the old one * so animate the view */ @@ -241,7 +241,7 @@ void view3d_smooth_view(bContext *C, View3D *v3d, ARegion *ar, Object *oldcamera /* if we get here nothing happens */ if (ok == FALSE) { - if (sms.to_camera == 0) { + if (sms.to_camera == FALSE) { copy_v3_v3(rv3d->ofs, sms.new_ofs); copy_qt_qt(rv3d->viewquat, sms.new_quat); rv3d->dist = sms.new_dist; @@ -860,8 +860,7 @@ void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3 eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base) { - eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN); + eV3DProjStatus ret = ED_view3d_project_short_global(ar, base->object->obmat[3], &base->sx, V3D_PROJ_TEST_CLIP_DEFAULT); if (ret != V3D_PROJ_RET_OK) { base->sx = IS_CLIPPED; @@ -912,10 +911,13 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) */ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, float perspmat[4][4], const int is_local, /* normally hidden */ - const float co[3], float r_co[2], eV3DProjTest flag) + const float co[3], float r_co[2], const eV3DProjTest flag) { float fx, fy, vec4[4]; + /* check for bad flags */ + BLI_assert((flag & V3D_PROJ_TEST_ALL) == flag); + if (flag & V3D_PROJ_TEST_CLIP_BB) { RegionView3D *rv3d = ar->regiondata; if (rv3d->rflag & RV3D_CLIPPING) { @@ -953,7 +955,7 @@ static eV3DProjStatus ed_view3d_project__internal(ARegion *ar, } eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], short r_co[2], eV3DProjTest flag) + const float co[3], short r_co[2], const eV3DProjTest flag) { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); @@ -972,7 +974,7 @@ eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], con } eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], int r_co[2], eV3DProjTest flag) + const float co[3], int r_co[2], const eV3DProjTest flag) { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); @@ -991,7 +993,7 @@ eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const } eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, - const float co[3], float r_co[2], eV3DProjTest flag) + const float co[3], float r_co[2], const eV3DProjTest flag) { float tvec[2]; eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); @@ -1009,39 +1011,39 @@ eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], con } /* --- short --- */ -eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_short_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_short_object(ARegion *ar, const float co[3], short r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } /* --- int --- */ -eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_int_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_int_object(ARegion *ar, const float co[3], int r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); } /* --- float --- */ -eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_float_ex(ar, rv3d->persmat, FALSE, co, r_co, flag); } /* object space, use ED_view3d_init_mats_rv3d before calling */ -eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], eV3DProjTest flag) +eV3DProjStatus ED_view3d_project_float_object(ARegion *ar, const float co[3], float r_co[2], const eV3DProjTest flag) { RegionView3D *rv3d = ar->regiondata; return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 49439b8daa5..2b225118472 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -1007,7 +1007,7 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no normalize_v2(normal); } -static void stitch_draw(const bContext *C, ARegion *UNUSED(ar), void *arg) +static void stitch_draw(const bContext *UNUSED(C), ARegion *UNUSED(ar), void *UNUSED(arg)) { int i, index = 0; float pointsize = UI_GetThemeValuef(TH_VERTEX_SIZE); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index d75c6019825..d8d1ad78451 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -563,6 +563,7 @@ typedef enum eDopeSheet_FilterFlag { /* general filtering 3 */ ADS_FILTER_INCL_HIDDEN = (1 << 26), /* include 'hidden' channels too (i.e. those from hidden Objects/Bones) */ ADS_FILTER_BY_FCU_NAME = (1 << 27), /* for F-Curves, filter by the displayed name (i.e. to isolate all Location curves only) */ + ADS_FILTER_ONLY_ERRORS = (1 << 28), /* show only F-Curves which are disabled/have errors - for debugging drivers */ /* combination filters (some only used at runtime) */ ADS_FILTER_NOOBDATA = (ADS_FILTER_NOCAM | ADS_FILTER_NOMAT | ADS_FILTER_NOLAM | ADS_FILTER_NOCUR | ADS_FILTER_NOPART | ADS_FILTER_NOARM | ADS_FILTER_NOSPK) diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index 00a257ab4f9..f08b9084b3c 100644 --- a/source/blender/makesrna/intern/rna_action.c +++ b/source/blender/makesrna/intern/rna_action.c @@ -287,6 +287,13 @@ static void rna_def_dopesheet(BlenderRNA *brna) RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0); RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + /* Debug Filtering Settings */ + prop = RNA_def_property(srna, "show_only_errors", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLY_ERRORS); + RNA_def_property_ui_text(prop, "Show Errors", "Only include F-Curves and Drivers that are disabled or have errors"); + RNA_def_property_ui_icon(prop, ICON_HELP, 0); // XXX: this doesn't quite fit? + RNA_def_property_update(prop, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + /* Object Group Filtering Settings */ prop = RNA_def_property(srna, "show_only_group_objects", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "filterflag", ADS_FILTER_ONLYOBGROUP); diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 85dbd9356f4..8474d9ff09e 100644 --- a/source/blender/render/intern/include/render_types.h +++ b/source/blender/render/intern/include/render_types.h @@ -120,6 +120,9 @@ struct Render /* state settings */ short flag, osa, ok, result_ok; + /* due to performance issues, getting initialized from color management settings once on Render initialization */ + short scene_color_manage; + /* result of rendering */ RenderResult *result; /* if render with single-layer option, other rendered layers are stored here */ diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 03eb21dfa23..96b33a0bf1a 100644 --- a/source/blender/render/intern/source/envmap.c +++ b/source/blender/render/intern/source/envmap.c @@ -154,6 +154,7 @@ static Render *envmap_render_copy(Render *re, EnvMap *env) RE_InitState(envre, NULL, &envre->r, NULL, cuberes, cuberes, NULL); envre->scene = re->scene; /* unsure about this... */ + envre->scene_color_manage = re->scene_color_manage; envre->lay = re->lay; /* view stuff in env render */ diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 1859de0039d..84d57aa7d09 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -1519,6 +1519,7 @@ void RE_MergeFullSample(Render *re, Main *bmain, Scene *sce, bNodeTree *ntree) re->main = bmain; re->scene = sce; + re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); /* first call RE_ReadRenderResult on every renderlayer scene. this creates Render structs */ @@ -2014,6 +2015,7 @@ static int render_initialize_from_main(Render *re, Main *bmain, Scene *scene, Sc re->main = bmain; re->scene = scene; + re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); re->camera_override = camera_override; re->lay = lay; @@ -2352,6 +2354,7 @@ void RE_PreviewRender(Render *re, Main *bmain, Scene *sce) re->main = bmain; re->scene = sce; + re->scene_color_manage = BKE_scene_check_color_management_enabled(sce); re->lay = sce->lay; camera = RE_GetCamera(re); @@ -2396,6 +2399,7 @@ int RE_ReadRenderResult(Scene *scene, Scene *scenode) re = RE_NewRender(scene->id.name); RE_InitState(re, NULL, &scene->r, NULL, winx, winy, &disprect); re->scene = scene; + re->scene_color_manage = BKE_scene_check_color_management_enabled(scene); BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); success = render_result_exr_file_read(re, 0); diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index bcc2f2ff51c..9bd2395ca79 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -1234,7 +1234,7 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, ImBuf *ibuf = BKE_image_get_ibuf(tex->ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres->tr, ibuf->rect_colorspace); } } @@ -2384,7 +2384,7 @@ void do_material_tex(ShadeInput *shi, Render *re) ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); } @@ -2916,7 +2916,7 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) ImBuf *ibuf = BKE_image_get_ibuf(ima, &mtex->tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); } @@ -3135,7 +3135,7 @@ void do_sky_tex(const float rco[3], float lo[3], const float dxyview[2], float h ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(tcol, ibuf->rect_colorspace); } @@ -3349,7 +3349,7 @@ void do_lamp_tex(LampRen *la, const float lavec[3], ShadeInput *shi, float col_r ImBuf *ibuf = BKE_image_get_ibuf(ima, &tex->iuser); /* don't linearize float buffers, assumed to be linear */ - if (ibuf && !(ibuf->rect_float)) + if (ibuf && !(ibuf->rect_float) && R.scene_color_manage) IMB_colormanagement_colorspace_to_scene_linear_v3(&texres.tr, ibuf->rect_colorspace); } |