diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-10-20 20:48:48 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-10-20 20:48:48 +0400 |
commit | 55015daa43f0ab45341e316abcf11f23c87b5ebe (patch) | |
tree | 3156892b6d807d9ba513d444adb870b0ae358e7a /source/blender | |
parent | 1fe70c07a008185c4e5925aff2c214c93ff396b7 (diff) | |
parent | a9e2e2279780ec2fb58e6820b9cad95ba03f4cad (diff) |
Merged changes in the trunk up to revision 51448.
Conflicts resolved:
source/blender/blenkernel/CMakeLists.txt
source/blender/blenloader/intern/readfile.c
source/blender/editors/mesh/editmesh_tools.c
source/blender/makesrna/intern/rna_main_api.c
Diffstat (limited to 'source/blender')
479 files changed, 12672 insertions, 6033 deletions
diff --git a/source/blender/CMakeLists.txt b/source/blender/CMakeLists.txt index 611a920b7f1..e8558806a72 100644 --- a/source/blender/CMakeLists.txt +++ b/source/blender/CMakeLists.txt @@ -102,7 +102,6 @@ add_subdirectory(blenloader) add_subdirectory(ikplugin) add_subdirectory(gpu) add_subdirectory(imbuf) -add_subdirectory(avi) add_subdirectory(nodes) add_subdirectory(modifiers) add_subdirectory(makesdna) @@ -126,6 +125,10 @@ if(WITH_IMAGE_CINEON) add_subdirectory(imbuf/intern/cineon) endif() +if(WITH_CODEC_AVI) + add_subdirectory(avi) +endif() + if(WITH_CODEC_QUICKTIME) add_subdirectory(quicktime) endif() diff --git a/source/blender/avi/AVI_avi.h b/source/blender/avi/AVI_avi.h index bdfdbc117ed..4dc52970119 100644 --- a/source/blender/avi/AVI_avi.h +++ b/source/blender/avi/AVI_avi.h @@ -178,7 +178,7 @@ typedef struct _AviStreamRec { } AviStreamRec; typedef struct _AviMovie { - FILE *fp; + FILE *fp; int type; #define AVI_MOVIE_READ 0 diff --git a/source/blender/avi/CMakeLists.txt b/source/blender/avi/CMakeLists.txt index 79422dff917..292206d8cb9 100644 --- a/source/blender/avi/CMakeLists.txt +++ b/source/blender/avi/CMakeLists.txt @@ -35,19 +35,19 @@ set(INC_SYS set(SRC intern/avi.c - intern/avirgb.c - intern/codecs.c - intern/endian.c - intern/mjpeg.c - intern/options.c - intern/rgb32.c + intern/avi_rgb.c + intern/avi_codecs.c + intern/avi_endian.c + intern/avi_mjpeg.c + intern/avi_options.c + intern/avi_rgb32.c AVI_avi.h intern/avi_intern.h - intern/avirgb.h - intern/endian.h - intern/mjpeg.h - intern/rgb32.h + intern/avi_rgb.h + intern/avi_endian.h + intern/avi_mjpeg.h + intern/avi_rgb32.h ) blender_add_lib(bf_avi "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/avi/intern/avi.c b/source/blender/avi/intern/avi.c index 2845b2f95c9..15d8702a5ec 100644 --- a/source/blender/avi/intern/avi.c +++ b/source/blender/avi/intern/avi.c @@ -32,7 +32,6 @@ * This is external code. */ - #include <stdlib.h> #include <string.h> #include <stdarg.h> @@ -49,7 +48,7 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "endian.h" +#include "avi_endian.h" static int AVI_DEBUG = 0; static char DEBUG_FCC[4]; diff --git a/source/blender/avi/intern/codecs.c b/source/blender/avi/intern/avi_codecs.c index 01e228d570e..e43826064a6 100644 --- a/source/blender/avi/intern/codecs.c +++ b/source/blender/avi/intern/avi_codecs.c @@ -25,7 +25,7 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/codecs.c +/** \file blender/avi/intern/avi_codecs.c * \ingroup avi * * This is external code. Identify and convert different avi-files. @@ -35,9 +35,9 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "avirgb.h" -#include "mjpeg.h" -#include "rgb32.h" +#include "avi_rgb.h" +#include "avi_mjpeg.h" +#include "avi_rgb32.h" void *avi_format_convert(AviMovie *movie, int stream, void *buffer, AviFormat from, AviFormat to, int *size) { diff --git a/source/blender/avi/intern/endian.c b/source/blender/avi/intern/avi_endian.c index c9b95d25810..70add8bd90f 100644 --- a/source/blender/avi/intern/endian.c +++ b/source/blender/avi/intern/avi_endian.c @@ -26,7 +26,7 @@ * */ -/** \file blender/avi/intern/endian.c +/** \file blender/avi/intern/avi_endian.c * \ingroup avi * * This is external code. Streams bytes to output depending on the @@ -36,9 +36,10 @@ #include <stdlib.h> #include <string.h> -#include <stdio.h> +#include <stdio.h> + #include "AVI_avi.h" -#include "endian.h" +#include "avi_endian.h" #include "avi_intern.h" #ifdef __BIG_ENDIAN__ @@ -46,31 +47,22 @@ #endif #ifdef __BIG_ENDIAN__ + +/* copied from BLI_endian_switch_inline.h */ static void invert(int *num) { - int new = 0, i, j; - - for (j = 0; j < 4; j++) { - for (i = 0; i < 8; i++) { - new |= ((*num >> (j * 8 + i)) & 1) << ((3 - j) * 8 + i); - } - } - - *num = new; + int tval = *val; + *val = ((tval >> 24)) | + ((tval << 8) & 0x00ff0000) | + ((tval >> 8) & 0x0000ff00) | + ((tval << 24)); } -static void sinvert(short int *num) +static void sinvert(short int *val) { - short int new = 0; - int i, j; - - for (j = 0; j < 2; j++) { - for (i = 0; i < 8; i++) { - new |= ((*num >> (j * 8 + i)) & 1) << ((1 - j) * 8 + i); - } - } - - *num = new; + short tval = *val; + *val = (tval >> 8) | + (tval << 8); } static void Ichunk(AviChunk *chunk) diff --git a/source/blender/avi/intern/endian.h b/source/blender/avi/intern/avi_endian.h index 7ef49cb1699..8cea283a553 100644 --- a/source/blender/avi/intern/endian.h +++ b/source/blender/avi/intern/avi_endian.h @@ -25,17 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/endian.h +/** \file blender/avi/intern/avi_endian.h * \ingroup avi * * This is external code. */ -#ifndef __ENDIAN_H__ -#define __ENDIAN_H__ - -#include <stdio.h> -#include "AVI_avi.h" +#ifndef __AVI_ENDIAN_H__ +#define __AVI_ENDIAN_H__ #define AVI_RAW 0 #define AVI_CHUNK 1 @@ -48,5 +45,4 @@ void awrite(AviMovie *movie, void *datain, int block, int size, FILE *fp, int type); -#endif - +#endif /* __AVI_ENDIAN_H__ */ diff --git a/source/blender/avi/intern/mjpeg.c b/source/blender/avi/intern/avi_mjpeg.c index a700284bf68..b98e03d6a19 100644 --- a/source/blender/avi/intern/mjpeg.c +++ b/source/blender/avi/intern/avi_mjpeg.c @@ -26,21 +26,23 @@ * */ -/** \file blender/avi/intern/mjpeg.c +/** \file blender/avi/intern/avi_mjpeg.c * \ingroup avi * * This is external code. Converts between avi and mpeg/jpeg. */ - -#include "AVI_avi.h" #include <stdlib.h> #include <string.h> + +#include "AVI_avi.h" + +#include "MEM_guardedalloc.h" + #include "jpeglib.h" #include "jerror.h" -#include "MEM_guardedalloc.h" -#include "mjpeg.h" +#include "avi_mjpeg.h" #define PADUP(num, amt) ((num + (amt - 1)) & ~(amt - 1)) diff --git a/source/blender/avi/intern/mjpeg.h b/source/blender/avi/intern/avi_mjpeg.h index 75649891f2b..6ae0e56ffa4 100644 --- a/source/blender/avi/intern/mjpeg.h +++ b/source/blender/avi/intern/avi_mjpeg.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/mjpeg.h +/** \file blender/avi/intern/avi_mjpeg.h * \ingroup avi */ +#ifndef __AVI_MJPEG_H__ +#define __AVI_MJPEG_H__ void *avi_converter_from_mjpeg (AviMovie *movie, int stream, unsigned char *buffer, int *size); void *avi_converter_to_mjpeg (AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_MJPEG_H__ */ diff --git a/source/blender/avi/intern/options.c b/source/blender/avi/intern/avi_options.c index 7de91318ecf..f7759a1099f 100644 --- a/source/blender/avi/intern/options.c +++ b/source/blender/avi/intern/avi_options.c @@ -26,7 +26,7 @@ * */ -/** \file blender/avi/intern/options.c +/** \file blender/avi/intern/avi_options.c * \ingroup avi * * This is external code. Sets some compression related options @@ -35,7 +35,7 @@ #include "AVI_avi.h" #include "avi_intern.h" -#include "endian.h" +#include "avi_endian.h" #ifdef WIN32 # include "BLI_winstuff.h" diff --git a/source/blender/avi/intern/avirgb.c b/source/blender/avi/intern/avi_rgb.c index 7a95972845a..61587e15e61 100644 --- a/source/blender/avi/intern/avirgb.c +++ b/source/blender/avi/intern/avi_rgb.c @@ -26,19 +26,19 @@ * */ -/** \file blender/avi/intern/avirgb.c +/** \file blender/avi/intern/avi_rgb.c * \ingroup avi * * This is external code. Converts rgb-type avi-s. */ - -#include "AVI_avi.h" #include <stdlib.h> #include <string.h> #include "MEM_guardedalloc.h" -#include "avirgb.h" + +#include "AVI_avi.h" +#include "avi_rgb.h" /* implementation */ diff --git a/source/blender/avi/intern/avirgb.h b/source/blender/avi/intern/avi_rgb.h index 20211d6ab2d..773166e9fab 100644 --- a/source/blender/avi/intern/avirgb.h +++ b/source/blender/avi/intern/avi_rgb.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/avirgb.h +/** \file blender/avi/intern/avi_rgb.h * \ingroup avi */ +#ifndef __AVI_RGB_H__ +#define __AVI_RGB_H__ -void *avi_converter_from_avi_rgb (AviMovie *movie, int stream, unsigned char *buffer, int *size); -void *avi_converter_to_avi_rgb (AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_from_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_to_avi_rgb(AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_RGB_H__ */ diff --git a/source/blender/avi/intern/rgb32.c b/source/blender/avi/intern/avi_rgb32.c index 84630f09fe5..5c7a4889d97 100644 --- a/source/blender/avi/intern/rgb32.c +++ b/source/blender/avi/intern/avi_rgb32.c @@ -26,18 +26,19 @@ * */ -/** \file blender/avi/intern/rgb32.c +/** \file blender/avi/intern/avi_rgb32.c * \ingroup avi * * This is external code. Converts between rgb32 and avi. */ - -#include "AVI_avi.h" #include <stdlib.h> #include <string.h> + #include "MEM_guardedalloc.h" -#include "rgb32.h" + +#include "AVI_avi.h" +#include "avi_rgb32.h" void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size) { diff --git a/source/blender/avi/intern/rgb32.h b/source/blender/avi/intern/avi_rgb32.h index 55f9771a4df..523f9e795fd 100644 --- a/source/blender/avi/intern/rgb32.h +++ b/source/blender/avi/intern/avi_rgb32.h @@ -25,11 +25,14 @@ * ***** END GPL LICENSE BLOCK ***** */ -/** \file blender/avi/intern/rgb32.h +/** \file blender/avi/intern/avi_rgb32.h * \ingroup avi */ +#ifndef __AVI_RGB32_H__ +#define __AVI_RGB32_H__ -void *avi_converter_from_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size); -void *avi_converter_to_rgb32 (AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_from_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size); +void *avi_converter_to_rgb32(AviMovie *movie, int stream, unsigned char *buffer, int *size); +#endif /* __AVI_RGB32_H__ */ diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h index ce10951d6ff..6f348ccc267 100644 --- a/source/blender/blenfont/BLF_api.h +++ b/source/blender/blenfont/BLF_api.h @@ -109,6 +109,7 @@ float BLF_fixed_width(int fontid); * of the string, using the default font and both value * are multiplied by the aspect of the font. */ +void BLF_width_and_height_default(const char *str, float *width, float *height); float BLF_width_default(const char *str); float BLF_height_default(const char *str); diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c index 92fcb576e7d..f3cc92e7a27 100644 --- a/source/blender/blenfont/intern/blf.c +++ b/source/blender/blenfont/intern/blf.c @@ -69,7 +69,7 @@ static int global_font_dpi = 72; int blf_mono_font = -1; int blf_mono_font_render = -1; -static FontBLF *BLF_get(int fontid) +static FontBLF *blf_get(int fontid) { if (fontid >= 0 && fontid < BLF_MAX_FONT) return global_font[fontid]; @@ -141,6 +141,21 @@ static int blf_search_available(void) return -1; } +static int blf_global_font_init(void) +{ + if (global_font_default == -1) { + global_font_default = blf_search("default"); + } + + if (global_font_default == -1) { + printf("Warning: Can't find default font!\n"); + return 0; + } + else { + return 1; + } +} + int BLF_load(const char *name) { FontBLF *font; @@ -219,7 +234,7 @@ int BLF_load_unique(const char *name) void BLF_metrics_attach(int fontid, unsigned char *mem, int mem_size) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_attach_from_mem(font, mem, mem_size); @@ -311,7 +326,7 @@ void BLF_unload(const char *name) void BLF_enable(int fontid, int option) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->flags |= option; @@ -320,7 +335,7 @@ void BLF_enable(int fontid, int option) void BLF_disable(int fontid, int option) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->flags &= ~option; @@ -329,7 +344,7 @@ void BLF_disable(int fontid, int option) void BLF_enable_default(int option) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->flags |= option; @@ -338,7 +353,7 @@ void BLF_enable_default(int option) void BLF_disable_default(int option) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->flags &= ~option; @@ -347,7 +362,7 @@ void BLF_disable_default(int option) void BLF_aspect(int fontid, float x, float y, float z) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->aspect[0] = x; @@ -358,7 +373,7 @@ void BLF_aspect(int fontid, float x, float y, float z) void BLF_matrix(int fontid, const double m[16]) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { memcpy(font->m, m, sizeof(font->m)); @@ -367,7 +382,7 @@ void BLF_matrix(int fontid, const double m[16]) void BLF_position(int fontid, float x, float y, float z) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { float xa, ya, za; @@ -416,7 +431,7 @@ void BLF_position(int fontid, float x, float y, float z) void BLF_size(int fontid, int size, int dpi) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_size(font, size, dpi); @@ -425,7 +440,7 @@ void BLF_size(int fontid, int size, int dpi) void BLF_blur(int fontid, int size) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->blur = size; @@ -437,13 +452,8 @@ void BLF_draw_default(float x, float y, float z, const char *str, size_t len) if (!str) return; - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Warning: Can't found default font!!\n"); + if (!blf_global_font_init()) return; - } BLF_size(global_font_default, global_font_points, global_font_dpi); BLF_position(global_font_default, x, y, z); @@ -456,13 +466,8 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l if (!str) return; - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Warning: Can't found default font!!\n"); + if (!blf_global_font_init()) return; - } BLF_size(global_font_default, global_font_points, global_font_dpi); BLF_position(global_font_default, x, y, z); @@ -471,7 +476,7 @@ void BLF_draw_default_ascii(float x, float y, float z, const char *str, size_t l void BLF_rotation_default(float angle) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->angle = angle; @@ -543,7 +548,7 @@ static void blf_draw__end(GLint mode, GLint param) void BLF_draw(int fontid, const char *str, size_t len) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); GLint mode, param; if (font && font->glyph_cache) { @@ -555,7 +560,7 @@ void BLF_draw(int fontid, const char *str, size_t len) void BLF_draw_ascii(int fontid, const char *str, size_t len) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); GLint mode, param; if (font && font->glyph_cache) { @@ -567,7 +572,7 @@ void BLF_draw_ascii(int fontid, const char *str, size_t len) void BLF_boundbox(int fontid, const char *str, rctf *box) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { blf_font_boundbox(font, str, box); @@ -576,16 +581,29 @@ void BLF_boundbox(int fontid, const char *str, rctf *box) void BLF_width_and_height(int fontid, const char *str, float *width, float *height) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { blf_font_width_and_height(font, str, width, height); } + else { + *width = *height = 0.0f; + } +} + +void BLF_width_and_height_default(const char *str, float *width, float *height) +{ + if (!blf_global_font_init()) { + *width = *height = 0.0f; + return; + } + + BLF_width_and_height(global_font_default, str, width, height); } float BLF_width(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_width(font, str); @@ -596,7 +614,7 @@ float BLF_width(int fontid, const char *str) float BLF_fixed_width(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_fixed_width(font); @@ -607,13 +625,8 @@ float BLF_fixed_width(int fontid) float BLF_width_default(const char *str) { - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Error: Can't found default font!!\n"); + if (!blf_global_font_init()) return 0.0f; - } BLF_size(global_font_default, global_font_points, global_font_dpi); return BLF_width(global_font_default, str); @@ -621,7 +634,7 @@ float BLF_width_default(const char *str) float BLF_height(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return blf_font_height(font, str); @@ -632,7 +645,7 @@ float BLF_height(int fontid, const char *str) float BLF_height_max(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->max_glyph_height; @@ -643,7 +656,7 @@ float BLF_height_max(int fontid) float BLF_width_max(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->max_glyph_width; @@ -654,7 +667,7 @@ float BLF_width_max(int fontid) float BLF_descender(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->descender; @@ -665,7 +678,7 @@ float BLF_descender(int fontid) float BLF_ascender(int fontid) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache) { return font->glyph_cache->ascender; @@ -676,13 +689,8 @@ float BLF_ascender(int fontid) float BLF_height_default(const char *str) { - if (global_font_default == -1) - global_font_default = blf_search("default"); - - if (global_font_default == -1) { - printf("Error: Can't found default font!!\n"); + if (!blf_global_font_init()) return 0.0f; - } BLF_size(global_font_default, global_font_points, global_font_dpi); @@ -691,7 +699,7 @@ float BLF_height_default(const char *str) void BLF_rotation(int fontid, float angle) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->angle = angle; @@ -700,7 +708,7 @@ void BLF_rotation(int fontid, float angle) void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->clip_rec.xmin = xmin; @@ -712,7 +720,7 @@ void BLF_clipping(int fontid, float xmin, float ymin, float xmax, float ymax) void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax) { - FontBLF *font = BLF_get(global_font_default); + FontBLF *font = blf_get(global_font_default); if (font) { font->clip_rec.xmin = xmin; @@ -724,7 +732,7 @@ void BLF_clipping_default(float xmin, float ymin, float xmax, float ymax) void BLF_shadow(int fontid, int level, float r, float g, float b, float a) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->shadow = level; @@ -737,7 +745,7 @@ void BLF_shadow(int fontid, int level, float r, float g, float b, float a) void BLF_shadow_offset(int fontid, int x, int y) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->shadow_x = x; @@ -747,7 +755,7 @@ void BLF_shadow_offset(int fontid, int x, int y) void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int nch, struct ColorManagedDisplay *display) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->buf_info.fbuf = fbuf; @@ -761,7 +769,7 @@ void BLF_buffer(int fontid, float *fbuf, unsigned char *cbuf, int w, int h, int void BLF_buffer_col(int fontid, float r, float g, float b, float a) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font) { font->buf_info.col[0] = r; @@ -773,7 +781,7 @@ void BLF_buffer_col(int fontid, float r, float g, float b, float a) void BLF_draw_buffer(int fontid, const char *str) { - FontBLF *font = BLF_get(fontid); + FontBLF *font = blf_get(fontid); if (font && font->glyph_cache && (font->buf_info.fbuf || font->buf_info.cbuf)) { blf_font_buffer(font, str); diff --git a/source/blender/blenfont/intern/blf_lang.c b/source/blender/blenfont/intern/blf_lang.c index b694f1fafa7..af2f9df3c00 100644 --- a/source/blender/blenfont/intern/blf_lang.c +++ b/source/blender/blenfont/intern/blf_lang.c @@ -109,6 +109,8 @@ static const char *locales[] = { "hungarian", "hu_HU", "portuguese-brazilian", "pt_BR", "hebrew", "he_IL", + "estonian", "et_EE", + "esperanto", "eo", /* No country code for esperanto! ;) */ }; void BLF_lang_init(void) @@ -169,7 +171,6 @@ void BLF_lang_set(const char *str) char *locreturn; const char *short_locale; int ok = 1; - const char *long_locale = locales[2 * U.language]; if ((U.transopts & USER_DOTRANSLATE) == 0) return; @@ -180,25 +181,29 @@ void BLF_lang_set(const char *str) short_locale = locales[2 * U.language + 1]; #if defined(_WIN32) && !defined(FREE_WINDOWS) - if (short_locale) { - char *envStr; + { + const char *long_locale = locales[2 * U.language]; - if (U.language == 0) /* Use system setting. */ - envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); - else - envStr = BLI_sprintfN("LANG=%s", short_locale); + if (short_locale) { + char *envStr; - gettext_putenv(envStr); - MEM_freeN(envStr); - } + if (U.language == 0) /* Use system setting. */ + envStr = BLI_sprintfN("LANG=%s", getenv("LANG")); + else + envStr = BLI_sprintfN("LANG=%s", short_locale); - locreturn = setlocale(LC_ALL, long_locale); + gettext_putenv(envStr); + MEM_freeN(envStr); + } - if (locreturn == NULL) { - if (G.debug & G_DEBUG) - printf("Could not change locale to %s\n", long_locale); + locreturn = setlocale(LC_ALL, long_locale); - ok = 0; + if (locreturn == NULL) { + if (G.debug & G_DEBUG) + printf("Could not change locale to %s\n", long_locale); + + ok = 0; + } } #else { @@ -212,11 +217,33 @@ void BLF_lang_set(const char *str) get_language_variable("LANGUAGE", default_language, sizeof(default_language)); if (short_locale[0]) { + char *short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); + if (G.debug & G_DEBUG) - printf("Setting LANG= and LANGUAGE to %s\n", short_locale); + printf("Setting LANG and LANGUAGE to %s\n", short_locale_utf8); + + locreturn = setlocale(LC_ALL, short_locale_utf8); + + if (locreturn != NULL) { + BLI_setenv("LANG", short_locale_utf8); + BLI_setenv("LANGUAGE", short_locale_utf8); + } + else { + if (G.debug & G_DEBUG) + printf("Setting LANG and LANGUAGE to %s\n", short_locale); - BLI_setenv("LANG", short_locale); - BLI_setenv("LANGUAGE", short_locale); + locreturn = setlocale(LC_ALL, short_locale); + + if (locreturn != NULL) { + BLI_setenv("LANG", short_locale); + BLI_setenv("LANGUAGE", short_locale); + } + } + + if (G.debug & G_DEBUG && locreturn == NULL) + printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); + + MEM_freeN(short_locale_utf8); } else { if (G.debug & G_DEBUG) @@ -224,43 +251,27 @@ void BLF_lang_set(const char *str) BLI_setenv("LANG", default_lang); BLI_setenv("LANGUAGE", default_language); - } + locreturn = setlocale(LC_ALL, ""); - locreturn = setlocale(LC_ALL, short_locale); + if (G.debug & G_DEBUG && locreturn == NULL) + printf("Could not reset locale\n"); + } if (locreturn == NULL) { - char *short_locale_utf8 = NULL; - - if (short_locale[0]) { - short_locale_utf8 = BLI_sprintfN("%s.UTF-8", short_locale); - locreturn = setlocale(LC_ALL, short_locale_utf8); - } - - if (locreturn == NULL) { - char language[65]; + char language[65]; - get_language(long_locale, default_lang, language, sizeof(language)); + get_language(short_locale, default_lang, language, sizeof(language)); - if (G.debug & G_DEBUG) { - if (short_locale[0]) - printf("Could not change locale to %s nor %s\n", short_locale, short_locale_utf8); - else - printf("Could not reset locale\n"); - - printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); - } - - /* Fallback to default settings. */ - BLI_setenv("LANG", default_lang); - BLI_setenv("LANGUAGE", language); + if (G.debug & G_DEBUG) + printf("Fallback to LANG=%s and LANGUAGE=%s\n", default_lang, language); - locreturn = setlocale(LC_ALL, ""); + /* Fallback to default settings. */ + BLI_setenv("LANG", default_lang); + BLI_setenv("LANGUAGE", language); - ok = 0; - } + locreturn = setlocale(LC_ALL, ""); - if (short_locale_utf8) - MEM_freeN(short_locale_utf8); + ok = 0; } } #endif diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h index a3f3beefbaf..b0f372e0bac 100644 --- a/source/blender/blenkernel/BKE_armature.h +++ b/source/blender/blenkernel/BKE_armature.h @@ -99,7 +99,7 @@ void BKE_pose_where_is_bone_tail(struct bPoseChannel *pchan); /* get_objectspace_bone_matrix has to be removed still */ void get_objectspace_bone_matrix(struct Bone *bone, float M_accumulatedMatrix[][4], int root, int posed); void vec_roll_to_mat3(const float vec[3], const float roll, float mat[][3]); -void mat3_to_vec_roll(float mat[][3], float *vec, float *roll); +void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll); /* Common Conversions Between Co-ordinate Spaces */ void BKE_armature_mat_world_to_pose(struct Object *ob, float inmat[][4], float outmat[][4]); @@ -131,8 +131,14 @@ typedef struct Mat4 { Mat4 *b_bone_spline_setup(struct bPoseChannel *pchan, int rest); /* like EBONE_VISIBLE */ -#define PBONE_VISIBLE(arm, bone) (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P)) -#define PBONE_SELECTABLE(arm, bone) (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE)) +#define PBONE_VISIBLE(arm, bone) ( \ + CHECK_TYPE_INLINE(arm, bArmature), \ + CHECK_TYPE_INLINE(bone, Bone), \ + (((bone)->layer & (arm)->layer) && !((bone)->flag & BONE_HIDDEN_P)) \ + ) + +#define PBONE_SELECTABLE(arm, bone) \ + (PBONE_VISIBLE(arm, bone) && !((bone)->flag & BONE_UNSELECTABLE)) #ifdef __cplusplus } diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 56dfdf404f8..cf67899dfb0 100644 --- a/source/blender/blenkernel/BKE_blender.h +++ b/source/blender/blenkernel/BKE_blender.h @@ -42,7 +42,7 @@ extern "C" { * and keep comment above the defines. * Use STRINGIFY() rather than defining with quotes */ #define BLENDER_VERSION 264 -#define BLENDER_SUBVERSION 1 +#define BLENDER_SUBVERSION 4 /* 262 was the last editmesh release but its has compatibility code for bmesh data, * so set the minversion to 2.61 */ @@ -51,7 +51,7 @@ extern "C" { /* used by packaging tools */ /* can be left blank, otherwise a,b,c... etc with no quotes */ -#define BLENDER_VERSION_CHAR +#define BLENDER_VERSION_CHAR a /* alpha/beta/rc/release, docs use this */ #define BLENDER_VERSION_CYCLE alpha diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h index 728f88b3c16..f30cc57bde4 100644 --- a/source/blender/blenkernel/BKE_colortools.h +++ b/source/blender/blenkernel/BKE_colortools.h @@ -88,7 +88,6 @@ int curvemapping_RGBA_does_something(const struct CurveMapping * void curvemapping_table_RGBA(const struct CurveMapping *cumap, float **array, int *size); /* non-const, these modify the curve */ -void curvemapping_do_ibuf(struct CurveMapping *cumap, struct ImBuf *ibuf); void curvemapping_premultiply(struct CurveMapping *cumap, int restore); diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h index e6161cebf54..536bbecb79b 100644 --- a/source/blender/blenkernel/BKE_curve.h +++ b/source/blender/blenkernel/BKE_curve.h @@ -108,7 +108,7 @@ void BKE_nurb_free(struct Nurb *nu); struct Nurb *BKE_nurb_duplicate(struct Nurb *nu); void BKE_nurb_test2D(struct Nurb *nu); -void BKE_nurb_minmax(struct Nurb *nu, float *min, float *max); +void BKE_nurb_minmax(struct Nurb *nu, float min[3], float max[3]); void BKE_nurb_makeFaces(struct Nurb *nu, float *coord_array, int rowstride, int resolu, int resolv); void BKE_nurb_makeCurve(struct Nurb *nu, float *coord_array, float *tilt_array, float *radius_array, float *weight_array, int resolu, int stride); diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h index 01baf8feb2a..d7d75b4c4c9 100644 --- a/source/blender/blenkernel/BKE_key.h +++ b/source/blender/blenkernel/BKE_key.h @@ -92,4 +92,4 @@ extern int slurph_opt; }; #endif -#endif // __BKE_KEY_H__ +#endif /* __BKE_KEY_H__ */ diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h index 31626ef4a58..34baa48dbe2 100644 --- a/source/blender/blenkernel/BKE_lattice.h +++ b/source/blender/blenkernel/BKE_lattice.h @@ -46,7 +46,7 @@ struct Lattice *BKE_lattice_add(const char *name); struct Lattice *BKE_lattice_copy(struct Lattice *lt); void BKE_lattice_free(struct Lattice *lt); void BKE_lattice_make_local(struct Lattice *lt); -void calc_lat_fudu(int flag, int res, float *fu, float *du); +void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du); void init_latt_deform(struct Object *oblatt, struct Object *ob); void calc_latt_deform(struct Object *, float co[3], float weight); diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h index c14085a559a..9fffb71785b 100644 --- a/source/blender/blenkernel/BKE_mesh.h +++ b/source/blender/blenkernel/BKE_mesh.h @@ -130,7 +130,7 @@ struct Mesh *BKE_mesh_copy(struct Mesh *me); void mesh_update_customdata_pointers(struct Mesh *me, const short do_ensure_tess_cd); void BKE_mesh_make_local(struct Mesh *me); -void BKE_mesh_boundbox_calc(struct Mesh *me, float *loc, float *size); +void BKE_mesh_boundbox_calc(struct Mesh *me, float r_loc[3], float r_size[3]); void BKE_mesh_texspace_calc(struct Mesh *me); float *BKE_mesh_orco_verts_get(struct Object *ob); void BKE_mesh_orco_verts_transform(struct Mesh *me, float (*orco)[3], int totvert, int invert); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 3b675f3b620..7ee1c85d0de 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -352,6 +352,7 @@ int modifiers_isParticleEnabled(struct Object *ob); struct Object *modifiers_isDeformedByArmature(struct Object *ob); struct Object *modifiers_isDeformedByLattice(struct Object *ob); +struct Object *modifiers_isDeformedByCurve(struct Object *ob); int modifiers_usesArmature(struct Object *ob, struct bArmature *arm); int modifiers_isCorrectableDeformed(struct Object *ob); void modifier_freeTemporaryData(struct ModifierData *md); diff --git a/source/blender/blenkernel/BKE_multires.h b/source/blender/blenkernel/BKE_multires.h index 82a791348dd..8fa20eb2cc2 100644 --- a/source/blender/blenkernel/BKE_multires.h +++ b/source/blender/blenkernel/BKE_multires.h @@ -116,5 +116,4 @@ void multires_topology_changed(struct Mesh *me); void old_mdisps_bilinear(float out[3], float (*disps)[3], const int st, float u, float v); int mdisp_rot_face_to_crn(const int corners, const int face_side, const float u, const float v, float *x, float *y); -#endif // __BKE_MULTIRES_H__ - +#endif /* __BKE_MULTIRES_H__ */ diff --git a/source/blender/blenkernel/BKE_navmesh_conversion.h b/source/blender/blenkernel/BKE_navmesh_conversion.h index aab359b307a..cc9c18c764d 100644 --- a/source/blender/blenkernel/BKE_navmesh_conversion.h +++ b/source/blender/blenkernel/BKE_navmesh_conversion.h @@ -60,4 +60,4 @@ int polyFindVertex(const unsigned short *p, const int vertsPerPoly, unsigned sho float distPointToSegmentSq(const float *point, const float *a, const float *b); -#endif //NAVMESH_CONVERSION_H +#endif /* NAVMESH_CONVERSION_H */ diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index acd6f120f93..4ee5c894b5c 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -349,7 +349,7 @@ struct bNodeSocket *nodeInsertSocket(struct bNodeTree *ntree, struct bNode *node void nodeRemoveSocket(struct bNodeTree *ntree, struct bNode *node, struct bNodeSocket *sock); void nodeRemoveAllSockets(struct bNodeTree *ntree, struct bNode *node); -void nodeAddToPreview(struct bNode *node, float col[4], int x, int y, int do_manage); +void nodeAddToPreview(struct bNode *node, const float col[4], int x, int y, int do_manage); struct bNode *nodeAddNode(struct bNodeTree *ntree, struct bNodeTemplate *ntemp); void nodeUnlinkNode(struct bNodeTree *ntree, struct bNode *node); @@ -551,6 +551,7 @@ struct ShadeResult; #define SH_NODE_OBJECT_INFO 167 #define SH_NODE_PARTICLE_INFO 168 #define SH_NODE_TEX_BRICK 169 +#define SH_NODE_BUMP 170 /* custom defines options for Material node */ #define SH_NODE_MAT_DIFF 1 @@ -784,7 +785,9 @@ void ntreeTexCheckCyclics(struct bNodeTree *ntree); struct bNodeTreeExec *ntreeTexBeginExecTree(struct bNodeTree *ntree, int use_tree_data); void ntreeTexEndExecTree(struct bNodeTreeExec *exec, int use_tree_data); -int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, float *coord, float *dxt, float *dyt, int osatex, short thread, struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); +int ntreeTexExecTree(struct bNodeTree *ntree, struct TexResult *target, + float coord[3], float dxt[3], float dyt[3], int osatex, const short thread, + struct Tex *tex, short which_output, int cfra, int preview, struct ShadeInput *shi, struct MTex *mtex); /*************************************************/ diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h index b3e650b2aa5..ec03f53dbdb 100644 --- a/source/blender/blenkernel/BKE_particle.h +++ b/source/blender/blenkernel/BKE_particle.h @@ -257,7 +257,9 @@ void psys_interpolate_mcol(const struct MCol *mcol, int quad, const float w[4], void copy_particle_key(struct ParticleKey *to, struct ParticleKey *from, int time); -void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); +void psys_particle_on_emitter(struct ParticleSystemModifierData *psmd, int distr, int index, int index_dmcache, + float fuv[4], float foffset, float vec[3], float nor[3], + float utan[3], float vtan[3], float orco[3], float ornor[3]); struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct ParticleSystem *psys); struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name); @@ -282,8 +284,11 @@ void psys_get_particle_on_path(struct ParticleSimulationData *sim, int pa_num, s int psys_get_particle_state(struct ParticleSimulationData *sim, int p, struct ParticleKey *state, int always); /* for anim.c */ -void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, float *uv, float *orco); -void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, struct ParticleCacheKey *cache, float mat[][4], float *scale); +void psys_get_dupli_texture(struct ParticleSystem *psys, struct ParticleSettings *part, + struct ParticleSystemModifierData *psmd, struct ParticleData *pa, struct ChildParticle *cpa, + float uv[2], float orco[3]); +void psys_get_dupli_path_transform(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ChildParticle *cpa, + struct ParticleCacheKey *cache, float mat[][4], float *scale); ParticleThread *psys_threads_create(struct ParticleSimulationData *sim); void psys_threads_free(ParticleThread *threads); @@ -327,13 +332,17 @@ void psys_free_pdd(struct ParticleSystem *psys); float *psys_cache_vgroup(struct DerivedMesh *dm, struct ParticleSystem *psys, int vgroup); void psys_get_texture(struct ParticleSimulationData *sim, struct ParticleData *pa, struct ParticleTexture *ptex, int event, float cfra); -void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, float (*orcodata)[3], float *uv, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor); +void psys_interpolate_face(struct MVert *mvert, struct MFace *mface, struct MTFace *tface, + float (*orcodata)[3], float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]); float psys_particle_value_from_verts(struct DerivedMesh *dm, short from, struct ParticleData *pa, float *values); -void psys_get_from_key(struct ParticleKey *key, float *loc, float *vel, float *rot, float *time); +void psys_get_from_key(struct ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time); /* BLI_bvhtree_ray_cast callback */ void BKE_psys_collision_neartest_cb(void *userdata, int index, const struct BVHTreeRay *ray, struct BVHTreeRayHit *hit); -void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]); +void psys_particle_on_dm(struct DerivedMesh *dm, int from, int index, int index_dmcache, + const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]); /* particle_system.c */ void initialize_particle(struct ParticleSimulationData *sim, struct ParticleData *pa, int p); diff --git a/source/blender/blenkernel/BKE_scene.h b/source/blender/blenkernel/BKE_scene.h index c12e913be45..9927c7a42ed 100644 --- a/source/blender/blenkernel/BKE_scene.h +++ b/source/blender/blenkernel/BKE_scene.h @@ -55,7 +55,12 @@ struct Text; #define SCE_COPY_LINK_DATA 3 #define SCE_COPY_FULL 4 -#define SETLOOPER(_sce_basis, _sce_iter, _base) _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, NULL); _base; _base = _setlooper_base_step(&_sce_iter, _base) +/* Use as the contents of a 'for' loop: for (SETLOOPER(...)) { ... */ +#define SETLOOPER(_sce_basis, _sce_iter, _base) \ + _sce_iter = _sce_basis, _base = _setlooper_base_step(&_sce_iter, NULL); \ + _base; \ + _base = _setlooper_base_step(&_sce_iter, _base) + struct Base *_setlooper_base_step(struct Scene **sce_iter, struct Base *base); void free_avicodecdata(struct AviCodecData *acd); diff --git a/source/blender/blenkernel/BKE_sequencer.h b/source/blender/blenkernel/BKE_sequencer.h index cecff2d9516..1667c119790 100644 --- a/source/blender/blenkernel/BKE_sequencer.h +++ b/source/blender/blenkernel/BKE_sequencer.h @@ -68,25 +68,27 @@ void BKE_sequence_iterator_begin(struct Editing *ed, SeqIterator *iter, int use_ void BKE_sequence_iterator_next(SeqIterator *iter); void BKE_sequence_iterator_end(SeqIterator *iter); -#define SEQP_BEGIN(ed, _seq) \ +#define SEQP_BEGIN(_ed, _seq) \ { \ - SeqIterator iter; \ - for (BKE_sequence_iterator_begin(ed, &iter, 1); \ - iter.valid; \ - BKE_sequence_iterator_next(&iter)) { \ - _seq = iter.seq; - + SeqIterator iter_macro; \ + for (BKE_sequence_iterator_begin(_ed, &iter_macro, 1); \ + iter_macro.valid; \ + BKE_sequence_iterator_next(&iter_macro)) \ + { \ + _seq = iter_macro.seq; + #define SEQ_BEGIN(ed, _seq) \ { \ - SeqIterator iter; \ - for (BKE_sequence_iterator_begin(ed, &iter, 0); \ - iter.valid; \ - BKE_sequence_iterator_next(&iter)) { \ - _seq = iter.seq; + SeqIterator iter_macro; \ + for (BKE_sequence_iterator_begin(ed, &iter_macro, 0); \ + iter_macro.valid; \ + BKE_sequence_iterator_next(&iter_macro)) \ + { \ + _seq = iter_macro.seq; #define SEQ_END \ } \ - BKE_sequence_iterator_end(&iter); \ + BKE_sequence_iterator_end(&iter_macro); \ } typedef struct SeqRenderData { diff --git a/source/blender/blenkernel/BKE_smoke.h b/source/blender/blenkernel/BKE_smoke.h index 1f824ccbafc..3a9d2b86b41 100644 --- a/source/blender/blenkernel/BKE_smoke.h +++ b/source/blender/blenkernel/BKE_smoke.h @@ -35,8 +35,10 @@ typedef float (*bresenham_callback)(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); -void smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm); +struct DerivedMesh *smokeModifier_do(struct SmokeModifierData *smd, struct Scene *scene, struct Object *ob, struct DerivedMesh *dm); +void smoke_reallocate_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old); +void smoke_reallocate_highres_fluid(struct SmokeDomainSettings *sds, float dx, int res[3], int free_old); void smokeModifier_free(struct SmokeModifierData *smd); void smokeModifier_reset(struct SmokeModifierData *smd); void smokeModifier_reset_turbulence(struct SmokeModifierData *smd); @@ -44,5 +46,7 @@ void smokeModifier_createType(struct SmokeModifierData *smd); void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData *tsmd); long long smoke_get_mem_req(int xres, int yres, int zres, int amplify); +float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity[3]); +int smoke_get_data_flags(struct SmokeDomainSettings *sds); #endif /* __BKE_SMOKE_H__ */ diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h index c14476a3b59..167f7bd831a 100644 --- a/source/blender/blenkernel/BKE_tracking.h +++ b/source/blender/blenkernel/BKE_tracking.h @@ -80,7 +80,7 @@ int BKE_tracking_track_has_marker_at_frame(struct MovieTrackingTrack *track, int int BKE_tracking_track_has_enabled_marker_at_frame(struct MovieTrackingTrack *track, int framenr); void BKE_tracking_track_path_clear(struct MovieTrackingTrack *track, int ref_frame, int action); -void BKE_tracking_tracks_join(struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); +void BKE_tracking_tracks_join(struct MovieTracking *tracking, struct MovieTrackingTrack *dst_track, struct MovieTrackingTrack *src_track); struct MovieTrackingTrack *BKE_tracking_track_get_named(struct MovieTracking *tracking, struct MovieTrackingObject *object, diff --git a/source/blender/blenkernel/BKE_utildefines.h b/source/blender/blenkernel/BKE_utildefines.h index 63f5ec59a0b..06f8b89ec05 100644 --- a/source/blender/blenkernel/BKE_utildefines.h +++ b/source/blender/blenkernel/BKE_utildefines.h @@ -38,4 +38,4 @@ extern "C" { } #endif -#endif // __BKE_UTILDEFINES_H__ +#endif /* __BKE_UTILDEFINES_H__ */ diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 9a24a3ca4e0..f690c9dcda4 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -25,7 +25,6 @@ set(INC . - ../avi ../blenfont ../blenlib ../blenloader @@ -196,8 +195,8 @@ set(SRC BKE_lattice.h BKE_library.h BKE_linestyle.h - BKE_mask.h BKE_main.h + BKE_mask.h BKE_material.h BKE_mball.h BKE_mesh.h @@ -252,7 +251,7 @@ if(WITH_AUDASPACE) endif() if(WITH_BULLET) - list(APPEND INC + list(APPEND INC_SYS ../../../extern/bullet2/src ) add_definitions(-DUSE_BULLET) @@ -294,6 +293,13 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() +if(WITH_CODEC_AVI) + list(APPEND INC + ../avi + ) + add_definitions(-DWITH_AVI) +endif() + if(WITH_CODEC_QUICKTIME) list(APPEND INC ../quicktime diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 9aaeb4c8baf..30804518e1d 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -2249,8 +2249,16 @@ DerivedMesh *mesh_create_derived_view(Scene *scene, Object *ob, CustomDataMask d { DerivedMesh *final; + /* XXX hack + * psys modifier updates particle state when called during dupli-list generation, + * which can lead to wrong transforms. This disables particle system modifier execution. + */ + ob->transflag |= OB_NO_PSYS_UPDATE; + mesh_calc_modifiers(scene, ob, NULL, NULL, &final, 0, 1, 0, dataMask, -1, 0, 0); + ob->transflag &= ~OB_NO_PSYS_UPDATE; + return final; } diff --git a/source/blender/blenkernel/intern/anim.c b/source/blender/blenkernel/intern/anim.c index 58d20fff2bc..622658e0a49 100644 --- a/source/blender/blenkernel/intern/anim.c +++ b/source/blender/blenkernel/intern/anim.c @@ -40,6 +40,8 @@ #include "BLI_rand.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_group_types.h" @@ -174,10 +176,10 @@ bMotionPath *animviz_verify_motionpaths(ReportList *reports, Scene *scene, Objec /* avoid 0 size allocs */ if (avs->path_sf >= avs->path_ef) { BKE_reportf(reports, RPT_ERROR, - "Motion Path frame extents invalid for %s (%d to %d).%s\n", + "Motion Path frame extents invalid for %s (%d to %d)%s", (pchan) ? pchan->name : ob->id.name, avs->path_sf, avs->path_ef, - (avs->path_sf == avs->path_ef) ? " Cannot have single-frame paths." : ""); + (avs->path_sf == avs->path_ef) ? TIP_(", cannot have single-frame paths") : ""); return NULL; } @@ -1678,8 +1680,8 @@ ListBase *object_duplilist_ex(Scene *sce, Object *ob, int update, int for_render ListBase *duplilist = MEM_mallocN(sizeof(ListBase), "duplilist"); int flag = 0; - if(update) flag |= DUPLILIST_DO_UPDATE; - if(for_render) flag |= DUPLILIST_FOR_RENDER; + if (update) flag |= DUPLILIST_DO_UPDATE; + if (for_render) flag |= DUPLILIST_FOR_RENDER; duplilist->first = duplilist->last = NULL; object_duplilist_recursive((ID *)sce, sce, ob, duplilist, NULL, 0, 0, flag); diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c index b87342f85fa..f5c7cab6019 100644 --- a/source/blender/blenkernel/intern/armature.c +++ b/source/blender/blenkernel/intern/armature.c @@ -534,10 +534,12 @@ Mat4 *b_bone_spline_setup(bPoseChannel *pchan, int rest) mul_m4_v3(imat, h2); /* if next bone is B-bone too, use average handle direction */ - if (next->bone->segments > 1) - ; - else + if (next->bone->segments > 1) { + /* pass */ + } + else { h2[1] -= length; + } normalize_v3(h2); /* find the next roll to interpolate as well */ @@ -1423,19 +1425,20 @@ void BKE_rotMode_change_values(float quat[4], float eul[3], float axis[3], float * *************************************************************************** */ /* Computes vector and roll based on a rotation. * "mat" must contain only a rotation, and no scaling. */ -void mat3_to_vec_roll(float mat[][3], float vec[3], float *roll) +void mat3_to_vec_roll(float mat[][3], float r_vec[3], float *r_roll) { - if (vec) - copy_v3_v3(vec, mat[1]); + if (r_vec) { + copy_v3_v3(r_vec, mat[1]); + } - if (roll) { + if (r_roll) { float vecmat[3][3], vecmatinv[3][3], rollmat[3][3]; vec_roll_to_mat3(mat[1], 0.0f, vecmat); invert_m3_m3(vecmatinv, vecmat); mul_m3_m3m3(rollmat, vecmatinv, mat); - *roll = (float)atan2(rollmat[2][0], rollmat[2][2]); + *r_roll = atan2f(rollmat[2][0], rollmat[2][2]); } } diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 99b788e80ce..197e38ac778 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -621,7 +621,9 @@ void BKE_undo_step(bContext *C, int step) } else if (step == 1) { /* curundo should never be NULL, after restart or load file it should call undo_save */ - if (curundo == NULL || curundo->prev == NULL) ; // XXX error("No undo available"); + if (curundo == NULL || curundo->prev == NULL) { + // XXX error("No undo available"); + } else { if (G.debug & G_DEBUG) printf("undo %s\n", curundo->name); curundo = curundo->prev; @@ -631,7 +633,9 @@ void BKE_undo_step(bContext *C, int step) else { /* curundo has to remain current situation! */ - if (curundo == NULL || curundo->next == NULL) ; // XXX error("No redo available"); + if (curundo == NULL || curundo->next == NULL) { + // XXX error("No redo available"); + } else { read_undosave(C, curundo->next); curundo = curundo->next; diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c index 79d5e092a10..aafc7fe89b4 100644 --- a/source/blender/blenkernel/intern/boids.c +++ b/source/blender/blenkernel/intern/boids.c @@ -101,13 +101,15 @@ static int rule_goal_avoid(BoidRule *rule, BoidBrainData *bbd, BoidValues *val, break; } } - else if (rule->type == eBoidRuleType_Goal && eob == bpa->ground) - ; /* skip current object */ + else if (rule->type == eBoidRuleType_Goal && eob == bpa->ground) { + /* skip current object */ + } else if (pd->forcefield == PFIELD_BOID && mul * pd->f_strength > 0.0f && get_effector_data(cur, &cur_efd, &epoint, 0)) { float temp = mul * pd->f_strength * effector_falloff(cur, &cur_efd, &epoint, bbd->part->effector_weights); - if (temp == 0.0f) - ; /* do nothing */ + if (temp == 0.0f) { + /* do nothing */ + } else if (temp > priority) { priority = temp; eff = cur; diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index ce39eea5ceb..f4efc30068c 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -741,7 +741,7 @@ void BKE_brush_scale_unprojected_radius(float *unprojected_radius, } /* scale brush size to reflect a change in the brush's unprojected radius */ -void BKE_brush_scale_size(int *BKE_brush_size_get, +void BKE_brush_scale_size(int *r_brush_size, float new_unprojected_radius, float old_unprojected_radius) { @@ -749,7 +749,7 @@ void BKE_brush_scale_size(int *BKE_brush_size_get, /* avoid division by zero */ if (old_unprojected_radius != 0) scale /= new_unprojected_radius; - (*BKE_brush_size_get) = (int)((float)(*BKE_brush_size_get) * scale); + (*r_brush_size) = (int)((float)(*r_brush_size) * scale); } /* Brush Painting */ diff --git a/source/blender/blenkernel/intern/cloth.c b/source/blender/blenkernel/intern/cloth.c index 4241756a109..da162ab37d0 100644 --- a/source/blender/blenkernel/intern/cloth.c +++ b/source/blender/blenkernel/intern/cloth.c @@ -773,11 +773,13 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) else verts->goal= 0.0f; + /* Reset vertex flags */ + verts->flags &= ~CLOTH_VERT_FLAG_PINNED; + verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL; + dvert = dm->getVertData ( dm, i, CD_MDEFORMVERT ); if ( dvert ) { - for ( j = 0; j < dvert->totweight; j++ ) { - verts->flags &= ~CLOTH_VERT_FLAG_PINNED; if (( dvert->dw[j].def_nr == (clmd->sim_parms->vgroup_mass-1)) && (clmd->sim_parms->flags & CLOTH_SIMSETTINGS_FLAG_GOAL )) { verts->goal = dvert->dw [j].weight; @@ -789,7 +791,7 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) */ verts->goal = powf(verts->goal, 4.0f); - if ( verts->goal >=SOFTGOALSNAP ) + if ( verts->goal >= SOFTGOALSNAP ) verts->flags |= CLOTH_VERT_FLAG_PINNED; } @@ -804,7 +806,6 @@ static void cloth_apply_vgroup ( ClothModifierData *clmd, DerivedMesh *dm ) } } - verts->flags &= ~CLOTH_VERT_FLAG_NOSELFCOLL; if (clmd->coll_parms->flags & CLOTH_COLLSETTINGS_FLAG_SELF ) { if ( dvert->dw[j].def_nr == (clmd->coll_parms->vgroup_selfcol-1)) { if (dvert->dw [j].weight > 0.0f) { diff --git a/source/blender/blenkernel/intern/collision.c b/source/blender/blenkernel/intern/collision.c index 6631afcddaf..05c916f9362 100644 --- a/source/blender/blenkernel/intern/collision.c +++ b/source/blender/blenkernel/intern/collision.c @@ -458,7 +458,8 @@ static CollPair* cloth_collision(ModifierData *md1, ModifierData *md2, distance = 2.0 * (double)( epsilon1 + epsilon2 + ALMOST_ZERO ); #endif - if (distance <= (epsilon1 + epsilon2 + ALMOST_ZERO)) { + // distance -1 means no collision result + if (distance != -1.0f && (distance <= (epsilon1 + epsilon2 + ALMOST_ZERO))) { normalize_v3_v3(collpair->normal, collpair->vector); collpair->distance = distance; diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c index 1bd5786debd..d5d6d31b1e1 100644 --- a/source/blender/blenkernel/intern/colortools.c +++ b/source/blender/blenkernel/intern/colortools.c @@ -835,64 +835,6 @@ void curvemapping_evaluate_premulRGB(const CurveMapping *cumap, unsigned char ve vecout_byte[2] = FTOCHAR(vecout[2]); } - -/* only used for image editor curves */ -void curvemapping_do_ibuf(CurveMapping *cumap, ImBuf *ibuf) -{ - ImBuf *tmpbuf; - int pixel; - float *pix_in; - float col[3]; - int stride = 4; - float *pix_out; - - if (ibuf == NULL) - return; - if (ibuf->rect_float == NULL) - IMB_float_from_rect(ibuf); - else if (ibuf->rect == NULL) - imb_addrectImBuf(ibuf); - - if (!ibuf->rect || !ibuf->rect_float) - return; - - /* work on a temp buffer, so can color manage afterwards. - * No worse off memory wise than comp nodes */ - tmpbuf = IMB_dupImBuf(ibuf); - - curvemapping_premultiply(cumap, 0); - - pix_in = ibuf->rect_float; - pix_out = tmpbuf->rect_float; - - if (ibuf->channels) - stride = ibuf->channels; - - for (pixel = ibuf->x * ibuf->y; pixel > 0; pixel--, pix_in += stride, pix_out += stride) { - if (stride < 3) { - col[0] = curvemap_evaluateF(cumap->cm, *pix_in); - - pix_out[1] = pix_out[2] = pix_out[3] = pix_out[0] = col[0]; - } - else { - curvemapping_evaluate_premulRGBF(cumap, col, pix_in); - pix_out[0] = col[0]; - pix_out[1] = col[1]; - pix_out[2] = col[2]; - if (stride > 3) - pix_out[3] = pix_in[3]; - else - pix_out[3] = 1.f; - } - } - - IMB_rect_from_float(tmpbuf); - SWAP(unsigned int *, tmpbuf->rect, ibuf->rect); - IMB_freeImBuf(tmpbuf); - - curvemapping_premultiply(cumap, 1); -} - int curvemapping_RGBA_does_something(const CurveMapping *cumap) { int a; diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c index 0bda3b266b8..e09e2eeb493 100644 --- a/source/blender/blenkernel/intern/curve.c +++ b/source/blender/blenkernel/intern/curve.c @@ -2109,7 +2109,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) BevPoint *bevp2, *bevp1, *bevp0; /* standard for all make_bevel_list_3D_* funcs */ int nr; - float bevp0_tan[3], cross_tmp[3]; + float bevp0_tan[3]; bevel_list_calc_bisect(bl); if (bl->poly == -1) /* check its not cyclic */ @@ -2123,6 +2123,7 @@ static void make_bevel_list_3D_tangent(BevList *bl) nr = bl->nr; while (nr--) { + float cross_tmp[3]; cross_v3_v3v3(cross_tmp, bevp1->tan, bevp1->dir); cross_v3_v3v3(bevp1->tan, cross_tmp, bevp1->dir); normalize_v3(bevp1->tan); diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c index de55751f2ec..423bd93c70f 100644 --- a/source/blender/blenkernel/intern/customdata.c +++ b/source/blender/blenkernel/intern/customdata.c @@ -2358,7 +2358,9 @@ void CustomData_bmesh_free_block(CustomData *data, void **block) const LayerTypeInfo *typeInfo; int i; - if (!*block) return; + if (*block == NULL) + return; + for (i = 0; i < data->totlayer; ++i) { if (!(data->layers[i].flag & CD_FLAG_NOFREE)) { typeInfo = layerType_getInfo(data->layers[i].type); @@ -2394,7 +2396,7 @@ void CustomData_bmesh_copy_data(const CustomData *source, CustomData *dest, const LayerTypeInfo *typeInfo; int dest_i, src_i; - if (!*dest_block) { + if (*dest_block == NULL) { CustomData_bmesh_alloc_block(dest, dest_block); if (*dest_block) memset(*dest_block, 0, dest->totsize); @@ -2614,7 +2616,7 @@ void CustomData_bmesh_set_default(CustomData *data, void **block) const LayerTypeInfo *typeInfo; int i; - if (!*block) + if (*block == NULL) CustomData_bmesh_alloc_block(data, block); for (i = 0; i < data->totlayer; ++i) { @@ -2634,7 +2636,7 @@ void CustomData_to_bmesh_block(const CustomData *source, CustomData *dest, const LayerTypeInfo *typeInfo; int dest_i, src_i, src_offset; - if (!*dest_block) + if (*dest_block == NULL) CustomData_bmesh_alloc_block(dest, dest_block); /* copies a layer at a time */ @@ -2866,7 +2868,9 @@ void CustomData_external_reload(CustomData *data, ID *UNUSED(id), CustomDataMask layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } else if ((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) { if (typeInfo->free) typeInfo->free(layer->data, totelem, typeInfo->size); @@ -2892,10 +2896,15 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if (layer->flag & CD_FLAG_IN_MEMORY) ; - else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if (layer->flag & CD_FLAG_IN_MEMORY) { + /* pass */ + } + else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { update = 1; + } } if (!update) @@ -2913,15 +2922,23 @@ void CustomData_external_read(CustomData *data, ID *id, CustomDataMask mask, int layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if (layer->flag & CD_FLAG_IN_MEMORY) ; + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if (layer->flag & CD_FLAG_IN_MEMORY) { + /* pass */ + } else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->read) { blay = cdf_layer_find(cdf, layer->type, layer->name); if (blay) { if (cdf_read_layer(cdf, blay)) { - if (typeInfo->read(cdf, layer->data, totelem)) ; - else break; + if (typeInfo->read(cdf, layer->data, totelem)) { + /* pass */ + } + else { + break; + } layer->flag |= CD_FLAG_IN_MEMORY; } else @@ -2952,9 +2969,12 @@ void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in layer = &data->layers[i]; typeInfo = layerType_getInfo(layer->type); - if (!(mask & CD_TYPE_AS_MASK(layer->type))) ; - else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) + if (!(mask & CD_TYPE_AS_MASK(layer->type))) { + /* pass */ + } + else if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) { update = 1; + } } if (!update) @@ -2995,11 +3015,16 @@ void CustomData_external_write(CustomData *data, ID *id, CustomDataMask mask, in blay = cdf_layer_find(cdf, layer->type, layer->name); if (cdf_write_layer(cdf, blay)) { - if (typeInfo->write(cdf, layer->data, totelem)) ; - else break; + if (typeInfo->write(cdf, layer->data, totelem)) { + /* pass */ + } + else { + break; + } } - else + else { break; + } } } diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c index 31a6f768f89..20b029371f1 100644 --- a/source/blender/blenkernel/intern/depsgraph.c +++ b/source/blender/blenkernel/intern/depsgraph.c @@ -400,8 +400,7 @@ static void dag_add_material_driver_relations(DagForest *dag, DagNode *node, Mat } } -static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node) -{ +static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Object *ob, DagNode *node, int skip_forcefield){ Base *base; DagNode *node2; @@ -411,6 +410,8 @@ static void dag_add_collision_field_relation(DagForest *dag, Scene *scene, Objec if ((base->lay & ob->lay) && base->object->pd) { Object *ob1 = base->object; if ((ob1->pd->deflect || ob1->pd->forcefield) && (ob1 != ob)) { + if (skip_forcefield && ob1->pd->forcefield == skip_forcefield) + continue; node2 = dag_get_node(dag, ob1); dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Collision"); } @@ -443,7 +444,6 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O if (ob->type == OB_ARMATURE) { if (ob->pose) { bPoseChannel *pchan; - bConstraint *con; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { for (con = pchan->constraints.first; con; con = con->next) { @@ -570,12 +570,14 @@ static void build_dag_object(DagForest *dag, DagNode *scenenode, Scene *scene, O /* softbody collision */ if ((ob->type == OB_MESH) || (ob->type == OB_CURVE) || (ob->type == OB_LATTICE)) { if (ob->particlesystem.first || - modifiers_isModifierEnabled(ob, eModifierType_Softbody) || - modifiers_isModifierEnabled(ob, eModifierType_Cloth) || - modifiers_isModifierEnabled(ob, eModifierType_Smoke) || - modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) + modifiers_isModifierEnabled(ob, eModifierType_Softbody) || + modifiers_isModifierEnabled(ob, eModifierType_Cloth) || + modifiers_isModifierEnabled(ob, eModifierType_DynamicPaint)) { - dag_add_collision_field_relation(dag, scene, ob, node); /* TODO: use effectorweight->group */ + dag_add_collision_field_relation(dag, scene, ob, node, 0); /* TODO: use effectorweight->group */ + } + else if (modifiers_isModifierEnabled(ob, eModifierType_Smoke)) { + dag_add_collision_field_relation(dag, scene, ob, node, PFIELD_SMOKEFLOW); } } diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c index 64959fd3aa1..10c9f30f5ee 100644 --- a/source/blender/blenkernel/intern/displist.c +++ b/source/blender/blenkernel/intern/displist.c @@ -299,7 +299,9 @@ static void curve_to_displist(Curve *cu, ListBase *nubase, ListBase *dispbase, i else resolu = nu->resolu; - if (!BKE_nurb_check_valid_u(nu)) ; + if (!BKE_nurb_check_valid_u(nu)) { + /* pass */ + } else if (nu->type == CU_BEZIER) { /* count */ len = 0; diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c index 4f4bafd00b4..7c0b43c24df 100644 --- a/source/blender/blenkernel/intern/effect.c +++ b/source/blender/blenkernel/intern/effect.c @@ -54,6 +54,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_jitter.h" #include "BLI_rand.h" #include "BLI_utildefines.h" @@ -84,6 +85,7 @@ #include "BKE_object.h" #include "BKE_particle.h" #include "BKE_scene.h" +#include "BKE_smoke.h" #include "RE_render_ext.h" @@ -137,6 +139,9 @@ PartDeflect *object_add_collision_fields(int type) case PFIELD_TEXTURE: pd->f_size = 1.0f; break; + case PFIELD_SMOKEFLOW: + pd->f_flow = 1.0f; + break; } pd->flag = PFIELD_DO_LOCATION|PFIELD_DO_ROTATION; @@ -922,12 +927,27 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected mul_v3_fl(force, -efd->falloff * fac * (strength * fac + damp)); break; + case PFIELD_SMOKEFLOW: + zero_v3(force); + if (pd->f_source) { + float density; + if ((density = smoke_get_velocity_at(pd->f_source, point->loc, force)) >= 0.0f) { + float influence = strength * efd->falloff; + if (pd->flag & PFIELD_SMOKE_DENSITY) + influence *= density; + mul_v3_fl(force, influence); + /* apply flow */ + madd_v3_v3fl(total_force, point->vel, -pd->f_flow * influence); + } + } + break; + } if (pd->flag & PFIELD_DO_LOCATION) { madd_v3_v3fl(total_force, force, 1.0f/point->vel_to_sec); - if (ELEM(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG)==0 && pd->f_flow != 0.0f) { + if (ELEM3(pd->forcefield, PFIELD_HARMONIC, PFIELD_DRAG, PFIELD_SMOKEFLOW)==0 && pd->f_flow != 0.0f) { madd_v3_v3fl(total_force, point->vel, -pd->f_flow * efd->falloff); } } @@ -993,10 +1013,12 @@ void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *we if (efd.falloff > 0.0f) efd.falloff *= eff_calc_visibility(colliders, eff, &efd, point); - if (efd.falloff <= 0.0f) - ; /* don't do anything */ - else if (eff->pd->forcefield == PFIELD_TEXTURE) + if (efd.falloff <= 0.0f) { + /* don't do anything */ + } + else if (eff->pd->forcefield == PFIELD_TEXTURE) { do_texture_effector(eff, &efd, point, force); + } else { float temp1[3]={0, 0, 0}, temp2[3]; copy_v3_v3(temp1, force); diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c index 68321076398..1e6eb77f666 100644 --- a/source/blender/blenkernel/intern/fmodifier.c +++ b/source/blender/blenkernel/intern/fmodifier.c @@ -42,6 +42,7 @@ #include "BLF_translation.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" /* windows needs for M_PI */ #include "BLI_utildefines.h" diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c index 8b35974ea62..06b21fbbd29 100644 --- a/source/blender/blenkernel/intern/font.c +++ b/source/blender/blenkernel/intern/font.c @@ -928,8 +928,12 @@ makebreak: * 3: curs down */ ct = chartransdata + cu->pos; - if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) ; - else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) ; + if ((mode == FO_CURSUP || mode == FO_PAGEUP) && ct->linenr == 0) { + /* pass */ + } + else if ((mode == FO_CURSDOWN || mode == FO_PAGEDOWN) && ct->linenr == lnr) { + /* pass */ + } else { switch (mode) { case FO_CURSUP: lnr = ct->linenr - 1; break; diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c index 84871375788..76b00ffdb1c 100644 --- a/source/blender/blenkernel/intern/gpencil.c +++ b/source/blender/blenkernel/intern/gpencil.c @@ -87,6 +87,7 @@ void free_gpencil_frames(bGPDlayer *gpl) free_gpencil_strokes(gpf); BLI_freelinkN(&gpl->frames, gpf); } + gpl->actframe = NULL; } /* Free all of the gp-layers for a viewport (list should be &gpd->layers or so) */ diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c003a86a0b7..9a1ea15da97 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -2617,11 +2617,21 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **lock_ /* free rect buffer if float buffer changes, so it can be recreated with * the updated result, and also in case we got byte buffer from sequencer, * so we don't keep reference to freed buffer */ - if (ibuf->rect_float != rectf || rect || !rectf) + if (ibuf->rect_float != rectf || rect) imb_freerectImBuf(ibuf); - if (rect) + if (rect) { ibuf->rect = rect; + } + else { + /* byte buffer of render result has been freed, make sure image buffers + * does not reference to this buffer anymore + * need check for whether byte buffer was allocated and owned by image itself + * or if it's reusing buffer from render result + */ + if ((ibuf->mall & IB_rect) == 0) + ibuf->rect = NULL; + } if (rectf) { ibuf->rect_float = rectf; diff --git a/source/blender/blenkernel/intern/implicit.c b/source/blender/blenkernel/intern/implicit.c index ebb95a6561e..235d7858e17 100644 --- a/source/blender/blenkernel/intern/implicit.c +++ b/source/blender/blenkernel/intern/implicit.c @@ -857,23 +857,22 @@ DO_INLINE float fbderiv(float length, float L) DO_INLINE float fbstar(float length, float L, float kb, float cb) { - float tempfb = kb * fb(length, L); - - float fbstar = cb * (length - L); + float tempfb_fl = kb * fb(length, L); + float fbstar_fl = cb * (length - L); - if (tempfb < fbstar) - return fbstar; + if (tempfb_fl < fbstar_fl) + return fbstar_fl; else - return tempfb; + return tempfb_fl; } // function to calculae bending spring force (taken from Choi & Co) DO_INLINE float fbstar_jacobi(float length, float L, float kb, float cb) { - float tempfb = kb * fb(length, L); - float fbstar = cb * (length - L); + float tempfb_fl = kb * fb(length, L); + float fbstar_fl = cb * (length - L); - if (tempfb < fbstar) { + if (tempfb_fl < fbstar_fl) { return cb; } else { @@ -1450,7 +1449,7 @@ static void hair_velocity_smoothing(ClothModifierData *clmd, lfVector *lF, lfVec i = HAIR_GRID_INDEX(lX[v], gmin, gmax, 0); j = HAIR_GRID_INDEX(lX[v], gmin, gmax, 1); k = HAIR_GRID_INDEX(lX[v], gmin, gmax, 2); - if (i < 0 || j < 0 || k < 0 || i > 10 || j >= 10 || k >= 10) + if (i < 0 || j < 0 || k < 0 || i >= 10 || j >= 10 || k >= 10) continue; grid[i][j][k].velocity[0] += lV[v][0]; diff --git a/source/blender/blenkernel/intern/ipo.c b/source/blender/blenkernel/intern/ipo.c index 5216aefab58..b7e33f1cf71 100644 --- a/source/blender/blenkernel/intern/ipo.c +++ b/source/blender/blenkernel/intern/ipo.c @@ -2093,7 +2093,7 @@ void do_versions_ipos_to_animato(Main *main) bAction *new_act; /* add a new action for this, and convert all data into that action */ - new_act = add_empty_action(id->name+2); + new_act = add_empty_action(id->name + 2); ipo_to_animato(NULL, ipo, NULL, NULL, NULL, NULL, &new_act->curves, &drivers); new_act->idroot = ipo->blocktype; } diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c index 17e4103c7d3..5382ea453eb 100644 --- a/source/blender/blenkernel/intern/lattice.c +++ b/source/blender/blenkernel/intern/lattice.c @@ -64,19 +64,19 @@ #include "BKE_deform.h" -void calc_lat_fudu(int flag, int res, float *fu, float *du) +void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du) { if (res == 1) { - *fu = 0.0; - *du = 0.0; + *r_fu = 0.0; + *r_du = 0.0; } else if (flag & LT_GRID) { - *fu = -0.5f * (res - 1); - *du = 1.0f; + *r_fu = -0.5f * (res - 1); + *r_du = 1.0f; } else { - *fu = -1.0f; - *du = 2.0f / (res - 1); + *r_fu = -1.0f; + *r_du = 2.0f / (res - 1); } } @@ -879,9 +879,10 @@ void outside_lattice(Lattice *lt) for (v = 0; v < lt->pntsv; v++) { for (u = 0; u < lt->pntsu; u++, bp++) { - if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 || w == lt->pntsw - 1) ; + if (u == 0 || v == 0 || w == 0 || u == lt->pntsu - 1 || v == lt->pntsv - 1 || w == lt->pntsw - 1) { + /* pass */ + } else { - bp->hide = 1; bp->f1 &= ~SELECT; diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c index b8f891eabe1..ad28e3a6d79 100644 --- a/source/blender/blenkernel/intern/material.c +++ b/source/blender/blenkernel/intern/material.c @@ -38,6 +38,7 @@ #include "DNA_anim_types.h" #include "DNA_curve_types.h" +#include "DNA_group_types.h" #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" @@ -981,6 +982,15 @@ static void do_init_render_material(Material *ma, int r_mode, float *amb) /* parses the geom+tex nodes */ if (ma->nodetree && ma->use_nodes) ntreeShaderGetTexcoMode(ma->nodetree, r_mode, &ma->texco, &ma->mode_l); + + /* local group override */ + if((ma->shade_flag & MA_GROUP_LOCAL) && ma->id.lib && ma->group && ma->group->id.lib) { + Group *group; + + for(group= G.main->group.first; group; group= group->id.next) + if(!group->id.lib && strcmp(group->id.name, ma->group->id.name) == 0) + ma->group = group; + } } static void init_render_nodetree(bNodeTree *ntree, Material *basemat, int r_mode, float *amb) diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 1aaeebf5109..c244317ccb7 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -576,7 +576,7 @@ static void expand_local_mesh(Mesh *me) for (i = 0; i < me->pdata.totlayer; i++) { if (me->pdata.layers[i].type == CD_MTEXPOLY) { - MTexPoly *txface = (MTexPoly *)me->fdata.layers[i].data; + MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data; for (a = 0; a < me->totpoly; a++, txface++) { /* special case: ima always local immediately */ @@ -2039,7 +2039,7 @@ static void bm_corners_to_loops_ex(ID *id, CustomData *fdata, CustomData *ldata, MDisps *ld = CustomData_get(ldata, loopstart, CD_MDISPS); MDisps *fd = CustomData_get(fdata, findex, CD_MDISPS); float (*disps)[3] = fd->disps; - int i, tot = mf->v4 ? 4 : 3; + int tot = mf->v4 ? 4 : 3; int side, corners; if (CustomData_external_test(fdata, CD_MDISPS)) { diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 79e3fc19d20..c4d663e17bd 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -228,7 +228,6 @@ int BKE_mesh_validate_arrays(Mesh *mesh, } for (i = 1; i < totvert; i++, mv++) { - int j; int fix_normal = TRUE; for (j = 0; j < 3; j++) { @@ -717,7 +716,6 @@ int BKE_mesh_validate_arrays(Mesh *mesh, MDeformVert *dv; for (i = 0, dv = dverts; i < totvert; i++, dv++) { MDeformWeight *dw; - unsigned int j; for (j = 0, dw = dv->dw; j < dv->totweight; j++, dw++) { /* note, greater then max defgroups is accounted for in our code, but not < 0 */ @@ -914,7 +912,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) { CustomData edata; EdgeHashIterator *ehi; - MPoly *mp = mesh->mpoly; + MPoly *mp; MEdge *med, *med_orig; EdgeHash *eh = BLI_edgehash_new(); int i, totedge, totpoly = mesh->totpoly; @@ -932,7 +930,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) } /* mesh loops (bmesh only) */ - for (i = 0; i < totpoly; i++, mp++) { + for (mp = mesh->mpoly, i = 0; i < totpoly; mp++, i++) { MLoop *l = &mesh->mloop[mp->loopstart]; int j, l_prev = (l + (mp->totloop - 1))->v; for (j = 0; j < mp->totloop; j++, l++) { @@ -970,8 +968,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, int update) if (mesh->totpoly) { /* second pass, iterate through all loops again and assign * the newly created edges to them. */ - MPoly *mp = mesh->mpoly; - for (i = 0; i < mesh->totpoly; i++, mp++) { + for (mp = mesh->mpoly, i = 0; i < mesh->totpoly; mp++, i++) { MLoop *l = &mesh->mloop[mp->loopstart]; MLoop *l_prev = (l + (mp->totloop - 1)); int j; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index 28de80a7157..0afd048e7f2 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -494,8 +494,8 @@ ModifierData *modifiers_getVirtualModifierList(Object *ob) return md; } -/* Takes an object and returns its first selected armature, else just its - * armature + +/* Takes an object and returns its first selected armature, else just its armature * This should work for multiple armatures per object */ Object *modifiers_isDeformedByArmature(Object *ob) @@ -518,9 +518,8 @@ Object *modifiers_isDeformedByArmature(Object *ob) return NULL; } -/* Takes an object and returns its first selected lattice, else just its - * lattice - * This should work for multiple lattics per object +/* Takes an object and returns its first selected lattice, else just its lattice + * This should work for multiple lattices per object */ Object *modifiers_isDeformedByLattice(Object *ob) { @@ -542,7 +541,28 @@ Object *modifiers_isDeformedByLattice(Object *ob) return NULL; } - +/* Takes an object and returns its first selected curve, else just its curve + * This should work for multiple curves per object + */ +Object *modifiers_isDeformedByCurve(Object *ob) +{ + ModifierData *md = modifiers_getVirtualModifierList(ob); + CurveModifierData *cmd = NULL; + + /* return the first selected curve, this lets us use multiple curves */ + for (; md; md = md->next) { + if (md->type == eModifierType_Curve) { + cmd = (CurveModifierData *) md; + if (cmd->object && (cmd->object->flag & SELECT)) + return cmd->object; + } + } + + if (cmd) /* if were still here then return the last curve */ + return cmd->object; + + return NULL; +} int modifiers_usesArmature(Object *ob, bArmature *arm) { @@ -574,10 +594,12 @@ int modifiers_isCorrectableDeformed(Object *ob) ModifierData *md = modifiers_getVirtualModifierList(ob); for (; md; md = md->next) { - if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) ; - else - if (modifier_isCorrectableDeformed(md)) + if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) { + /* pass */ + } + else if (modifier_isCorrectableDeformed(md)) { return 1; + } } return 0; } diff --git a/source/blender/blenkernel/intern/modifiers_bmesh.c b/source/blender/blenkernel/intern/modifiers_bmesh.c index dc3d4a89e62..98eac9b95af 100644 --- a/source/blender/blenkernel/intern/modifiers_bmesh.c +++ b/source/blender/blenkernel/intern/modifiers_bmesh.c @@ -55,6 +55,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BLI_array_declare(verts); BLI_array_declare(edges); int i, j, k, totvert, totedge /* , totface */ /* UNUSED */ ; + int is_init = (bm->totvert == 0) && (bm->totedge == 0) && (bm->totface == 0); /*merge custom data layout*/ CustomData_bmesh_merge(&dm->vertData, &bm->vdata, CD_MASK_DERIVEDMESH, CD_CALLOC, bm, BM_VERT); @@ -81,6 +82,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) v = BM_vert_create(bm, mv->co, NULL); normal_short_to_float_v3(v->no, mv->no); v->head.hflag = BM_vert_flag_from_mflag(mv->flag); + BM_elem_index_set(v, i); /* set_inline */ CustomData_to_bmesh_block(&dm->vertData, &bm->vdata, i, &v->head.data); @@ -89,13 +91,16 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) vtable[i] = v; } MEM_freeN(mvert); + if (is_init) bm->elem_index_dirty &= ~BM_VERT; /*do edges*/ me = medge = dm->dupEdgeArray(dm); for (i = 0; i < totedge; i++, me++) { + //BLI_assert(BM_edge_exists(vtable[me->v1], vtable[me->v2]) == NULL); e = BM_edge_create(bm, vtable[me->v1], vtable[me->v2], NULL, FALSE); e->head.hflag = BM_edge_flag_from_mflag(me->flag); + BM_elem_index_set(e, i); /* set_inline */ CustomData_to_bmesh_block(&dm->edgeData, &bm->edata, i, &e->head.data); etable[i] = e; @@ -106,8 +111,10 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_elem_float_data_set(&bm->edata, e, CD_BWEIGHT, (float)me->bweight / 255.0f); } MEM_freeN(medge); + if (is_init) bm->elem_index_dirty &= ~BM_EDGE; - /*do faces*/ + /* do faces */ + /* note: i_alt is aligned with bmesh faces which may not always align with mpolys */ mp = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); face_normals = CustomData_get_layer(&dm->polyData, CD_NORMAL); /* can be NULL */ @@ -134,6 +141,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) } f->head.hflag = BM_face_flag_from_mflag(mp->flag); + BM_elem_index_set(f, bm->totface - 1); /* set_inline */ f->mat_nr = mp->mat_nr; l = BM_iter_new(&liter, bm, BM_LOOPS_OF_FACE, f); @@ -151,6 +159,7 @@ void DM_to_bmesh_ex(DerivedMesh *dm, BMesh *bm) BM_face_normal_update(f); } } + if (is_init) bm->elem_index_dirty &= ~BM_FACE; MEM_freeN(vtable); MEM_freeN(etable); diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c index 0aa1f9e0822..4bd6676608e 100644 --- a/source/blender/blenkernel/intern/movieclip.c +++ b/source/blender/blenkernel/intern/movieclip.c @@ -616,11 +616,6 @@ static ImBuf *get_undistorted_ibuf(MovieClip *clip, struct MovieDistortion *dist else undistibuf = BKE_tracking_undistort_frame(&clip->tracking, ibuf, ibuf->x, ibuf->y, 0.0f); - if (undistibuf->userflags & IB_RECT_INVALID) { - ibuf->userflags &= ~IB_RECT_INVALID; - IMB_rect_from_float(undistibuf); - } - IMB_scaleImBuf(undistibuf, ibuf->x, ibuf->y); return undistibuf; @@ -1096,6 +1091,18 @@ void BKE_movieclip_reload(MovieClip *clip) movieclip_load_get_szie(clip); movieclip_calc_length(clip); + + /* same as for image update -- don't use notifiers because they are not 100% sure to succeeded + * (node trees which are not currently visible wouldn't be refreshed) + */ + { + Scene *scene; + for (scene = G.main->scene.first; scene; scene = scene->id.next) { + if (scene->nodetree) { + nodeUpdateID(scene->nodetree, &clip->id); + } + } + } } void BKE_movieclip_update_scopes(MovieClip *clip, MovieClipUser *user, MovieClipScopes *scopes) diff --git a/source/blender/blenkernel/intern/multires.c b/source/blender/blenkernel/intern/multires.c index 591524e5156..58348483c61 100644 --- a/source/blender/blenkernel/intern/multires.c +++ b/source/blender/blenkernel/intern/multires.c @@ -1161,7 +1161,6 @@ void multires_modifier_update_mdisps(struct DerivedMesh *dm) int totlvl = ccgdm->multires.totlvl; if (lvl < totlvl) { - Mesh *me = ob->data; DerivedMesh *lowdm, *cddm, *highdm; CCGElem **highGridData, **lowGridData, **subGridData, **gridData, *diffGrid; CCGKey highGridKey, lowGridKey; diff --git a/source/blender/blenkernel/intern/navmesh_conversion.c b/source/blender/blenkernel/intern/navmesh_conversion.c index a21878d1d7d..5fe4f8e90ba 100644 --- a/source/blender/blenkernel/intern/navmesh_conversion.c +++ b/source/blender/blenkernel/intern/navmesh_conversion.c @@ -44,36 +44,36 @@ #include "recast-capi.h" -BLI_INLINE float area2(const float* a, const float* b, const float* c) +BLI_INLINE float area2(const float *a, const float *b, const float *c) { return (b[0] - a[0]) * (c[2] - a[2]) - (c[0] - a[0]) * (b[2] - a[2]); } -BLI_INLINE int left(const float* a, const float* b, const float* c) +BLI_INLINE int left(const float *a, const float *b, const float *c) { return area2(a, b, c) < 0; } -int polyNumVerts(const unsigned short* p, const int vertsPerPoly) +int polyNumVerts(const unsigned short *p, const int vertsPerPoly) { int i, nv = 0; - for (i=0; i<vertsPerPoly; i++) { - if (p[i]==0xffff) + for (i = 0; i < vertsPerPoly; i++) { + if (p[i] == 0xffff) break; nv++; } return nv; } -int polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* verts) +int polyIsConvex(const unsigned short *p, const int vertsPerPoly, const float *verts) { int j, nv = polyNumVerts(p, vertsPerPoly); - if (nv<3) + if (nv < 3) return 0; - for (j=0; j<nv; j++) { - const float* v = &verts[3*p[j]]; - const float* v_next = &verts[3*p[(j+1)%nv]]; - const float* v_prev = &verts[3*p[(nv+j-1)%nv]]; + for (j = 0; j < nv; j++) { + const float *v = &verts[3 * p[j]]; + const float *v_next = &verts[3 * p[(j + 1) % nv]]; + const float *v_prev = &verts[3 * p[(nv + j - 1) % nv]]; if (!left(v_prev, v, v_next)) return 0; @@ -81,7 +81,8 @@ int polyIsConvex(const unsigned short* p, const int vertsPerPoly, const float* v return 1; } -float distPointToSegmentSq(const float* point, const float* a, const float* b) +/* XXX, could replace with #dist_to_line_segment_v3(), or add a squared version */ +float distPointToSegmentSq(const float point[3], const float a[3], const float b[3]) { float abx[3], dx[3]; float d, t; @@ -89,24 +90,24 @@ float distPointToSegmentSq(const float* point, const float* a, const float* b) sub_v3_v3v3(abx, b, a); sub_v3_v3v3(dx, point, a); - d = abx[0]*abx[0]+abx[2]*abx[2]; - t = abx[0]*dx[0]+abx[2]*dx[2]; + d = abx[0] * abx[0] + abx[2] * abx[2]; + t = abx[0] * dx[0] + abx[2] * dx[2]; - if (d > 0) + if (d > 0.0f) t /= d; - if (t < 0) - t = 0; - else if (t > 1) - t = 1; - dx[0] = a[0] + t*abx[0] - point[0]; - dx[2] = a[2] + t*abx[2] - point[2]; - - return dx[0]*dx[0] + dx[2]*dx[2]; + if (t < 0.0f) + t = 0.0f; + else if (t > 1.0f) + t = 1.0f; + dx[0] = a[0] + t * abx[0] - point[0]; + dx[2] = a[2] + t * abx[2] - point[2]; + + return dx[0] * dx[0] + dx[2] * dx[2]; } -int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, - int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, - int **recastData) +int buildRawVertIndicesData(DerivedMesh *dm, int *nverts_r, float **verts_r, + int *ntris_r, unsigned short **tris_r, int **trisToFacesMap_r, + int **recastData) { int vi, fi, triIdx; int nverts, ntris; @@ -117,49 +118,49 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, MFace *faces; nverts = dm->getNumVerts(dm); - if (nverts>=0xffff) { + if (nverts >= 0xffff) { printf("Converting navmesh: Error! Too many vertices. Max number of vertices %d\n", 0xffff); return 0; } - verts = MEM_callocN(sizeof(float)*3*nverts, "buildRawVertIndicesData verts"); + verts = MEM_callocN(sizeof(float) * 3 * nverts, "buildRawVertIndicesData verts"); dm->getVertCos(dm, (float(*)[3])verts); - //flip coordinates - for (vi=0; vi<nverts; vi++) { - SWAP(float, verts[3*vi+1], verts[3*vi+2]); + /* flip coordinates */ + for (vi = 0; vi < nverts; vi++) { + SWAP(float, verts[3 * vi + 1], verts[3 * vi + 2]); } - //calculate number of tris + /* calculate number of tris */ nfaces = dm->getNumTessFaces(dm); faces = dm->getTessFaceArray(dm); ntris = nfaces; - for (fi=0; fi<nfaces; fi++) { - MFace* face = &faces[fi]; + for (fi = 0; fi < nfaces; fi++) { + MFace *face = &faces[fi]; if (face->v4) ntris++; } - //copy and transform to triangles (reorder on the run) - trisToFacesMap = MEM_callocN(sizeof(int)*ntris, "buildRawVertIndicesData trisToFacesMap"); - tris = MEM_callocN(sizeof(unsigned short)*3*ntris, "buildRawVertIndicesData tris"); + /* copy and transform to triangles (reorder on the run) */ + trisToFacesMap = MEM_callocN(sizeof(int) * ntris, "buildRawVertIndicesData trisToFacesMap"); + tris = MEM_callocN(sizeof(unsigned short) * 3 * ntris, "buildRawVertIndicesData tris"); tri = tris; triIdx = 0; - for (fi=0; fi<nfaces; fi++) { - MFace* face = &faces[fi]; - tri[3*triIdx+0] = (unsigned short) face->v1; - tri[3*triIdx+1] = (unsigned short) face->v3; - tri[3*triIdx+2] = (unsigned short) face->v2; - trisToFacesMap[triIdx++]=fi; + for (fi = 0; fi < nfaces; fi++) { + MFace *face = &faces[fi]; + tri[3 * triIdx + 0] = (unsigned short) face->v1; + tri[3 * triIdx + 1] = (unsigned short) face->v3; + tri[3 * triIdx + 2] = (unsigned short) face->v2; + trisToFacesMap[triIdx++] = fi; if (face->v4) { - tri[3*triIdx+0] = (unsigned short) face->v1; - tri[3*triIdx+1] = (unsigned short) face->v4; - tri[3*triIdx+2] = (unsigned short) face->v3; - trisToFacesMap[triIdx++]=fi; + tri[3 * triIdx + 0] = (unsigned short) face->v1; + tri[3 * triIdx + 1] = (unsigned short) face->v4; + tri[3 * triIdx + 2] = (unsigned short) face->v3; + trisToFacesMap[triIdx++] = fi; } } - //carefully, recast data is just reference to data in derived mesh - *recastData = (int*)CustomData_get_layer(&dm->polyData, CD_RECAST); + /* carefully, recast data is just reference to data in derived mesh */ + *recastData = (int *)CustomData_get_layer(&dm->polyData, CD_RECAST); *nverts_r = nverts; *verts_r = verts; @@ -170,122 +171,122 @@ int buildRawVertIndicesData(DerivedMesh* dm, int *nverts_r, float **verts_r, return 1; } -int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, - unsigned short* polys, const unsigned short* dmeshes, - const float* verts, const unsigned short* dtris, - const int* dtrisToPolysMap) +int buildPolygonsByDetailedMeshes(const int vertsPerPoly, const int npolys, + unsigned short *polys, const unsigned short *dmeshes, + const float *verts, const unsigned short *dtris, + const int *dtrisToPolysMap) { int polyidx; int capacity = vertsPerPoly; - unsigned short* newPoly = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPoly"); - memset(newPoly, 0xff, sizeof(unsigned short)*capacity); + unsigned short *newPoly = MEM_callocN(sizeof(unsigned short) * capacity, "buildPolygonsByDetailedMeshes newPoly"); + memset(newPoly, 0xff, sizeof(unsigned short) * capacity); - for (polyidx=0; polyidx<npolys; polyidx++) { + for (polyidx = 0; polyidx < npolys; polyidx++) { size_t i; int j, k; int nv = 0; - //search border + /* search border */ int tri, btri = -1; int edge, bedge = -1; - int dtrisNum = dmeshes[polyidx*4+3]; - int dtrisBase = dmeshes[polyidx*4+2]; - unsigned char *traversedTris = MEM_callocN(sizeof(unsigned char)*dtrisNum, "buildPolygonsByDetailedMeshes traversedTris"); - unsigned short* adjustedPoly; + int dtrisNum = dmeshes[polyidx * 4 + 3]; + int dtrisBase = dmeshes[polyidx * 4 + 2]; + unsigned char *traversedTris = MEM_callocN(sizeof(unsigned char) * dtrisNum, "buildPolygonsByDetailedMeshes traversedTris"); + unsigned short *adjustedPoly; int adjustedNv; int allBorderTraversed; - for (j=0; j<dtrisNum && btri==-1;j++) { - int curpolytri = dtrisBase+j; - for (k=0; k<3; k++) { - unsigned short neighbortri = dtris[curpolytri*3*2+3+k]; - if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) { + for (j = 0; j < dtrisNum && btri == -1; j++) { + int curpolytri = dtrisBase + j; + for (k = 0; k < 3; k++) { + unsigned short neighbortri = dtris[curpolytri * 3 * 2 + 3 + k]; + if (neighbortri == 0xffff || dtrisToPolysMap[neighbortri] != polyidx + 1) { btri = curpolytri; bedge = k; break; } - } + } } - if (btri==-1 || bedge==-1) { - //can't find triangle with border edge + if (btri == -1 || bedge == -1) { + /* can't find triangle with border edge */ MEM_freeN(traversedTris); MEM_freeN(newPoly); return 0; } - newPoly[nv++] = dtris[btri*3*2+bedge]; + newPoly[nv++] = dtris[btri * 3 * 2 + bedge]; tri = btri; - edge = (bedge+1)%3; - traversedTris[tri-dtrisBase] = 1; + edge = (bedge + 1) % 3; + traversedTris[tri - dtrisBase] = 1; while (tri != btri || edge != bedge) { - int neighbortri = dtris[tri*3*2+3+edge]; - if (neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) { - if (nv==capacity) { - unsigned short* newPolyBig; + int neighbortri = dtris[tri * 3 * 2 + 3 + edge]; + if (neighbortri == 0xffff || dtrisToPolysMap[neighbortri] != polyidx + 1) { + if (nv == capacity) { + unsigned short *newPolyBig; capacity += vertsPerPoly; - newPolyBig = MEM_callocN(sizeof(unsigned short)*capacity, "buildPolygonsByDetailedMeshes newPolyBig"); - memset(newPolyBig, 0xff, sizeof(unsigned short)*capacity); - memcpy(newPolyBig, newPoly, sizeof(unsigned short)*nv); + newPolyBig = MEM_callocN(sizeof(unsigned short) * capacity, "buildPolygonsByDetailedMeshes newPolyBig"); + memset(newPolyBig, 0xff, sizeof(unsigned short) * capacity); + memcpy(newPolyBig, newPoly, sizeof(unsigned short) * nv); MEM_freeN(newPoly); - newPoly = newPolyBig; + newPoly = newPolyBig; } - newPoly[nv++] = dtris[tri*3*2+edge]; - //move to next edge - edge = (edge+1)%3; + newPoly[nv++] = dtris[tri * 3 * 2 + edge]; + /* move to next edge */ + edge = (edge + 1) % 3; } else { - //move to next tri + /* move to next tri */ int twinedge = -1; - for (k=0; k<3; k++) { - if (dtris[neighbortri*3*2+3+k] == tri) { + for (k = 0; k < 3; k++) { + if (dtris[neighbortri * 3 * 2 + 3 + k] == tri) { twinedge = k; break; } } - if (twinedge==-1) { + if (twinedge == -1) { printf("Converting navmesh: Error! Can't find neighbor edge - invalid adjacency info\n"); MEM_freeN(traversedTris); goto returnLabel; } tri = neighbortri; - edge = (twinedge+1)%3; - traversedTris[tri-dtrisBase] = 1; + edge = (twinedge + 1) % 3; + traversedTris[tri - dtrisBase] = 1; } } - adjustedPoly = MEM_callocN(sizeof(unsigned short)*nv, "buildPolygonsByDetailedMeshes adjustedPoly"); + adjustedPoly = MEM_callocN(sizeof(unsigned short) * nv, "buildPolygonsByDetailedMeshes adjustedPoly"); adjustedNv = 0; - for (i=0; i<nv; i++) { - unsigned short prev = newPoly[(nv+i-1)%nv]; + for (i = 0; i < nv; i++) { + unsigned short prev = newPoly[(nv + i - 1) % nv]; unsigned short cur = newPoly[i]; - unsigned short next = newPoly[(i+1)%nv]; - float distSq = distPointToSegmentSq(&verts[3*cur], &verts[3*prev], &verts[3*next]); + unsigned short next = newPoly[(i + 1) % nv]; + float distSq = distPointToSegmentSq(&verts[3 * cur], &verts[3 * prev], &verts[3 * next]); static const float tolerance = 0.001f; - if (distSq>tolerance) + if (distSq > tolerance) adjustedPoly[adjustedNv++] = cur; } - memcpy(newPoly, adjustedPoly, adjustedNv*sizeof(unsigned short)); + memcpy(newPoly, adjustedPoly, adjustedNv * sizeof(unsigned short)); MEM_freeN(adjustedPoly); nv = adjustedNv; allBorderTraversed = 1; - for (i=0; i<dtrisNum; i++) { - if (traversedTris[i]==0) { - //check whether it has border edges - int curpolytri = dtrisBase+i; - for (k=0; k<3; k++) { - unsigned short neighbortri = dtris[curpolytri*3*2+3+k]; - if ( neighbortri==0xffff || dtrisToPolysMap[neighbortri]!=polyidx+1) { + for (i = 0; i < dtrisNum; i++) { + if (traversedTris[i] == 0) { + /* check whether it has border edges */ + int curpolytri = dtrisBase + i; + for (k = 0; k < 3; k++) { + unsigned short neighbortri = dtris[curpolytri * 3 * 2 + 3 + k]; + if (neighbortri == 0xffff || dtrisToPolysMap[neighbortri] != polyidx + 1) { allBorderTraversed = 0; break; } } - } + } } - if (nv<=vertsPerPoly && allBorderTraversed) { - for (i=0; i<nv; i++) { - polys[polyidx*vertsPerPoly*2+i] = newPoly[i]; + if (nv <= vertsPerPoly && allBorderTraversed) { + for (i = 0; i < nv; i++) { + polys[polyidx * vertsPerPoly * 2 + i] = newPoly[i]; } } @@ -298,21 +299,20 @@ returnLabel: return 1; } -struct SortContext -{ - const int* recastData; - const int* trisToFacesMap; +struct SortContext { + const int *recastData; + const int *trisToFacesMap; }; -static int compareByData(void *ctx, const void * a, const void * b) +static int compareByData(void *ctx, const void *a, const void *b) { - return (((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)a]] - - ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int*)b]] ); + return (((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int *)a]] - + ((struct SortContext *)ctx)->recastData[((struct SortContext *)ctx)->trisToFacesMap[*(int *)b]]); } -int buildNavMeshData(const int nverts, const float* verts, +int buildNavMeshData(const int nverts, const float *verts, const int ntris, const unsigned short *tris, - const int* recastData, const int* trisToFacesMap, + const int *recastData, const int *trisToFacesMap, int *ndtris_r, unsigned short **dtris_r, int *npolys_r, unsigned short **dmeshes_r, unsigned short **polys_r, int *vertsPerPoly_r, int **dtrisToPolysMap_r, int **dtrisToTrisMap_r) @@ -333,86 +333,86 @@ int buildNavMeshData(const int nverts, const float* verts, return 0; } - trisMapping = MEM_callocN(sizeof(int)*ntris, "buildNavMeshData trisMapping"); + trisMapping = MEM_callocN(sizeof(int) * ntris, "buildNavMeshData trisMapping"); - //sort the triangles by polygon idx - for (i=0; i<ntris; i++) - trisMapping[i]=i; + /* sort the triangles by polygon idx */ + for (i = 0; i < ntris; i++) + trisMapping[i] = i; context.recastData = recastData; context.trisToFacesMap = trisToFacesMap; recast_qsort(trisMapping, ntris, sizeof(int), &context, compareByData); - //search first valid triangle - triangle of convex polygon + /* search first valid triangle - triangle of convex polygon */ validTriStart = -1; - for (i=0; i< ntris; i++) { - if (recastData[trisToFacesMap[trisMapping[i]]]>0) { + for (i = 0; i < ntris; i++) { + if (recastData[trisToFacesMap[trisMapping[i]]] > 0) { validTriStart = i; break; } } - if (validTriStart<0) { + if (validTriStart < 0) { printf("Converting navmesh: Error! No valid polygons in mesh\n"); MEM_freeN(trisMapping); return 0; } - ndtris = ntris-validTriStart; - //fill dtris to faces mapping - dtrisToTrisMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToTrisMap"); - memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris*sizeof(int)); + ndtris = ntris - validTriStart; + /* fill dtris to faces mapping */ + dtrisToTrisMap = MEM_callocN(sizeof(int) * ndtris, "buildNavMeshData dtrisToTrisMap"); + memcpy(dtrisToTrisMap, &trisMapping[validTriStart], ndtris * sizeof(int)); MEM_freeN(trisMapping); - //create detailed mesh triangles - copy only valid triangles - //and reserve memory for adjacency info - dtris = MEM_callocN(sizeof(unsigned short)*3*2*ndtris, "buildNavMeshData dtris"); - memset(dtris, 0xffff, sizeof(unsigned short)*3*2*ndtris); - for (i=0; i<ndtris; i++) { - memcpy(dtris+3*2*i, tris+3*dtrisToTrisMap[i], sizeof(unsigned short)*3); + /* create detailed mesh triangles - copy only valid triangles + * and reserve memory for adjacency info */ + dtris = MEM_callocN(sizeof(unsigned short) * 3 * 2 * ndtris, "buildNavMeshData dtris"); + memset(dtris, 0xffff, sizeof(unsigned short) * 3 * 2 * ndtris); + for (i = 0; i < ndtris; i++) { + memcpy(dtris + 3 * 2 * i, tris + 3 * dtrisToTrisMap[i], sizeof(unsigned short) * 3); } - //create new recast data corresponded to dtris and renumber for continuous indices + /* create new recast data corresponded to dtris and renumber for continuous indices */ prevPolyIdx = -1; newPolyIdx = 0; - dtrisToPolysMap = MEM_callocN(sizeof(int)*ndtris, "buildNavMeshData dtrisToPolysMap"); - for (i=0; i<ndtris; i++) { + dtrisToPolysMap = MEM_callocN(sizeof(int) * ndtris, "buildNavMeshData dtrisToPolysMap"); + for (i = 0; i < ndtris; i++) { curPolyIdx = recastData[trisToFacesMap[dtrisToTrisMap[i]]]; - if (curPolyIdx!=prevPolyIdx) { + if (curPolyIdx != prevPolyIdx) { newPolyIdx++; - prevPolyIdx=curPolyIdx; + prevPolyIdx = curPolyIdx; } dtrisToPolysMap[i] = newPolyIdx; } - //build adjacency info for detailed mesh triangles + /* build adjacency info for detailed mesh triangles */ recast_buildMeshAdjacency(dtris, ndtris, nverts, 3); - //create detailed mesh description for each navigation polygon - npolys = dtrisToPolysMap[ndtris-1]; - dmeshes = MEM_callocN(sizeof(unsigned short)*npolys*4, "buildNavMeshData dmeshes"); - memset(dmeshes, 0, npolys*4*sizeof(unsigned short)); + /* create detailed mesh description for each navigation polygon */ + npolys = dtrisToPolysMap[ndtris - 1]; + dmeshes = MEM_callocN(sizeof(unsigned short) * npolys * 4, "buildNavMeshData dmeshes"); + memset(dmeshes, 0, npolys * 4 * sizeof(unsigned short)); dmesh = NULL; prevpolyidx = 0; - for (i=0; i<ndtris; i++) { + for (i = 0; i < ndtris; i++) { int curpolyidx = dtrisToPolysMap[i]; - if (curpolyidx!=prevpolyidx) { - if (curpolyidx!=prevpolyidx+1) { + if (curpolyidx != prevpolyidx) { + if (curpolyidx != prevpolyidx + 1) { printf("Converting navmesh: Error! Wrong order of detailed mesh faces\n"); return 0; } - dmesh = dmesh==NULL ? dmeshes : dmesh+4; - dmesh[2] = (unsigned short)i; //tbase - dmesh[3] = 0; //tnum + dmesh = dmesh == NULL ? dmeshes : dmesh + 4; + dmesh[2] = (unsigned short)i; /* tbase */ + dmesh[3] = 0; /* tnum */ prevpolyidx = curpolyidx; } dmesh[3]++; } - //create navigation polygons + /* create navigation polygons */ vertsPerPoly = 6; - polys = MEM_callocN(sizeof(unsigned short)*npolys*vertsPerPoly*2, "buildNavMeshData polys"); - memset(polys, 0xff, sizeof(unsigned short)*vertsPerPoly*2*npolys); + polys = MEM_callocN(sizeof(unsigned short) * npolys * vertsPerPoly * 2, "buildNavMeshData polys"); + memset(polys, 0xff, sizeof(unsigned short) * vertsPerPoly * 2 * npolys); buildPolygonsByDetailedMeshes(vertsPerPoly, npolys, polys, dmeshes, verts, dtris, dtrisToPolysMap); @@ -429,16 +429,16 @@ int buildNavMeshData(const int nverts, const float* verts, } -int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly, - int *nverts, float **verts, - int *ndtris, unsigned short **dtris, - int *npolys, unsigned short **dmeshes, - unsigned short **polys, int **dtrisToPolysMap, - int **dtrisToTrisMap, int **trisToFacesMap) +int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly, + int *nverts, float **verts, + int *ndtris, unsigned short **dtris, + int *npolys, unsigned short **dmeshes, + unsigned short **polys, int **dtrisToPolysMap, + int **dtrisToTrisMap, int **trisToFacesMap) { int res = 1; - int ntris = 0, *recastData=NULL; - unsigned short *tris=NULL; + int ntris = 0, *recastData = NULL; + unsigned short *tris = NULL; res = buildRawVertIndicesData(dm, nverts, verts, &ntris, &tris, trisToFacesMap, &recastData); if (!res) { @@ -447,8 +447,8 @@ int buildNavMeshDataByDerivedMesh(DerivedMesh *dm, int *vertsPerPoly, } res = buildNavMeshData(*nverts, *verts, ntris, tris, recastData, *trisToFacesMap, - ndtris, dtris, npolys, dmeshes, polys, vertsPerPoly, - dtrisToPolysMap, dtrisToTrisMap); + ndtris, dtris, npolys, dmeshes, polys, vertsPerPoly, + dtrisToPolysMap, dtrisToTrisMap); if (!res) { printf("Converting navmesh: Error! Can't get vertices and indices from mesh\n"); goto exit; @@ -461,11 +461,11 @@ exit: return res; } -int polyFindVertex(const unsigned short* p, const int vertsPerPoly, unsigned short vertexIdx) +int polyFindVertex(const unsigned short *p, const int vertsPerPoly, unsigned short vertexIdx) { int i, res = -1; - for (i=0; i<vertsPerPoly; i++) { - if (p[i]==0xffff) + for (i = 0; i < vertsPerPoly; i++) { + if (p[i] == 0xffff) break; if (p[i] == vertexIdx) { res = i; diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 8cede4f51a5..0ff6b7abbca 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -326,10 +326,13 @@ bNode *nodeAddNode(bNodeTree *ntree, struct bNodeTemplate *ntemp) ntype->initfunc(ntree, node, ntemp); /* initialize the node name with the node label. - * note: do this after the initfunc so nodes get - * their data set which may be used in naming + * note: do this after the initfunc so nodes get their data set which may be used in naming * (node groups for example) */ - BLI_strncpy(node->name, nodeLabel(node), NODE_MAXSTR); + /* XXX Do not use nodeLabel() here, it returns translated content, which should *only* be used + * in UI, *never* in data... + * This solution may be a bit rougher than nodeLabel()'s returned string, but it's simpler + * than adding a "no translate" flag to this func (and labelfunc() as well). */ + BLI_strncpy(node->name, node->typeinfo->name, NODE_MAXSTR); nodeUniqueName(ntree, node); ntree->update |= NTREE_UPDATE_NODES; @@ -886,7 +889,7 @@ void ntreeClearPreview(bNodeTree *ntree) /* hack warning! this function is only used for shader previews, and * since it gets called multiple times per pixel for Ztransp we only * add the color once. Preview gets cleared before it starts render though */ -void nodeAddToPreview(bNode *node, float col[4], int x, int y, int do_manage) +void nodeAddToPreview(bNode *node, const float col[4], int x, int y, int do_manage) { bNodePreview *preview = node->preview; if (preview) { @@ -1638,21 +1641,21 @@ int BKE_node_clipboard_get_type(void) /* ************** dependency stuff *********** */ /* node is guaranteed to be not checked before */ -static int node_get_deplist_recurs(bNode *node, bNode ***nsort) +static int node_get_deplist_recurs(bNodeTree *ntree, bNode *node, bNode ***nsort) { bNode *fromnode; - bNodeSocket *sock; + bNodeLink *link; int level = 0xFFF; node->done = TRUE; /* check linked nodes */ - for (sock = node->inputs.first; sock; sock = sock->next) { - if (sock->link) { - fromnode = sock->link->fromnode; + for (link = ntree->links.first; link; link = link->next) { + if (link->tonode == node) { + fromnode = link->fromnode; if (fromnode) { if (fromnode->done == 0) - fromnode->level = node_get_deplist_recurs(fromnode, nsort); + fromnode->level = node_get_deplist_recurs(ntree, fromnode, nsort); if (fromnode->level <= level) level = fromnode->level - 1; } @@ -1662,7 +1665,7 @@ static int node_get_deplist_recurs(bNode *node, bNode ***nsort) /* check parent node */ if (node->parent) { if (node->parent->done == 0) - node->parent->level = node_get_deplist_recurs(node->parent, nsort); + node->parent->level = node_get_deplist_recurs(ntree, node->parent, nsort); if (node->parent->level <= level) level = node->parent->level - 1; } @@ -1696,7 +1699,7 @@ void ntreeGetDependencyList(struct bNodeTree *ntree, struct bNode ***deplist, in /* recursive check */ for (node = ntree->nodes.first; node; node = node->next) { if (node->done == 0) { - node->level = node_get_deplist_recurs(node, &nsort); + node->level = node_get_deplist_recurs(ntree, node, &nsort); } } } @@ -1714,7 +1717,7 @@ static void ntree_update_node_level(bNodeTree *ntree) /* recursive check */ for (node = ntree->nodes.first; node; node = node->next) { if (node->done == 0) { - node->level = node_get_deplist_recurs(node, NULL); + node->level = node_get_deplist_recurs(ntree, node, NULL); } } } @@ -2243,8 +2246,10 @@ static void registerShaderNodes(bNodeTreeType *ttype) register_node_type_sh_layer_weight(ttype); register_node_type_sh_tex_coord(ttype); register_node_type_sh_particle_info(ttype); + register_node_type_sh_bump(ttype); register_node_type_sh_background(ttype); + register_node_type_sh_bsdf_anisotropic(ttype); register_node_type_sh_bsdf_diffuse(ttype); register_node_type_sh_bsdf_glossy(ttype); register_node_type_sh_bsdf_glass(ttype); diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 2e379e10c60..ff778a4b71b 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -699,8 +699,8 @@ void BKE_object_unlink(Object *ob) if (so->treestore) { TreeStoreElem *tselem = so->treestore->data; - int a; - for (a = 0; a < so->treestore->usedelem; a++, tselem++) { + int i; + for (i = 0; i < so->treestore->usedelem; i++, tselem++) { if (tselem->id == (ID *)ob) tselem->id = NULL; } } @@ -2310,11 +2310,9 @@ void BKE_object_minmax(Object *ob, float min_r[3], float max_r[3], const short u bPoseChannel *pchan; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - - if ((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE)) { - /* pass */ - } - else { + /* XXX pchan->bone may be NULL for duplicated bones, see duplicateEditBoneObjects() comment + * (editarmature.c:2592)... Skip in this case too! */ + if (pchan->bone && !((use_hidden == FALSE) && (PBONE_VISIBLE(arm, pchan->bone) == FALSE))) { mul_v3_m4v3(vec, ob->obmat, pchan->pose_head); minmax_v3v3_v3(min_r, max_r, vec); mul_v3_m4v3(vec, ob->obmat, pchan->pose_tail); diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c index 03342d0f6d1..f16748bf20a 100644 --- a/source/blender/blenkernel/intern/packedFile.c +++ b/source/blender/blenkernel/intern/packedFile.c @@ -238,7 +238,8 @@ void packAll(Main *bmain, ReportList *reports) ima->packedfile = newPackedFile(reports, ima->name, ID_BLEND_PATH(bmain, &ima->id)); } else if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) { - BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported.", ima->id.name + 2); + BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported", + ima->id.name + 2); } } } @@ -323,7 +324,7 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i if (remove_tmp) { if (ret_value == RET_ERROR) { if (BLI_rename(tempname, name) != 0) { - BKE_reportf(reports, RPT_ERROR, "Error restoring tempfile. Check files: '%s' '%s'", tempname, name); + BKE_reportf(reports, RPT_ERROR, "Error restoring temp file. Check files: '%s' '%s'", tempname, name); } } else { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index e8af794eaea..60d3b7a8846 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -48,6 +48,7 @@ #include "DNA_dynamicpaint_types.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" #include "BLI_utildefines.h" #include "BLI_kdtree.h" @@ -97,8 +98,8 @@ int count_particles(ParticleSystem *psys) int tot = 0; LOOP_SHOWN_PARTICLES { - if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ; - else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ; + if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {} + else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {} else tot++; } return tot; @@ -110,8 +111,8 @@ int count_particles_mod(ParticleSystem *psys, int totgr, int cur) int tot = 0; LOOP_SHOWN_PARTICLES { - if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ; - else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ; + if (pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) {} + else if (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) {} else if (p % totgr == cur) tot++; } return tot; @@ -1403,7 +1404,8 @@ static void interpolate_pathcache(ParticleCacheKey *first, float t, ParticleCach /************************************************/ /* interpolate a location on a face based on face coordinates */ void psys_interpolate_face(MVert *mvert, MFace *mface, MTFace *tface, float (*orcodata)[3], - float *w, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) + float w[4], float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { float *v1 = 0, *v2 = 0, *v3 = 0, *v4 = 0; float e1[3], e2[3], s1, s2, t1, t2; @@ -1746,7 +1748,9 @@ static int psys_map_index_on_dm(DerivedMesh *dm, int from, int index, int index_ } /* interprets particle data to get a point on a mesh in object space */ -void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], float orco[3], float ornor[3]) +void psys_particle_on_dm(DerivedMesh *dm, int from, int index, int index_dmcache, + const float fw[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { float tmpnor[3], mapfw[4]; float (*orcodata)[3]; @@ -1842,7 +1846,9 @@ ParticleSystemModifierData *psys_get_modifier(Object *ob, ParticleSystem *psys) /* Particles on a shape */ /************************************************/ /* ready for future use */ -static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float *UNUSED(fuv), float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), + float *UNUSED(fuv), float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { /* TODO */ float zerovec[3] = {0.0f, 0.0f, 0.0f}; @@ -1868,7 +1874,9 @@ static void psys_particle_on_shape(int UNUSED(distr), int UNUSED(index), float * /************************************************/ /* Particles on emitter */ /************************************************/ -void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, float *fuv, float foffset, float *vec, float *nor, float *utan, float *vtan, float *orco, float *ornor) +void psys_particle_on_emitter(ParticleSystemModifierData *psmd, int from, int index, int index_dmcache, + float fuv[4], float foffset, float vec[3], float nor[3], float utan[3], float vtan[3], + float orco[3], float ornor[3]) { if (psmd) { if (psmd->psys->part->distr == PART_DISTR_GRID && psmd->psys->part->from != PART_FROM_VERT) { @@ -3298,7 +3306,7 @@ void copy_particle_key(ParticleKey *to, ParticleKey *from, int time) to->time = to_time; } } -void psys_get_from_key(ParticleKey *key, float *loc, float *vel, float *rot, float *time) +void psys_get_from_key(ParticleKey *key, float loc[3], float vel[3], float rot[4], float *time) { if (loc) copy_v3_v3(loc, key->co); if (vel) copy_v3_v3(vel, key->vel); @@ -4319,7 +4327,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta if (pa) { if (!always) { if ((cfra < pa->time && (part->flag & PART_UNBORN) == 0) || - (cfra > pa->dietime && (part->flag & PART_DIED) == 0)) + (cfra >= pa->dietime && (part->flag & PART_DIED) == 0)) { return 0; } @@ -4414,7 +4422,9 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta } } -void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, float *uv, float *orco) +void psys_get_dupli_texture(ParticleSystem *psys, ParticleSettings *part, + ParticleSystemModifierData *psmd, ParticleData *pa, ChildParticle *cpa, + float uv[2], float orco[3]) { MFace *mface; MTFace *mtface; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 8c0d19ba1fd..84301972ddf 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -532,20 +532,31 @@ static int ptcache_smoke_totpoint(void *smoke_v, int UNUSED(cfra)) SmokeDomainSettings *sds = smd->domain; if (sds->fluid) { - return sds->res[0]*sds->res[1]*sds->res[2]; + return sds->base_res[0]*sds->base_res[1]*sds->base_res[2]; } else return 0; } + +#define SMOKE_CACHE_VERSION "1.04" + static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; int ret = 0; + int fluid_fields = smoke_get_data_flags(sds); + + /* version header */ + ptcache_file_write(pf, SMOKE_CACHE_VERSION, 4, sizeof(char)); + ptcache_file_write(pf, &fluid_fields, 1, sizeof(int)); + ptcache_file_write(pf, &sds->active_fields, 1, sizeof(int)); + ptcache_file_write(pf, &sds->res, 3, sizeof(int)); + ptcache_file_write(pf, &sds->dx, 1, sizeof(float)); if (sds->fluid) { size_t res = sds->res[0]*sds->res[1]*sds->res[2]; - float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold; + float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned char *out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len)*4, "pointcache_lzo_buffer"); @@ -553,22 +564,40 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) int mode=1; // light if (sds->cache_comp == SM_CACHE_HEAVY) mode=2; // heavy - smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); + smoke_export(sds->fluid, &dt, &dx, &dens, &react, &flame, &fuel, &heat, &heatold, &vx, &vy, &vz, &r, &g, &b, &obstacles); ptcache_file_compressed_write(pf, (unsigned char *)sds->shadow, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode); + if (fluid_fields & SM_ACTIVE_HEAT) { + ptcache_file_compressed_write(pf, (unsigned char *)heat, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)heatold, in_len, out, mode); + } + if (fluid_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_write(pf, (unsigned char *)flame, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)fuel, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)react, in_len, out, mode); + } + if (fluid_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_write(pf, (unsigned char *)r, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)g, in_len, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)b, in_len, out, mode); + } ptcache_file_compressed_write(pf, (unsigned char *)vx, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)vy, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)vz, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vxold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vyold, in_len, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)vzold, in_len, out, mode); ptcache_file_compressed_write(pf, (unsigned char *)obstacles, (unsigned int)res, out, mode); ptcache_file_write(pf, &dt, 1, sizeof(float)); ptcache_file_write(pf, &dx, 1, sizeof(float)); + ptcache_file_write(pf, &sds->p0, 3, sizeof(float)); + ptcache_file_write(pf, &sds->p1, 3, sizeof(float)); + ptcache_file_write(pf, &sds->dp0, 3, sizeof(float)); + ptcache_file_write(pf, &sds->shift, 3, sizeof(int)); + ptcache_file_write(pf, &sds->obj_shift_f, 3, sizeof(float)); + ptcache_file_write(pf, &sds->obmat, 16, sizeof(float)); + ptcache_file_write(pf, &sds->base_res, 3, sizeof(int)); + ptcache_file_write(pf, &sds->res_min, 3, sizeof(int)); + ptcache_file_write(pf, &sds->res_max, 3, sizeof(int)); + ptcache_file_write(pf, &sds->active_color, 3, sizeof(float)); MEM_freeN(out); @@ -579,7 +608,7 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) int res_big_array[3]; int res_big; int res = sds->res[0]*sds->res[1]*sds->res[2]; - float *dens, *densold, *tcu, *tcv, *tcw; + float *dens, *react, *fuel, *flame, *tcu, *tcv, *tcw, *r, *g, *b; unsigned int in_len = sizeof(float)*(unsigned int)res; unsigned int in_len_big; unsigned char *out; @@ -593,11 +622,20 @@ static int ptcache_smoke_write(PTCacheFile *pf, void *smoke_v) in_len_big = sizeof(float) * (unsigned int)res_big; - smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); + smoke_turbulence_export(sds->wt, &dens, &react, &flame, &fuel, &r, &g, &b, &tcu, &tcv, &tcw); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len_big), "pointcache_lzo_buffer"); ptcache_file_compressed_write(pf, (unsigned char *)dens, in_len_big, out, mode); - ptcache_file_compressed_write(pf, (unsigned char *)densold, in_len_big, out, mode); + if (fluid_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_write(pf, (unsigned char *)flame, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)fuel, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)react, in_len_big, out, mode); + } + if (fluid_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_write(pf, (unsigned char *)r, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)g, in_len_big, out, mode); + ptcache_file_compressed_write(pf, (unsigned char *)b, in_len_big, out, mode); + } MEM_freeN(out); out = (unsigned char *)MEM_callocN(LZO_OUT_LEN(in_len), "pointcache_lzo_buffer"); @@ -615,34 +653,95 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) { SmokeModifierData *smd= (SmokeModifierData *)smoke_v; SmokeDomainSettings *sds = smd->domain; + char version[4]; + int ch_res[3]; + float ch_dx; + int fluid_fields = smoke_get_data_flags(sds); + int cache_fields = 0; + int active_fields = 0; + int reallocate = 0; + + /* version header */ + ptcache_file_read(pf, version, 4, sizeof(char)); + if (strncmp(version, SMOKE_CACHE_VERSION, 4)) return 0; + /* fluid info */ + ptcache_file_read(pf, &cache_fields, 1, sizeof(int)); + ptcache_file_read(pf, &active_fields, 1, sizeof(int)); + ptcache_file_read(pf, &ch_res, 3, sizeof(int)); + ptcache_file_read(pf, &ch_dx, 1, sizeof(float)); + + /* check if resolution has changed */ + if (sds->res[0] != ch_res[0] || + sds->res[1] != ch_res[1] || + sds->res[2] != ch_res[2]) { + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) + reallocate = 1; + else + return 0; + } + /* check if active fields have changed */ + if (fluid_fields != cache_fields || + active_fields != sds->active_fields) + reallocate = 1; + + /* reallocate fluid if needed*/ + if (reallocate) { + sds->active_fields = active_fields; + smoke_reallocate_fluid(sds, ch_dx, ch_res, 1); + sds->dx = ch_dx; + VECCOPY(sds->res, ch_res); + sds->total_cells = ch_res[0]*ch_res[1]*ch_res[2]; + if(sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, ch_dx, ch_res, 1); + } + } if (sds->fluid) { size_t res = sds->res[0]*sds->res[1]*sds->res[2]; - float dt, dx, *dens, *densold, *heat, *heatold, *vx, *vy, *vz, *vxold, *vyold, *vzold; + float dt, dx, *dens, *react, *fuel, *flame, *heat, *heatold, *vx, *vy, *vz, *r, *g, *b; unsigned char *obstacles; unsigned int out_len = (unsigned int)res * sizeof(float); - smoke_export(sds->fluid, &dt, &dx, &dens, &densold, &heat, &heatold, &vx, &vy, &vz, &vxold, &vyold, &vzold, &obstacles); + smoke_export(sds->fluid, &dt, &dx, &dens, &react, &flame, &fuel, &heat, &heatold, &vx, &vy, &vz, &r, &g, &b, &obstacles); ptcache_file_compressed_read(pf, (unsigned char *)sds->shadow, out_len); ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)heat, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)heatold, out_len); + if (cache_fields & SM_ACTIVE_HEAT) { + ptcache_file_compressed_read(pf, (unsigned char*)heat, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)heatold, out_len); + } + if (cache_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_read(pf, (unsigned char*)flame, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)fuel, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)react, out_len); + } + if (cache_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_read(pf, (unsigned char*)r, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)g, out_len); + ptcache_file_compressed_read(pf, (unsigned char*)b, out_len); + } ptcache_file_compressed_read(pf, (unsigned char*)vx, out_len); ptcache_file_compressed_read(pf, (unsigned char*)vy, out_len); ptcache_file_compressed_read(pf, (unsigned char*)vz, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vxold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vyold, out_len); - ptcache_file_compressed_read(pf, (unsigned char*)vzold, out_len); ptcache_file_compressed_read(pf, (unsigned char*)obstacles, (unsigned int)res); ptcache_file_read(pf, &dt, 1, sizeof(float)); ptcache_file_read(pf, &dx, 1, sizeof(float)); - - if (pf->data_types & (1<<BPHYS_DATA_SMOKE_HIGH) && sds->wt) { + ptcache_file_read(pf, &sds->p0, 3, sizeof(float)); + ptcache_file_read(pf, &sds->p1, 3, sizeof(float)); + ptcache_file_read(pf, &sds->dp0, 3, sizeof(float)); + ptcache_file_read(pf, &sds->shift, 3, sizeof(int)); + ptcache_file_read(pf, &sds->obj_shift_f, 3, sizeof(float)); + ptcache_file_read(pf, &sds->obmat, 16, sizeof(float)); + ptcache_file_read(pf, &sds->base_res, 3, sizeof(int)); + ptcache_file_read(pf, &sds->res_min, 3, sizeof(int)); + ptcache_file_read(pf, &sds->res_max, 3, sizeof(int)); + ptcache_file_read(pf, &sds->active_color, 3, sizeof(float)); + } + + if (pf->data_types & (1<<BPHYS_DATA_SMOKE_HIGH) && sds->wt) { int res = sds->res[0]*sds->res[1]*sds->res[2]; int res_big, res_big_array[3]; - float *dens, *densold, *tcu, *tcv, *tcw; + float *dens, *react, *fuel, *flame, *tcu, *tcv, *tcw, *r, *g, *b; unsigned int out_len = sizeof(float)*(unsigned int)res; unsigned int out_len_big; @@ -650,16 +749,23 @@ static int ptcache_smoke_read(PTCacheFile *pf, void *smoke_v) res_big = res_big_array[0]*res_big_array[1]*res_big_array[2]; out_len_big = sizeof(float) * (unsigned int)res_big; - smoke_turbulence_export(sds->wt, &dens, &densold, &tcu, &tcv, &tcw); + smoke_turbulence_export(sds->wt, &dens, &react, &flame, &fuel, &r, &g, &b, &tcu, &tcv, &tcw); ptcache_file_compressed_read(pf, (unsigned char*)dens, out_len_big); - ptcache_file_compressed_read(pf, (unsigned char*)densold, out_len_big); + if (cache_fields & SM_ACTIVE_FIRE) { + ptcache_file_compressed_read(pf, (unsigned char*)flame, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)fuel, out_len_big); + } + if (cache_fields & SM_ACTIVE_COLORS) { + ptcache_file_compressed_read(pf, (unsigned char*)r, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)g, out_len_big); + ptcache_file_compressed_read(pf, (unsigned char*)b, out_len_big); + } ptcache_file_compressed_read(pf, (unsigned char*)tcu, out_len); ptcache_file_compressed_read(pf, (unsigned char*)tcv, out_len); ptcache_file_compressed_read(pf, (unsigned char*)tcw, out_len); } - } return 1; } @@ -2466,10 +2572,10 @@ int BKE_ptcache_id_reset(Scene *scene, PTCacheID *pid, int mode) sbFreeSimulation(pid->calldata); else if (pid->type == PTCACHE_TYPE_PARTICLES) psys_reset(pid->calldata, PSYS_RESET_DEPSGRAPH); - else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) + /*else if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) smokeModifier_reset(pid->calldata); else if (pid->type == PTCACHE_TYPE_SMOKE_HIGHRES) - smokeModifier_reset_turbulence(pid->calldata); + smokeModifier_reset_turbulence(pid->calldata);*/ else if (pid->type == PTCACHE_TYPE_DYNAMICPAINT) dynamicPaint_clearSurface((DynamicPaintSurface*)pid->calldata); } @@ -3222,8 +3328,9 @@ void BKE_ptcache_load_external(PTCacheID *pid) cache->endframe = end; cache->totpoint = 0; - if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) - ; /*necessary info in every file*/ + if (pid->type == PTCACHE_TYPE_SMOKE_DOMAIN) { + /* necessary info in every file */ + } /* read totpoint from info file (frame 0) */ else if (info) { pf= ptcache_file_open(pid, PTCACHE_FILE_READ, 0); diff --git a/source/blender/blenkernel/intern/report.c b/source/blender/blenkernel/intern/report.c index 3a66ec23412..d925d736358 100644 --- a/source/blender/blenkernel/intern/report.c +++ b/source/blender/blenkernel/intern/report.c @@ -34,6 +34,8 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "BKE_report.h" #include "BKE_global.h" /* G.background only */ @@ -44,15 +46,24 @@ static const char *report_type_str(int type) { switch (type) { - case RPT_DEBUG: return "Debug"; - case RPT_INFO: return "Info"; - case RPT_OPERATOR: return "Operator"; - case RPT_WARNING: return "Warning"; - case RPT_ERROR: return "Error"; - case RPT_ERROR_INVALID_INPUT: return "Invalid Input Error"; - case RPT_ERROR_INVALID_CONTEXT: return "Invalid Context Error"; - case RPT_ERROR_OUT_OF_MEMORY: return "Out Of Memory Error"; - default: return "Undefined Type"; + case RPT_DEBUG: + return TIP_("Debug"); + case RPT_INFO: + return TIP_("Info"); + case RPT_OPERATOR: + return TIP_("Operator"); + case RPT_WARNING: + return TIP_("Warning"); + case RPT_ERROR: + return TIP_("Error"); + case RPT_ERROR_INVALID_INPUT: + return TIP_("Invalid Input Error"); + case RPT_ERROR_INVALID_CONTEXT: + return TIP_("Invalid Context Error"); + case RPT_ERROR_OUT_OF_MEMORY: + return TIP_("Out Of Memory Error"); + default: + return TIP_("Undefined Type"); } } @@ -87,10 +98,11 @@ void BKE_reports_clear(ReportList *reports) reports->list.first = reports->list.last = NULL; } -void BKE_report(ReportList *reports, ReportType type, const char *message) +void BKE_report(ReportList *reports, ReportType type, const char *_message) { Report *report; int len; + const char *message = TIP_(_message); /* in background mode always print otherwise there are cases the errors wont be displayed, * but still add to the report list since this is used for python exception handling */ @@ -114,14 +126,16 @@ void BKE_report(ReportList *reports, ReportType type, const char *message) } } -void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) +void BKE_reportf(ReportList *reports, ReportType type, const char *_format, ...) { DynStr *ds; Report *report; va_list args; + const char *format = TIP_(_format); if (G.background || !reports || ((reports->flag & RPT_PRINT) && (type >= reports->printlevel))) { - va_start(args, format); + printf("%s: ", report_type_str(type)); + va_start(args, _format); vprintf(format, args); va_end(args); fprintf(stdout, "\n"); /* otherise each report needs to include a \n */ @@ -132,7 +146,7 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) report = MEM_callocN(sizeof(Report), "Report"); ds = BLI_dynstr_new(); - va_start(args, format); + va_start(args, _format); BLI_dynstr_vappendf(ds, format, args); va_end(args); @@ -147,10 +161,11 @@ void BKE_reportf(ReportList *reports, ReportType type, const char *format, ...) } } -void BKE_reports_prepend(ReportList *reports, const char *prepend) +void BKE_reports_prepend(ReportList *reports, const char *_prepend) { Report *report; DynStr *ds; + const char *prepend = TIP_(_prepend); if (!reports) return; @@ -169,18 +184,19 @@ void BKE_reports_prepend(ReportList *reports, const char *prepend) } } -void BKE_reports_prependf(ReportList *reports, const char *prepend, ...) +void BKE_reports_prependf(ReportList *reports, const char *_prepend, ...) { Report *report; DynStr *ds; va_list args; + const char *prepend = TIP_(_prepend); if (!reports) return; for (report = reports->list.first; report; report = report->next) { ds = BLI_dynstr_new(); - va_start(args, prepend); + va_start(args, _prepend); BLI_dynstr_vappendf(ds, prepend, args); va_end(args); diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c index b519a59b6d6..628a251ed26 100644 --- a/source/blender/blenkernel/intern/scene.c +++ b/source/blender/blenkernel/intern/scene.c @@ -54,6 +54,7 @@ #include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_callbacks.h" +#include "BLI_string.h" #include "BKE_anim.h" #include "BKE_animsys.h" @@ -177,6 +178,9 @@ Scene *BKE_scene_copy(Scene *sce, int type) BKE_color_managed_display_settings_copy(&scen->display_settings, &sce->display_settings); BKE_color_managed_view_settings_copy(&scen->view_settings, &sce->view_settings); BKE_color_managed_view_settings_copy(&scen->r.im_format.view_settings, &sce->r.im_format.view_settings); + + BLI_strncpy(scen->sequencer_colorspace_settings.name, sce->sequencer_colorspace_settings.name, + sizeof(scen->sequencer_colorspace_settings.name)); } /* tool settings */ @@ -357,6 +361,7 @@ Scene *BKE_scene_add(const char *name) Scene *sce; ParticleEditSettings *pset; int a; + const char *colorspace_name; sce = BKE_libblock_alloc(&bmain->scene, ID_SCE, name); sce->lay = sce->layact = 1; @@ -448,6 +453,7 @@ Scene *BKE_scene_add(const char *name) sce->toolsettings->uvcalc_cubesize = 1.0f; sce->toolsettings->uvcalc_mapdir = 1; sce->toolsettings->uvcalc_mapalign = 1; + sce->toolsettings->uvcalc_margin = 0.001f; sce->toolsettings->unwrapper = 1; sce->toolsettings->select_thresh = 0.01f; sce->toolsettings->jointrilimit = 0.8f; @@ -570,8 +576,13 @@ Scene *BKE_scene_add(const char *name) sound_create_scene(sce); + /* color management */ + colorspace_name = IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_SEQUENCER); + BKE_color_managed_display_settings_init(&sce->display_settings); BKE_color_managed_view_settings_init(&sce->view_settings); + BLI_strncpy(sce->sequencer_colorspace_settings.name, colorspace_name, + sizeof(sce->sequencer_colorspace_settings.name)); return sce; } diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c index 90c3347a1df..49ed7f80be3 100644 --- a/source/blender/blenkernel/intern/sequencer.c +++ b/source/blender/blenkernel/intern/sequencer.c @@ -1965,13 +1965,16 @@ static ImBuf *copy_from_ibuf_still(SeqRenderData context, Sequence *seq, float n static void copy_to_ibuf_still(SeqRenderData context, Sequence *seq, float nr, ImBuf *ibuf) { + /* warning: ibuf may be NULL if the video fails to load */ if (nr == 0 || nr == seq->len - 1) { /* we have to store a copy, since the passed ibuf * could be preprocessed afterwards (thereby silently * changing the cached image... */ ibuf = IMB_dupImBuf(ibuf); - sequencer_imbuf_assign_spaces(context.scene, ibuf); + if (ibuf) { + sequencer_imbuf_assign_spaces(context.scene, ibuf); + } if (nr == 0) { BKE_sequencer_cache_put(context, seq, seq->start, SEQ_STRIPELEM_IBUF_STARTSTILL, ibuf); diff --git a/source/blender/blenkernel/intern/smoke.c b/source/blender/blenkernel/intern/smoke.c index 5e67e094e43..c8d6ec73d28 100644 --- a/source/blender/blenkernel/intern/smoke.c +++ b/source/blender/blenkernel/intern/smoke.c @@ -51,18 +51,7 @@ #include "BLI_kdtree.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" - -#include "BKE_bvhutils.h" -#include "BKE_cdderivedmesh.h" -#include "BKE_collision.h" -#include "BKE_customdata.h" -#include "BKE_DerivedMesh.h" -#include "BKE_effect.h" -#include "BKE_modifier.h" -#include "BKE_particle.h" -#include "BKE_pointcache.h" -#include "BKE_smoke.h" - +#include "BLI_voxel.h" #include "DNA_customdata_types.h" #include "DNA_group_types.h" @@ -75,8 +64,20 @@ #include "DNA_scene_types.h" #include "DNA_smoke_types.h" +#include "BKE_bvhutils.h" +#include "BKE_cdderivedmesh.h" +#include "BKE_collision.h" +#include "BKE_customdata.h" +#include "BKE_deform.h" +#include "BKE_DerivedMesh.h" +#include "BKE_effect.h" +#include "BKE_modifier.h" +#include "BKE_particle.h" +#include "BKE_pointcache.h" #include "BKE_smoke.h" +#include "RE_shader_ext.h" + /* UNUSED so far, may be enabled later */ /* #define USE_SMOKE_COLLISION_DM */ @@ -94,38 +95,38 @@ static LARGE_INTEGER liFrequency; static LARGE_INTEGER liStartTime; static LARGE_INTEGER liCurrentTime; -static void tstart ( void ) +static void tstart(void) { - QueryPerformanceFrequency ( &liFrequency ); - QueryPerformanceCounter ( &liStartTime ); + QueryPerformanceFrequency(&liFrequency); + QueryPerformanceCounter(&liStartTime); } -static void tend ( void ) +static void tend(void) { - QueryPerformanceCounter ( &liCurrentTime ); + QueryPerformanceCounter(&liCurrentTime); } -static double UNUSED_FUNCTION(tval)( void ) +static double tval(void) { - return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart)* (double)1000.0/(double)liFrequency.QuadPart )); + return ((double)( (liCurrentTime.QuadPart - liStartTime.QuadPart) * (double)1000.0 / (double)liFrequency.QuadPart)); } #else #include <sys/time.h> static struct timeval _tstart, _tend; static struct timezone tz; -static void tstart ( void ) +static void tstart(void) { - gettimeofday ( &_tstart, &tz ); + gettimeofday(&_tstart, &tz); } -static void tend ( void ) +static void tend(void) { - gettimeofday ( &_tend,&tz ); + gettimeofday(&_tend, &tz); } -static double UNUSED_FUNCTION(tval)( void ) +static double UNUSED_FUNCTION(tval) (void) { double t1, t2; - t1 = ( double ) _tstart.tv_sec*1000 + ( double ) _tstart.tv_usec/ ( 1000 ); - t2 = ( double ) _tend.tv_sec*1000 + ( double ) _tend.tv_usec/ ( 1000 ); - return t2-t1; + t1 = ( double ) _tstart.tv_sec * 1000 + ( double ) _tstart.tv_usec / (1000); + t2 = ( double ) _tend.tv_sec * 1000 + ( double ) _tend.tv_usec / (1000); + return t2 - t1; } #endif @@ -134,608 +135,238 @@ struct Scene; struct DerivedMesh; struct SmokeModifierData; -#define TRI_UVOFFSET (1./4.) - // timestep default value for nice appearance 0.1f #define DT_DEFAULT 0.1f -/* forward declerations */ -static void calcTriangleDivs(Object *ob, MVert *verts, int numverts, MFace *tris, int numfaces, int numtris, int **tridivs, float cell_len); -static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct); -static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs); +#define ADD_IF_LOWER_POS(a, b) (MIN2((a) + (b), MAX2((a), (b)))) +#define ADD_IF_LOWER_NEG(a, b) (MAX2((a) + (b), MIN2((a), (b)))) +#define ADD_IF_LOWER(a, b) (((b) > 0) ? ADD_IF_LOWER_POS((a), (b)) : ADD_IF_LOWER_NEG((a), (b))) #else /* WITH_SMOKE */ /* Stubs to use when smoke is disabled */ -struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype)) { return NULL; } -// struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(p0)) { return NULL; } +struct WTURBULENCE *smoke_turbulence_init(int *UNUSED(res), int UNUSED(amplify), int UNUSED(noisetype), int UNUSED(use_fire), int UNUSED(use_colors)) { return NULL; } +//struct FLUID_3D *smoke_init(int *UNUSED(res), float *UNUSED(dx), float *UNUSED(dtdef), int UNUSED(use_heat), int UNUSED(use_fire), int UNUSED(use_colors)) { return NULL; } void smoke_free(struct FLUID_3D *UNUSED(fluid)) {} float *smoke_get_density(struct FLUID_3D *UNUSED(fluid)) { return NULL; } void smoke_turbulence_free(struct WTURBULENCE *UNUSED(wt)) {} void smoke_initWaveletBlenderRNA(struct WTURBULENCE *UNUSED(wt), float *UNUSED(strength)) {} -void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), int *UNUSED(border_colli)) {} -long long smoke_get_mem_req(int UNUSED(xres), int UNUSED(yres), int UNUSED(zres), int UNUSED(amplify)) { return 0; } -void smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) {} +void smoke_initBlenderRNA(struct FLUID_3D *UNUSED(fluid), float *UNUSED(alpha), float *UNUSED(beta), float *UNUSED(dt_factor), float *UNUSED(vorticity), + int *UNUSED(border_colli), float *UNUSED(burning_rate), float *UNUSED(flame_smoke), float *UNUSED(flame_smoke_color), + float *UNUSED(flame_vorticity), float *UNUSED(flame_ignition_temp), float *UNUSED(flame_max_temp)) {} +struct DerivedMesh *smokeModifier_do(SmokeModifierData *UNUSED(smd), Scene *UNUSED(scene), Object *UNUSED(ob), DerivedMesh *UNUSED(dm)) { return NULL; } +float smoke_get_velocity_at(struct Object *UNUSED(ob), float UNUSED(position[3]), float UNUSED(velocity[3])) { return 0.0f; } +void flame_get_spectrum(unsigned char *UNUSED(spec), int UNUSED(width), float UNUSED(t1), float UNUSED(t2)) {} #endif /* WITH_SMOKE */ #ifdef WITH_SMOKE -static int smokeModifier_init (SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) +void smoke_reallocate_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { - if((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) - { - size_t i; - float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; - float size[3]; - MVert *verts = dm->getVertArray(dm); - float scale = 0.0; - int res; - - res = smd->domain->maxres; - - // get BB of domain - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmp[3]; - - copy_v3_v3(tmp, verts[i].co); - mul_m4_v3(ob->obmat, tmp); - - // min BB - min[0] = MIN2(min[0], tmp[0]); - min[1] = MIN2(min[1], tmp[1]); - min[2] = MIN2(min[2], tmp[2]); - - // max BB - max[0] = MAX2(max[0], tmp[0]); - max[1] = MAX2(max[1], tmp[1]); - max[2] = MAX2(max[2], tmp[2]); - } - - copy_v3_v3(smd->domain->p0, min); - copy_v3_v3(smd->domain->p1, max); - - // calc other res with max_res provided - sub_v3_v3v3(size, max, min); - - // prevent crash when initializing a plane as domain - if((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) - return 0; - - if(size[0] > size[1]) - { - if(size[0] > size[2]) - { - scale = res / size[0]; - smd->domain->scale = size[0]; - smd->domain->dx = 1.0f / res; - smd->domain->res[0] = res; - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - smd->domain->res[2] = (int)(size[2] * scale + 0.5); - } - else { - scale = res / size[2]; - smd->domain->scale = size[2]; - smd->domain->dx = 1.0f / res; - smd->domain->res[2] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - } - } - else { - if(size[1] > size[2]) - { - scale = res / size[1]; - smd->domain->scale = size[1]; - smd->domain->dx = 1.0f / res; - smd->domain->res[1] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[2] = (int)(size[2] * scale + 0.5); - } - else { - scale = res / size[2]; - smd->domain->scale = size[2]; - smd->domain->dx = 1.0f / res; - smd->domain->res[2] = res; - smd->domain->res[0] = (int)(size[0] * scale + 0.5); - smd->domain->res[1] = (int)(size[1] * scale + 0.5); - } - } - - // TODO: put in failsafe if res<=0 - dg - - // dt max is 0.1 - smd->domain->fluid = smoke_init(smd->domain->res, smd->domain->p0, DT_DEFAULT); - smd->time = scene->r.cfra; - - if(smd->domain->flags & MOD_SMOKE_HIGHRES) - { - smd->domain->wt = smoke_turbulence_init(smd->domain->res, smd->domain->amplify + 1, smd->domain->noise); - smd->domain->res_wt[0] = smd->domain->res[0] * (smd->domain->amplify + 1); - smd->domain->res_wt[1] = smd->domain->res[1] * (smd->domain->amplify + 1); - smd->domain->res_wt[2] = smd->domain->res[2] * (smd->domain->amplify + 1); - smd->domain->dx_wt = smd->domain->dx / (smd->domain->amplify + 1); - } - - if(!smd->domain->shadow) - smd->domain->shadow = MEM_callocN(sizeof(float) * smd->domain->res[0] * smd->domain->res[1] * smd->domain->res[2], "SmokeDomainShadow"); - - smoke_initBlenderRNA(smd->domain->fluid, &(smd->domain->alpha), &(smd->domain->beta), &(smd->domain->time_scale), &(smd->domain->vorticity), &(smd->domain->border_collisions)); - - if(smd->domain->wt) - { - smoke_initWaveletBlenderRNA(smd->domain->wt, &(smd->domain->strength)); - } - return 1; - } - else if((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) - { - // handle flow object here - // XXX TODO - - smd->time = scene->r.cfra; - - return 1; - } - else if((smd->type & MOD_SMOKE_TYPE_COLL)) - { - // todo: delete this when loading colls work -dg - - if(!smd->coll) - { - smokeModifier_createType(smd); - } - - if(!smd->coll->points) - { - // init collision points - SmokeCollSettings *scs = smd->coll; - - smd->time = scene->r.cfra; - - // copy obmat - copy_m4_m4(scs->mat, ob->obmat); - copy_m4_m4(scs->mat_old, ob->obmat); - - DM_ensure_tessface(dm); - fill_scs_points(ob, dm, scs); - } - - if(!smd->coll->bvhtree) - { - smd->coll->bvhtree = NULL; // bvhtree_build_from_smoke ( ob->obmat, dm->getTessFaceArray(dm), dm->getNumTessFaces(dm), dm->getVertArray(dm), dm->getNumVerts(dm), 0.0 ); - } - return 1; + int use_heat = (sds->active_fields & SM_ACTIVE_HEAT); + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); + int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); + + if (free_old && sds->fluid) + smoke_free(sds->fluid); + if (!MIN3(res[0], res[1], res[2])) { + sds->fluid = NULL; + return; } - - return 2; + sds->fluid = smoke_init(res, dx, DT_DEFAULT, use_heat, use_fire, use_colors); + smoke_initBlenderRNA(sds->fluid, &(sds->alpha), &(sds->beta), &(sds->time_scale), &(sds->vorticity), &(sds->border_collisions), + &(sds->burning_rate), &(sds->flame_smoke), sds->flame_smoke_color, &(sds->flame_vorticity), &(sds->flame_ignition), &(sds->flame_max_temp)); + + /* reallocate shadow buffer */ + if (sds->shadow) + MEM_freeN(sds->shadow); + sds->shadow = MEM_callocN(sizeof(float) * res[0] * res[1] * res[2], "SmokeDomainShadow"); } -static void fill_scs_points(Object *ob, DerivedMesh *dm, SmokeCollSettings *scs) +void smoke_reallocate_highres_fluid(SmokeDomainSettings *sds, float dx, int res[3], int free_old) { - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int i = 0, divs = 0; - - // DG TODO: need to do this dynamically according to the domain object! - float cell_len = scs->dx; - int newdivs = 0; - int quads = 0, facecounter = 0; + int use_fire = (sds->active_fields & (SM_ACTIVE_HEAT | SM_ACTIVE_FIRE)); + int use_colors = (sds->active_fields & SM_ACTIVE_COLORS); - // count quads - for(i = 0; i < dm->getNumTessFaces(dm); i++) - { - if(mface[i].v4) - quads++; + if (free_old && sds->wt) + smoke_turbulence_free(sds->wt); + if (!MIN3(res[0], res[1], res[2])) { + sds->wt = NULL; + return; } + sds->wt = smoke_turbulence_init(res, sds->amplify + 1, sds->noise, use_fire, use_colors); + sds->res_wt[0] = res[0] * (sds->amplify + 1); + sds->res_wt[1] = res[1] * (sds->amplify + 1); + sds->res_wt[2] = res[2] * (sds->amplify + 1); + sds->dx_wt = dx / (sds->amplify + 1); + smoke_initWaveletBlenderRNA(sds->wt, &(sds->strength)); +} - scs->numtris = dm->getNumTessFaces(dm) + quads; - scs->tridivs = NULL; - calcTriangleDivs(ob, mvert, dm->getNumVerts(dm), mface, dm->getNumTessFaces(dm), scs->numtris, &(scs->tridivs), cell_len); +/* convert global position to domain cell space */ +static void smoke_pos_to_cell(SmokeDomainSettings *sds, float pos[3]) +{ + mul_m4_v3(sds->imat, pos); + sub_v3_v3(pos, sds->p0); + pos[0] *= 1.0f / sds->cell_size[0]; + pos[1] *= 1.0f / sds->cell_size[1]; + pos[2] *= 1.0f / sds->cell_size[2]; +} - // count triangle divisions - for(i = 0; i < dm->getNumTessFaces(dm) + quads; i++) - { - divs += (scs->tridivs[3 * i] + 1) * (scs->tridivs[3 * i + 1] + 1) * (scs->tridivs[3 * i + 2] + 1); - } +/* set domain resolution and dimensions from object derivedmesh */ +static void smoke_set_domain_from_derivedmesh(SmokeDomainSettings *sds, Object *ob, DerivedMesh *dm) +{ + size_t i; + float min[3] = {FLT_MAX, FLT_MAX, FLT_MAX}, max[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX}; + float size[3]; + MVert *verts = dm->getVertArray(dm); + float scale = 0.0; + int res; - scs->points = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPoints"); - scs->points_old = MEM_callocN(sizeof(float) * (dm->getNumVerts(dm) + divs) * 3, "SmokeCollPointsOld"); + res = sds->maxres; - for(i = 0; i < dm->getNumVerts(dm); i++) + // get BB of domain + for (i = 0; i < dm->getNumVerts(dm); i++) { - float tmpvec[3]; - copy_v3_v3(tmpvec, mvert[i].co); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[i * 3], tmpvec); + // min BB + min[0] = MIN2(min[0], verts[i].co[0]); + min[1] = MIN2(min[1], verts[i].co[1]); + min[2] = MIN2(min[2], verts[i].co[2]); + + // max BB + max[0] = MAX2(max[0], verts[i].co[0]); + max[1] = MAX2(max[1], verts[i].co[1]); + max[2] = MAX2(max[2], verts[i].co[2]); } - - for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++) - { - int again = 0; - do - { - int j, k; - int divs1 = scs->tridivs[3 * facecounter + 0]; - int divs2 = scs->tridivs[3 * facecounter + 1]; - //int divs3 = scs->tridivs[3 * facecounter + 2]; - float side1[3], side2[3], trinormorg[3], trinorm[3]; - - if(again == 1 && mface[i].v4) - { - sub_v3_v3v3(side1, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - sub_v3_v3v3(side2, mvert[ mface[i].v4 ].co, mvert[ mface[i].v1 ].co); - } - else { - sub_v3_v3v3(side1, mvert[ mface[i].v2 ].co, mvert[ mface[i].v1 ].co); - sub_v3_v3v3(side2, mvert[ mface[i].v3 ].co, mvert[ mface[i].v1 ].co); - } - cross_v3_v3v3(trinormorg, side1, side2); - normalize_v3(trinormorg); - copy_v3_v3(trinorm, trinormorg); - mul_v3_fl(trinorm, 0.25 * cell_len); + /* set domain bounds */ + copy_v3_v3(sds->p0, min); + copy_v3_v3(sds->p1, max); + sds->dx = 1.0f / res; - for(j = 0; j <= divs1; j++) - { - for(k = 0; k <= divs2; k++) - { - float p1[3], p2[3], p3[3], p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } + /* calculate domain dimensions */ + sub_v3_v3v3(size, max, min); + copy_v3_v3(sds->cell_size, size); + mul_v3_v3(size, ob->size); + copy_v3_v3(sds->global_size, size); + copy_v3_v3(sds->dp0, min); - copy_v3_v3(p1, mvert[ mface[i].v1 ].co); - if(again == 1 && mface[i].v4) - { - copy_v3_v3(p2, mvert[ mface[i].v3 ].co); - copy_v3_v3(p3, mvert[ mface[i].v4 ].co); - } - else { - copy_v3_v3(p2, mvert[ mface[i].v2 ].co); - copy_v3_v3(p3, mvert[ mface[i].v3 ].co); - } + invert_m4_m4(sds->imat, ob->obmat); - mul_v3_fl(p1, (1.0-uf-vf)); - mul_v3_fl(p2, uf); - mul_v3_fl(p3, vf); - - add_v3_v3v3(p, p1, p2); - add_v3_v3(p, p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - add_v3_v3v3(tmpvec, p, trinorm); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - copy_v3_v3(tmpvec, p); - sub_v3_v3(tmpvec, trinorm); - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], tmpvec); - newdivs++; - } - } - - if(again == 0 && mface[i].v4) - again++; - else - again = 0; - - facecounter++; + // prevent crash when initializing a plane as domain + if ((size[0] < FLT_EPSILON) || (size[1] < FLT_EPSILON) || (size[2] < FLT_EPSILON)) + return; - } while(again!=0); + /* define grid resolutions from longest domain side */ + if (size[0] > MAX2(size[1], size[2])) { + scale = res / size[0]; + sds->scale = size[0] / ob->size[0]; + sds->base_res[0] = res; + sds->base_res[1] = (int)(size[1] * scale + 0.5); + sds->base_res[2] = (int)(size[2] * scale + 0.5); } - - scs->numverts = dm->getNumVerts(dm); - // DG TODO: also save triangle count? - - scs->numpoints = dm->getNumVerts(dm) + newdivs; - - for(i = 0; i < scs->numpoints * 3; i++) - { - scs->points_old[i] = scs->points[i]; + else if (size[1] > MAX2(size[0], size[2])) { + scale = res / size[1]; + sds->scale = size[1] / ob->size[1]; + sds->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[1] = res; + sds->base_res[2] = (int)(size[2] * scale + 0.5); + } + else { + scale = res / size[2]; + sds->scale = size[2] / ob->size[2]; + sds->base_res[0] = (int)(size[0] * scale + 0.5); + sds->base_res[1] = (int)(size[1] * scale + 0.5); + sds->base_res[2] = res; } -} + /* set cell size */ + sds->cell_size[0] /= (float)sds->base_res[0]; + sds->cell_size[1] /= (float)sds->base_res[1]; + sds->cell_size[2] /= (float)sds->base_res[2]; +} -static void fill_scs_points_anim(Object *UNUSED(ob), DerivedMesh *dm, SmokeCollSettings *scs) +static int smokeModifier_init(SmokeModifierData *smd, Object *ob, Scene *scene, DerivedMesh *dm) { - MVert *mvert = dm->getVertArray(dm); - MFace *mface = dm->getTessFaceArray(dm); - int quads = 0, numtris = 0, facecounter = 0; - unsigned int i = 0; - int divs = 0, newdivs = 0; - - // DG TODO: need to do this dynamically according to the domain object! - float cell_len = scs->dx; - - // count quads - for(i = 0; i < dm->getNumTessFaces(dm); i++) + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && !smd->domain->fluid) { - if(mface[i].v4) - quads++; - } + SmokeDomainSettings *sds = smd->domain; + int res[3]; + /* set domain dimensions from derivedmesh */ + smoke_set_domain_from_derivedmesh(sds, ob, dm); + /* reset domain values */ + zero_v3_int(sds->shift); + zero_v3(sds->shift_f); + add_v3_fl(sds->shift_f, 0.5f); + zero_v3(sds->prev_loc); + mul_m4_v3(ob->obmat, sds->prev_loc); + + /* set resolutions */ + if (smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + res[0] = res[1] = res[2] = 1; /* use minimum res for adaptive init */ + } + else { + VECCOPY(res, sds->base_res); + } + VECCOPY(sds->res, res); + sds->total_cells = sds->res[0] * sds->res[1] * sds->res[2]; + sds->res_min[0] = sds->res_min[1] = sds->res_min[2] = 0; + VECCOPY(sds->res_max, res); - numtris = dm->getNumTessFaces(dm) + quads; + /* allocate fluid */ + smoke_reallocate_fluid(sds, sds->dx, sds->res, 0); - // check if mesh changed topology - if(scs->numtris != numtris) - return; - if(scs->numverts != dm->getNumVerts(dm)) - return; + smd->time = scene->r.cfra; - // update new positions - for(i = 0; i < dm->getNumVerts(dm); i++) - { - float tmpvec[3]; - copy_v3_v3(tmpvec, mvert[i].co); - copy_v3_v3(&scs->points[i * 3], tmpvec); - } + /* allocate highres fluid */ + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, sds->dx, sds->res, 0); + } + /* allocate shadow buffer */ + if (!sds->shadow) + sds->shadow = MEM_callocN(sizeof(float) * sds->res[0] * sds->res[1] * sds->res[2], "SmokeDomainShadow"); - // for every triangle // update div points - for(i = 0, facecounter = 0; i < dm->getNumTessFaces(dm); i++) + return 1; + } + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { - int again = 0; - do - { - int j, k; - int divs1 = scs->tridivs[3 * facecounter + 0]; - int divs2 = scs->tridivs[3 * facecounter + 1]; - float srcside1[3], srcside2[3], destside1[3], destside2[3], src_trinormorg[3], dest_trinormorg[3], src_trinorm[3], dest_trinorm[3]; - - if(again == 1 && mface[i].v4) - { - sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside1, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]); - - sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v4 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside2, &scs->points[mface[i].v4 * 3], &scs->points[mface[i].v1 * 3]); - } - else { - sub_v3_v3v3(srcside1, &scs->points_old[mface[i].v2 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside1, &scs->points[mface[i].v2 * 3], &scs->points[mface[i].v1 * 3]); - - sub_v3_v3v3(srcside2, &scs->points_old[mface[i].v3 * 3], &scs->points_old[mface[i].v1 * 3]); - sub_v3_v3v3(destside2, &scs->points[mface[i].v3 * 3], &scs->points[mface[i].v1 * 3]); - } - - cross_v3_v3v3(src_trinormorg, srcside1, srcside2); - cross_v3_v3v3(dest_trinormorg, destside1, destside2); - - normalize_v3(src_trinormorg); - normalize_v3(dest_trinormorg); - - copy_v3_v3(src_trinorm, src_trinormorg); - copy_v3_v3(dest_trinorm, dest_trinormorg); - - mul_v3_fl(src_trinorm, 0.25 * cell_len); - mul_v3_fl(dest_trinorm, 0.25 * cell_len); - - for(j = 0; j <= divs1; j++) - { - for(k = 0; k <= divs2; k++) - { - float src_p1[3], src_p2[3], src_p3[3], src_p[3]={0,0,0}; - float dest_p1[3], dest_p2[3], dest_p3[3], dest_p[3]={0,0,0}; - const float uf = (float)(j + TRI_UVOFFSET) / (float)(divs1 + 0.0); - const float vf = (float)(k + TRI_UVOFFSET) / (float)(divs2 + 0.0); - float src_tmpvec[3], dest_tmpvec[3]; - - if(uf+vf > 1.0) - { - // printf("bigger - divs1: %d, divs2: %d\n", divs1, divs2); - continue; - } - - copy_v3_v3(src_p1, &scs->points_old[mface[i].v1 * 3]); - copy_v3_v3(dest_p1, &scs->points[mface[i].v1 * 3]); - if(again == 1 && mface[i].v4) - { - copy_v3_v3(src_p2, &scs->points_old[mface[i].v3 * 3]); - copy_v3_v3(dest_p2, &scs->points[mface[i].v3 * 3]); - - copy_v3_v3(src_p3,&scs->points_old[mface[i].v4 * 3]); - copy_v3_v3(dest_p3, &scs->points[mface[i].v4 * 3]); - } - else { - copy_v3_v3(src_p2, &scs->points_old[mface[i].v2 * 3]); - copy_v3_v3(dest_p2, &scs->points[mface[i].v2 * 3]); - copy_v3_v3(src_p3, &scs->points_old[mface[i].v3 * 3]); - copy_v3_v3(dest_p3, &scs->points[mface[i].v3 * 3]); - } - - mul_v3_fl(src_p1, (1.0-uf-vf)); - mul_v3_fl(dest_p1, (1.0-uf-vf)); - - mul_v3_fl(src_p2, uf); - mul_v3_fl(dest_p2, uf); - - mul_v3_fl(src_p3, vf); - mul_v3_fl(dest_p3, vf); - - add_v3_v3v3(src_p, src_p1, src_p2); - add_v3_v3v3(dest_p, dest_p1, dest_p2); - - add_v3_v3(src_p, src_p3); - add_v3_v3(dest_p, dest_p3); - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p + trinorm); - add_v3_v3v3(src_tmpvec, src_p, src_trinorm); - add_v3_v3v3(dest_tmpvec, dest_p, dest_trinorm); - - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec); - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec); - newdivs++; - - if(newdivs > divs) - printf("mem problem\n"); - - // mMovPoints.push_back(p - trinorm); - copy_v3_v3(src_tmpvec, src_p); - copy_v3_v3(dest_tmpvec, dest_p); - - sub_v3_v3(src_tmpvec, src_trinorm); - sub_v3_v3(dest_tmpvec, dest_trinorm); - - // mul_m4_v3(ob->obmat, tmpvec); // DG: use local coordinates, we save MAT anyway - copy_v3_v3(&scs->points_old[3 * (dm->getNumVerts(dm) + newdivs)], src_tmpvec); - copy_v3_v3(&scs->points[3 * (dm->getNumVerts(dm) + newdivs)], dest_tmpvec); - newdivs++; - } - } - - if(again == 0 && mface[i].v4) - again++; - else - again = 0; - - facecounter++; + smd->time = scene->r.cfra; - } while(again!=0); + return 1; } - - // scs->numpoints = dm->getNumVerts(dm) + newdivs; - -} - -/*! init triangle divisions */ -static void calcTriangleDivs(Object *ob, MVert *verts, int UNUSED(numverts), MFace *faces, int numfaces, int numtris, int **tridivs, float cell_len) -{ - // mTriangleDivs1.resize( faces.size() ); - // mTriangleDivs2.resize( faces.size() ); - // mTriangleDivs3.resize( faces.size() ); - - size_t i = 0, facecounter = 0; - float maxscale[3] = {1,1,1}; // = channelFindMaxVf(mcScale); get max scale value - float maxpart = ABS(maxscale[0]); - float scaleFac = 0; - float fsTri = 0; - if(ABS(maxscale[1])>maxpart) maxpart = ABS(maxscale[1]); - if(ABS(maxscale[2])>maxpart) maxpart = ABS(maxscale[2]); - scaleFac = 1.0 / maxpart; - // featureSize = mLevel[mMaxRefine].nodeSize - fsTri = cell_len * 0.75 * scaleFac; // fsTri = cell_len * 0.9; - - if(*tridivs) - MEM_freeN(*tridivs); - - *tridivs = MEM_callocN(sizeof(int) * numtris * 3, "Smoke_Tridivs"); - - for(i = 0, facecounter = 0; i < numfaces; i++) + else if ((smd->type & MOD_SMOKE_TYPE_COLL)) { - float p0[3], p1[3], p2[3]; - float side1[3]; - float side2[3]; - float side3[3]; - int divs1=0, divs2=0, divs3=0; - - copy_v3_v3(p0, verts[faces[i].v1].co); - mul_m4_v3(ob->obmat, p0); - copy_v3_v3(p1, verts[faces[i].v2].co); - mul_m4_v3(ob->obmat, p1); - copy_v3_v3(p2, verts[faces[i].v3].co); - mul_m4_v3(ob->obmat, p2); - - sub_v3_v3v3(side1, p1, p0); - sub_v3_v3v3(side2, p2, p0); - sub_v3_v3v3(side3, p1, p2); - - if(dot_v3v3(side1, side1) > fsTri*fsTri) - { - float tmp = normalize_v3(side1); - divs1 = (int)ceil(tmp/fsTri); - } - if(dot_v3v3(side2, side2) > fsTri*fsTri) - { - float tmp = normalize_v3(side2); - divs2 = (int)ceil(tmp/fsTri); - - /* - // debug - if(i==0) - printf("b tmp: %f, fsTri: %f, divs2: %d\n", tmp, fsTri, divs2); - */ - + if (!smd->coll) + { + smokeModifier_createType(smd); } - (*tridivs)[3 * facecounter + 0] = divs1; - (*tridivs)[3 * facecounter + 1] = divs2; - (*tridivs)[3 * facecounter + 2] = divs3; - - // TODO quad case - if(faces[i].v4) - { - divs1=0, divs2=0, divs3=0; - - facecounter++; - - copy_v3_v3(p0, verts[faces[i].v3].co); - mul_m4_v3(ob->obmat, p0); - copy_v3_v3(p1, verts[faces[i].v4].co); - mul_m4_v3(ob->obmat, p1); - copy_v3_v3(p2, verts[faces[i].v1].co); - mul_m4_v3(ob->obmat, p2); - - sub_v3_v3v3(side1, p1, p0); - sub_v3_v3v3(side2, p2, p0); - sub_v3_v3v3(side3, p1, p2); - - if(dot_v3v3(side1, side1) > fsTri*fsTri) - { - float tmp = normalize_v3(side1); - divs1 = (int)ceil(tmp/fsTri); - } - if(dot_v3v3(side2, side2) > fsTri*fsTri) - { - float tmp = normalize_v3(side2); - divs2 = (int)ceil(tmp/fsTri); - } + smd->time = scene->r.cfra; - (*tridivs)[3 * facecounter + 0] = divs1; - (*tridivs)[3 * facecounter + 1] = divs2; - (*tridivs)[3 * facecounter + 2] = divs3; - } - facecounter++; + return 1; } + + return 2; } #endif /* WITH_SMOKE */ static void smokeModifier_freeDomain(SmokeModifierData *smd) { - if(smd->domain) + if (smd->domain) { - if(smd->domain->shadow) - MEM_freeN(smd->domain->shadow); - smd->domain->shadow = NULL; + if (smd->domain->shadow) + MEM_freeN(smd->domain->shadow); + smd->domain->shadow = NULL; - if(smd->domain->fluid) + if (smd->domain->fluid) smoke_free(smd->domain->fluid); - if(smd->domain->wt) + if (smd->domain->wt) smoke_turbulence_free(smd->domain->wt); - if(smd->domain->effector_weights) - MEM_freeN(smd->domain->effector_weights); + if (smd->domain->effector_weights) + MEM_freeN(smd->domain->effector_weights); smd->domain->effector_weights = NULL; BKE_ptcache_free_list(&(smd->domain->ptcaches[0])); @@ -748,16 +379,10 @@ static void smokeModifier_freeDomain(SmokeModifierData *smd) static void smokeModifier_freeFlow(SmokeModifierData *smd) { - if(smd->flow) + if (smd->flow) { -/* - if(smd->flow->bvh) - { - free_bvhtree_from_mesh(smd->flow->bvh); - MEM_freeN(smd->flow->bvh); - } - smd->flow->bvh = NULL; -*/ + if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); + if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); MEM_freeN(smd->flow); smd->flow = NULL; } @@ -765,40 +390,22 @@ static void smokeModifier_freeFlow(SmokeModifierData *smd) static void smokeModifier_freeCollision(SmokeModifierData *smd) { - if(smd->coll) + if (smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numpoints) + if (scs->numverts) { - if(scs->points) + if (scs->verts_old) { - MEM_freeN(scs->points); - scs->points = NULL; - } - if(scs->points_old) - { - MEM_freeN(scs->points_old); - scs->points_old = NULL; - } - if(scs->tridivs) - { - MEM_freeN(scs->tridivs); - scs->tridivs = NULL; + MEM_freeN(scs->verts_old); + scs->verts_old = NULL; } } - if(scs->bvhtree) - { - BLI_bvhtree_free(scs->bvhtree); - scs->bvhtree = NULL; - } - -#ifdef USE_SMOKE_COLLISION_DM - if(smd->coll->dm) + if (smd->coll->dm) smd->coll->dm->release(smd->coll->dm); smd->coll->dm = NULL; -#endif MEM_freeN(smd->coll); smd->coll = NULL; @@ -807,7 +414,7 @@ static void smokeModifier_freeCollision(SmokeModifierData *smd) void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) { - if(smd && smd->domain && smd->domain->wt) + if (smd && smd->domain && smd->domain->wt) { smoke_turbulence_free(smd->domain->wt); smd->domain->wt = NULL; @@ -816,15 +423,15 @@ void smokeModifier_reset_turbulence(struct SmokeModifierData *smd) void smokeModifier_reset(struct SmokeModifierData *smd) { - if(smd) + if (smd) { - if(smd->domain) + if (smd->domain) { - if(smd->domain->shadow) + if (smd->domain->shadow) MEM_freeN(smd->domain->shadow); smd->domain->shadow = NULL; - if(smd->domain->fluid) + if (smd->domain->fluid) { smoke_free(smd->domain->fluid); smd->domain->fluid = NULL; @@ -833,39 +440,23 @@ void smokeModifier_reset(struct SmokeModifierData *smd) smokeModifier_reset_turbulence(smd); smd->time = -1; - - // printf("reset domain end\n"); + smd->domain->total_cells = 0; + smd->domain->active_fields = 0; } - else if(smd->flow) + else if (smd->flow) { - /* - if(smd->flow->bvh) - { - free_bvhtree_from_mesh(smd->flow->bvh); - MEM_freeN(smd->flow->bvh); - } - smd->flow->bvh = NULL; - */ + if (smd->flow->verts_old) MEM_freeN(smd->flow->verts_old); + smd->flow->verts_old = NULL; + smd->flow->numverts = 0; } - else if(smd->coll) + else if (smd->coll) { SmokeCollSettings *scs = smd->coll; - if(scs->numpoints && scs->points) + if (scs->numverts && scs->verts_old) { - MEM_freeN(scs->points); - scs->points = NULL; - - if(scs->points_old) - { - MEM_freeN(scs->points_old); - scs->points_old = NULL; - } - if(scs->tridivs) - { - MEM_freeN(scs->tridivs); - scs->tridivs = NULL; - } + MEM_freeN(scs->verts_old); + scs->verts_old = NULL; } } } @@ -873,7 +464,7 @@ void smokeModifier_reset(struct SmokeModifierData *smd) void smokeModifier_free(SmokeModifierData *smd) { - if(smd) + if (smd) { smokeModifier_freeDomain(smd); smokeModifier_freeFlow(smd); @@ -883,11 +474,11 @@ void smokeModifier_free(SmokeModifierData *smd) void smokeModifier_createType(struct SmokeModifierData *smd) { - if(smd) + if (smd) { - if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { - if(smd->domain) + if (smd->domain) smokeModifier_freeDomain(smd); smd->domain = MEM_callocN(sizeof(SmokeDomainSettings), "SmokeDomain"); @@ -903,13 +494,12 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->ptcaches[1].first = smd->domain->ptcaches[1].last = NULL; /* set some standard values */ smd->domain->fluid = NULL; - smd->domain->wt = NULL; + smd->domain->wt = NULL; smd->domain->eff_group = NULL; smd->domain->fluid_group = NULL; smd->domain->coll_group = NULL; smd->domain->maxres = 32; - smd->domain->amplify = 1; - smd->domain->omega = 1.0; + smd->domain->amplify = 1; smd->domain->alpha = -0.001; smd->domain->beta = 0.1; smd->domain->time_scale = 1.0; @@ -919,14 +509,28 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->domain->strength = 2.0; smd->domain->noise = MOD_SMOKE_NOISEWAVE; smd->domain->diss_speed = 5; - // init 3dview buffer + smd->domain->active_fields = 0; + + smd->domain->adapt_margin = 4; + smd->domain->adapt_res = 0; + smd->domain->adapt_threshold = 0.02f; + + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + /* color */ + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; smd->domain->viewsettings = MOD_SMOKE_VIEW_SHOWBIG; smd->domain->effector_weights = BKE_add_effector_weights(NULL); } - else if(smd->type & MOD_SMOKE_TYPE_FLOW) + else if (smd->type & MOD_SMOKE_TYPE_FLOW) { - if(smd->flow) + if (smd->flow) smokeModifier_freeFlow(smd); smd->flow = MEM_callocN(sizeof(SmokeFlowSettings), "SmokeFlow"); @@ -934,31 +538,35 @@ void smokeModifier_createType(struct SmokeModifierData *smd) smd->flow->smd = smd; /* set some standard values */ - smd->flow->density = 1.0; - smd->flow->temp = 1.0; + smd->flow->density = 1.0f; + smd->flow->fuel_amount = 1.0f; + smd->flow->temp = 1.0f; smd->flow->flags = MOD_SMOKE_FLOW_ABSOLUTE; - smd->flow->vel_multi = 1.0; + smd->flow->vel_multi = 1.0f; + smd->flow->surface_distance = 1.5f; + smd->flow->source = MOD_SMOKE_FLOW_SOURCE_MESH; + smd->flow->texture_size = 1.0f; + + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + smd->flow->dm = NULL; smd->flow->psys = NULL; } - else if(smd->type & MOD_SMOKE_TYPE_COLL) + else if (smd->type & MOD_SMOKE_TYPE_COLL) { - if(smd->coll) + if (smd->coll) smokeModifier_freeCollision(smd); smd->coll = MEM_callocN(sizeof(SmokeCollSettings), "SmokeColl"); smd->coll->smd = smd; - smd->coll->points = NULL; - smd->coll->points_old = NULL; - smd->coll->tridivs = NULL; - smd->coll->vel = NULL; - smd->coll->numpoints = 0; - smd->coll->numtris = 0; - smd->coll->bvhtree = NULL; + smd->coll->verts_old = NULL; + smd->coll->numverts = 0; smd->coll->type = 0; // static obstacle - smd->coll->dx = 1.0f / 50.0f; + smd->coll->dm = NULL; #ifdef USE_SMOKE_COLLISION_DM smd->coll->dm = NULL; @@ -971,36 +579,65 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData { tsmd->type = smd->type; tsmd->time = smd->time; - + smokeModifier_createType(tsmd); if (tsmd->domain) { - tsmd->domain->maxres = smd->domain->maxres; - tsmd->domain->amplify = smd->domain->amplify; - tsmd->domain->omega = smd->domain->omega; + tsmd->domain->fluid_group = smd->domain->fluid_group; + tsmd->domain->coll_group = smd->domain->coll_group; + + tsmd->domain->adapt_margin = smd->domain->adapt_margin; + tsmd->domain->adapt_res = smd->domain->adapt_res; + tsmd->domain->adapt_threshold = smd->domain->adapt_threshold; + tsmd->domain->alpha = smd->domain->alpha; tsmd->domain->beta = smd->domain->beta; + tsmd->domain->amplify = smd->domain->amplify; + tsmd->domain->maxres = smd->domain->maxres; tsmd->domain->flags = smd->domain->flags; - tsmd->domain->strength = smd->domain->strength; + tsmd->domain->viewsettings = smd->domain->viewsettings; tsmd->domain->noise = smd->domain->noise; tsmd->domain->diss_speed = smd->domain->diss_speed; - tsmd->domain->viewsettings = smd->domain->viewsettings; - tsmd->domain->fluid_group = smd->domain->fluid_group; - tsmd->domain->coll_group = smd->domain->coll_group; + tsmd->domain->strength = smd->domain->strength; + + tsmd->domain->border_collisions = smd->domain->border_collisions; tsmd->domain->vorticity = smd->domain->vorticity; tsmd->domain->time_scale = smd->domain->time_scale; - tsmd->domain->border_collisions = smd->domain->border_collisions; - + + tsmd->domain->burning_rate = smd->domain->burning_rate; + tsmd->domain->flame_smoke = smd->domain->flame_smoke; + tsmd->domain->flame_vorticity = smd->domain->flame_vorticity; + tsmd->domain->flame_ignition = smd->domain->flame_ignition; + tsmd->domain->flame_max_temp = smd->domain->flame_max_temp; + copy_v3_v3(tsmd->domain->flame_smoke_color, smd->domain->flame_smoke_color); + MEM_freeN(tsmd->domain->effector_weights); tsmd->domain->effector_weights = MEM_dupallocN(smd->domain->effector_weights); - } + } else if (tsmd->flow) { + tsmd->flow->psys = smd->flow->psys; + tsmd->flow->noise_texture = smd->flow->noise_texture; + + tsmd->flow->vel_multi = smd->flow->vel_multi; + tsmd->flow->vel_normal = smd->flow->vel_normal; + tsmd->flow->vel_random = smd->flow->vel_random; + tsmd->flow->density = smd->flow->density; + copy_v3_v3(tsmd->flow->color, smd->flow->color); + tsmd->flow->fuel_amount = smd->flow->fuel_amount; tsmd->flow->temp = smd->flow->temp; - tsmd->flow->psys = smd->flow->psys; + tsmd->flow->volume_density = smd->flow->volume_density; + tsmd->flow->surface_distance = smd->flow->surface_distance; + + tsmd->flow->texture_size = smd->flow->texture_size; + tsmd->flow->texture_offset = smd->flow->texture_offset; + BLI_strncpy(tsmd->flow->uvlayer_name, tsmd->flow->uvlayer_name, sizeof(tsmd->flow->uvlayer_name)); + tsmd->flow->vgroup_density = smd->flow->vgroup_density; + tsmd->flow->type = smd->flow->type; + tsmd->flow->source = smd->flow->source; + tsmd->flow->texture_type = smd->flow->texture_type; tsmd->flow->flags = smd->flow->flags; - tsmd->flow->vel_multi = smd->flow->vel_multi; } else if (tsmd->coll) { ; @@ -1011,24 +648,24 @@ void smokeModifier_copy(struct SmokeModifierData *smd, struct SmokeModifierData #ifdef WITH_SMOKE // forward decleration -static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct); +static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene); static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct); static int get_lamp(Scene *scene, float *light) -{ - Base *base_tmp = NULL; +{ + Base *base_tmp = NULL; int found_lamp = 0; // try to find a lamp, preferably local - for(base_tmp = scene->base.first; base_tmp; base_tmp= base_tmp->next) { - if(base_tmp->object->type == OB_LAMP) { + for (base_tmp = scene->base.first; base_tmp; base_tmp = base_tmp->next) { + if (base_tmp->object->type == OB_LAMP) { Lamp *la = base_tmp->object->data; - if(la->type == LA_LOCAL) { + if (la->type == LA_LOCAL) { copy_v3_v3(light, base_tmp->object->obmat[3]); return 1; } - else if(!found_lamp) { + else if (!found_lamp) { copy_v3_v3(light, base_tmp->object->obmat[3]); found_lamp = 1; } @@ -1038,48 +675,131 @@ static int get_lamp(Scene *scene, float *light) return found_lamp; } -static void smoke_calc_domain(Scene *UNUSED(scene), Object *UNUSED(ob), SmokeModifierData *UNUSED(smd)) +static void obstacles_from_derivedmesh(Object *coll_ob, SmokeDomainSettings *sds, SmokeCollSettings *scs, unsigned char *obstacle_map, float *velocityX, float *velocityY, float *velocityZ, float dt) { -#if 0 - SmokeDomainSettings *sds = smd->domain; - GroupObject *go = NULL; - Base *base = NULL; - - /* do collisions, needs to be done before emission, so that smoke isn't emitted inside collision cells */ - if(1) + if (!scs->dm) return; { - unsigned int i; - Object **collobjs = NULL; - unsigned int numcollobj = 0; - collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj); + DerivedMesh *dm = NULL; + MVert *mvert = NULL; + MFace *mface = NULL; + BVHTreeFromMesh treeData = {0}; + int numverts, i, z; + + float surface_distance = 0.6; + + float *vert_vel = NULL; + int has_velocity = 0; + + tstart(); + + dm = CDDM_copy(scs->dm); + CDDM_calc_normals(dm); + mvert = dm->getVertArray(dm); + mface = dm->getTessFaceArray(dm); + numverts = dm->getNumVerts(dm); + + // DG TODO + // if(scs->type > SM_COLL_STATIC) + // if line above is used, the code is in trouble if the object moves but is declared as "does not move" - for(i = 0; i < numcollobj; i++) { - Object *collob= collobjs[i]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); - - // check for active smoke modifier - // if(md && md->mode & (eModifierMode_Realtime | eModifierMode_Render)) - // SmokeModifierData *smd2 = (SmokeModifierData *)md; - - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old) + vert_vel = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_velocity"); + + if (scs->numverts != numverts || !scs->verts_old) { + if (scs->verts_old) MEM_freeN(scs->verts_old); + + scs->verts_old = MEM_callocN(sizeof(float) * numverts * 3, "smoke_obs_verts_old"); + scs->numverts = numverts; + } + else { + has_velocity = 1; + } + } + + /* Transform collider vertices to + * domain grid space for fast lookups */ + for (i = 0; i < numverts; i++) { + float n[3]; + float co[3]; + + /* vert pos */ + mul_m4_v3(coll_ob->obmat, mvert[i].co); + smoke_pos_to_cell(sds, mvert[i].co); + + /* vert normal */ + normal_short_to_float_v3(n, mvert[i].no); + mul_mat3_m4_v3(coll_ob->obmat, n); + mul_mat3_m4_v3(sds->imat, n); + normalize_v3(n); + normal_float_to_short_v3(mvert[i].no, n); + + /* vert velocity */ + VECADD(co, mvert[i].co, sds->shift); + if (has_velocity) { - // ??? anything to do here? + sub_v3_v3v3(&vert_vel[i * 3], co, &scs->verts_old[i * 3]); + mul_v3_fl(&vert_vel[i * 3], sds->dx / dt); + } + copy_v3_v3(&scs->verts_old[i * 3], co); + } + + if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { + #pragma omp parallel for schedule(static) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) { + int x, y; + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) { + int index = smoke_get_index(x - sds->res_min[0], sds->res[0], y - sds->res_min[1], sds->res[1], z - sds->res_min[2]); + + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + BVHTreeNearest nearest = {0}; + nearest.index = -1; + nearest.dist = surface_distance * surface_distance; /* find_nearest uses squared distance */ + + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + // DG TODO + if (has_velocity) + { + /* apply object velocity */ + { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); + velocityX[index] += hit_vel[0]; + velocityY[index] += hit_vel[1]; + velocityZ[index] += hit_vel[2]; + } + } - // TODO: only something to do for ANIMATED obstacles: need to update positions + /* tag obstacle cells */ + obstacle_map[index] = 1; + if (has_velocity) + obstacle_map[index] |= 8; + } + } } } + /* free bvh tree */ + free_bvhtree_from_mesh(&treeData); + dm->release(dm); - if(collobjs) - MEM_freeN(collobjs); + if (vert_vel) MEM_freeN(vert_vel); } - -#endif } /* Animated obstacles: dx_step = ((x_new - x_old) / totalsteps) * substep */ -static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, int substep, int totalsteps) +static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float dt, + int UNUSED(substep), int UNUSED(totalsteps)) { Object **collobjs = NULL; unsigned int numcollobj = 0; @@ -1092,24 +812,20 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, float *velxOrig = smoke_get_velocity_x(sds->fluid); float *velyOrig = smoke_get_velocity_y(sds->fluid); float *velzOrig = smoke_get_velocity_z(sds->fluid); - // float *density = smoke_get_density(sds->fluid); + float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *flame = smoke_get_flame(sds->fluid); + float *r = smoke_get_color_r(sds->fluid); + float *g = smoke_get_color_g(sds->fluid); + float *b = smoke_get_color_b(sds->fluid); unsigned int z; smoke_get_ob_velocity(sds->fluid, &velx, &vely, &velz); // TODO: delete old obstacle flags - for(z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) { - if(obstacles[z]) - { - // density[z] = 0; - - velxOrig[z] = 0; - velyOrig[z] = 0; - velzOrig[z] = 0; - } - - if(obstacles[z] & 8) // Do not delete static obstacles + if (obstacles[z] & 8) // Do not delete static obstacles { obstacles[z] = 0; } @@ -1119,410 +835,1064 @@ static void update_obstacles(Scene *scene, Object *ob, SmokeDomainSettings *sds, velz[z] = 0; } + collobjs = get_collisionobjects(scene, ob, sds->coll_group, &numcollobj, eModifierType_Smoke); // update obstacle tags in cells - for(collIndex = 0; collIndex < numcollobj; collIndex++) + for (collIndex = 0; collIndex < numcollobj; collIndex++) { - Object *collob= collobjs[collIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + Object *collob = collobjs[collIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); // DG TODO: check if modifier is active? - - if((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll && smd2->coll->points && smd2->coll->points_old) + + if ((smd2->type & MOD_SMOKE_TYPE_COLL) && smd2->coll) { SmokeCollSettings *scs = smd2->coll; - unsigned int i; + obstacles_from_derivedmesh(collob, sds, scs, obstacles, velx, vely, velz, dt); + } + } + + if (collobjs) + MEM_freeN(collobjs); + + /* obstacle cells should not contain any velocity from the smoke simulation */ + for (z = 0; z < sds->res[0] * sds->res[1] * sds->res[2]; z++) + { + if (obstacles[z]) + { + velxOrig[z] = 0; + velyOrig[z] = 0; + velzOrig[z] = 0; + density[z] = 0; + if (fuel) { + fuel[z] = 0; + flame[z] = 0; + } + if (r) { + r[z] = 0; + g[z] = 0; + b[z] = 0; + } + } + } +} + + +typedef struct EmissionMap { + float *influence; + float *velocity; + int min[3], max[3], res[3]; + int total_cells, valid; +} EmissionMap; + +static void em_boundInsert(EmissionMap *em, float point[3]) +{ + int i = 0; + if (!em->valid) { + VECCOPY(em->min, point); + VECCOPY(em->max, point); + em->valid = 1; + } + else { + for (; i < 3; i++) { + if (point[i] < em->min[i]) em->min[i] = (int)floor(point[i]); + if (point[i] > em->max[i]) em->max[i] = (int)ceil(point[i]); + } + } +} - /* - // DG TODO: support static cobstacles, but basicly we could even support static + rigid with one set of code - if(scs->type > SM_COLL_STATIC) - */ +static void clampBoundsInDomain(SmokeDomainSettings *sds, int min[3], int max[3], float *min_vel, float *max_vel, int margin, float dt) +{ + int i; + for (i = 0; i < 3; i++) { + int adapt = (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) ? sds->adapt_res : 0; + /* add margin */ + min[i] -= margin; + max[i] += margin; + + /* adapt to velocity */ + if (min_vel && min_vel[i] < 0.0f) { + min[i] += (int)ceil(min_vel[i] * dt); + } + if (max_vel && max_vel[i] > 0.0f) { + max[i] += (int)ceil(max_vel[i] * dt); + } + + /* clamp within domain max size */ + CLAMP(min[i], -adapt, sds->base_res[i] + adapt); + CLAMP(max[i], -adapt, sds->base_res[i] + adapt); + } +} + +static void em_allocateData(EmissionMap *em, int use_velocity) { + int i, res[3]; + + for (i = 0; i < 3; i++) { + res[i] = em->max[i] - em->min[i]; + if (res[i] <= 0) + return; + } + em->total_cells = res[0] * res[1] * res[2]; + copy_v3_v3_int(em->res, res); - /* Handle collisions */ - for(i = 0; i < scs->numpoints; i++) + + em->influence = MEM_callocN(sizeof(float) * em->total_cells, "smoke_flow_influence"); + if (use_velocity) + em->velocity = MEM_callocN(sizeof(float) * em->total_cells * 3, "smoke_flow_velocity"); +} + +static void em_freeData(EmissionMap *em) { + if (em->influence) + MEM_freeN(em->influence); + if (em->velocity) + MEM_freeN(em->velocity); +} + + +static void emit_from_particles(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, Scene *scene, float time, float dt) +{ + if (sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type == PART_EMITTER) // is particle system selected + { + ParticleSimulationData sim; + ParticleSystem *psys = sfs->psys; + float *particle_pos; + float *particle_vel; + int totpart = psys->totpart, totchild; + int p = 0; + int valid_particles = 0; + + sim.scene = scene; + sim.ob = flow_ob; + sim.psys = psys; + + if (psys->part->type == PART_HAIR) + { + // TODO: PART_HAIR not supported whatsoever + totchild = 0; + } + else + totchild = psys->totchild * psys->part->disp / 100; + + particle_pos = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); + particle_vel = MEM_callocN(sizeof(float) * (totpart + totchild) * 3, "smoke_flow_particles"); + + /* calculate local position for each particle */ + for (p = 0; p < totpart + totchild; p++) + { + ParticleKey state; + float *pos; + if (p < totpart) { + if (psys->particles[p].flag & (PARS_NO_DISP | PARS_UNEXIST)) + continue; + } + else { + /* handle child particle */ + ChildParticle *cpa = &psys->child[p - totpart]; + if (psys->particles[cpa->parent].flag & (PARS_NO_DISP | PARS_UNEXIST)) + continue; + } + + state.time = time; + if (psys_get_particle_state(&sim, p, &state, 0) == 0) + continue; + + /* location */ + pos = &particle_pos[valid_particles * 3]; + copy_v3_v3(pos, state.co); + smoke_pos_to_cell(sds, pos); + + /* velocity */ + copy_v3_v3(&particle_vel[valid_particles * 3], state.vel); + mul_mat3_m4_v3(sds->imat, &particle_vel[valid_particles * 3]); + + /* calculate emission map bounds */ + em_boundInsert(em, pos); + valid_particles++; + } + + /* set emission map */ + clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, 1, dt); + em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); + + for (p = 0; p < valid_particles; p++) + { + int cell[3]; + size_t i = 0; + size_t index = 0; + int badcell = 0; + + /* 1. get corresponding cell */ + cell[0] = floor(particle_pos[p * 3]) - em->min[0]; + cell[1] = floor(particle_pos[p * 3 + 1]) - em->min[1]; + cell[2] = floor(particle_pos[p * 3 + 2]) - em->min[2]; + /* check if cell is valid (in the domain boundary) */ + for (i = 0; i < 3; i++) { + if ((cell[i] > em->res[i] - 1) || (cell[i] < 0)) { + badcell = 1; + break; + } + } + if (badcell) + continue; + /* get cell index */ + index = smoke_get_index(cell[0], em->res[0], cell[1], em->res[1], cell[2]); + /* Add influence to emission map */ + em->influence[index] = 1.0f; + /* Uses particle velocity as initial velocity for smoke */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) { - // 1. get corresponding cell - int cell[3]; - float pos[3], oldpos[3], vel[3]; - float cPos[3], cOldpos[3]; /* current position in substeps */ - int badcell = 0; - size_t index; - int j; - - // translate local points into global positions - copy_v3_v3(cPos, &scs->points[3 * i]); - mul_m4_v3(scs->mat, cPos); - copy_v3_v3(pos, cPos); - - copy_v3_v3(cOldpos, &scs->points_old[3 * i]); - mul_m4_v3(scs->mat_old, cOldpos); - copy_v3_v3(oldpos, cOldpos); - - /* support for rigid bodies, armatures etc */ - { - float tmp[3]; + VECADDFAC(&em->velocity[index * 3], &em->velocity[index * 3], &particle_vel[p * 3], sfs->vel_multi); + } + } // particles loop + + /* free data */ + if (particle_pos) + MEM_freeN(particle_pos); + if (particle_vel) + MEM_freeN(particle_vel); + } +} - /* x_current = x_old + (x_new - x_old) * step_current / steps_total */ - float mulStep = (float)(((float)substep) / ((float)totalsteps)); +static void get_texture_value(Tex *texture, float tex_co[3], TexResult *texres) +{ + int result_type; + + /* no node textures for now */ + result_type = multitex_ext_safe(texture, tex_co, texres); + + /* if the texture gave an RGB value, we assume it didn't give a valid + * intensity, since this is in the context of modifiers don't use perceptual color conversion. + * if the texture didn't give an RGB value, copy the intensity across + */ + if (result_type & TEX_RGB) { + texres->tin = (1.0f / 3.0f) * (texres->tr + texres->tg + texres->tb); + } + else { + copy_v3_fl(&texres->tr, texres->tin); + } +} + +static void emit_from_derivedmesh(Object *flow_ob, SmokeDomainSettings *sds, SmokeFlowSettings *sfs, EmissionMap *em, float dt) +{ + if (!sfs->dm) return; + { + DerivedMesh *dm = sfs->dm; + int defgrp_index = sfs->vgroup_density - 1; + MDeformVert *dvert = NULL; + MVert *mvert = NULL; + MVert *mvert_orig = NULL; + MFace *mface = NULL; + MTFace *tface = NULL; + BVHTreeFromMesh treeData = {0}; + int numOfVerts, i, z; + float flow_center[3] = {0}; + + float *vert_vel = NULL; + int has_velocity = 0; + + CDDM_calc_normals(dm); + mvert = dm->getVertArray(dm); + mvert_orig = dm->dupVertArray(dm); /* copy original mvert and restore when done */ + mface = dm->getTessFaceArray(dm); + numOfVerts = dm->getNumVerts(dm); + dvert = dm->getVertDataArray(dm, CD_MDEFORMVERT); + tface = CustomData_get_layer_named(&dm->faceData, CD_MTFACE, sfs->uvlayer_name); + + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + vert_vel = MEM_callocN(sizeof(float) * numOfVerts * 3, "smoke_flow_velocity"); + + if (sfs->numverts != numOfVerts || !sfs->verts_old) { + if (sfs->verts_old) MEM_freeN(sfs->verts_old); + sfs->verts_old = MEM_callocN(sizeof(float) * numOfVerts * 3, "smoke_flow_verts_old"); + sfs->numverts = numOfVerts; + } + else { + has_velocity = 1; + } + } - sub_v3_v3v3(tmp, cPos, cOldpos); - mul_v3_fl(tmp, mulStep); - add_v3_v3(cOldpos, tmp); + /* Transform dm vertices to + * domain grid space for fast lookups */ + for (i = 0; i < numOfVerts; i++) { + float n[3]; + /* vert pos */ + mul_m4_v3(flow_ob->obmat, mvert[i].co); + smoke_pos_to_cell(sds, mvert[i].co); + /* vert normal */ + normal_short_to_float_v3(n, mvert[i].no); + mul_mat3_m4_v3(flow_ob->obmat, n); + mul_mat3_m4_v3(sds->imat, n); + normalize_v3(n); + normal_float_to_short_v3(mvert[i].no, n); + /* vert velocity */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + float co[3]; + VECADD(co, mvert[i].co, sds->shift); + if (has_velocity) { + sub_v3_v3v3(&vert_vel[i * 3], co, &sfs->verts_old[i * 3]); + mul_v3_fl(&vert_vel[i * 3], sds->dx / dt); } + copy_v3_v3(&sfs->verts_old[i * 3], co); + } - sub_v3_v3v3(vel, pos, oldpos); - /* Scale velocity to incorperate the object movement during this step */ - mul_v3_fl(vel, 1.0 / (totalsteps * dt * sds->scale)); - // mul_v3_fl(vel, 1.0 / dt); + /* calculate emission map bounds */ + em_boundInsert(em, mvert[i].co); + } + mul_m4_v3(flow_ob->obmat, flow_center); + smoke_pos_to_cell(sds, flow_center); + + /* set emission map */ + clampBoundsInDomain(sds, em->min, em->max, NULL, NULL, sfs->surface_distance, dt); + em_allocateData(em, sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY); + + if (bvhtree_from_mesh_faces(&treeData, dm, 0.0f, 4, 6)) { + #pragma omp parallel for schedule(static) + for (z = em->min[2]; z < em->max[2]; z++) { + int x, y; + for (x = em->min[0]; x < em->max[0]; x++) + for (y = em->min[1]; y < em->max[1]; y++) { + int index = smoke_get_index(x - em->min[0], em->res[0], y - em->min[1], em->res[1], z - em->min[2]); + + float ray_start[3] = {(float)x + 0.5f, (float)y + 0.5f, (float)z + 0.5f}; + float ray_dir[3] = {1.0f, 0.0f, 0.0f}; + + BVHTreeRayHit hit = {0}; + BVHTreeNearest nearest = {0}; + + float volume_factor = 0.0f; + float sample_str = 0.0f; + + hit.index = -1; + hit.dist = 9999; + nearest.index = -1; + nearest.dist = sfs->surface_distance * sfs->surface_distance; /* find_nearest uses squared distance */ + + /* Check volume collision */ + if (sfs->volume_density) { + if (BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData) != -1) { + float dot = ray_dir[0] * hit.no[0] + ray_dir[1] * hit.no[1] + ray_dir[2] * hit.no[2]; + /* If ray and hit face normal are facing same direction + * hit point is inside a closed mesh. */ + if (dot >= 0) { + /* Also cast a ray in opposite direction to make sure + * point is at least surrounded by two faces */ + negate_v3(ray_dir); + hit.index = -1; + hit.dist = 9999; + + BLI_bvhtree_ray_cast(treeData.tree, ray_start, ray_dir, 0.0f, &hit, treeData.raycast_callback, &treeData); + if (hit.index != -1) { + volume_factor = sfs->volume_density; + nearest.dist = hit.dist * hit.dist; + } + } + } + } - // DG TODO: cap velocity to maxVelMag (or maxvel) + /* find the nearest point on the mesh */ + if (BLI_bvhtree_find_nearest(treeData.tree, ray_start, &nearest, treeData.nearest_callback, &treeData) != -1) { + float weights[4]; + int v1, v2, v3, f_index = nearest.index; + float n1[3], n2[3], n3[3], hit_normal[3]; + + /* emit from surface based on distance */ + if (sfs->surface_distance) { + sample_str = sqrtf(nearest.dist) / sfs->surface_distance; + CLAMP(sample_str, 0.0f, 1.0f); + sample_str = pow(1.0f - sample_str, 0.5f); + } + else + sample_str = 0.0f; + + /* calculate barycentric weights for nearest point */ + v1 = mface[f_index].v1; + v2 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v3 : mface[f_index].v2; + v3 = (nearest.flags & BVH_ONQUAD) ? mface[f_index].v4 : mface[f_index].v3; + interp_weights_face_v3(weights, mvert[v1].co, mvert[v2].co, mvert[v3].co, NULL, nearest.co); + + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + /* apply normal directional velocity */ + if (sfs->vel_normal) { + /* interpolate vertex normal vectors to get nearest point normal */ + normal_short_to_float_v3(n1, mvert[v1].no); + normal_short_to_float_v3(n2, mvert[v2].no); + normal_short_to_float_v3(n3, mvert[v3].no); + interp_v3_v3v3v3(hit_normal, n1, n2, n3, weights); + normalize_v3(hit_normal); + /* apply normal directional and random velocity + * - TODO: random disabled for now since it doesnt really work well as pressure calc smoothens it out... */ + em->velocity[index * 3] += hit_normal[0] * sfs->vel_normal * 0.25f; + em->velocity[index * 3 + 1] += hit_normal[1] * sfs->vel_normal * 0.25f; + em->velocity[index * 3 + 2] += hit_normal[2] * sfs->vel_normal * 0.25f; + /* TODO: for fire emitted from mesh surface we can use + * Vf = Vs + (Ps/Pf - 1)*S to model gaseous expansion from solid to fuel */ + } + /* apply object velocity */ + if (has_velocity && sfs->vel_multi) { + float hit_vel[3]; + interp_v3_v3v3v3(hit_vel, &vert_vel[v1 * 3], &vert_vel[v2 * 3], &vert_vel[v3 * 3], weights); + em->velocity[index * 3] += hit_vel[0] * sfs->vel_multi; + em->velocity[index * 3 + 1] += hit_vel[1] * sfs->vel_multi; + em->velocity[index * 3 + 2] += hit_vel[2] * sfs->vel_multi; + } + } + + /* apply vertex group influence if used */ + if (defgrp_index >= 0 && dvert) { + float weight_mask = defvert_find_weight(&dvert[v1], defgrp_index) * weights[0] + + defvert_find_weight(&dvert[v2], defgrp_index) * weights[1] + + defvert_find_weight(&dvert[v3], defgrp_index) * weights[2]; + sample_str *= weight_mask; + } + + /* apply emission texture */ + if ((sfs->flags & MOD_SMOKE_FLOW_TEXTUREEMIT) && sfs->noise_texture) { + float tex_co[3] = {0}; + TexResult texres; + + if (sfs->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO) { + tex_co[0] = ((float)(x - flow_center[0]) / sds->base_res[0]) / sfs->texture_size; + tex_co[1] = ((float)(y - flow_center[1]) / sds->base_res[1]) / sfs->texture_size; + tex_co[2] = ((float)(z - flow_center[2]) / sds->base_res[2] - sfs->texture_offset) / sfs->texture_size; + } + else if (tface) { + interp_v2_v2v2v2(tex_co, tface[f_index].uv[0], tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 2 : 1], + tface[f_index].uv[(nearest.flags & BVH_ONQUAD) ? 3 : 2], weights); + /* map between -1.0f and 1.0f */ + tex_co[0] = tex_co[0] * 2.0f - 1.0f; + tex_co[1] = tex_co[1] * 2.0f - 1.0f; + tex_co[2] = sfs->texture_offset; + } + texres.nor = NULL; + get_texture_value(sfs->noise_texture, tex_co, &texres); + sample_str *= texres.tin; + } + } - // oldpos + velocity * dt = newpos - get_cell(sds->p0, sds->res, sds->dx*sds->scale, cOldpos /* use current position here instead of "pos" */, cell, 0); + /* multiply initial velocity by emitter influence */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + mul_v3_fl(&em->velocity[index * 3], sample_str); + } - // check if cell is valid (in the domain boundary) - for(j = 0; j < 3; j++) - if((cell[j] > sds->res[j] - 1) || (cell[j] < 0)) - { - badcell = 1; - break; + /* apply final influence based on volume factor */ + em->influence[index] = MAX2(volume_factor, sample_str); } - - if(badcell) - continue; + } + } + /* free bvh tree */ + free_bvhtree_from_mesh(&treeData); + /* restore original mverts */ + CustomData_set_layer(&dm->vertData, CD_MVERT, mvert_orig); + if (mvert) + MEM_freeN(mvert); + + if (vert_vel) MEM_freeN(vert_vel); + } +} - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); +static void adjustDomainResolution(SmokeDomainSettings *sds, int new_shift[3], EmissionMap *emaps, unsigned int numflowobj, float dt) +{ + int min[3] = {32767, 32767, 32767}, max[3] = {-32767, -32767, -32767}, res[3]; + int total_cells = 1, res_changed = 0, shift_changed = 0; + float min_vel[3], max_vel[3]; + int x, y, z, i; + float *density = smoke_get_density(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *vx = smoke_get_velocity_x(sds->fluid); + float *vy = smoke_get_velocity_y(sds->fluid); + float *vz = smoke_get_velocity_z(sds->fluid); + + INIT_MINMAX(min_vel, max_vel); + + /* Calculate bounds for current domain content */ + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) + { + int xn = x - new_shift[0]; + int yn = y - new_shift[1]; + int zn = z - new_shift[2]; + int index = smoke_get_index(x - sds->res_min[0], sds->res[0], y - sds->res_min[1], sds->res[1], z - sds->res_min[2]); + float max_den = (fuel) ? MAX2(density[index], fuel[index]) : density[index]; + + /* content bounds (use shifted coordinates) */ + if (max_den >= sds->adapt_threshold) { + if (min[0] > xn) min[0] = xn; + if (min[1] > yn) min[1] = yn; + if (min[2] > zn) min[2] = zn; + if (max[0] < xn) max[0] = xn; + if (max[1] < yn) max[1] = yn; + if (max[2] < zn) max[2] = zn; + } + /* velocity bounds */ + if (min_vel[0] > vx[index]) min_vel[0] = vx[index]; + if (min_vel[1] > vy[index]) min_vel[1] = vy[index]; + if (min_vel[2] > vz[index]) min_vel[2] = vz[index]; + if (max_vel[0] < vx[index]) max_vel[0] = vx[index]; + if (max_vel[1] < vy[index]) max_vel[1] = vy[index]; + if (max_vel[2] < vz[index]) max_vel[2] = vz[index]; + } - // Don't overwrite existing obstacles - if(obstacles[index]) - continue; - - // printf("cell[0]: %d, cell[1]: %d, cell[2]: %d\n", cell[0], cell[1], cell[2]); - // printf("res[0]: %d, res[1]: %d, res[2]: %d, index: %d\n\n", sds->res[0], sds->res[1], sds->res[2], index); - obstacles[index] = 1 | 8 /* ANIMATED */; + /* also apply emission maps */ + for (i = 0; i < numflowobj; i++) + { + EmissionMap *em = &emaps[i]; - if(len_v3(vel) > FLT_EPSILON) + for (x = em->min[0]; x < em->max[0]; x++) + for (y = em->min[1]; y < em->max[1]; y++) + for (z = em->min[2]; z < em->max[2]; z++) { - // Collision object is moving - - velx[index] = vel[0]; // use "+="? - vely[index] = vel[1]; - velz[index] = vel[2]; + int index = smoke_get_index(x - em->min[0], em->res[0], y - em->min[1], em->res[1], z - em->min[2]); + float max_den = em->influence[index]; + + /* density bounds */ + if (max_den >= sds->adapt_threshold) { + if (min[0] > x) min[0] = x; + if (min[1] > y) min[1] = y; + if (min[2] > z) min[2] = z; + if (max[0] < x) max[0] = x; + if (max[1] < y) max[1] = y; + if (max[2] < z) max[2] = z; + } + /* velocity bounds */ + if (em->velocity) { + if (min_vel[0] > em->velocity[index * 3]) min_vel[0] = em->velocity[index * 3]; + if (min_vel[1] > em->velocity[index * 3 + 1]) min_vel[1] = em->velocity[index * 3 + 1]; + if (min_vel[2] > em->velocity[index * 3 + 2]) min_vel[2] = em->velocity[index * 3 + 2]; + if (max_vel[0] < em->velocity[index * 3]) max_vel[0] = em->velocity[index * 3]; + if (max_vel[1] < em->velocity[index * 3 + 1]) max_vel[1] = em->velocity[index * 3 + 1]; + if (max_vel[2] < em->velocity[index * 3 + 2]) max_vel[2] = em->velocity[index * 3 + 2]; + } } + } + + /* calculate new bounds based on these values */ + clampBoundsInDomain(sds, min, max, min_vel, max_vel, sds->adapt_margin + 1, dt); + + for (i = 0; i < 3; i++) { + /* calculate new resolution */ + res[i] = max[i] - min[i]; + total_cells *= res[i]; + + if (new_shift[i]) + shift_changed = 1; + + /* if no content set minimum dimensions */ + if (res[i] <= 0) { + int j; + for (j = 0; j < 3; j++) { + min[j] = 0; + max[j] = 1; + res[j] = 1; } + res_changed = 1; + total_cells = 1; + break; } + if (min[i] != sds->res_min[i] || max[i] != sds->res_max[i]) + res_changed = 1; } - if(collobjs) - MEM_freeN(collobjs); + if (res_changed || shift_changed) { + struct FLUID_3D *fluid_old = sds->fluid; + struct WTURBULENCE *turb_old = sds->wt; + /* allocate new fluid data */ + smoke_reallocate_fluid(sds, sds->dx, res, 0); + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_reallocate_highres_fluid(sds, sds->dx, res, 0); + } + + /* copy values from old fluid to new */ + if (sds->total_cells > 1 && total_cells > 1) { + /* low res smoke */ + float *o_dens, *o_react, *o_flame, *o_fuel, *o_heat, *o_heatold, *o_vx, *o_vy, *o_vz, *o_r, *o_g, *o_b; + float *n_dens, *n_react, *n_flame, *n_fuel, *n_heat, *n_heatold, *n_vx, *n_vy, *n_vz, *n_r, *n_g, *n_b; + float dummy; + unsigned char *dummy_p; + /* high res smoke */ + int wt_res_old[3]; + float *o_wt_dens, *o_wt_react, *o_wt_flame, *o_wt_fuel, *o_wt_tcu, *o_wt_tcv, *o_wt_tcw, *o_wt_r, *o_wt_g, *o_wt_b; + float *n_wt_dens, *n_wt_react, *n_wt_flame, *n_wt_fuel, *n_wt_tcu, *n_wt_tcv, *n_wt_tcw, *n_wt_r, *n_wt_g, *n_wt_b; + + smoke_export(fluid_old, &dummy, &dummy, &o_dens, &o_react, &o_flame, &o_fuel, &o_heat, &o_heatold, &o_vx, &o_vy, &o_vz, &o_r, &o_g, &o_b, &dummy_p); + smoke_export(sds->fluid, &dummy, &dummy, &n_dens, &n_react, &n_flame, &n_fuel, &n_heat, &n_heatold, &n_vx, &n_vy, &n_vz, &n_r, &n_g, &n_b, &dummy_p); + + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_turbulence_export(turb_old, &o_wt_dens, &o_wt_react, &o_wt_flame, &o_wt_fuel, &o_wt_r, &o_wt_g, &o_wt_b, &o_wt_tcu, &o_wt_tcv, &o_wt_tcw); + smoke_turbulence_get_res(turb_old, wt_res_old); + smoke_turbulence_export(sds->wt, &n_wt_dens, &n_wt_react, &n_wt_flame, &n_wt_fuel, &n_wt_r, &n_wt_g, &n_wt_b, &n_wt_tcu, &n_wt_tcv, &n_wt_tcw); + } + + + for (x = sds->res_min[0]; x < sds->res_max[0]; x++) + for (y = sds->res_min[1]; y < sds->res_max[1]; y++) + for (z = sds->res_min[2]; z < sds->res_max[2]; z++) + { + /* old grid index */ + int xo = x - sds->res_min[0]; + int yo = y - sds->res_min[1]; + int zo = z - sds->res_min[2]; + int index_old = smoke_get_index(xo, sds->res[0], yo, sds->res[1], zo); + /* new grid index */ + int xn = x - min[0] - new_shift[0]; + int yn = y - min[1] - new_shift[1]; + int zn = z - min[2] - new_shift[2]; + int index_new = smoke_get_index(xn, res[0], yn, res[1], zn); + + /* skip if outside new domain */ + if (xn < 0 || xn >= res[0] || + yn < 0 || yn >= res[1] || + zn < 0 || zn >= res[2]) + continue; + + /* copy data */ + n_dens[index_new] = o_dens[index_old]; + /* heat */ + if (n_heat && o_heat) { + n_heat[index_new] = o_heat[index_old]; + n_heatold[index_new] = o_heatold[index_old]; + } + /* fuel */ + if (n_fuel && o_fuel) { + n_flame[index_new] = o_flame[index_old]; + n_fuel[index_new] = o_fuel[index_old]; + n_react[index_new] = o_react[index_old]; + } + /* color */ + if (o_r && n_r) { + n_r[index_new] = o_r[index_old]; + n_g[index_new] = o_g[index_old]; + n_b[index_new] = o_b[index_old]; + } + n_vx[index_new] = o_vx[index_old]; + n_vy[index_new] = o_vy[index_old]; + n_vz[index_new] = o_vz[index_old]; + + if (sds->flags & MOD_SMOKE_HIGHRES && turb_old) { + int block_size = sds->amplify + 1; + int i, j, k; + /* old grid index */ + int xx_o = xo * block_size; + int yy_o = yo * block_size; + int zz_o = zo * block_size; + /* new grid index */ + int xx_n = xn * block_size; + int yy_n = yn * block_size; + int zz_n = zn * block_size; + + n_wt_tcu[index_new] = o_wt_tcu[index_old]; + n_wt_tcv[index_new] = o_wt_tcv[index_old]; + n_wt_tcw[index_new] = o_wt_tcw[index_old]; + + for (i = 0; i < block_size; i++) + for (j = 0; j < block_size; j++) + for (k = 0; k < block_size; k++) + { + int big_index_old = smoke_get_index(xx_o + i, wt_res_old[0], yy_o + j, wt_res_old[1], zz_o + k); + int big_index_new = smoke_get_index(xx_n + i, sds->res_wt[0], yy_n + j, sds->res_wt[1], zz_n + k); + /* copy data */ + n_wt_dens[big_index_new] = o_wt_dens[big_index_old]; + if (n_wt_flame && o_wt_flame) { + n_wt_flame[big_index_new] = o_wt_flame[big_index_old]; + n_wt_fuel[big_index_new] = o_wt_fuel[big_index_old]; + n_wt_react[big_index_new] = o_wt_react[big_index_old]; + } + if (n_wt_r && o_wt_r) { + n_wt_r[big_index_new] = o_wt_r[big_index_old]; + n_wt_g[big_index_new] = o_wt_g[big_index_old]; + n_wt_b[big_index_new] = o_wt_b[big_index_old]; + } + } + } + } + } + smoke_free(fluid_old); + if (turb_old) + smoke_turbulence_free(turb_old); + + /* set new domain dimensions */ + VECCOPY(sds->res_min, min); + VECCOPY(sds->res_max, max); + VECCOPY(sds->res, res); + sds->total_cells = total_cells; + } +} + +BLI_INLINE void apply_outflow_fields(int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b) +{ + density[index] = 0.f; + if (heat) { + heat[index] = 0.f; + } + if (fuel) { + fuel[index] = 0.f; + react[index] = 0.f; + } + if (color_r) { + color_r[index] = 0.f; + color_g[index] = 0.f; + color_b[index] = 0.f; + } +} + +BLI_INLINE void apply_inflow_fields(SmokeFlowSettings *sfs, float emission_value, int index, float *density, float *heat, float *fuel, float *react, float *color_r, float *color_g, float *color_b) +{ + int absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); + float dens_old = density[index]; + // float fuel_old = (fuel) ? fuel[index] : 0.0f; /* UNUSED */ + float dens_flow = (sfs->type == MOD_SMOKE_FLOW_TYPE_FIRE) ? 0.0f : emission_value * sfs->density; + float fuel_flow = emission_value * sfs->fuel_amount; + /* add heat */ + if (heat) { + heat[index] = MAX2(emission_value * sfs->temp, heat[index]); + } + /* absolute */ + if (absolute_flow) { + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE) { + if (dens_flow > density[index]) + density[index] = dens_flow; + } + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && fuel && fuel_flow) { + if (fuel_flow > fuel[index]) + fuel[index] = fuel_flow; + } + } + /* additive */ + else { + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE) { + density[index] += dens_flow; + CLAMP(density[index], 0.0f, 1.0f); + } + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && fuel && sfs->fuel_amount) { + fuel[index] += fuel_flow; + CLAMP(fuel[index], 0.0f, 10.0f); + } + } + + /* set color */ + if (color_r && dens_flow) { + float total_dens = density[index] / (dens_old + dens_flow); + color_r[index] = (color_r[index] + sfs->color[0] * dens_flow) * total_dens; + color_g[index] = (color_g[index] + sfs->color[1] * dens_flow) * total_dens; + color_b[index] = (color_b[index] + sfs->color[2] * dens_flow) * total_dens; + } + + /* set fire reaction coordinate */ + if (fuel && fuel[index]) { + /* instead of using 1.0 for all new fuel add slight falloff + * to reduce flow blockiness */ + float value = 1.0f - pow(1.0f - emission_value, 2.0f); + + if (value > react[index]) { + float f = fuel_flow / fuel[index]; + react[index] = value * f + (1.0f - f) * react[index]; + } + } } -static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time) +static void update_flowsfluids(Scene *scene, Object *ob, SmokeDomainSettings *sds, float time, float dt) { Object **flowobjs = NULL; + EmissionMap *emaps = NULL; unsigned int numflowobj = 0; unsigned int flowIndex; + int new_shift[3] = {0}; + int active_fields = sds->active_fields; + + /* calculate domain shift for current frame if using adaptive domain */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + int total_shift[3]; + float frame_shift_f[3]; + float ob_loc[3] = {0}; + + mul_m4_v3(ob->obmat, ob_loc); + + VECSUB(frame_shift_f, ob_loc, sds->prev_loc); + copy_v3_v3(sds->prev_loc, ob_loc); + /* convert global space shift to local "cell" space */ + mul_mat3_m4_v3(sds->imat, frame_shift_f); + frame_shift_f[0] = frame_shift_f[0] / sds->cell_size[0]; + frame_shift_f[1] = frame_shift_f[1] / sds->cell_size[1]; + frame_shift_f[2] = frame_shift_f[2] / sds->cell_size[2]; + /* add to total shift */ + VECADD(sds->shift_f, sds->shift_f, frame_shift_f); + /* convert to integer */ + total_shift[0] = floor(sds->shift_f[0]); + total_shift[1] = floor(sds->shift_f[1]); + total_shift[2] = floor(sds->shift_f[2]); + VECSUB(new_shift, total_shift, sds->shift); + copy_v3_v3_int(sds->shift, total_shift); + + /* calculate new domain boundary points so that smoke doesnt slide on sub-cell movement */ + sds->p0[0] = sds->dp0[0] - sds->cell_size[0] * (sds->shift_f[0] - total_shift[0] - 0.5f); + sds->p0[1] = sds->dp0[1] - sds->cell_size[1] * (sds->shift_f[1] - total_shift[1] - 0.5f); + sds->p0[2] = sds->dp0[2] - sds->cell_size[2] * (sds->shift_f[2] - total_shift[2] - 0.5f); + sds->p1[0] = sds->p0[0] + sds->cell_size[0] * sds->base_res[0]; + sds->p1[1] = sds->p0[1] + sds->cell_size[1] * sds->base_res[1]; + sds->p1[2] = sds->p0[2] + sds->cell_size[2] * sds->base_res[2]; + } flowobjs = get_collisionobjects(scene, ob, sds->fluid_group, &numflowobj, eModifierType_Smoke); - // update obstacle tags in cells - for(flowIndex = 0; flowIndex < numflowobj; flowIndex++) + /* init emission maps for each flow */ + emaps = MEM_callocN(sizeof(struct EmissionMap) * numflowobj, "smoke_flow_maps"); + + /* Prepare flow emission maps */ + for (flowIndex = 0; flowIndex < numflowobj; flowIndex++) { - Object *collob= flowobjs[flowIndex]; - SmokeModifierData *smd2 = (SmokeModifierData*)modifiers_findByType(collob, eModifierType_Smoke); + Object *collob = flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); // check for initialized smoke object - if((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + if ((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) { // we got nice flow object SmokeFlowSettings *sfs = smd2->flow; + EmissionMap *em = &emaps[flowIndex]; - if(sfs && sfs->psys && sfs->psys->part && sfs->psys->part->type==PART_EMITTER) // is particle system selected - { - ParticleSimulationData sim; - ParticleSystem *psys = sfs->psys; - int totpart=psys->totpart, totchild; - int p = 0; - float *density = smoke_get_density(sds->fluid); - float *bigdensity = smoke_turbulence_get_density(sds->wt); - float *heat = smoke_get_heat(sds->fluid); - float *velocity_x = smoke_get_velocity_x(sds->fluid); - float *velocity_y = smoke_get_velocity_y(sds->fluid); - float *velocity_z = smoke_get_velocity_z(sds->fluid); - unsigned char *obstacle = smoke_get_obstacle(sds->fluid); - // DG TODO UNUSED unsigned char *obstacleAnim = smoke_get_obstacle_anim(sds->fluid); - int bigres[3]; - short absolute_flow = (sfs->flags & MOD_SMOKE_FLOW_ABSOLUTE); - short high_emission_smoothing = bigdensity ? (sds->flags & MOD_SMOKE_HIGH_SMOOTH) : 0; - - /* - * A temporary volume map used to store whole emissive - * area to be added to smoke density and interpolated - * for high resolution smoke. - */ - float *temp_emission_map = NULL; - - sim.scene = scene; - sim.ob = collob; - sim.psys = psys; - - // initialize temp emission map - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) - { - int i; - temp_emission_map = MEM_callocN(sizeof(float) * sds->res[0]*sds->res[1]*sds->res[2], "SmokeTempEmission"); - // set whole volume to 0.0f - for (i=0; i<sds->res[0]*sds->res[1]*sds->res[2]; i++) { - temp_emission_map[i] = 0.0f; - } - } + if (sfs->source == MOD_SMOKE_FLOW_SOURCE_PARTICLES) { + emit_from_particles(collob, sds, sfs, em, scene, time, dt); + } + else { + emit_from_derivedmesh(collob, sds, sfs, em, dt); + } - // mostly copied from particle code - if(psys->part->type==PART_HAIR) - { - /* - if(psys->childcache) - { - totchild = psys->totchildcache; + /* update required data fields */ + if (em->total_cells && sfs->type != MOD_SMOKE_FLOW_TYPE_OUTFLOW) { + /* activate heat field if flow produces any heat */ + if (sfs->temp) { + active_fields |= SM_ACTIVE_HEAT; + } + /* activate fuel field if flow adds any fuel */ + if (sfs->type != MOD_SMOKE_FLOW_TYPE_SMOKE && sfs->fuel_amount) { + active_fields |= SM_ACTIVE_FIRE; + } + /* activate color field if flows add smoke with varying colors */ + if (sfs->type != MOD_SMOKE_FLOW_TYPE_FIRE && sfs->density) { + if (!(active_fields & SM_ACTIVE_COLOR_SET)) { + copy_v3_v3(sds->active_color, sfs->color); + active_fields |= SM_ACTIVE_COLOR_SET; + } + else if (!equals_v3v3(sds->active_color, sfs->color)) { + active_fields |= SM_ACTIVE_COLORS; } - else - */ - - // TODO: PART_HAIR not supported whatsoever - totchild=0; } - else - totchild=psys->totchild*psys->part->disp/100; + } + } + } - for(p=0; p<totpart+totchild; p++) - { - int cell[3]; - size_t i = 0; - size_t index = 0; - int badcell = 0; - ParticleKey state; + /* monitor active fields based on domain settings */ + /* if domain has fire, activate new fields if required */ + if (active_fields & SM_ACTIVE_FIRE) { + /* heat is always needed for fire */ + active_fields |= SM_ACTIVE_HEAT; + /* also activate colors if domain smoke color differs from active color */ + if (!(active_fields & SM_ACTIVE_COLOR_SET)) { + copy_v3_v3(sds->active_color, sds->flame_smoke_color); + active_fields |= SM_ACTIVE_COLOR_SET; + } + else if (!equals_v3v3(sds->active_color, sds->flame_smoke_color)) { + active_fields |= SM_ACTIVE_COLORS; + } + } - if(p < totpart) - { - if(psys->particles[p].flag & (PARS_NO_DISP|PARS_UNEXIST)) - continue; - } - else { - /* handle child particle */ - ChildParticle *cpa = &psys->child[p - totpart]; + /* Adjust domain size if needed */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + adjustDomainResolution(sds, new_shift, emaps, numflowobj, dt); + } - if(psys->particles[cpa->parent].flag & (PARS_NO_DISP|PARS_UNEXIST)) - continue; - } + /* Initialize new data fields if any */ + if (active_fields & SM_ACTIVE_HEAT) { + smoke_ensure_heat(sds->fluid); + } + if (active_fields & SM_ACTIVE_FIRE) { + smoke_ensure_fire(sds->fluid, sds->wt); + } + if (active_fields & SM_ACTIVE_COLORS) { + /* initialize all smoke with "active_color" */ + smoke_ensure_colors(sds->fluid, sds->wt, sds->active_color[0], sds->active_color[1], sds->active_color[2]); + } + sds->active_fields = active_fields; - state.time = time; - if(psys_get_particle_state(&sim, p, &state, 0) == 0) - continue; + /* Apply emission data */ + if (sds->fluid) { + for (flowIndex = 0; flowIndex < numflowobj; flowIndex++) + { + Object *collob = flowobjs[flowIndex]; + SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(collob, eModifierType_Smoke); - // copy_v3_v3(pos, pa->state.co); - // mul_m4_v3(ob->imat, pos); - // 1. get corresponding cell - get_cell(sds->p0, sds->res, sds->dx*sds->scale, state.co, cell, 0); - // check if cell is valid (in the domain boundary) - for(i = 0; i < 3; i++) - { - if((cell[i] > sds->res[i] - 1) || (cell[i] < 0)) - { - badcell = 1; - break; - } - } - if(badcell) - continue; - // 2. set cell values (heat, density and velocity) - index = smoke_get_index(cell[0], sds->res[0], cell[1], sds->res[1], cell[2]); - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) && !(obstacle[index])) // this is inflow - { - // heat[index] += sfs->temp * 0.1; - // density[index] += sfs->density * 0.1; - heat[index] = sfs->temp; - - // Add emitter density to temp emission map - temp_emission_map[index] = sfs->density; - - // Uses particle velocity as initial velocity for smoke - if(sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY && (psys->part->phystype != PART_PHYS_NO)) - { - velocity_x[index] = state.vel[0]*sfs->vel_multi; - velocity_y[index] = state.vel[1]*sfs->vel_multi; - velocity_z[index] = state.vel[2]*sfs->vel_multi; - } - } - else if(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW) // outflow - { - heat[index] = 0.f; - density[index] = 0.f; - velocity_x[index] = 0.f; - velocity_y[index] = 0.f; - velocity_z[index] = 0.f; - // we need different handling for the high-res feature - if(bigdensity) - { - // init all surrounding cells according to amplification, too - int i, j, k; - smoke_turbulence_get_res(sds->wt, bigres); - - for(i = 0; i < sds->amplify + 1; i++) - for(j = 0; j < sds->amplify + 1; j++) - for(k = 0; k < sds->amplify + 1; k++) - { - index = smoke_get_index((sds->amplify + 1)* cell[0] + i, bigres[0], (sds->amplify + 1)* cell[1] + j, bigres[1], (sds->amplify + 1)* cell[2] + k); - bigdensity[index] = 0.f; - } - } - } - } // particles loop + // check for initialized smoke object + if ((smd2->type & MOD_SMOKE_TYPE_FLOW) && smd2->flow) + { + // we got nice flow object + SmokeFlowSettings *sfs = smd2->flow; + EmissionMap *em = &emaps[flowIndex]; + + float *density = smoke_get_density(sds->fluid); + float *color_r = smoke_get_color_r(sds->fluid); + float *color_g = smoke_get_color_g(sds->fluid); + float *color_b = smoke_get_color_b(sds->fluid); + float *fuel = smoke_get_fuel(sds->fluid); + float *react = smoke_get_react(sds->fluid); + float *bigdensity = smoke_turbulence_get_density(sds->wt); + float *bigfuel = smoke_turbulence_get_fuel(sds->wt); + float *bigreact = smoke_turbulence_get_react(sds->wt); + float *bigcolor_r = smoke_turbulence_get_color_r(sds->wt); + float *bigcolor_g = smoke_turbulence_get_color_g(sds->wt); + float *bigcolor_b = smoke_turbulence_get_color_b(sds->wt); + float *heat = smoke_get_heat(sds->fluid); + float *velocity_x = smoke_get_velocity_x(sds->fluid); + float *velocity_y = smoke_get_velocity_y(sds->fluid); + float *velocity_z = smoke_get_velocity_z(sds->fluid); + //unsigned char *obstacle = smoke_get_obstacle(sds->fluid); + // DG TODO UNUSED unsigned char *obstacleAnim = smoke_get_obstacle_anim(sds->fluid); + int bigres[3]; + short high_emission_smoothing = (sds->flags & MOD_SMOKE_HIGH_SMOOTH); + float *velocity_map = em->velocity; + float *emission_map = em->influence; - // apply emission values - if(!(sfs->type & MOD_SMOKE_FLOW_TYPE_OUTFLOW)) - { - // initialize variables - int ii, jj, kk, x, y, z, block_size; - size_t index, index_big; + int ii, jj, kk, gx, gy, gz, ex, ey, ez, dx, dy, dz, block_size; + size_t e_index, d_index, index_big; - smoke_turbulence_get_res(sds->wt, bigres); - block_size = sds->amplify + 1; // high res block size + // loop through every emission map cell + for (gx = em->min[0]; gx < em->max[0]; gx++) + for (gy = em->min[1]; gy < em->max[1]; gy++) + for (gz = em->min[2]; gz < em->max[2]; gz++) + { + /* get emission map index */ + ex = gx - em->min[0]; + ey = gy - em->min[1]; + ez = gz - em->min[2]; + e_index = smoke_get_index(ex, em->res[0], ey, em->res[1], ez); + if (!emission_map[e_index]) continue; + /* get domain index */ + dx = gx - sds->res_min[0]; + dy = gy - sds->res_min[1]; + dz = gz - sds->res_min[2]; + d_index = smoke_get_index(dx, sds->res[0], dy, sds->res[1], dz); + + if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + apply_outflow_fields(d_index, density, heat, fuel, react, color_r, color_g, color_b); + } + else { // inflow + apply_inflow_fields(sfs, emission_map[e_index], d_index, density, heat, fuel, react, color_r, color_g, color_b); + + /* initial velocity */ + if (sfs->flags & MOD_SMOKE_FLOW_INITVELOCITY) { + velocity_x[d_index] = ADD_IF_LOWER(velocity_x[d_index], velocity_map[e_index * 3]); + velocity_y[d_index] = ADD_IF_LOWER(velocity_y[d_index], velocity_map[e_index * 3 + 1]); + velocity_z[d_index] = ADD_IF_LOWER(velocity_z[d_index], velocity_map[e_index * 3 + 2]); + } + } - // loop through every low res cell - for(x = 0; x < sds->res[0]; x++) - for(y = 0; y < sds->res[1]; y++) - for(z = 0; z < sds->res[2]; z++) - { + /* loop through high res blocks if high res enabled */ + if (bigdensity) { // neighbor cell emission densities (for high resolution smoke smooth interpolation) float c000, c001, c010, c011, c100, c101, c110, c111; - c000 = (x>0 && y>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z-1)] : 0; - c001 = (x>0 && y>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y-1, sds->res[1], z)] : 0; - c010 = (x>0 && z>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z-1)] : 0; - c011 = (x>0) ? temp_emission_map[smoke_get_index(x-1, sds->res[0], y, sds->res[1], z)] : 0; + smoke_turbulence_get_res(sds->wt, bigres); + block_size = sds->amplify + 1; // high res block size - c100 = (y>0 && z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z-1)] : 0; - c101 = (y>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y-1, sds->res[1], z)] : 0; - c110 = (z>0) ? temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z-1)] : 0; - c111 = temp_emission_map[smoke_get_index(x, sds->res[0], y, sds->res[1], z)]; // this cell + c000 = (ex > 0 && ey > 0 && ez > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey - 1, em->res[1], ez - 1)] : 0; + c001 = (ex > 0 && ey > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey - 1, em->res[1], ez)] : 0; + c010 = (ex > 0 && ez > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey, em->res[1], ez - 1)] : 0; + c011 = (ex > 0) ? emission_map[smoke_get_index(ex - 1, em->res[0], ey, em->res[1], ez)] : 0; - // get cell index - index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + c100 = (ey > 0 && ez > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey - 1, em->res[1], ez - 1)] : 0; + c101 = (ey > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey - 1, em->res[1], ez)] : 0; + c110 = (ez > 0) ? emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez - 1)] : 0; + c111 = emission_map[smoke_get_index(ex, em->res[0], ey, em->res[1], ez)]; // this cell - // add emission to low resolution density - if (absolute_flow) - { - if (temp_emission_map[index]>0) - density[index] = temp_emission_map[index]; - } - else - { - density[index] += temp_emission_map[index]; + for (ii = 0; ii < block_size; ii++) + for (jj = 0; jj < block_size; jj++) + for (kk = 0; kk < block_size; kk++) + { - if (density[index]>1) - density[index]=1.0f; - } + float fx, fy, fz, interpolated_value; + int shift_x, shift_y, shift_z; - smoke_turbulence_get_res(sds->wt, bigres); - /* loop through high res blocks if high res enabled */ - if (bigdensity) - for(ii = 0; ii < block_size; ii++) - for(jj = 0; jj < block_size; jj++) - for(kk = 0; kk < block_size; kk++) + /* + * Do volume interpolation if emitter smoothing + * is enabled + */ + if (high_emission_smoothing) { - - float fx,fy,fz, interpolated_value; - int shift_x, shift_y, shift_z; - - - /* - * Do volume interpolation if emitter smoothing - * is enabled - */ - if (high_emission_smoothing) - { - // convert block position to relative - // for interpolation smoothing - fx = (float)ii/block_size + 0.5f/block_size; - fy = (float)jj/block_size + 0.5f/block_size; - fz = (float)kk/block_size + 0.5f/block_size; - - // calculate trilinear interpolation - interpolated_value = c000 * (1-fx) * (1-fy) * (1-fz) + - c100 * fx * (1-fy) * (1-fz) + - c010 * (1-fx) * fy * (1-fz) + - c001 * (1-fx) * (1-fy) * fz + - c101 * fx * (1-fy) * fz + - c011 * (1-fx) * fy * fz + - c110 * fx * fy * (1-fz) + - c111 * fx * fy * fz; - - - // add some contrast / sharpness - // depending on hi-res block size - - interpolated_value = (interpolated_value-0.4f*sfs->density)*(block_size/2) + 0.4f*sfs->density; - if (interpolated_value<0.0f) interpolated_value = 0.0f; - if (interpolated_value>1.0f) interpolated_value = 1.0f; - - // shift smoke block index - // (because pixel center is actually - // in halfway of the low res block) - shift_x = (x < 1) ? 0 : block_size/2; - shift_y = (y < 1) ? 0 : block_size/2; - shift_z = (z < 1) ? 0 : block_size/2; - } - else - { - // without interpolation use same low resolution - // block value for all hi-res blocks - interpolated_value = c111; - shift_x = 0; - shift_y = 0; - shift_z = 0; + /* get relative block position + * for interpolation smoothing */ + fx = (float)ii / block_size + 0.5f / block_size; + fy = (float)jj / block_size + 0.5f / block_size; + fz = (float)kk / block_size + 0.5f / block_size; + + /* calculate trilinear interpolation */ + interpolated_value = c000 * (1 - fx) * (1 - fy) * (1 - fz) + + c100 * fx * (1 - fy) * (1 - fz) + + c010 * (1 - fx) * fy * (1 - fz) + + c001 * (1 - fx) * (1 - fy) * fz + + c101 * fx * (1 - fy) * fz + + c011 * (1 - fx) * fy * fz + + c110 * fx * fy * (1 - fz) + + c111 * fx * fy * fz; + + + /* add some contrast / sharpness + * depending on hi-res block size */ + interpolated_value = (interpolated_value - 0.4f) * (block_size / 2) + 0.4f; + CLAMP(interpolated_value, 0.0f, 1.0f); + + /* shift smoke block index + * (because pixel center is actually + * in halfway of the low res block) */ + shift_x = (dx < 1) ? 0 : block_size / 2; + shift_y = (dy < 1) ? 0 : block_size / 2; + shift_z = (dz < 1) ? 0 : block_size / 2; + } + else { + /* without interpolation use same low resolution + * block value for all hi-res blocks */ + interpolated_value = c111; + shift_x = 0; + shift_y = 0; + shift_z = 0; + } + + /* get shifted index for current high resolution block */ + index_big = smoke_get_index(block_size * dx + ii - shift_x, bigres[0], block_size * dy + jj - shift_y, bigres[1], block_size * dz + kk - shift_z); + + if (sfs->type == MOD_SMOKE_FLOW_TYPE_OUTFLOW) { // outflow + if (interpolated_value) { + apply_outflow_fields(index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); } - - // get shifted index for current high resolution block - index_big = smoke_get_index(block_size * x + ii - shift_x, bigres[0], block_size * y + jj - shift_y, bigres[1], block_size * z + kk - shift_z); - - // add emission data to high resolution density - if (absolute_flow) - { - if (interpolated_value > 0) - bigdensity[index_big] = interpolated_value; - } - else - { - bigdensity[index_big] += interpolated_value; - - if (bigdensity[index_big]>1) - bigdensity[index_big]=1.0f; - } - } // end of hires loop - - } // end of low res loop - - // free temporary emission map - if (temp_emission_map) - MEM_freeN(temp_emission_map); - - } // end emission - } + } + else { // inflow + apply_inflow_fields(sfs, interpolated_value, index_big, bigdensity, NULL, bigfuel, bigreact, bigcolor_r, bigcolor_g, bigcolor_b); + } + } // hires loop + } // bigdensity + } // low res loop + + // free emission maps + em_freeData(em); + + } // end emission } } - if(flowobjs) + if (flowobjs) MEM_freeN(flowobjs); + if (emaps) + MEM_freeN(emaps); } static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float UNUSED(dt)) { - ListBase *effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); + ListBase *effectors; + /* make sure smoke flow influence is 0.0f */ + sds->effector_weights->weight[PFIELD_SMOKEFLOW] = 0.0f; + effectors = pdInitEffectors(scene, ob, NULL, sds->effector_weights); - if(effectors) + if (effectors) { float *density = smoke_get_density(sds->fluid); float *force_x = smoke_get_force_x(sds->fluid); @@ -1532,76 +1902,113 @@ static void update_effectors(Scene *scene, Object *ob, SmokeDomainSettings *sds, float *velocity_y = smoke_get_velocity_y(sds->fluid); float *velocity_z = smoke_get_velocity_z(sds->fluid); unsigned char *obstacle = smoke_get_obstacle(sds->fluid); - int x, y, z; + int x; // precalculate wind forces - for(x = 0; x < sds->res[0]; x++) - for(y = 0; y < sds->res[1]; y++) - for(z = 0; z < sds->res[2]; z++) - { - EffectedPoint epoint; - float voxelCenter[3] = {0,0,0}, vel[3] = {0,0,0}, retvel[3] = {0,0,0}; - unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); - - if((density[index] < FLT_EPSILON) || obstacle[index]) - continue; - - vel[0] = velocity_x[index]; - vel[1] = velocity_y[index]; - vel[2] = velocity_z[index]; - - voxelCenter[0] = sds->p0[0] + sds->dx * sds->scale * x + sds->dx * sds->scale * 0.5; - voxelCenter[1] = sds->p0[1] + sds->dx * sds->scale * y + sds->dx * sds->scale * 0.5; - voxelCenter[2] = sds->p0[2] + sds->dx * sds->scale * z + sds->dx * sds->scale * 0.5; - - pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); - pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); - - // TODO dg - do in force! - force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); - force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); - force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + #pragma omp parallel for schedule(static) + for (x = 0; x < sds->res[0]; x++) + { + int y, z; + for (y = 0; y < sds->res[1]; y++) + for (z = 0; z < sds->res[2]; z++) + { + EffectedPoint epoint; + float mag; + float voxelCenter[3] = {0, 0, 0}, vel[3] = {0, 0, 0}, retvel[3] = {0, 0, 0}; + unsigned int index = smoke_get_index(x, sds->res[0], y, sds->res[1], z); + + if ((density[index] < FLT_EPSILON) || obstacle[index]) + continue; + + vel[0] = velocity_x[index]; + vel[1] = velocity_y[index]; + vel[2] = velocity_z[index]; + + /* convert vel to global space */ + mag = len_v3(vel); + mul_mat3_m4_v3(sds->obmat, vel); + normalize_v3(vel); + mul_v3_fl(vel, mag); + + voxelCenter[0] = sds->p0[0] + sds->cell_size[0] * ((float)(x + sds->res_min[0]) + 0.5f); + voxelCenter[1] = sds->p0[1] + sds->cell_size[1] * ((float)(y + sds->res_min[1]) + 0.5f); + voxelCenter[2] = sds->p0[2] + sds->cell_size[2] * ((float)(z + sds->res_min[2]) + 0.5f); + mul_m4_v3(sds->obmat, voxelCenter); + + pd_point_from_loc(scene, voxelCenter, vel, index, &epoint); + pdDoEffectors(effectors, NULL, sds->effector_weights, &epoint, retvel, NULL); + + /* convert retvel to local space */ + mag = len_v3(retvel); + mul_mat3_m4_v3(sds->imat, retvel); + normalize_v3(retvel); + mul_v3_fl(retvel, mag); + + // TODO dg - do in force! + force_x[index] = MIN2(MAX2(-1.0, retvel[0] * 0.2), 1.0); + force_y[index] = MIN2(MAX2(-1.0, retvel[1] * 0.2), 1.0); + force_z[index] = MIN2(MAX2(-1.0, retvel[2] * 0.2), 1.0); + } } } pdEndEffectors(&effectors); } -static void step(Scene *scene, Object *ob, SmokeModifierData *smd, float fps) +static void step(Scene *scene, Object *ob, SmokeModifierData *smd, DerivedMesh *domain_dm, float fps) { + SmokeDomainSettings *sds = smd->domain; /* stability values copied from wturbulence.cpp */ const int maxSubSteps = 25; float maxVel; // maxVel should be 1.5 (1.5 cell max movement) * dx (cell size) - float dt = DT_DEFAULT; + float dt; float maxVelMag = 0.0f; int totalSubsteps; int substep = 0; float dtSubdiv; + float gravity[3] = {0.0f, 0.0f, -1.0f}; + float gravity_mag; - SmokeDomainSettings *sds = smd->domain; - - /* get max velocity and lower the dt value if it is too high */ - size_t size= sds->res[0] * sds->res[1] * sds->res[2]; - +#if 0 /* UNUSED */ + /* get max velocity and lower the dt value if it is too high */ + size_t size = sds->res[0] * sds->res[1] * sds->res[2]; float *velX = smoke_get_velocity_x(sds->fluid); float *velY = smoke_get_velocity_y(sds->fluid); float *velZ = smoke_get_velocity_z(sds->fluid); size_t i; +#endif - /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ - dt *= (25.0f / fps); + /* update object state */ + invert_m4_m4(sds->imat, ob->obmat); + copy_m4_m4(sds->obmat, ob->obmat); + smoke_set_domain_from_derivedmesh(sds, ob, domain_dm); + /* use global gravity if enabled */ + if (scene->physics_settings.flag & PHYS_GLOBAL_GRAVITY) { + copy_v3_v3(gravity, scene->physics_settings.gravity); + /* map default value to 1.0 */ + mul_v3_fl(gravity, 1.0f / 9.810f); + } + /* convert gravity to domain space */ + gravity_mag = len_v3(gravity); + mul_mat3_m4_v3(sds->imat, gravity); + normalize_v3(gravity); + mul_v3_fl(gravity, gravity_mag); + + /* adapt timestep for different framerates, dt = 0.1 is at 25fps */ + dt = DT_DEFAULT * (25.0f / fps); // maximum timestep/"CFL" constraint: dt < 5.0 *dx / maxVel maxVel = (sds->dx * 5.0); - for(i = 0; i < size; i++) - { - float vtemp = (velX[i]*velX[i]+velY[i]*velY[i]+velZ[i]*velZ[i]); - if(vtemp > maxVelMag) +#if 0 + for (i = 0; i < size; i++) { + float vtemp = (velX[i] * velX[i] + velY[i] * velY[i] + velZ[i] * velZ[i]); + if (vtemp > maxVelMag) maxVelMag = vtemp; } +#endif maxVelMag = sqrt(maxVelMag) * dt * sds->time_scale; totalSubsteps = (int)((maxVelMag / maxVel) + 1.0f); /* always round up */ @@ -1609,146 +2016,155 @@ static void step(Scene *scene, Object *ob, SmokeModifierData *smd, float fps) totalSubsteps = (totalSubsteps > maxSubSteps) ? maxSubSteps : totalSubsteps; /* Disable substeps for now, since it results in numerical instability */ - totalSubsteps = 1.0f; + totalSubsteps = 1.0f; dtSubdiv = (float)dt / (float)totalSubsteps; // printf("totalSubsteps: %d, maxVelMag: %f, dt: %f\n", totalSubsteps, maxVelMag, dt); - for(substep = 0; substep < totalSubsteps; substep++) + for (substep = 0; substep < totalSubsteps; substep++) { // calc animated obstacle velocities + update_flowsfluids(scene, ob, sds, smd->time, dtSubdiv); update_obstacles(scene, ob, sds, dtSubdiv, substep, totalSubsteps); - update_flowsfluids(scene, ob, sds, smd->time); - update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt - smoke_step(sds->fluid, dtSubdiv); + if (sds->total_cells > 1) { + update_effectors(scene, ob, sds, dtSubdiv); // DG TODO? problem --> uses forces instead of velocity, need to check how they need to be changed with variable dt + smoke_step(sds->fluid, gravity, dtSubdiv); + } + } +} - // move animated obstacle: Done in update_obstacles() */ +static DerivedMesh *createDomainGeometry(SmokeDomainSettings *sds, Object *ob) +{ + DerivedMesh *result; + MVert *mverts; + MPoly *mpolys; + MLoop *mloops; + float min[3]; + float max[3]; + float *co; + MPoly *mp; + MLoop *ml; + + int num_verts = 8; + int num_faces = 6; + int i; + float ob_loc[3] = {0}; + float ob_cache_loc[3] = {0}; + + /* dont generate any mesh if there isnt any content */ + if (sds->total_cells <= 1) { + num_verts = 0; + num_faces = 0; + } - // where to delete old obstacles from array? Done in update_obstacles() */ + result = CDDM_new(num_verts, 0, 0, num_faces * 4, num_faces); + mverts = CDDM_get_verts(result); + mpolys = CDDM_get_polys(result); + mloops = CDDM_get_loops(result); + + + if (num_verts) { + /* volume bounds */ + VECMADD(min, sds->p0, sds->cell_size, sds->res_min); + VECMADD(max, sds->p0, sds->cell_size, sds->res_max); + + /* set vertices */ + /* top slab */ + co = mverts[0].co; co[0] = min[0]; co[1] = min[1]; co[2] = max[2]; + co = mverts[1].co; co[0] = max[0]; co[1] = min[1]; co[2] = max[2]; + co = mverts[2].co; co[0] = max[0]; co[1] = max[1]; co[2] = max[2]; + co = mverts[3].co; co[0] = min[0]; co[1] = max[1]; co[2] = max[2]; + /* bottom slab */ + co = mverts[4].co; co[0] = min[0]; co[1] = min[1]; co[2] = min[2]; + co = mverts[5].co; co[0] = max[0]; co[1] = min[1]; co[2] = min[2]; + co = mverts[6].co; co[0] = max[0]; co[1] = max[1]; co[2] = min[2]; + co = mverts[7].co; co[0] = min[0]; co[1] = max[1]; co[2] = min[2]; + + /* create faces */ + /* top */ + mp = &mpolys[0]; ml = &mloops[0 * 4]; mp->loopstart = 0 * 4; mp->totloop = 4; + ml[0].v = 0; ml[1].v = 1; ml[2].v = 2; ml[3].v = 3; + /* right */ + mp = &mpolys[1]; ml = &mloops[1 * 4]; mp->loopstart = 1 * 4; mp->totloop = 4; + ml[0].v = 2; ml[1].v = 1; ml[2].v = 5; ml[3].v = 6; + /* bottom */ + mp = &mpolys[2]; ml = &mloops[2 * 4]; mp->loopstart = 2 * 4; mp->totloop = 4; + ml[0].v = 7; ml[1].v = 6; ml[2].v = 5; ml[3].v = 4; + /* left */ + mp = &mpolys[3]; ml = &mloops[3 * 4]; mp->loopstart = 3 * 4; mp->totloop = 4; + ml[0].v = 0; ml[1].v = 3; ml[2].v = 7; ml[3].v = 4; + /* front */ + mp = &mpolys[4]; ml = &mloops[4 * 4]; mp->loopstart = 4 * 4; mp->totloop = 4; + ml[0].v = 3; ml[1].v = 2; ml[2].v = 6; ml[3].v = 7; + /* back */ + mp = &mpolys[5]; ml = &mloops[5 * 4]; mp->loopstart = 5 * 4; mp->totloop = 4; + ml[0].v = 1; ml[1].v = 0; ml[2].v = 4; ml[3].v = 5; + + /* calculate required shift to match domain's global position + * it was originally simulated at (if object moves without smoke step) */ + invert_m4_m4(ob->imat, ob->obmat); + mul_m4_v3(ob->obmat, ob_loc); + mul_m4_v3(sds->obmat, ob_cache_loc); + VECSUB(sds->obj_shift_f, ob_cache_loc, ob_loc); + /* convert shift to local space and apply to vertices */ + mul_mat3_m4_v3(ob->imat, sds->obj_shift_f); + /* apply */ + for (i = 0; i < num_verts; i++) { + add_v3_v3(mverts[i].co, sds->obj_shift_f); + } } + + + CDDM_calc_edges(result); + return result; } -void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) -{ - if((smd->type & MOD_SMOKE_TYPE_FLOW)) +static void smokeModifier_process(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm) +{ + if ((smd->type & MOD_SMOKE_TYPE_FLOW)) { - if(scene->r.cfra >= smd->time) + if (scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); - if(scene->r.cfra > smd->time) + if (smd->flow->dm) smd->flow->dm->release(smd->flow->dm); + smd->flow->dm = CDDM_copy(dm); + DM_ensure_tessface(smd->flow->dm); + + if (scene->r.cfra > smd->time) { - // XXX TODO smd->time = scene->r.cfra; - - // rigid movement support - /* - copy_m4_m4(smd->flow->mat_old, smd->flow->mat); - copy_m4_m4(smd->flow->mat, ob->obmat); - */ } - else if(scene->r.cfra < smd->time) + else if (scene->r.cfra < smd->time) { smd->time = scene->r.cfra; smokeModifier_reset(smd); } } - else if(smd->type & MOD_SMOKE_TYPE_COLL) + else if (smd->type & MOD_SMOKE_TYPE_COLL) { - /* Check if domain resolution changed */ - /* DG TODO: can this be solved more elegant using dependancy graph? */ - { - SmokeCollSettings *scs = smd->coll; - Base *base = scene->base.first; - int changed = 0; - float dx = FLT_MAX; - float scale = 1.0f; - int haveDomain = 0; - - for ( ; base; base = base->next) - { - SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke); - - if (smd2 && (smd2->type & MOD_SMOKE_TYPE_DOMAIN) && smd2->domain) - { - SmokeDomainSettings *sds = smd2->domain; - - if(sds->dx * sds->scale < dx) - { - dx = sds->dx; - scale = sds->scale; - changed = 1; - } - - haveDomain = 1; - } - } - - if(!haveDomain) - return; - - if(changed) - { - if(dx*scale != scs->dx) - { - scs->dx = dx*scale; - smokeModifier_reset(smd); - } - } - } - - if(scene->r.cfra >= smd->time) + if (scene->r.cfra >= smd->time) smokeModifier_init(smd, ob, scene, dm); - if(scene->r.cfra > smd->time) + if (smd->coll) { - unsigned int i; - SmokeCollSettings *scs = smd->coll; - float *points_old = scs->points_old; - float *points = scs->points; - unsigned int numpoints = scs->numpoints; - - // XXX TODO <-- DG: what is TODO here? - smd->time = scene->r.cfra; - - // rigid movement support - copy_m4_m4(scs->mat_old, scs->mat); - copy_m4_m4(scs->mat, ob->obmat); - - if(scs->type != SM_COLL_ANIMATED) // if(not_animated) - { - // nothing to do, "mat" is already up to date - } - else - { - // XXX TODO: need to update positions + divs - - if(scs->numverts != dm->getNumVerts(dm)) - { - // DG TODO: reset modifier? - return; - } + if (smd->coll->dm) + smd->coll->dm->release(smd->coll->dm); - for(i = 0; i < numpoints * 3; i++) - { - points_old[i] = points[i]; - } - - DM_ensure_tessface(dm); - fill_scs_points_anim(ob, dm, scs); - } + smd->coll->dm = CDDM_copy(dm); + DM_ensure_tessface(smd->coll->dm); } - else if(scene->r.cfra < smd->time) + + smd->time = scene->r.cfra; + if (scene->r.cfra < smd->time) { - smd->time = scene->r.cfra; smokeModifier_reset(smd); } } - else if(smd->type & MOD_SMOKE_TYPE_DOMAIN) + else if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { SmokeDomainSettings *sds = smd->domain; - float light[3]; PointCache *cache = NULL; PTCacheID pid; int startframe, endframe, framenr; @@ -1762,41 +2178,39 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM BKE_ptcache_id_from_smoke(&pid, ob, smd); BKE_ptcache_id_time(&pid, scene, framenr, &startframe, &endframe, ×cale); - if(!smd->domain->fluid || framenr == startframe) + if (!smd->domain->fluid || framenr == startframe) { BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED); + smokeModifier_reset(smd); BKE_ptcache_validate(cache, framenr); cache->flag &= ~PTCACHE_REDO_NEEDED; } - if(!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD)==0 && (cache->flag & PTCACHE_BAKED)==0) + if (!smd->domain->fluid && (framenr != startframe) && (smd->domain->flags & MOD_SMOKE_FILE_LOAD) == 0 && (cache->flag & PTCACHE_BAKED) == 0) return; smd->domain->flags &= ~MOD_SMOKE_FILE_LOAD; - CLAMP(framenr, startframe, endframe); /* If already viewing a pre/after frame, no need to reload */ if ((smd->time == framenr) && (framenr != scene->r.cfra)) return; - // printf("startframe: %d, framenr: %d\n", startframe, framenr); - - if(smokeModifier_init(smd, ob, scene, dm)==0) + if (smokeModifier_init(smd, ob, scene, dm) == 0) { printf("bad smokeModifier_init\n"); return; } /* try to read from cache */ - if(BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) { + if (BKE_ptcache_read(&pid, (float)framenr) == PTCACHE_READ_EXACT) { BKE_ptcache_validate(cache, framenr); smd->time = framenr; return; } - + /* only calculate something when we advanced a single frame */ - if(framenr != (int)smd->time+1) + if (framenr != (int)smd->time + 1) return; /* don't simulate if viewing start frame, but scene frame is not real start frame */ @@ -1805,54 +2219,48 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM tstart(); - smoke_calc_domain(scene, ob, smd); - /* if on second frame, write cache for first frame */ - if((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact==0)) { + if ((int)smd->time == startframe && (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0)) { // create shadows straight after domain initialization so we get nice shadows for startframe, too - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + smoke_calc_transparency(sds, scene); - if(sds->wt) + if (sds->wt && sds->total_cells > 1) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); } BKE_ptcache_write(&pid, startframe); } - + // set new time smd->time = scene->r.cfra; /* do simulation */ - // low res - // simulate the actual smoke (c++ code in intern/smoke) // DG: interesting commenting this line + deactivating loading of noise files - if(framenr!=startframe) + if (framenr != startframe) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve(sds->fluid, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); - - step(scene, ob, smd, scene->r.frs_sec / scene->r.frs_sec_base); + + step(scene, ob, smd, dm, scene->r.frs_sec / scene->r.frs_sec_base); } // create shadows before writing cache so they get stored - if(get_lamp(scene, light)) - smoke_calc_transparency(sds->shadow, smoke_get_density(sds->fluid), sds->p0, sds->p1, sds->res, sds->dx, light, calc_voxel_transp, -7.0*sds->dx); + smoke_calc_transparency(sds, scene); - if(sds->wt) + if (sds->wt) { - if(sds->flags & MOD_SMOKE_DISSOLVE) + if (sds->flags & MOD_SMOKE_DISSOLVE) smoke_dissolve_wavelet(sds->wt, sds->diss_speed, sds->flags & MOD_SMOKE_DISSOLVE_LOG); smoke_turbulence_step(sds->wt, sds->fluid); } - + BKE_ptcache_validate(cache, framenr); - if(framenr != startframe) + if (framenr != startframe) BKE_ptcache_write(&pid, framenr); tend(); @@ -1860,38 +2268,33 @@ void smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedM } } -static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct) -{ - const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); +struct DerivedMesh *smokeModifier_do(SmokeModifierData *smd, Scene *scene, Object *ob, DerivedMesh *dm){ + smokeModifier_process(smd, scene, ob, dm); - // T_ray *= T_vox - *tRay *= exp(input[index]*correct); - - if(result[index] < 0.0f) + /* return generated geometry for adaptive domain */ + if (smd->type & MOD_SMOKE_TYPE_DOMAIN && smd->domain && + smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN && + smd->domain->base_res[0]) { -// #pragma omp critical - result[index] = *tRay; - } - - return *tRay; + return createDomainGeometry(smd->domain, ob); + } + else return CDDM_copy(dm); } -long long smoke_get_mem_req(int xres, int yres, int zres, int amplify) +static float calc_voxel_transp(float *result, float *input, int res[3], int *pixel, float *tRay, float correct) { - int totalCells = xres * yres * zres; - int amplifiedCells = totalCells * amplify * amplify * amplify; - - // print out memory requirements - long long int coarseSize = sizeof(float) * totalCells * 22 + - sizeof(unsigned char) * totalCells; + const size_t index = smoke_get_index(pixel[0], res[0], pixel[1], res[1], pixel[2]); - long long int fineSize = sizeof(float) * amplifiedCells * 7 + // big grids - sizeof(float) * totalCells * 8 + // small grids - sizeof(float) * 128 * 128 * 128; // noise tile + // T_ray *= T_vox + *tRay *= exp(input[index] * correct); - long long int totalMB = (coarseSize + fineSize) / (1024 * 1024); + if (result[index] < 0.0f) + { +// #pragma omp critical + result[index] = *tRay; + } - return totalMB; + return *tRay; } static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, float *tRay, bresenham_callback cb, float *result, float *input, int res[3], float correct) @@ -1921,7 +2324,7 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_1 = dy2 - l; err_2 = dz2 - l; for (i = 0; i < l; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[1] += y_inc; @@ -1935,12 +2338,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_2 += dz2; pixel[0] += x_inc; } - } + } else if ((m >= l) && (m >= n)) { err_1 = dx2 - m; err_2 = dz2 - m; for (i = 0; i < m; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[0] += x_inc; @@ -1954,12 +2357,12 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f err_2 += dz2; pixel[1] += y_inc; } - } + } else { err_1 = dy2 - n; err_2 = dx2 - n; for (i = 0; i < n; i++) { - if(cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) + if (cb(result, input, res, pixel, tRay, correct) <= FLT_EPSILON) break; if (err_1 > 0) { pixel[1] += y_inc; @@ -1977,80 +2380,142 @@ static void bresenham_linie_3D(int x1, int y1, int z1, int x2, int y2, int z2, f cb(result, input, res, pixel, tRay, correct); } -static void get_cell(const float p0[3], const int res[3], float dx, const float pos[3], int cell[3], int correct) +static void smoke_calc_transparency(SmokeDomainSettings *sds, Scene *scene) { - float tmp[3]; + float bv[6] = {0}; + float light[3]; + int a, z, slabsize = sds->res[0] * sds->res[1], size = sds->res[0] * sds->res[1] * sds->res[2]; + float *density = smoke_get_density(sds->fluid); + float correct = -7.0 * sds->dx; - sub_v3_v3v3(tmp, pos, p0); - mul_v3_fl(tmp, 1.0 / dx); + if (!get_lamp(scene, light)) return; - if (correct) { - cell[0] = MIN2(res[0] - 1, MAX2(0, (int)floor(tmp[0]))); - cell[1] = MIN2(res[1] - 1, MAX2(0, (int)floor(tmp[1]))); - cell[2] = MIN2(res[2] - 1, MAX2(0, (int)floor(tmp[2]))); - } - else { - cell[0] = (int)floor(tmp[0]); - cell[1] = (int)floor(tmp[1]); - cell[2] = (int)floor(tmp[2]); - } -} - -static void smoke_calc_transparency(float *result, float *input, float *p0, float *p1, int res[3], float dx, float *light, bresenham_callback cb, float correct) -{ - float bv[6]; - int a, z, slabsize=res[0]*res[1], size= res[0]*res[1]*res[2]; + /* convert light pos to sim cell space */ + mul_m4_v3(sds->imat, light); + light[0] = (light[0] - sds->p0[0]) / sds->cell_size[0] - 0.5f - (float)sds->res_min[0]; + light[1] = (light[1] - sds->p0[1]) / sds->cell_size[1] - 0.5f - (float)sds->res_min[1]; + light[2] = (light[2] - sds->p0[2]) / sds->cell_size[2] - 0.5f - (float)sds->res_min[2]; - for(a=0; a<size; a++) - result[a]= -1.0f; + for (a = 0; a < size; a++) + sds->shadow[a] = -1.0f; - bv[0] = p0[0]; - bv[1] = p1[0]; - // y - bv[2] = p0[1]; - bv[3] = p1[1]; - // z - bv[4] = p0[2]; - bv[5] = p1[2]; + /* calculate domain bounds in sim cell space */ + // 0,2,4 = 0.0f + bv[1] = (float)sds->res[0]; // x + bv[3] = (float)sds->res[1]; // y + bv[5] = (float)sds->res[2]; // z // #pragma omp parallel for schedule(static,1) - for(z = 0; z < res[2]; z++) + for (z = 0; z < sds->res[2]; z++) { - size_t index = z*slabsize; - int x,y; + size_t index = z * slabsize; + int x, y; - for(y = 0; y < res[1]; y++) - for(x = 0; x < res[0]; x++, index++) + for (y = 0; y < sds->res[1]; y++) + for (x = 0; x < sds->res[0]; x++, index++) { float voxelCenter[3]; float pos[3]; int cell[3]; float tRay = 1.0; - if(result[index] >= 0.0f) - continue; - voxelCenter[0] = p0[0] + dx * x + dx * 0.5; - voxelCenter[1] = p0[1] + dx * y + dx * 0.5; - voxelCenter[2] = p0[2] + dx * z + dx * 0.5; + if (sds->shadow[index] >= 0.0f) + continue; + voxelCenter[0] = (float)x; + voxelCenter[1] = (float)y; + voxelCenter[2] = (float)z; - // get starting position (in voxel coords) - if(BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) + // get starting cell (light pos) + if (BLI_bvhtree_bb_raycast(bv, light, voxelCenter, pos) > FLT_EPSILON) { - // we're ouside - get_cell(p0, res, dx, pos, cell, 1); + // we're ouside -> use point on side of domain + cell[0] = (int)floor(pos[0]); + cell[1] = (int)floor(pos[1]); + cell[2] = (int)floor(pos[2]); } else { - // we're inside - get_cell(p0, res, dx, light, cell, 1); + // we're inside -> use light itself + cell[0] = (int)floor(light[0]); + cell[1] = (int)floor(light[1]); + cell[2] = (int)floor(light[2]); } + /* clamp within grid bounds */ + CLAMP(cell[0], 0, sds->res[0] - 1); + CLAMP(cell[1], 0, sds->res[1] - 1); + CLAMP(cell[2], 0, sds->res[2] - 1); - bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, cb, result, input, res, correct); + bresenham_linie_3D(cell[0], cell[1], cell[2], x, y, z, &tRay, calc_voxel_transp, sds->shadow, density, sds->res, correct); // convention -> from a RGBA float array, use G value for tRay // #pragma omp critical - result[index] = tRay; + sds->shadow[index] = tRay; } } } +/* get smoke velocity and density at given coordinates + * returns fluid density or -1.0f if outside domain*/ +float smoke_get_velocity_at(struct Object *ob, float position[3], float velocity[3]) +{ + SmokeModifierData *smd = (SmokeModifierData *)modifiers_findByType(ob, eModifierType_Smoke); + zero_v3(velocity); + + if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain && smd->domain->fluid) { + SmokeDomainSettings *sds = smd->domain; + float time_mult = 25.f * DT_DEFAULT; + float vel_mag; + float *velX = smoke_get_velocity_x(sds->fluid); + float *velY = smoke_get_velocity_y(sds->fluid); + float *velZ = smoke_get_velocity_z(sds->fluid); + float density = 0.0f, fuel = 0.0f; + float pos[3]; + copy_v3_v3(pos, position); + smoke_pos_to_cell(sds, pos); + + /* check if point is outside domain max bounds */ + if (pos[0] < sds->res_min[0] || pos[1] < sds->res_min[1] || pos[2] < sds->res_min[2]) return -1.0f; + if (pos[0] > sds->res_max[0] || pos[1] > sds->res_max[1] || pos[2] > sds->res_max[2]) return -1.0f; + + /* map pos between 0.0 - 1.0 */ + pos[0] = (pos[0] - sds->res_min[0]) / ((float)sds->res[0]); + pos[1] = (pos[1] - sds->res_min[1]) / ((float)sds->res[1]); + pos[2] = (pos[2] - sds->res_min[2]) / ((float)sds->res[2]); + + + /* check if point is outside active area */ + if (smd->domain->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + if (pos[0] < 0.0f || pos[1] < 0.0f || pos[2] < 0.0f) return 0.0f; + if (pos[0] > 1.0f || pos[1] > 1.0f || pos[2] > 1.0f) return 0.0f; + } + + /* get interpolated velocity */ + velocity[0] = BLI_voxel_sample_trilinear(velX, sds->res, pos) * sds->global_size[0] * time_mult; + velocity[1] = BLI_voxel_sample_trilinear(velY, sds->res, pos) * sds->global_size[1] * time_mult; + velocity[2] = BLI_voxel_sample_trilinear(velZ, sds->res, pos) * sds->global_size[2] * time_mult; + + /* convert velocity direction to global space */ + vel_mag = len_v3(velocity); + mul_mat3_m4_v3(sds->obmat, velocity); + normalize_v3(velocity); + mul_v3_fl(velocity, vel_mag); + + /* use max value of fuel or smoke density */ + density = BLI_voxel_sample_trilinear(smoke_get_density(sds->fluid), sds->res, pos); + if (smoke_has_fuel(sds->fluid)) { + fuel = BLI_voxel_sample_trilinear(smoke_get_fuel(sds->fluid), sds->res, pos); + } + return MAX2(density, fuel); + } + return -1.0f; +} + +int smoke_get_data_flags(SmokeDomainSettings *sds) { + int flags = 0; + if (smoke_has_heat(sds->fluid)) flags |= SM_ACTIVE_HEAT; + if (smoke_has_fuel(sds->fluid)) flags |= SM_ACTIVE_FIRE; + if (smoke_has_colors(sds->fluid)) flags |= SM_ACTIVE_COLORS; + + return flags; +} + #endif /* WITH_SMOKE */ diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c index 9dd83181521..300d272b86b 100644 --- a/source/blender/blenkernel/intern/texture.c +++ b/source/blender/blenkernel/intern/texture.c @@ -571,7 +571,7 @@ void default_mtex(MTex *mtex) mtex->size[1] = 1.0; mtex->size[2] = 1.0; mtex->tex = NULL; - mtex->texflag = MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE; + mtex->texflag = MTEX_3TAP_BUMP | MTEX_BUMP_OBJECTSPACE | MTEX_MAPTO_BOUNDS; mtex->colormodel = 0; mtex->r = 1.0; mtex->g = 0.0; diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c index c9d7ec3964f..0d304482060 100644 --- a/source/blender/blenkernel/intern/tracking.c +++ b/source/blender/blenkernel/intern/tracking.c @@ -169,8 +169,6 @@ void BKE_tracking_settings_init(MovieTracking *tracking) tracking->settings.default_minimum_correlation = 0.75; tracking->settings.default_pattern_size = 11; tracking->settings.default_search_size = 61; - tracking->settings.keyframe1 = 1; - tracking->settings.keyframe2 = 30; tracking->settings.dist = 1; tracking->settings.object_distance = 1; @@ -633,7 +631,7 @@ void BKE_tracking_track_path_clear(MovieTrackingTrack *track, int ref_frame, int } } -void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) +void BKE_tracking_tracks_join(MovieTracking *tracking, MovieTrackingTrack *dst_track, MovieTrackingTrack *src_track) { int i = 0, a = 0, b = 0, tot; MovieTrackingMarker *markers; @@ -736,6 +734,8 @@ void BKE_tracking_tracks_join(MovieTrackingTrack *dst_track, MovieTrackingTrack dst_track->markersnr = i; MEM_freeN(markers); + + BKE_tracking_dopesheet_tag_update(tracking); } MovieTrackingTrack *BKE_tracking_track_get_named(MovieTracking *tracking, MovieTrackingObject *object, const char *name) @@ -1179,6 +1179,8 @@ MovieTrackingObject *BKE_tracking_object_add(MovieTracking *tracking, const char tracking->objectnr = BLI_countlist(&tracking->objects) - 1; object->scale = 1.0f; + object->keyframe1 = 1; + object->keyframe2 = 30; BKE_tracking_object_unique_name(tracking, object); @@ -1494,7 +1496,8 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * ibuf->x, ibuf->y, overscan, ibuf->channels); } - resibuf->userflags |= IB_RECT_INVALID; + if (ibuf->rect) + imb_freerectImBuf(ibuf); } else { if (undistort) { @@ -1512,9 +1515,8 @@ ImBuf *BKE_tracking_distortion_exec(MovieDistortion *distortion, MovieTracking * (void) overscan; (void) undistort; - if (ibuf->rect_float) { - resibuf->userflags |= IB_RECT_INVALID; - } + if (ibuf->rect_float && ibuf->rect) + imb_freerectImBuf(ibuf); #endif return resibuf; @@ -2755,10 +2757,11 @@ static int reconstruct_refine_intrinsics_get_flags(MovieTracking *tracking, Movi return flags; } -static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, ListBase *tracksbase) +static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, MovieTrackingObject *object) { + ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); int tot = 0; - int frame1 = tracking->settings.keyframe1, frame2 = tracking->settings.keyframe2; + int frame1 = object->keyframe1, frame2 = object->keyframe2; MovieTrackingTrack *track; track = tracksbase->first; @@ -2779,13 +2782,11 @@ static int reconstruct_count_tracks_on_both_keyframes(MovieTracking *tracking, L int BKE_tracking_reconstruction_check(MovieTracking *tracking, MovieTrackingObject *object, char *error_msg, int error_size) { #ifdef WITH_LIBMV - ListBase *tracksbase = BKE_tracking_object_get_tracks(tracking, object); - if (tracking->settings.motion_flag & TRACKING_MOTION_MODAL) { /* TODO: check for number of tracks? */ return TRUE; } - else if (reconstruct_count_tracks_on_both_keyframes(tracking, tracksbase) < 8) { + else if (reconstruct_count_tracks_on_both_keyframes(tracking, object) < 8) { BLI_strncpy(error_msg, "At least 8 common tracks on both of keyframes are needed for reconstruction", error_size); diff --git a/source/blender/blenkernel/intern/writeavi.c b/source/blender/blenkernel/intern/writeavi.c index dab44b5463c..9f29cb8b137 100644 --- a/source/blender/blenkernel/intern/writeavi.c +++ b/source/blender/blenkernel/intern/writeavi.c @@ -47,7 +47,11 @@ #include "BKE_report.h" #include "BKE_writeavi.h" -#include "AVI_avi.h" + +/* ********************** general blender movie support ***************************** */ + +#ifdef WITH_AVI +# include "AVI_avi.h" /* callbacks */ static int start_avi(Scene *scene, RenderData *rd, int rectx, int recty, ReportList *reports); @@ -55,30 +59,31 @@ static void end_avi(void); static int append_avi(RenderData *rd, int start_frame, int frame, int *pixels, int rectx, int recty, ReportList *reports); static void filepath_avi(char *string, RenderData *rd); - -/* ********************** general blender movie support ***************************** */ +#endif /* WITH_AVI */ #ifdef WITH_QUICKTIME -#include "quicktime_export.h" +# include "quicktime_export.h" #endif #ifdef WITH_FFMPEG -#include "BKE_writeffmpeg.h" +# include "BKE_writeffmpeg.h" #endif #include "BKE_writeframeserver.h" bMovieHandle *BKE_movie_handle_get(const char imtype) { - static bMovieHandle mh; + static bMovieHandle mh = {0}; /* set the default handle, as builtin */ +#ifdef WITH_AVI mh.start_movie = start_avi; mh.append_movie = append_avi; mh.end_movie = end_avi; mh.get_next_frame = NULL; mh.get_movie_path = filepath_avi; - +#endif + /* do the platform specific handles */ #ifdef WITH_QUICKTIME if (imtype == R_IMF_IMTYPE_QUICKTIME) { @@ -114,6 +119,8 @@ bMovieHandle *BKE_movie_handle_get(const char imtype) /* ****************************************************************** */ +#ifdef WITH_AVI + static AviMovie *avi = NULL; static void filepath_avi(char *string, RenderData *rd) @@ -219,6 +226,7 @@ static void end_avi(void) MEM_freeN(avi); avi = NULL; } +#endif /* WITH_AVI */ /* similar to BKE_makepicstring() */ void BKE_movie_filepath_get(char *string, RenderData *rd) diff --git a/source/blender/blenkernel/nla_private.h b/source/blender/blenkernel/nla_private.h index 941a74ec2ab..f068c4c58f0 100644 --- a/source/blender/blenkernel/nla_private.h +++ b/source/blender/blenkernel/nla_private.h @@ -85,4 +85,4 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list, ListBase *strips, short void nlastrip_evaluate(PointerRNA *ptr, ListBase *channels, ListBase *modifiers, NlaEvalStrip *nes); void nladata_flush_channels(ListBase *channels); -#endif // __NLA_PRIVATE_H__ +#endif /* __NLA_PRIVATE_H__ */ diff --git a/source/blender/blenlib/BLI_blenlib.h b/source/blender/blenlib/BLI_blenlib.h index 74b477bacaf..03b75975af4 100644 --- a/source/blender/blenlib/BLI_blenlib.h +++ b/source/blender/blenlib/BLI_blenlib.h @@ -78,8 +78,6 @@ extern "C" { #include "BLI_rect.h" -#include "BLI_noise.h" - #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_bpath.h b/source/blender/blenlib/BLI_bpath.h index 52b839d11a9..a86b362c271 100644 --- a/source/blender/blenlib/BLI_bpath.h +++ b/source/blender/blenlib/BLI_bpath.h @@ -64,4 +64,4 @@ void BLI_bpath_missing_files_find(struct Main *bmain, const char *searchpath, st void BLI_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); void BLI_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports); -#endif // __BLI_BPATH_H__ +#endif /* __BLI_BPATH_H__ */ diff --git a/source/blender/blenlib/BLI_dlrbTree.h b/source/blender/blenlib/BLI_dlrbTree.h index 92356b24403..d04e544376a 100644 --- a/source/blender/blenlib/BLI_dlrbTree.h +++ b/source/blender/blenlib/BLI_dlrbTree.h @@ -158,4 +158,4 @@ void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node); /* ********************************************** */ -#endif // __BLI_DLRBTREE_H__ +#endif /* __BLI_DLRBTREE_H__ */ diff --git a/source/blender/blenlib/BLI_endian_switch_inline.h b/source/blender/blenlib/BLI_endian_switch_inline.h index b747da3b738..4bc6d3828b9 100644 --- a/source/blender/blenlib/BLI_endian_switch_inline.h +++ b/source/blender/blenlib/BLI_endian_switch_inline.h @@ -32,85 +32,63 @@ * \ingroup bli */ +/* note: using a temp char to switch endian is a lot slower, + * use bit shifting instead. */ +/* *** 16 *** */ BLI_INLINE void BLI_endian_switch_int16(short *val) { - char *p_i = (char *)val; - char s_i; + short tval = *val; + *val = (tval >> 8) | + (tval << 8); - s_i = p_i[0]; - p_i[0] = p_i[1]; - p_i[1] = s_i; } - BLI_INLINE void BLI_endian_switch_uint16(unsigned short *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; - p_i[0] = p_i[1]; - p_i[1] = s_i; + BLI_endian_switch_int16((short *)val); } + +/* *** 32 *** */ BLI_INLINE void BLI_endian_switch_int32(int *val) { - char *p_i = (char *)val; - char s_i; + int tval = *val; + *val = ((tval >> 24)) | + ((tval << 8) & 0x00ff0000) | + ((tval >> 8) & 0x0000ff00) | + ((tval << 24)); - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; } - BLI_INLINE void BLI_endian_switch_uint32(unsigned int *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; + BLI_endian_switch_int32((int *)val); } - BLI_INLINE void BLI_endian_switch_float(float *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[3]; p_i[3] = s_i; - s_i = p_i[1]; p_i[1] = p_i[2]; p_i[2] = s_i; + BLI_endian_switch_int32((int *)val); } + +/* *** 64 *** */ BLI_INLINE void BLI_endian_switch_int64(int64_t *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + int64_t tval = *val; + *val = ((tval >> 56)) | + ((tval << 40) & 0x00ff000000000000ll) | + ((tval << 24) & 0x0000ff0000000000ll) | + ((tval << 8) & 0x000000ff00000000ll) | + ((tval >> 8) & 0x00000000ff000000ll) | + ((tval >> 24) & 0x0000000000ff0000ll) | + ((tval >> 40) & 0x000000000000ff00ll) | + ((tval << 56)); } - BLI_INLINE void BLI_endian_switch_uint64(uint64_t *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + BLI_endian_switch_int64((int64_t *)val); } - BLI_INLINE void BLI_endian_switch_double(double *val) { - char *p_i = (char *)val; - char s_i; - - s_i = p_i[0]; p_i[0] = p_i[7]; p_i[7] = s_i; - s_i = p_i[1]; p_i[1] = p_i[6]; p_i[6] = s_i; - s_i = p_i[2]; p_i[2] = p_i[5]; p_i[5] = s_i; - s_i = p_i[3]; p_i[3] = p_i[4]; p_i[4] = s_i; + BLI_endian_switch_int64((int64_t *)val); } #endif /* __BLI_ENDIAN_SWITCH_INLINE_H__ */ diff --git a/source/blender/blenlib/BLI_heap.h b/source/blender/blenlib/BLI_heap.h index b378f2bb365..9d7e6107f19 100644 --- a/source/blender/blenlib/BLI_heap.h +++ b/source/blender/blenlib/BLI_heap.h @@ -42,6 +42,7 @@ typedef void (*HeapFreeFP)(void *ptr); /* Creates a new heap. BLI_memarena is used for allocating nodes. Removed nodes * are recycled, so memory usage will not shrink. */ +Heap *BLI_heap_new_ex(unsigned int tot_reserve); Heap *BLI_heap_new(void); void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp); diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h index 985b5af3b94..8d0d4943ebe 100644 --- a/source/blender/blenlib/BLI_kdopbvh.h +++ b/source/blender/blenlib/BLI_kdopbvh.h @@ -75,7 +75,7 @@ typedef struct BVHTreeRayHit { } BVHTreeRayHit; /* callback must update nearest in case it finds a nearest result */ -typedef void (*BVHTree_NearestPointCallback)(void *userdata, int index, const float *co, BVHTreeNearest *nearest); +typedef void (*BVHTree_NearestPointCallback)(void *userdata, int index, const float co[3], BVHTreeNearest *nearest); /* callback must update hit in case it finds a nearest successful hit */ typedef void (*BVHTree_RayCastCallback)(void *userdata, int index, const BVHTreeRay *ray, BVHTreeRayHit *hit); @@ -87,11 +87,11 @@ BVHTree *BLI_bvhtree_new(int maxsize, float epsilon, char tree_type, char axis); void BLI_bvhtree_free(BVHTree *tree); /* construct: first insert points, then call balance */ -int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints); +int BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints); void BLI_bvhtree_balance(BVHTree *tree); /* update: first update points/nodes, then call update_tree to refit the bounding volumes */ -int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints); +int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints); void BLI_bvhtree_update_tree(BVHTree *tree); /* collision/overlap: check two trees if they overlap, alloc's *overlap with length of the int return value */ @@ -99,19 +99,22 @@ BVHTreeOverlap *BLI_bvhtree_overlap(BVHTree *tree1, BVHTree *tree2, unsigned int float BLI_bvhtree_getepsilon(BVHTree *tree); -/* find nearest node to the given coordinates (if nearest is given it will only search nodes where square distance is smaller than nearest->dist) */ -int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata); +/* find nearest node to the given coordinates + * (if nearest is given it will only search nodes where square distance is smaller than nearest->dist) */ +int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *nearest, + BVHTree_NearestPointCallback callback, void *userdata); -int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float *dir, float radius, BVHTreeRayHit *hit, BVHTree_RayCastCallback callback, void *userdata); +int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], float radius, BVHTreeRayHit *hit, + BVHTree_RayCastCallback callback, void *userdata); -float BLI_bvhtree_bb_raycast(const float *bv, const float light_start[3], const float light_end[3], float pos[3]); +float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]); /* range query */ -int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, BVHTree_RangeQuery callback, void *userdata); +int BLI_bvhtree_range_query(BVHTree *tree, const float co[3], float radius, + BVHTree_RangeQuery callback, void *userdata); #ifdef __cplusplus } #endif -#endif // __BLI_KDOPBVH_H__ - +#endif /* __BLI_KDOPBVH_H__ */ diff --git a/source/blender/blenlib/BLI_kdtree.h b/source/blender/blenlib/BLI_kdtree.h index e90566408d4..f9b52f34102 100644 --- a/source/blender/blenlib/BLI_kdtree.h +++ b/source/blender/blenlib/BLI_kdtree.h @@ -56,7 +56,7 @@ void BLI_kdtree_balance(KDTree *tree); /* Find nearest returns index, and -1 if no node is found. * Find n nearest returns number of points found, with results in nearest. * Normal is optional, but if given will limit results to points in normal direction from co. */ -int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest); +int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3], KDTreeNearest *nearest); int BLI_kdtree_find_n_nearest(KDTree *tree, int n, const float co[3], const float nor[3], KDTreeNearest *nearest); /* Range search returns number of points found, with results in nearest */ diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index de1d423bfad..83b07bae53f 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -67,6 +67,7 @@ MINLINE void copy_v2_v2_short(short r[2], const short a[2]); MINLINE void copy_v3_v3_short(short r[3], const short a[3]); MINLINE void copy_v4_v4_short(short r[4], const short a[4]); /* int */ +MINLINE void zero_v3_int(int r[3]); MINLINE void copy_v2_v2_int(int r[2], const int a[2]); MINLINE void copy_v3_v3_int(int r[3], const int a[3]); MINLINE void copy_v4_v4_int(int r[4], const int a[4]); @@ -139,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_quadric.h b/source/blender/blenlib/BLI_quadric.h new file mode 100644 index 00000000000..aec11ec2b44 --- /dev/null +++ b/source/blender/blenlib/BLI_quadric.h @@ -0,0 +1,56 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Laurence Bourn, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BLI_QUADRIC_H__ +#define __BLI_QUADRIC_H__ + +/** \file BLI_quadric.h + * \ingroup bli + */ + +typedef struct Quadric { + float a2, ab, ac, ad, + b2, bc, bd, + c2, cd, + d2; +} Quadric; + +/* conversion */ +void BLI_quadric_from_v3_dist(Quadric *q, const float v[3], const float offset); +void BLI_quadric_to_tensor_m3(const Quadric *q, float m[3][3]); +void BLI_quadric_to_vector_v3(const Quadric *q, float v[3]); + +void BLI_quadric_clear(Quadric *q); + +/* math */ +void BLI_quadric_add_qu_qu(Quadric *a, const Quadric *b); +void BLI_quadric_add_qu_ququ(Quadric *r, const Quadric *a, const Quadric *b); +void BLI_quadric_mul(Quadric *a, const float scalar); + +/* solve */ +float BLI_quadric_evaluate(const Quadric *q, const float v[3]); +int BLI_quadric_optimize(const Quadric *q, float v[3]); + +#endif /* __BLI_QUADRIC_H__ */ 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/BLI_utildefines.h b/source/blender/blenlib/BLI_utildefines.h index 29097a4c6c3..47c2256c1e1 100644 --- a/source/blender/blenlib/BLI_utildefines.h +++ b/source/blender/blenlib/BLI_utildefines.h @@ -128,6 +128,10 @@ #endif #endif +/* can be used in simple macros */ +#define CHECK_TYPE_INLINE(val, type) \ + ((void)(((type *)0) != (val))) + #ifndef SWAP # define SWAP(type, a, b) { \ type sw_ap; \ @@ -189,6 +193,11 @@ *(v1 + 1) = *(v2 + 1) + *(v3 + 1) * (fac); \ *(v1 + 2) = *(v2 + 2) + *(v3 + 2) * (fac); \ } (void)0 +#define VECMADD(v1, v2, v3, v4) { \ + *(v1) = *(v2) + *(v3) * (*(v4)); \ + *(v1 + 1) = *(v2 + 1) + *(v3 + 1) * (*(v4 + 1)); \ + *(v1 + 2) = *(v2 + 2) + *(v3 + 2) * (*(v4 + 2)); \ +} (void)0 #define VECSUBFAC(v1, v2, v3, fac) { \ *(v1) = *(v2) - *(v3) * (fac); \ *(v1 + 1) = *(v2 + 1) - *(v3 + 1) * (fac); \ @@ -326,4 +335,4 @@ # define UNLIKELY(x) (x) #endif -#endif // __BLI_UTILDEFINES_H__ +#endif /* __BLI_UTILDEFINES_H__ */ diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt index eef0a72d3b2..3aa0ffc3eaa 100644 --- a/source/blender/blenlib/CMakeLists.txt +++ b/source/blender/blenlib/CMakeLists.txt @@ -79,6 +79,7 @@ set(SRC intern/noise.c intern/path_util.c intern/pbvh.c + intern/quadric.c intern/rand.c intern/rct.c intern/scanfill.c @@ -91,8 +92,8 @@ set(SRC intern/threads.c intern/time.c intern/uvproject.c - intern/voxel.c intern/voronoi.c + intern/voxel.c intern/winstuff.c BLI_args.h @@ -136,6 +137,7 @@ set(SRC BLI_noise.h BLI_path_util.h BLI_pbvh.h + BLI_quadric.h BLI_rand.h BLI_rect.h BLI_scanfill.h diff --git a/source/blender/blenlib/PIL_time.h b/source/blender/blenlib/PIL_time.h index 288d2fe78e5..b8f895c5c82 100644 --- a/source/blender/blenlib/PIL_time.h +++ b/source/blender/blenlib/PIL_time.h @@ -30,7 +30,6 @@ * \brief Platform independent time functions. */ - #ifndef __PIL_TIME_H__ #define __PIL_TIME_H__ @@ -61,20 +60,24 @@ void PIL_sleep_ms(int ms); double _timeit_##var = PIL_check_seconds_timer(); \ printf("time start (" #var "): " AT "\n"); \ fflush(stdout); \ - { (void)0 \ - + { (void)0 #define TIMEIT_VALUE(var) (float)(PIL_check_seconds_timer() - _timeit_##var) +#define TIMEIT_VALUE_PRINT(var) \ + { \ + printf("time update(" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var));\ + fflush(stdout); \ + } (void)0 #define TIMEIT_END(var) \ } \ - printf("time end (" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var)); \ + printf("time end (" #var "): %.6f" " " AT "\n", TIMEIT_VALUE(var)); \ fflush(stdout); \ -} (void)0 \ +} (void)0 #ifdef __cplusplus } #endif -#endif /* !__PIL_TIME_H__ */ +#endif /* !__PIL_TIME_H__ */ diff --git a/source/blender/blenlib/intern/BLI_heap.c b/source/blender/blenlib/intern/BLI_heap.c index ee7d93ea1a9..5e0762a5d68 100644 --- a/source/blender/blenlib/intern/BLI_heap.c +++ b/source/blender/blenlib/intern/BLI_heap.c @@ -67,16 +67,22 @@ struct Heap { /***/ -Heap *BLI_heap_new(void) +/* use when the size of the heap is known in advance */ +Heap *BLI_heap_new_ex(unsigned int tot_reserve) { Heap *heap = (Heap *)MEM_callocN(sizeof(Heap), __func__); - heap->bufsize = 1; - heap->tree = (HeapNode **)MEM_mallocN(sizeof(HeapNode *), "BLIHeapTree"); + heap->bufsize = tot_reserve; + heap->tree = (HeapNode **)MEM_mallocN(tot_reserve * sizeof(HeapNode *), "BLIHeapTree"); heap->arena = BLI_memarena_new(1 << 16, "heap arena"); return heap; } +Heap *BLI_heap_new(void) +{ + return BLI_heap_new_ex(1); +} + void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) { int i; diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c index a86783f3450..46b0cfeaaac 100644 --- a/source/blender/blenlib/intern/BLI_kdopbvh.c +++ b/source/blender/blenlib/intern/BLI_kdopbvh.c @@ -921,7 +921,7 @@ void BLI_bvhtree_balance(BVHTree *tree) /* bvhtree_info(tree); */ } -int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints) +int BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints) { int i; BVHNode *node = NULL; @@ -952,7 +952,7 @@ int BLI_bvhtree_insert(BVHTree *tree, int index, const float *co, int numpoints) /* call before BLI_bvhtree_update_tree() */ -int BLI_bvhtree_update_node(BVHTree *tree, int index, const float *co, const float *co_moving, int numpoints) +int BLI_bvhtree_update_node(BVHTree *tree, int index, const float co[3], const float co_moving[3], int numpoints) { int i; BVHNode *node = NULL; @@ -1346,7 +1346,7 @@ int BLI_bvhtree_find_nearest(BVHTree *tree, const float co[3], BVHTreeNearest *n /* Determines the distance that the ray must travel to hit the bounding volume of the given node */ -static float ray_nearest_hit(BVHRayCastData *data, const float *bv) +static float ray_nearest_hit(BVHRayCastData *data, const float bv[6]) { int i; @@ -1524,7 +1524,7 @@ int BLI_bvhtree_ray_cast(BVHTree *tree, const float co[3], const float dir[3], f return data.hit.index; } -float BLI_bvhtree_bb_raycast(const float *bv, const float light_start[3], const float light_end[3], float pos[3]) +float BLI_bvhtree_bb_raycast(const float bv[6], const float light_start[3], const float light_end[3], float pos[3]) { BVHRayCastData data; float dist = 0.0; diff --git a/source/blender/blenlib/intern/BLI_kdtree.c b/source/blender/blenlib/intern/BLI_kdtree.c index 19985c56b84..900580317f2 100644 --- a/source/blender/blenlib/intern/BLI_kdtree.c +++ b/source/blender/blenlib/intern/BLI_kdtree.c @@ -132,7 +132,7 @@ void BLI_kdtree_balance(KDTree *tree) tree->root = kdtree_balance(tree->nodes, tree->totnode, 0); } -static float squared_distance(const float v2[3], const float v1[3], const float *UNUSED(n1), const float *n2) +static float squared_distance(const float v2[3], const float v1[3], const float UNUSED(n1[3]), const float n2[3]) { float d[3], dist; @@ -152,7 +152,7 @@ static float squared_distance(const float v2[3], const float v1[3], const float return dist; } -int BLI_kdtree_find_nearest(KDTree *tree, float *co, float *nor, KDTreeNearest *nearest) +int BLI_kdtree_find_nearest(KDTree *tree, const float co[3], const float nor[3], KDTreeNearest *nearest) { KDTreeNode *root, *node, *min_node; KDTreeNode **stack, *defaultstack[100]; diff --git a/source/blender/blenlib/intern/edgehash.c b/source/blender/blenlib/intern/edgehash.c index d58ccbbd48e..4fb48d19239 100644 --- a/source/blender/blenlib/intern/edgehash.c +++ b/source/blender/blenlib/intern/edgehash.c @@ -108,7 +108,7 @@ void BLI_edgehash_insert(EdgeHash *eh, unsigned int v0, unsigned int v1, void *v eh->buckets[hash] = e; if (++eh->nentries > eh->nbuckets * 3) { - EdgeEntry *e, **old = eh->buckets; + EdgeEntry **old = eh->buckets; int i, nold = eh->nbuckets; eh->nbuckets = _ehash_hashsizes[++eh->cursize]; diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 1df904f617a..883cdfde426 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -140,6 +140,8 @@ char *BLI_file_ungzip_to_mem(const char *from_file, int *size_r) } else break; } + + gzclose(gzfile); if (size == 0) { MEM_freeN(mem); diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 85239270541..daedd39d693 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -33,8 +33,8 @@ */ -#ifdef WIN32 -#pragma warning (disable:4244) +#ifdef _MSC_VER +# pragma warning (disable:4244) #endif #include <ft2build.h> diff --git a/source/blender/blenlib/intern/math_base_inline.c b/source/blender/blenlib/intern/math_base_inline.c index 97fc431d8fa..21ecfccf9d9 100644 --- a/source/blender/blenlib/intern/math_base_inline.c +++ b/source/blender/blenlib/intern/math_base_inline.c @@ -59,34 +59,34 @@ MINLINE float saacos(float fac) { if (fac <= -1.0f) return (float)M_PI; else if (fac >= 1.0f) return 0.0; - else return (float)acos(fac); + else return acosf(fac); } MINLINE float saasin(float fac) { if (fac <= -1.0f) return (float)-M_PI / 2.0f; else if (fac >= 1.0f) return (float)M_PI / 2.0f; - else return (float)asin(fac); + else return asinf(fac); } MINLINE float sasqrt(float fac) { if (fac <= 0.0f) return 0.0f; - return (float)sqrt(fac); + return sqrtf(fac); } MINLINE float saacosf(float fac) { if (fac <= -1.0f) return (float)M_PI; else if (fac >= 1.0f) return 0.0f; - else return (float)acosf(fac); + else return acosf(fac); } MINLINE float saasinf(float fac) { if (fac <= -1.0f) return (float)-M_PI / 2.0f; else if (fac >= 1.0f) return (float)M_PI / 2.0f; - else return (float)asinf(fac); + else return asinf(fac); } MINLINE float sasqrtf(float fac) diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index 2cfe999e032..191b0e16025 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -121,6 +121,13 @@ MINLINE void copy_v4_v4_char(char r[4], const char a[4]) } /* short */ +MINLINE void zero_v3_int(int r[3]) +{ + r[0] = 0; + r[1] = 0; + r[2] = 0; +} + MINLINE void copy_v2_v2_short(short r[2], const short a[2]) { r[0] = a[0]; @@ -561,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]); @@ -588,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/noise.c b/source/blender/blenlib/intern/noise.c index 792bf929182..124624ca137 100644 --- a/source/blender/blenlib/intern/noise.c +++ b/source/blender/blenlib/intern/noise.c @@ -31,9 +31,9 @@ */ -#ifdef _WIN32 -#pragma warning (disable : 4244) // "conversion from double to float" -#pragma warning (disable : 4305) // "truncation from const double to float" +#ifdef _MSC_VER +# pragma warning (disable:4244) /* "conversion from double to float" */ +# pragma warning (disable:4305) /* "truncation from const double to float" */ #endif #include <math.h> diff --git a/source/blender/blenlib/intern/quadric.c b/source/blender/blenlib/intern/quadric.c new file mode 100644 index 00000000000..1c04beacbfb --- /dev/null +++ b/source/blender/blenlib/intern/quadric.c @@ -0,0 +1,131 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): Laurence Bourn, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/blenlib/intern/quadric.c + * \ingroup bli + * + * \note This isn't fully complete, + * possible there are other useful functions to add here. + * + * \note try to follow BLI_math naming convention here. + */ + +//#include <string.h> + +#include "BLI_math.h" +#include "BLI_quadric.h" /* own include */ + + +#define QUADRIC_FLT_TOT (sizeof(Quadric) / sizeof(float)) + +void BLI_quadric_from_v3_dist(Quadric *q, const float v[3], const float offset) +{ + q->a2 = v[0] * v[0]; + q->b2 = v[1] * v[1]; + q->c2 = v[2] * v[2]; + + q->ab = v[0] * v[1]; + q->ac = v[0] * v[2]; + q->bc = v[1] * v[2]; + + q->ad = v[0] * offset; + q->bd = v[1] * offset; + q->cd = v[2] * offset; + + q->d2 = offset * offset; +} + +void BLI_quadric_to_tensor_m3(const Quadric *q, float m[3][3]) +{ + m[0][0] = q->a2; + m[0][1] = q->ab; + m[0][2] = q->ac; + + m[1][0] = q->ab; + m[1][1] = q->b2; + m[1][2] = q->bc; + + m[2][0] = q->ac; + m[2][1] = q->bc; + m[2][2] = q->c2; +} + +void BLI_quadric_to_vector_v3(const Quadric *q, float v[3]) +{ + v[0] = q->ad; + v[1] = q->bd; + v[2] = q->cd; +} + +void BLI_quadric_clear(Quadric *q) +{ + memset(q, 0, sizeof(*q)); +} + +void BLI_quadric_add_qu_qu(Quadric *a, const Quadric *b) +{ + add_vn_vn((float *)a, (float *)b, QUADRIC_FLT_TOT); +} + +void BLI_quadric_add_qu_ququ(Quadric *r, const Quadric *a, const Quadric *b) +{ + add_vn_vnvn((float *)r, (const float *)a, (const float *)b, QUADRIC_FLT_TOT); +} + +void BLI_quadric_mul(Quadric *a, const float scalar) +{ + mul_vn_fl((float *)a, QUADRIC_FLT_TOT, scalar); +} + +float BLI_quadric_evaluate(const Quadric *q, const float v[3]) +{ + return (v[0] * v[0] * q->a2 + 2.0f * v[0] * v[1] * q->ab + 2.0f * v[0] * v[2] * q->ac + 2.0f * v[0] * q->ad + + v[1] * v[1] * q->b2 + 2.0f * v[1] * v[2] * q->bc + 2.0f * v[1] * q->bd + + v[2] * v[2] * q->c2 + 2.0f * v[2] * q->cd + + q->d2); +} + +int BLI_quadric_optimize(const Quadric *q, float v[3]) +{ + float m[3][3]; + float det; + + BLI_quadric_to_tensor_m3(q, m); + det = determinant_m3(m[0][0], m[0][1], m[0][2], + m[1][0], m[1][1], m[1][2], + m[2][0], m[2][1], m[2][2]); + + if (det != 0.0f) { + invert_m3(m); + BLI_quadric_to_vector_v3(q, v); + mul_m3_v3(m, v); + negate_v3(v); + + return TRUE; + } + else { + return FALSE; + } +} diff --git a/source/blender/blenlib/intern/rand.c b/source/blender/blenlib/intern/rand.c index 4435e9ce09c..3c22d73d113 100644 --- a/source/blender/blenlib/intern/rand.c +++ b/source/blender/blenlib/intern/rand.c @@ -40,7 +40,7 @@ #include "BLI_threads.h" #include "BLI_rand.h" -#if defined(WIN32) && !defined(FREE_WINDOWS) +#ifdef _MSC_VER typedef unsigned __int64 r_uint64; #define MULTIPLIER 0x5DEECE66Di64 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/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 74df5211dad..3c5812fa513 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -25,6 +25,7 @@ set(INC . + ../blenfont ../blenkernel ../blenlib ../makesdna @@ -62,4 +63,8 @@ if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) endif() +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + blender_add_lib(bf_blenloader "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/blenloader/SConscript b/source/blender/blenloader/SConscript index 20b560744b3..49e8869637e 100644 --- a/source/blender/blenloader/SConscript +++ b/source/blender/blenloader/SConscript @@ -3,7 +3,7 @@ Import ('env') sources = env.Glob('intern/*.c') -incs = '. #/intern/guardedalloc ../blenlib ../blenkernel' +incs = '. #/intern/guardedalloc ../blenfont ../blenlib ../blenkernel' incs += ' ../makesdna ../editors/include' incs += ' ../render/extern/include ../makesrna ../nodes ../bmesh ../imbuf' @@ -11,6 +11,9 @@ incs += ' ' + env['BF_ZLIB_INC'] defs = [] +if env['WITH_BF_INTERNATIONAL']: + defs.append('WITH_INTERNATIONAL') + if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): env.BlenderLib ( 'bf_blenloader', sources, Split(incs), defs, libtype=['core','player'], priority = [167,30]) #, cc_compileflags=['/WX'] ) else: diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index b6c793bcdba..97ca210c3d0 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -106,6 +106,8 @@ #include "BLI_math.h" #include "BLI_edgehash.h" +#include "BLF_translation.h" + #include "BKE_anim.h" #include "BKE_action.h" #include "BKE_armature.h" @@ -977,13 +979,13 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports) if (fd->flags & FD_FLAGS_FILE_OK) { if (!read_file_dna(fd)) { - BKE_reportf(reports, RPT_ERROR, "Failed to read blend file: \"%s\", incomplete", fd->relabase); + BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', incomplete", fd->relabase); blo_freefiledata(fd); fd = NULL; } } else { - BKE_reportf(reports, RPT_ERROR, "Failed to read blend file: \"%s\", not a blend file", fd->relabase); + BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase); blo_freefiledata(fd); fd = NULL; } @@ -1000,7 +1002,8 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) gzfile = BLI_gzopen(filepath, "rb"); if (gzfile == (gzFile)Z_NULL) { - BKE_reportf(reports, RPT_WARNING, "Unable to open \"%s\": %s.", filepath, errno ? strerror(errno) : "Unknown error reading file"); + BKE_reportf(reports, RPT_WARNING, "Unable to open '%s': %s", + filepath, errno ? strerror(errno) : TIP_("Unknown error reading file")); return NULL; } else { @@ -1018,7 +1021,7 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) FileData *blo_openblendermemory(void *mem, int memsize, ReportList *reports) { if (!mem || memsize<SIZEOFBLENDERHEADER) { - BKE_report(reports, RPT_WARNING, (mem)? "Unable to read": "Unable to open"); + BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read"): TIP_("Unable to open")); return NULL; } else { @@ -3336,6 +3339,8 @@ static void lib_link_partdeflect(FileData *fd, ID *id, PartDeflect *pd) { if (pd && pd->tex) pd->tex = newlibadr_us(fd, id->lib, pd->tex); + if (pd && pd->f_source) + pd->f_source = newlibadr_us(fd, id->lib, pd->f_source); } static void lib_link_particlesettings(FileData *fd, Main *main) @@ -3568,10 +3573,10 @@ static void direct_link_particlesystems(FileData *fd, ListBase *particles) psys->clmd->clothObject = NULL; psys->clmd->sim_parms= newdataadr(fd, psys->clmd->sim_parms); - psys->clmd->sim_parms->effector_weights = NULL; psys->clmd->coll_parms= newdataadr(fd, psys->clmd->coll_parms); if (psys->clmd->sim_parms) { + psys->clmd->sim_parms->effector_weights = NULL; if (psys->clmd->sim_parms->presets > 10) psys->clmd->sim_parms->presets = 0; } @@ -3625,16 +3630,17 @@ static void lib_link_customdata_mtpoly(FileData *fd, Mesh *me, CustomData *pdata if (layer->type == CD_MTEXPOLY) { MTexPoly *tf= layer->data; - int i; + int j; - for (i = 0; i < totface; i++, tf++) { + for (j = 0; j < totface; j++, tf++) { tf->tpage = newlibadr(fd, me->id.lib, tf->tpage); - if (tf->tpage && tf->tpage->id.us==0) + if (tf->tpage && tf->tpage->id.us == 0) { tf->tpage->id.us = 1; } } } } +} static void lib_link_mesh(FileData *fd, Main *main) { @@ -4318,10 +4324,12 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) if (smd->domain->ptcaches[1].first || smd->domain->point_cache[1]) { if (smd->domain->point_cache[1]) { PointCache *cache = newdataadr(fd, smd->domain->point_cache[1]); - if (cache->flag & PTCACHE_FAKE_SMOKE) - ; /* Smoke was already saved in "new format" and this cache is a fake one. */ - else + if (cache->flag & PTCACHE_FAKE_SMOKE) { + /* Smoke was already saved in "new format" and this cache is a fake one. */ + } + else { printf("High resolution smoke cache not available due to pointcache update. Please reset the simulation.\n"); + } BKE_ptcache_free(cache); } smd->domain->ptcaches[1].first = NULL; @@ -4334,6 +4342,9 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->coll = NULL; smd->flow = newdataadr(fd, smd->flow); smd->flow->smd = smd; + smd->flow->dm = NULL; + smd->flow->verts_old = NULL; + smd->flow->numverts = 0; smd->flow->psys = newdataadr(fd, smd->flow->psys); } else if (smd->type == MOD_SMOKE_TYPE_COLL) { @@ -4342,11 +4353,15 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb) smd->coll = newdataadr(fd, smd->coll); if (smd->coll) { smd->coll->smd = smd; - smd->coll->points = NULL; - smd->coll->numpoints = 0; + smd->coll->verts_old = NULL; + smd->coll->numverts = 0; + smd->coll->dm = NULL; } else { smd->type = 0; + smd->flow = NULL; + smd->domain = NULL; + smd->coll = NULL; } } } @@ -4755,8 +4770,7 @@ static void lib_link_scene(FileData *fd, Main *main) base->object = newlibadr_us(fd, sce->id.lib, base->object); if (base->object == NULL) { - BKE_reportf_wrap(fd->reports, RPT_WARNING, - "LIB ERROR: Object lost from scene:'%s\'", + BKE_reportf_wrap(fd->reports, RPT_WARNING, "LIB ERROR: object lost from scene: '%s'", sce->id.name + 2); BLI_remlink(&sce->base, base); if (base == sce->basact) sce->basact = NULL; @@ -6791,7 +6805,7 @@ void convert_tface_mt(FileData *fd, Main *main) G.main = main; if (!(do_version_tface(main, 1))) { - BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem. Error in console"); + BKE_report(fd->reports, RPT_WARNING, "Texface conversion problem (see error in console)"); } //XXX hack, material.c uses G.main allover the place, instead of main @@ -6964,7 +6978,6 @@ static void do_versions_nodetree_socket_use_flags_2_62(bNodeTree *ntree) static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNodeTree *ntree) { bNode *node; - bNodeSocket *sock; for (node = ntree->nodes.first; node; node = node->next) { if (node->type == CMP_NODE_OUTPUT_FILE) { @@ -7041,6 +7054,7 @@ static void do_versions_nodetree_multi_file_output_format_2_62_1(Scene *sce, bNo } else if (node->type==CMP_NODE_OUTPUT_MULTI_FILE__DEPRECATED) { NodeImageMultiFile *nimf = node->storage; + bNodeSocket *sock; /* CMP_NODE_OUTPUT_MULTI_FILE has been redeclared as CMP_NODE_OUTPUT_FILE */ node->type = CMP_NODE_OUTPUT_FILE; @@ -7236,6 +7250,21 @@ static void do_version_ntree_tex_coord_from_dupli_264(void *UNUSED(data), ID *UN node->flag |= NODE_OPTIONS; } +static void do_version_node_cleanup_dynamic_sockets_264(void *UNUSED(data), ID *UNUSED(id), bNodeTree *ntree) +{ + bNode *node; + bNodeSocket *sock; + + for (node = ntree->nodes.first; node; node = node->next) { + if (!ELEM(node->type, NODE_GROUP, CMP_NODE_IMAGE)) { + for (sock = node->inputs.first; sock; sock = sock->next) + sock->flag &= ~SOCK_DYNAMIC; + for (sock = node->outputs.first; sock; sock = sock->next) + sock->flag &= ~SOCK_DYNAMIC; + } + } +} + static void do_versions(FileData *fd, Library *lib, Main *main) { /* WATCH IT!!!: pointers from libdata have not been converted */ @@ -7349,9 +7378,9 @@ static void do_versions(FileData *fd, Library *lib, Main *main) v3d->bundle_drawtype = OB_PLAINAXES; } else if (sl->spacetype == SPACE_CLIP) { - SpaceClip *sc = (SpaceClip *)sl; - if (sc->scopes.track_preview_height == 0) - sc->scopes.track_preview_height = 120; + SpaceClip *sclip = (SpaceClip *)sl; + if (sclip->scopes.track_preview_height == 0) + sclip->scopes.track_preview_height = 120; } } } @@ -7559,8 +7588,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) prop = BKE_bproperty_object_get(ob, "Text"); if (prop) { BKE_reportf_wrap(fd->reports, RPT_WARNING, - "Game property name conflict in object: \"%s\".\nText objects reserve the " - "[\"Text\"] game property to change their content through Logic Bricks.", + "Game property name conflict in object '%s':\ntext objects reserve the " + "['Text'] game property to change their content through logic bricks", ob->id.name + 2); } } @@ -7753,13 +7782,8 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (main->versionfile < 263) { /* Default for old files is to save particle rotations to pointcache */ ParticleSettings *part; - for (part = main->particle.first; part; part = part->id.next) + for (part = main->particle.first; part; part = part->id.next) { part->flag |= PART_ROTATIONS; - { - /* Default for old files is to save particle rotations to pointcache */ - ParticleSettings *part; - for (part = main->particle.first; part; part = part->id.next) - part->flag |= PART_ROTATIONS; } } @@ -8205,6 +8229,111 @@ static void do_versions(FileData *fd, Library *lib, Main *main) do_version_ntree_tex_coord_from_dupli_264(NULL, NULL, ntree); } + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 2)) { + MovieClip *clip; + + for (clip = main->movieclip.first; clip; clip = clip->id.next) { + MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *tracking_object; + + for (tracking_object = tracking->objects.first; + tracking_object; + tracking_object = tracking_object->next) + { + if (tracking_object->keyframe1 == 0 && tracking_object->keyframe2 == 0) { + tracking_object->keyframe1 = tracking->settings.keyframe1; + tracking_object->keyframe2 = tracking->settings.keyframe2; + } + } + } + } + + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 3)) { + /* smoke branch */ + { + Object *ob; + + for (ob = main->object.first; ob; ob = ob->id.next) { + ModifierData *md; + for (md = ob->modifiers.first; md; md = md->next) { + if (md->type == eModifierType_Smoke) { + SmokeModifierData *smd = (SmokeModifierData *)md; + if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { + /* keep branch saves if possible */ + if (!smd->domain->flame_max_temp) { + smd->domain->burning_rate = 0.75f; + smd->domain->flame_smoke = 1.0f; + smd->domain->flame_vorticity = 0.5f; + smd->domain->flame_ignition = 1.25f; + smd->domain->flame_max_temp = 1.75f; + smd->domain->adapt_threshold = 0.02f; + smd->domain->adapt_margin = 4; + smd->domain->flame_smoke_color[0] = 0.7f; + smd->domain->flame_smoke_color[1] = 0.7f; + smd->domain->flame_smoke_color[2] = 0.7f; + } + } + else if ((smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { + if (!smd->flow->texture_size) { + smd->flow->fuel_amount = 1.0; + smd->flow->surface_distance = 1.5; + smd->flow->color[0] = 0.7f; + smd->flow->color[1] = 0.7f; + smd->flow->color[2] = 0.7f; + smd->flow->texture_size = 1.0f; + } + } + } + } + } + } + + /* render border for viewport */ + { + bScreen *sc; + + for (sc = main->screen.first; sc; sc = sc->id.next) { + ScrArea *sa; + for (sa = sc->areabase.first; sa; sa = sa->next) { + SpaceLink *sl; + for (sl = sa->spacedata.first; sl; sl = sl->next) { + if (sl->spacetype == SPACE_VIEW3D) { + View3D *v3d = (View3D *)sl; + if (v3d->render_border.xmin == 0.0f && v3d->render_border.ymin == 0.0f && + v3d->render_border.xmax == 0.0f && v3d->render_border.ymax == 0.0f) + { + v3d->render_border.xmax = 1.0f; + v3d->render_border.ymax = 1.0f; + } + } + } + } + } + } + } + + if (main->versionfile < 264 || (main->versionfile == 264 && main->subversionfile < 4)) { + /* Fix for old node flags: Apparently the SOCK_DYNAMIC flag has been in use for other + * purposes before and then removed and later reused for SOCK_DYNAMIC. This socket should + * only be used by certain node types which don't use template lists, cleaning this up here. + */ + bNodeTreeType *ntreetype; + bNodeTree *ntree; + + ntreetype = ntreeGetType(NTREE_COMPOSIT); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + ntreetype = ntreeGetType(NTREE_SHADER); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + ntreetype = ntreeGetType(NTREE_TEXTURE); + if (ntreetype && ntreetype->foreach_nodetree) + ntreetype->foreach_nodetree(main, NULL, do_version_node_cleanup_dynamic_sockets_264); + + for (ntree=main->nodetree.first; ntree; ntree=ntree->id.next) + do_version_node_cleanup_dynamic_sockets_264(NULL, NULL, ntree); + } + /* default values in Freestyle settings */ { Scene *sce; @@ -9800,7 +9929,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (fd == NULL) { /* printf and reports for now... its important users know this */ BKE_reportf_wrap(basefd->reports, RPT_INFO, - "read library: '%s', '%s'", + "Read library: '%s', '%s'", mainptr->curlib->filepath, mainptr->curlib->name); fd = blo_openblenderfile(mainptr->curlib->filepath, basefd->reports); @@ -9854,7 +9983,7 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) if (fd == NULL) { BKE_reportf_wrap(basefd->reports, RPT_WARNING, - "Can't find lib '%s'", + "Cannot find lib '%s'", mainptr->curlib->filepath); } } diff --git a/source/blender/blenloader/intern/runtime.c b/source/blender/blenloader/intern/runtime.c index eaf725dda9e..4136f71f050 100644 --- a/source/blender/blenloader/intern/runtime.c +++ b/source/blender/blenloader/intern/runtime.c @@ -104,7 +104,7 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) fd = BLI_open(path, O_BINARY | O_RDONLY, 0); if (fd == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to open \"%s\": %s.", path, strerror(errno)); + BKE_reportf(reports, RPT_ERROR, "Unable to open '%s': %s", path, strerror(errno)); goto cleanup; } @@ -115,15 +115,15 @@ BlendFileData *BLO_read_runtime(const char *path, ReportList *reports) datastart = handle_read_msb_int(fd); if (datastart == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (problem seeking)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (problem seeking)", path); goto cleanup; } else if (read(fd, buf, 8) != 8) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (truncated header)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (truncated header)", path); goto cleanup; } else if (memcmp(buf, "BRUNTIME", 8) != 0) { - BKE_reportf(reports, RPT_ERROR, "Unable to read \"%s\" (not a blend file)", path); + BKE_reportf(reports, RPT_ERROR, "Unable to read '%s' (not a blend file)", path); goto cleanup; } else { diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index e6d68294cf4..99283cf9473 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -731,8 +731,9 @@ static void write_nodetree(WriteData *wd, bNodeTree *ntree) write_curvemapping(wd, node->storage); else if (ntree->type==NTREE_TEXTURE && (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME) ) write_curvemapping(wd, node->storage); - else if (ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION) - /* pass */; + else if (ntree->type==NTREE_COMPOSIT && node->type==CMP_NODE_MOVIEDISTORTION) { + /* pass */ + } else writestruct(wd, DATA, node->typeinfo->storagename, 1, node->storage); } @@ -777,13 +778,16 @@ typedef struct RenderInfo { char scene_name[MAX_ID_NAME - 2]; } RenderInfo; -static void write_renderinfo(WriteData *wd, Main *mainvar) /* for renderdeamon */ +/* was for historic render-deamon feature, + * now write because it can be easily extracted without + * reading the whole blend file */ +static void write_renderinfo(WriteData *wd, Main *mainvar) { bScreen *curscreen; Scene *sce; RenderInfo data; - /* XXX in future, handle multiple windows with multiple screnes? */ + /* XXX in future, handle multiple windows with multiple screens? */ current_screen_compat(mainvar, &curscreen); for (sce= mainvar->scene.first; sce; sce= sce->id.next) { @@ -3235,7 +3239,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL file = BLI_open(tempname, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666); if (file == -1) { - BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s.", tempname, strerror(errno)); + BKE_reportf(reports, RPT_ERROR, "Cannot open file %s for writing: %s", tempname, strerror(errno)); return 0; } @@ -3286,7 +3290,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL if (write_flags & G_FILE_HISTORY) { int err_hist = do_history(filepath, reports); if (err_hist) { - BKE_report(reports, RPT_ERROR, "Version backup failed. File saved with @"); + BKE_report(reports, RPT_ERROR, "Version backup failed (file saved with @)"); return 0; } } @@ -3303,23 +3307,23 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL if (0==ret) { /* now rename to real file name, and delete temp @ file too */ if (BLI_rename(gzname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @."); + BKE_report(reports, RPT_ERROR, "Cannot change old file (file saved with @)"); return 0; } BLI_delete(tempname, 0, 0); } else if (-1==ret) { - BKE_report(reports, RPT_ERROR, "Failed opening .gz file."); + BKE_report(reports, RPT_ERROR, "Failed opening .gz file"); return 0; } else if (-2==ret) { - BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression."); + BKE_report(reports, RPT_ERROR, "Failed opening .blend file for compression"); return 0; } } else if (BLI_rename(tempname, filepath) != 0) { - BKE_report(reports, RPT_ERROR, "Can't change old file. File saved with @"); + BKE_report(reports, RPT_ERROR, "Cannot change old file (file saved with @)"); return 0; } diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index 4bce7a6ff51..1e56314ab6e 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -52,9 +52,11 @@ set(SRC operators/bmo_mirror.c operators/bmo_primitive.c operators/bmo_removedoubles.c + operators/bmo_symmetrize.c operators/bmo_subdivide.c operators/bmo_subdivide.h operators/bmo_triangulate.c + operators/bmo_unsubdivide.c operators/bmo_utils.c operators/bmo_wireframe.c @@ -62,6 +64,8 @@ set(SRC intern/bmesh_construct.h intern/bmesh_core.c intern/bmesh_core.h + intern/bmesh_decimate.c + intern/bmesh_decimate.h intern/bmesh_inline.h intern/bmesh_interp.c intern/bmesh_interp.h diff --git a/source/blender/bmesh/bmesh.h b/source/blender/bmesh/bmesh.h index 955b1a729c5..a672ec0b6a7 100644 --- a/source/blender/bmesh/bmesh.h +++ b/source/blender/bmesh/bmesh.h @@ -252,6 +252,7 @@ extern "C" { #include "intern/bmesh_construct.h" #include "intern/bmesh_core.h" +#include "intern/bmesh_decimate.h" #include "intern/bmesh_interp.h" #include "intern/bmesh_iterators.h" #include "intern/bmesh_marking.h" diff --git a/source/blender/bmesh/intern/bmesh_core.c b/source/blender/bmesh/intern/bmesh_core.c index d50c94d5e6a..4e6decfa913 100644 --- a/source/blender/bmesh/intern/bmesh_core.c +++ b/source/blender/bmesh/intern/bmesh_core.c @@ -810,7 +810,7 @@ static int bm_loop_reverse_loop(BMesh *bm, BMFace *f int bmesh_loop_reverse(BMesh *bm, BMFace *f) { #ifdef USE_BMESH_HOLES - return bmesh_loop_reverse_loop(bm, f, f->loops.first); + return bm_loop_reverse_loop(bm, f, f->loops.first); #else return bm_loop_reverse_loop(bm, f); #endif @@ -1143,6 +1143,8 @@ static BMFace *bm_face_create__sfme(BMesh *bm, BMFace *UNUSED(example)) /** * \brief Split Face Make Edge (SFME) * + * \warning this is a low level function, most likely you want to use #BM_face_split() + * * Takes as input two vertices in a single face. An edge is created which divides the original face * into two distinct regions. One of the regions is assigned to the original face and it is closed off. * The second region has a new face assigned to it. @@ -1186,13 +1188,15 @@ BMFace *bmesh_sfme(BMesh *bm, BMFace *f, BMVert *v1, BMVert *v2, { #ifdef USE_BMESH_HOLES BMLoopList *lst, *lst2; +#else + int first_loop_f1; #endif BMFace *f2; BMLoop *l_iter, *l_first; BMLoop *v1loop = NULL, *v2loop = NULL, *f1loop = NULL, *f2loop = NULL; BMEdge *e; - int i, len, f1len, f2len, first_loop_f1; + int i, len, f1len, f2len; /* verify that v1 and v2 are in face */ len = f->len; @@ -1603,10 +1607,10 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou BMESH_ASSERT(edok != FALSE); } - /* deallocate edg */ + /* deallocate edge */ bm_kill_only_edge(bm, ke); - /* deallocate verte */ + /* deallocate vertex */ bm_kill_only_vert(bm, kv); /* Validate disk cycle lengths of ov, tv are unchanged */ @@ -1615,7 +1619,7 @@ BMEdge *bmesh_jekv(BMesh *bm, BMEdge *ke, BMVert *kv, const short check_edge_dou edok = bmesh_disk_validate(valence2, tv->e, tv); BMESH_ASSERT(edok != FALSE); - /* Validate loop cycle of all faces attached to oe */ + /* Validate loop cycle of all faces attached to 'oe' */ for (i = 0, l = oe->l; i < radlen; i++, l = l->radial_next) { BMESH_ASSERT(l->e == oe); edok = bmesh_verts_in_edge(l->v, l->next->v, oe); @@ -1796,8 +1800,12 @@ BMFace *bmesh_jfke(BMesh *bm, BMFace *f1, BMFace *f2, BMEdge *e) * Merges two verts into one (\a v into \a vtarget). * * \return Success + * + * \warning This does't work for collapsing edges, + * where \a v and \a vtarget are connected by an edge + * (assert checks for this case). */ -int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) +int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target) { BMEdge *e; @@ -1805,26 +1813,29 @@ int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget) int i, loops_tot; /* verts already spliced */ - if (v == vtarget) { + if (v == v_target) { return FALSE; } /* we can't modify the vert while iterating so first allocate an array of loops */ loops = BM_iter_as_arrayN(bm, BM_LOOPS_OF_VERT, v, &loops_tot); - for (i = 0; i < loops_tot; i++) { - loops[i]->v = vtarget; + if (loops) { + for (i = 0; i < loops_tot; i++) { + loops[i]->v = v_target; + } + MEM_freeN(loops); } - MEM_freeN(loops); /* move all the edges from v's disk to vtarget's disk */ while ((e = v->e)) { bmesh_disk_edge_remove(e, v); - bmesh_edge_swapverts(e, v, vtarget); - bmesh_disk_edge_append(e, vtarget); + bmesh_edge_swapverts(e, v, v_target); + bmesh_disk_edge_append(e, v_target); + BLI_assert(e->v1 != e->v2); } BM_CHECK_ELEMENT(v); - BM_CHECK_ELEMENT(vtarget); + BM_CHECK_ELEMENT(v_target); /* v is unused now, and can be killed */ BM_vert_kill(bm, v); @@ -1990,27 +2001,32 @@ int BM_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len, * * \note Edges must already have the same vertices. */ -int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget) +int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target) { BMLoop *l; - if (!BM_vert_in_edge(e, etarget->v1) || !BM_vert_in_edge(e, etarget->v2)) { + if (!BM_vert_in_edge(e, e_target->v1) || !BM_vert_in_edge(e, e_target->v2)) { /* not the same vertices can't splice */ + + /* the caller should really make sure this doesn't happen ever + * so assert on release builds */ + BLI_assert(0); + return FALSE; } while (e->l) { l = e->l; - BLI_assert(BM_vert_in_edge(etarget, l->v)); - BLI_assert(BM_vert_in_edge(etarget, l->next->v)); + BLI_assert(BM_vert_in_edge(e_target, l->v)); + BLI_assert(BM_vert_in_edge(e_target, l->next->v)); bmesh_radial_loop_remove(l, e); - bmesh_radial_append(etarget, l); + bmesh_radial_append(e_target, l); } BLI_assert(bmesh_radial_length(e->l) == 0); BM_CHECK_ELEMENT(e); - BM_CHECK_ELEMENT(etarget); + BM_CHECK_ELEMENT(e_target); /* removes from disks too */ BM_edge_kill(bm, e); diff --git a/source/blender/bmesh/intern/bmesh_core.h b/source/blender/bmesh/intern/bmesh_core.h index 491287993df..0667ed9ea1c 100644 --- a/source/blender/bmesh/intern/bmesh_core.h +++ b/source/blender/bmesh/intern/bmesh_core.h @@ -41,8 +41,8 @@ void BM_edge_kill(BMesh *bm, BMEdge *e); void BM_vert_kill(BMesh *bm, BMVert *v); int bmesh_edge_separate(BMesh *bm, BMEdge *e, BMLoop *l_sep); -int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *etarget); -int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *vtarget); +int BM_edge_splice(BMesh *bm, BMEdge *e, BMEdge *e_target); +int BM_vert_splice(BMesh *bm, BMVert *v, BMVert *v_target); int bmesh_vert_separate(BMesh *bm, BMVert *v, BMVert ***r_vout, int *r_vout_len); diff --git a/source/blender/bmesh/intern/bmesh_decimate.c b/source/blender/bmesh/intern/bmesh_decimate.c new file mode 100644 index 00000000000..519bdba02a9 --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_decimate.c @@ -0,0 +1,599 @@ +/* + * ***** 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): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/intern/bmesh_decimate.c + * \ingroup bmesh + * + * BMesh decimator. + */ + +#include <stddef.h> + +#include "MEM_guardedalloc.h" + +#include "DNA_scene_types.h" + +#include "BLI_math.h" +#include "BLI_quadric.h" +#include "BLI_heap.h" + +#include "bmesh.h" +#include "bmesh_structure.h" +#include "bmesh_decimate.h" + +/* defines for testing */ +#define USE_CUSTOMDATA +#define USE_TRIANGULATE + +/* these checks are for rare cases that we can't avoid since they are valid meshes still */ +#define USE_SAFETY_CHECKS + +#define BOUNDARY_PRESERVE_WEIGHT 100.0f + + +/* BMesh Helper Functions + * ********************** */ + +/** + * \param vquadrics must be calloc'd + */ +static void bm_decim_build_quadrics(BMesh *bm, Quadric *vquadrics) +{ + BMIter iter; + BMFace *f; + BMEdge *e; + + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMLoop *l_first; + BMLoop *l_iter; + + const float *co = BM_FACE_FIRST_LOOP(f)->v->co; + const float *no = f->no; + const float offset = -dot_v3v3(no, co); + Quadric q; + + BLI_quadric_from_v3_dist(&q, no, offset); + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(l_iter->v)], &q); + } while ((l_iter = l_iter->next) != l_first); + } + + /* boundary edges */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (UNLIKELY(BM_edge_is_boundary(e))) { + float edge_vector[3]; + float edge_cross[3]; + sub_v3_v3v3(edge_vector, e->v2->co, e->v1->co); + f = e->l->f; + cross_v3_v3v3(edge_cross, edge_vector, f->no); + + if (normalize_v3(edge_cross) != 0.0f) { + Quadric q; + BLI_quadric_from_v3_dist(&q, edge_vector, -dot_v3v3(edge_cross, e->v1->co)); + BLI_quadric_mul(&q, BOUNDARY_PRESERVE_WEIGHT); + + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(e->v1)], &q); + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(e->v2)], &q); + } + } + } +} + + +static void bm_decim_calc_target_co(BMEdge *e, float optimize_co[3], + const Quadric *vquadrics) +{ + /* compute an edge contration target for edge ei + * this is computed by summing it's vertices quadrics and + * optimizing the result. */ + Quadric q; + + BLI_quadric_add_qu_ququ(&q, + &vquadrics[BM_elem_index_get(e->v1)], + &vquadrics[BM_elem_index_get(e->v2)]); + + + if (BLI_quadric_optimize(&q, optimize_co)) { + return; /* all is good */ + } + else { + mid_v3_v3v3(optimize_co, e->v1->co, e->v2->co); + } +} + +static void bm_decim_build_edge_cost_single(BMEdge *e, + const Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + const Quadric *q1, *q2; + float optimize_co[3]; + float cost; + + if (eheap_table[BM_elem_index_get(e)]) { + BLI_heap_remove(eheap, eheap_table[BM_elem_index_get(e)]); + } + + /* check we can collapse, some edges we better not touch */ + if (BM_edge_is_boundary(e)) { + if (e->l->f->len == 3) { + /* pass */ + } + else { + /* only collapse tri's */ + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + } + else if (BM_edge_is_manifold(e)) { + if ((e->l->f->len == 3) && (e->l->radial_next->f->len == 3)) { + /* pass */ + } + else { + /* only collapse tri's */ + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + } + else { + eheap_table[BM_elem_index_get(e)] = NULL; + return; + } + /* end sanity check */ + + + bm_decim_calc_target_co(e, optimize_co, vquadrics); + + q1 = &vquadrics[BM_elem_index_get(e->v1)]; + q2 = &vquadrics[BM_elem_index_get(e->v2)]; + + cost = (BLI_quadric_evaluate(q1, optimize_co) + BLI_quadric_evaluate(q2, optimize_co)); + + eheap_table[BM_elem_index_get(e)] = BLI_heap_insert(eheap, cost, e); +} + +static void bm_decim_build_edge_cost(BMesh *bm, + const Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + BMIter iter; + BMEdge *e; + unsigned int i; + + BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) { + eheap_table[i] = NULL; /* keep sanity check happy */ + bm_decim_build_edge_cost_single(e, vquadrics, eheap, eheap_table); + } +} + +#ifdef USE_TRIANGULATE +/* Temp Triangulation + * ****************** */ + +/** + * To keep things simple we can only collapse edges on triangulated data + * (limitation with edge collapse and error calculation functions). + * + * But to avoid annoying users by only giving triangle results, we can + * triangulate, keeping a reference between the faces, then join after + * if the edges don't collapse, this will also allow more choices when + * collapsing edges so even has some advantage over decimating quads + * directly. + * + * \return TRUE if any faces were triangulated. + */ + +static int bm_decim_triangulate_begin(BMesh *bm) +{ +#ifdef USE_SAFETY_CHECKS + const int check_double_edges = TRUE; +#else + const int check_double_edges = FALSE; +#endif + + BMIter iter; + BMFace *f; + // int has_quad; // could optimize this a little + int has_cut = FALSE; + + BLI_assert((bm->elem_index_dirty & BM_VERT) == 0); + + /* first clear loop index values */ + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + BMLoop *l_iter; + BMLoop *l_first; + + l_iter = l_first = BM_FACE_FIRST_LOOP(f); + do { + BM_elem_index_set(l_iter, -1); + } while ((l_iter = l_iter->next) != l_first); + + // has_quad |= (f->len == 4) + } + + /* adding new faces as we loop over faces + * is normally best avoided, however in this case its not so bad because any face touched twice + * will already be triangulated*/ + BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { + if (f->len == 4) { + BMLoop *f_l[4]; + BMLoop *l_iter; + BMLoop *l_a, *l_b; + + l_iter = BM_FACE_FIRST_LOOP(f); + + f_l[0] = l_iter; l_iter = l_iter->next; + f_l[1] = l_iter; l_iter = l_iter->next; + f_l[2] = l_iter; l_iter = l_iter->next; + f_l[3] = l_iter; l_iter = l_iter->next; + + if (len_squared_v3v3(f_l[0]->v->co, f_l[2]->v->co) < len_squared_v3v3(f_l[1]->v->co, f_l[3]->v->co)) { + l_a = f_l[0]; + l_b = f_l[2]; + } + else { + l_a = f_l[1]; + l_b = f_l[3]; + } + + { + BMFace *f_new; + BMLoop *l_new; + + /* warning, NO_DOUBLE option here isn't handled as nice as it could be + * - if there is a quad that has a free standing edge joining it along + * where we want to split the face, there isnt a good way we can handle this. + * currently that edge will get removed when joining the tris back into a quad. */ + f_new = BM_face_split(bm, f, l_a->v, l_b->v, &l_new, NULL, check_double_edges); + + if (f_new) { + /* the value of this doesn't matter, only that the 2 loops match and have unique values */ + const int f_index = BM_elem_index_get(f); + + /* since we just split theres only ever 2 loops */ + BLI_assert(BM_edge_is_manifold(l_new->e)); + + BM_elem_index_set(l_new, f_index); + BM_elem_index_set(l_new->radial_next, f_index); + + has_cut = TRUE; + } + } + } + } + + BLI_assert((bm->elem_index_dirty & BM_VERT) == 0); + + if (has_cut) { + /* now triangulation is done we need to correct index values */ + BM_mesh_elem_index_ensure(bm, BM_EDGE | BM_FACE); + } + + return has_cut; +} + +static void bm_decim_triangulate_end(BMesh *bm) +{ + /* decimation finished, now re-join */ + BMIter iter; + BMEdge *e; + + /* boundary edges */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMLoop *l_a, *l_b; + if (BM_edge_loop_pair(e, &l_a, &l_b)) { + const int l_a_index = BM_elem_index_get(l_a); + if (l_a_index != -1) { + const int l_b_index = BM_elem_index_get(l_b); + if (l_a_index == l_b_index) { + /* highly unlikely to fail, but prevents possible double-ups */ + if (l_a->f->len == 3 && l_b->f->len == 3) { + BMFace *f[2] = {l_a->f, l_b->f}; + BM_faces_join(bm, f, 2, TRUE); + } + } + } + } + } +} + +#endif /* USE_TRIANGULATE */ + +/* Edge Collapse Functions + * *********************** */ + +/** + * special, highly limited edge collapse function + * intended for speed over flexibiliy. + * can only collapse edges connected to (1, 2) tris. + * + * Important - dont add vert/edge/face data on collapsing! + * + * \param ke_other let caller know what edges we remove besides \a ke + */ +static int bm_edge_collapse(BMesh *bm, BMEdge *ke, BMVert *kv, int ke_other[2], +#ifdef USE_CUSTOMDATA + const float customdata_fac +#else + const float UNUSED(customdata_fac) +#endif + ) +{ + BMVert *v_other = BM_edge_other_vert(ke, kv); + + BLI_assert(v_other != NULL); + + if (BM_edge_is_manifold(ke)) { + BMLoop *l_a, *l_b; + BMEdge *e_a_other[2], *e_b_other[2]; + int ok; + + ok = BM_edge_loop_pair(ke, &l_a, &l_b); + + BLI_assert(ok == TRUE); + BLI_assert(l_a->f->len == 3); + BLI_assert(l_b->f->len == 3); + + /* keep 'kv' 0th */ + if (BM_vert_in_edge(l_a->prev->e, kv)) { + e_a_other[0] = l_a->prev->e; + e_a_other[1] = l_a->next->e; + } + else { + e_a_other[1] = l_a->prev->e; + e_a_other[0] = l_a->next->e; + } + + if (BM_vert_in_edge(l_b->prev->e, kv)) { + e_b_other[0] = l_b->prev->e; + e_b_other[1] = l_b->next->e; + } + else { + e_b_other[1] = l_b->prev->e; + e_b_other[0] = l_b->next->e; + } + + BLI_assert(BM_edge_share_vert(e_a_other[0], e_b_other[0])); + BLI_assert(BM_edge_share_vert(e_a_other[1], e_b_other[1])); + + /* we could assert this case, but better just bail out */ +#if 0 + BLI_assert(e_a_other[0] != e_b_other[0]); + BLI_assert(e_a_other[0] != e_b_other[1]); + BLI_assert(e_b_other[0] != e_a_other[0]); + BLI_assert(e_b_other[0] != e_a_other[1]); +#endif + /* not totally common but we want to avoid */ + if (ELEM(e_a_other[0], e_b_other[0], e_b_other[1]) || + ELEM(e_a_other[1], e_b_other[0], e_b_other[1])) + { + return FALSE; + } + + ke_other[0] = BM_elem_index_get(e_a_other[0]); + ke_other[1] = BM_elem_index_get(e_b_other[0]); + +#ifdef USE_CUSTOMDATA + /* TODO, loops */ + // const float w[2] = {customdata_fac, 1.0f - customdata_fac}; + + /* before killing, do customdata */ + BM_data_interp_from_verts(bm, v_other, kv, v_other, customdata_fac); +#endif + + BM_edge_kill(bm, ke); + + BM_vert_splice(bm, kv, v_other); + + BM_edge_splice(bm, e_a_other[0], e_a_other[1]); + BM_edge_splice(bm, e_b_other[0], e_b_other[1]); + + // BM_mesh_validate(bm); + + return TRUE; + } + else if (BM_edge_is_boundary(ke)) { + /* same as above but only one triangle */ + BMLoop *l_a; + BMEdge *e_a_other[2]; + + l_a = ke->l; + + BLI_assert(l_a->f->len == 3); + + /* keep 'kv' 0th */ + if (BM_vert_in_edge(l_a->prev->e, kv)) { + e_a_other[0] = l_a->prev->e; + e_a_other[1] = l_a->next->e; + } + else { + e_a_other[1] = l_a->prev->e; + e_a_other[0] = l_a->next->e; + } + + ke_other[0] = BM_elem_index_get(e_a_other[0]); + ke_other[1] = -1; + +#ifdef USE_CUSTOMDATA + /* TODO, loops */ + // const float w[2] = {customdata_fac, 1.0f - customdata_fac}; + + /* before killing, do customdata */ + BM_data_interp_from_verts(bm, v_other, kv, v_other, customdata_fac); +#endif + + BM_edge_kill(bm, ke); + + BM_vert_splice(bm, kv, v_other); + + BM_edge_splice(bm, e_a_other[0], e_a_other[1]); + + // BM_mesh_validate(bm); + + return TRUE; + } + else { + return FALSE; + } +} + + +/* collapse e the edge, removing e->v2 */ +static void bm_decim_edge_collapse(BMesh *bm, BMEdge *e, + Quadric *vquadrics, + Heap *eheap, HeapNode **eheap_table) +{ + int ke_other[2]; + BMVert *v = e->v1; + int kv_index = BM_elem_index_get(e->v2); /* the vert is removed so only store the index */ + float optimize_co[3]; + float customdata_fac; + + bm_decim_calc_target_co(e, optimize_co, vquadrics); + + /* use for customdata merging */ + customdata_fac = line_point_factor_v3(optimize_co, e->v1->co, e->v2->co); + + if (bm_edge_collapse(bm, e, e->v2, ke_other, customdata_fac)) { + /* update collapse info */ + int i; + + e = NULL; /* paranoid safety check */ + + copy_v3_v3(v->co, optimize_co); + + /* remove eheap */ + for (i = 0; i < 2; i++) { + /* highly unlikely 'eheap_table[ke_other[i]]' would be NULL, but do for sanity sake */ + if ((ke_other[i] != -1) && (eheap_table[ke_other[i]] != NULL)) { + BLI_heap_remove(eheap, eheap_table[ke_other[i]]); + eheap_table[ke_other[i]] = NULL; + } + } + + /* update vertex quadric, add kept vertex from killed vertex */ + BLI_quadric_add_qu_qu(&vquadrics[BM_elem_index_get(v)], &vquadrics[kv_index]); + + /* update connected normals */ + BM_vert_normal_update_all(v); + + /* update error costs and the eheap */ + if (LIKELY(v->e)) { + BMEdge *e_iter; + BMEdge *e_first; + e_iter = e_first = v->e; + do { + //BLI_assert(BM_edge_find_double(e_iter) == NULL); +#ifdef USE_SAFETY_CHECKS + /* note! - this check is slow, but we can't avoid it - Campbell */ + BMEdge *e_double; + + e_double = BM_edge_find_double(e_iter); + + if (UNLIKELY(e_double != NULL)) { + int e_index = BM_elem_index_get(e_double); + if (BM_edge_splice(bm, e_double, e_iter)) { + if (eheap_table[e_index]) { + BLI_heap_remove(eheap, eheap_table[e_index]); + eheap_table[e_index] = NULL; + } + } + } + + /* if this happens, the e_double check could be put in a while loop, + * so as to keep removing doubles while they are found. so far this isnt needed */ + BLI_assert(BM_edge_find_double(e_iter) == NULL); +#endif + + bm_decim_build_edge_cost_single(e_iter, vquadrics, eheap, eheap_table); + } while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e_first); + + } + } +} + + +/* Main Decimate Function + * ********************** */ + +void BM_mesh_decimate(BMesh *bm, const float factor) +{ + Heap *eheap; /* edge heap */ + HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */ + Quadric *vquadrics; /* vert index aligned quadrics */ + int tot_edge_orig; + int face_tot_target; + int use_triangulate; + + +#ifdef USE_TRIANGULATE + /* temp convert quads to triangles */ + use_triangulate = bm_decim_triangulate_begin(bm); +#endif + + + /* alloc vars */ + vquadrics = MEM_callocN(sizeof(Quadric) * bm->totvert, __func__); + eheap = BLI_heap_new_ex(bm->totedge); + eheap_table = MEM_callocN(sizeof(HeapNode *) * bm->totedge, __func__); + tot_edge_orig = bm->totedge; + + + /* build initial edge collapse cost data */ + bm_decim_build_quadrics(bm, vquadrics); + + bm_decim_build_edge_cost(bm, vquadrics, eheap, eheap_table); + + face_tot_target = bm->totface * factor; + bm->elem_index_dirty |= BM_FACE | BM_EDGE | BM_VERT; + + + /* iterative edge collapse and maintain the eheap */ + while ((bm->totface > face_tot_target) && (BLI_heap_empty(eheap) == FALSE)) { + BMEdge *e = BLI_heap_popmin(eheap); + BLI_assert(BM_elem_index_get(e) < tot_edge_orig); /* handy to detect corruptions elsewhere */ + + /* under normal conditions wont be accessed again, + * but NULL just incase so we don't use freed node */ + eheap_table[BM_elem_index_get(e)] = NULL; + + bm_decim_edge_collapse(bm, e, vquadrics, eheap, eheap_table); + } + + +#ifdef USE_TRIANGULATE + /* its possible we only had triangles, skip this step in that case */ + if (LIKELY(use_triangulate)) { + /* temp convert quads to triangles */ + bm_decim_triangulate_end(bm); + } +#endif + + /* free vars */ + MEM_freeN(vquadrics); + MEM_freeN(eheap_table); + BLI_heap_free(eheap, NULL); + + /* testing only */ + // BM_mesh_validate(bm); +} diff --git a/source/blender/bmesh/intern/bmesh_decimate.h b/source/blender/bmesh/intern/bmesh_decimate.h new file mode 100644 index 00000000000..e44aa576bda --- /dev/null +++ b/source/blender/bmesh/intern/bmesh_decimate.h @@ -0,0 +1,32 @@ +/* + * ***** 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): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef __BMESH_DECIMATE_H__ +#define __BMESH_DECIMATE_H__ + +/** \file blender/bmesh/intern/bmesh_decimate.h + * \ingroup bmesh + */ + +void BM_mesh_decimate(BMesh *bm, const float factor); + +#endif /* __BMESH_DECIMATE_H__ */ diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index 726127fdcad..1cb95d94e9b 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -120,6 +120,21 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len) { BMIter iter; + /* we can't rely on coun't being set */ + switch (itype) { + case BM_VERTS_OF_MESH: + iter.count = bm->totvert; + break; + case BM_EDGES_OF_MESH: + iter.count = bm->totedge; + break; + case BM_FACES_OF_MESH: + iter.count = bm->totface; + break; + default: + break; + } + if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) { BMElem *ele; BMElem **array = MEM_mallocN(sizeof(ele) * iter.count, __func__); @@ -190,10 +205,10 @@ int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const */ static void init_iterator(BMIter *iter) { - iter->firstvert = iter->nextvert = NULL; - iter->firstedge = iter->nextedge = NULL; - iter->firstloop = iter->nextloop = NULL; - iter->firstpoly = iter->nextpoly = NULL; +// iter->v_first = iter->v_next = NULL; // UNUSED + iter->e_first = iter->e_next = NULL; + iter->l_first = iter->l_next = NULL; +// iter->f_first = iter->f_next = NULL; // UNUSED iter->ldata = NULL; } @@ -229,6 +244,7 @@ void *bmiter__vert_of_mesh_step(BMIter *iter) void bmiter__edge_of_mesh_begin(BMIter *iter) { BLI_mempool_iternew(iter->bm->epool, &iter->pooliter); + iter->count = iter->bm->totedge; /* */ } void *bmiter__edge_of_mesh_step(BMIter *iter) @@ -256,19 +272,19 @@ void bmiter__edge_of_vert_begin(BMIter *iter) { init_iterator(iter); if (iter->vdata->e) { - iter->firstedge = iter->vdata->e; - iter->nextedge = iter->vdata->e; + iter->e_first = iter->vdata->e; + iter->e_next = iter->vdata->e; } } void *bmiter__edge_of_vert_step(BMIter *iter) { - BMEdge *current = iter->nextedge; + BMEdge *current = iter->e_next; - if (iter->nextedge) - iter->nextedge = bmesh_disk_edge_next(iter->nextedge, iter->vdata); + if (iter->e_next) + iter->e_next = bmesh_disk_edge_next(iter->e_next, iter->vdata); - if (iter->nextedge == iter->firstedge) iter->nextedge = NULL; + if (iter->e_next == iter->e_first) iter->e_next = NULL; return current; } @@ -284,27 +300,27 @@ void bmiter__face_of_vert_begin(BMIter *iter) if (iter->vdata->e) iter->count = bmesh_disk_facevert_count(iter->vdata); if (iter->count) { - iter->firstedge = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); - iter->nextedge = iter->firstedge; - iter->firstloop = bmesh_radial_faceloop_find_first(iter->firstedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->e_first = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); + iter->e_next = iter->e_first; + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_first->l, iter->vdata); + iter->l_next = iter->l_first; } } void *bmiter__face_of_vert_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->count && iter->nextloop) { + if (iter->count && iter->l_next) { iter->count--; - iter->nextloop = bmesh_radial_faceloop_find_next(iter->nextloop, iter->vdata); - if (iter->nextloop == iter->firstloop) { - iter->nextedge = bmesh_disk_faceedge_find_next(iter->nextedge, iter->vdata); - iter->firstloop = bmesh_radial_faceloop_find_first(iter->nextedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata); + if (iter->l_next == iter->l_first) { + iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata); + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata); + iter->l_next = iter->l_first; } } - if (!iter->count) iter->nextloop = NULL; + if (!iter->count) iter->l_next = NULL; return current ? current->f : NULL; } @@ -322,27 +338,27 @@ void bmiter__loop_of_vert_begin(BMIter *iter) if (iter->vdata->e) iter->count = bmesh_disk_facevert_count(iter->vdata); if (iter->count) { - iter->firstedge = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); - iter->nextedge = iter->firstedge; - iter->firstloop = bmesh_radial_faceloop_find_first(iter->firstedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->e_first = bmesh_disk_faceedge_find_first(iter->vdata->e, iter->vdata); + iter->e_next = iter->e_first; + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_first->l, iter->vdata); + iter->l_next = iter->l_first; } } void *bmiter__loop_of_vert_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; if (iter->count) { iter->count--; - iter->nextloop = bmesh_radial_faceloop_find_next(iter->nextloop, iter->vdata); - if (iter->nextloop == iter->firstloop) { - iter->nextedge = bmesh_disk_faceedge_find_next(iter->nextedge, iter->vdata); - iter->firstloop = bmesh_radial_faceloop_find_first(iter->nextedge->l, iter->vdata); - iter->nextloop = iter->firstloop; + iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata); + if (iter->l_next == iter->l_first) { + iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata); + iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata); + iter->l_next = iter->l_first; } } - if (!iter->count) iter->nextloop = NULL; + if (!iter->count) iter->l_next = NULL; if (current) { @@ -362,19 +378,19 @@ void bmiter__loops_of_edge_begin(BMIter *iter) /* note sure why this sets ldata ... */ init_iterator(iter); - iter->firstloop = iter->nextloop = l; + iter->l_first = iter->l_next = l; } void *bmiter__loops_of_edge_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) { - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) { + iter->l_next = NULL; } if (current) { @@ -393,23 +409,23 @@ void bmiter__loops_of_loop_begin(BMIter *iter) /* note sure why this sets ldata ... */ init_iterator(iter); - iter->firstloop = l; - iter->nextloop = iter->firstloop->radial_next; + iter->l_first = l; + iter->l_next = iter->l_first->radial_next; - if (iter->nextloop == iter->firstloop) - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) + iter->l_next = NULL; } void *bmiter__loops_of_loop_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) { - iter->nextloop = NULL; + if (iter->l_next == iter->l_first) { + iter->l_next = NULL; } if (current) { @@ -428,20 +444,20 @@ void bmiter__face_of_edge_begin(BMIter *iter) init_iterator(iter); if (iter->edata->l) { - iter->firstloop = iter->edata->l; - iter->nextloop = iter->edata->l; + iter->l_first = iter->edata->l; + iter->l_next = iter->edata->l; } } void *bmiter__face_of_edge_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) { - iter->nextloop = iter->nextloop->radial_next; + if (iter->l_next) { + iter->l_next = iter->l_next->radial_next; } - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->f : NULL; } @@ -476,15 +492,15 @@ void *bmiter__vert_of_edge_step(BMIter *iter) void bmiter__vert_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__vert_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->v : NULL; } @@ -496,15 +512,15 @@ void *bmiter__vert_of_face_step(BMIter *iter) void bmiter__edge_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__edge_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current ? current->e : NULL; } @@ -516,15 +532,15 @@ void *bmiter__edge_of_face_step(BMIter *iter) void bmiter__loop_of_face_begin(BMIter *iter) { init_iterator(iter); - iter->firstloop = iter->nextloop = BM_FACE_FIRST_LOOP(iter->pdata); + iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata); } void *bmiter__loop_of_face_step(BMIter *iter) { - BMLoop *current = iter->nextloop; + BMLoop *current = iter->l_next; - if (iter->nextloop) iter->nextloop = iter->nextloop->next; - if (iter->nextloop == iter->firstloop) iter->nextloop = NULL; + if (iter->l_next) iter->l_next = iter->l_next->next; + if (iter->l_next == iter->l_first) iter->l_next = NULL; return current; } diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index 8d0eeca31ed..3c42b3d610c 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -95,23 +95,27 @@ extern const char bm_iter_itype_htype_map[BM_ITYPE_MAX]; for (ele = BM_iter_new(iter, NULL, itype, data), indexvar = 0; ele; ele = BM_iter_step(iter), (indexvar)++) /* Iterator Structure */ +/* note: some of these vars are not used, + * so they have beem commented to save stack space since this struct is used all over */ typedef struct BMIter { BLI_mempool_iter pooliter; - BMVert *firstvert, *nextvert, *vdata; - BMEdge *firstedge, *nextedge, *edata; - BMLoop *firstloop, *nextloop, *ldata, *l; - BMFace *firstpoly, *nextpoly, *pdata; + BMVert /* *v_first, *v_next, */ *vdata; + BMEdge *e_first, *e_next, *edata; + BMLoop *l_first, *l_next, *ldata; + BMFace /* *f_first, *f_next, */ *pdata; BMesh *bm; void (*begin)(struct BMIter *iter); void *(*step)(struct BMIter *iter); + /* union { void *p; int i; long l; float f; } filter; - int count; + */ + int count; /* note, only some iterators set this, don't rely on it */ char itype; } BMIter; diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c index 0d072da5327..360e2c93de3 100644 --- a/source/blender/bmesh/intern/bmesh_mesh.c +++ b/source/blender/bmesh/intern/bmesh_mesh.c @@ -57,7 +57,7 @@ static void bm_mempool_init(BMesh *bm, const BMAllocTemplate *allocsize) bm_mesh_chunksize_default.totface, BLI_MEMPOOL_ALLOW_ITER); #ifdef USE_BMESH_HOLES - bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), allocsize[3], allocsize[3], FALSE, FALSE); + bm->looplistpool = BLI_mempool_create(sizeof(BMLoopList), 512, 512, 0); #endif /* allocate one flag pool that we don't get rid of. */ diff --git a/source/blender/bmesh/intern/bmesh_mods.c b/source/blender/bmesh/intern/bmesh_mods.c index 3195899ef01..91ca7124fc2 100644 --- a/source/blender/bmesh/intern/bmesh_mods.c +++ b/source/blender/bmesh/intern/bmesh_mods.c @@ -130,6 +130,7 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) /* this code for handling 2 and 3-valence verts * may be totally bad */ if (keepedge == NULL && len == 3) { +#if 0 /* handle specific case for three-valence. solve it by * increasing valence to four. this may be hackish. . */ BMLoop *loop = e->l; @@ -140,6 +141,13 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) if (!BM_disk_dissolve(bm, v)) { return FALSE; } +#else + BM_faces_join_pair(bm, e->l->f, e->l->radial_next->f, e, TRUE); + + if (!BM_vert_collapse_faces(bm, v->e, v, 1.0, FALSE, TRUE)) { + return FALSE; + } +#endif return TRUE; } else if (keepedge == NULL && len == 2) { @@ -188,8 +196,9 @@ int BM_disk_dissolve(BMesh *bm, BMVert *v) } while (e != v->e); } - /* collapse the verte */ - e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, TRUE, TRUE); + /* collapse the vertex */ + /* note, the baseedge can be a boundary of manifold, use this as join_faces arg */ + e = BM_vert_collapse_faces(bm, baseedge, v, 1.0, !BM_edge_is_boundary(baseedge), TRUE); if (!e) { return FALSE; diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c index 362157ad71b..407e7caae0f 100644 --- a/source/blender/bmesh/intern/bmesh_opdefines.c +++ b/source/blender/bmesh/intern/bmesh_opdefines.c @@ -698,6 +698,15 @@ static BMOpDefine bmo_triangulate_def = { BMO_OP_FLAG_UNTAN_MULTIRES }; +static BMOpDefine bmo_unsubdivide_def = { + "unsubdivide", + {{BMO_OP_SLOT_ELEMENT_BUF, "verts"}, /* input vertices */ + {BMO_OP_SLOT_INT, "iterations"}, + {0} /* null-terminating sentinel */}, + bmo_unsubdivide_exec, + BMO_OP_FLAG_UNTAN_MULTIRES +}; + static BMOpDefine bmo_subdivide_edges_def = { "subdivide_edges", {{BMO_OP_SLOT_ELEMENT_BUF, "edges"}, @@ -1182,6 +1191,29 @@ static BMOpDefine bmo_convex_hull_def = { 0 }; +/* + * Symmetrize + * + * Mekes the mesh elements in the "input" slot symmetrical. Unlike + * normal mirroring, it only copies in one direction, as specified by + * the "direction" slot. The edges and faces that cross the plane of + * symmetry are split as needed to enforce symmetry. + * + * All new vertices, edges, and faces are added to the "geomout" slot. + */ +static BMOpDefine bmo_symmetrize_def = { + "symmetrize", + {{BMO_OP_SLOT_ELEMENT_BUF, "input"}, + {BMO_OP_SLOT_INT, "direction"}, + + /* Outputs */ + {BMO_OP_SLOT_ELEMENT_BUF, "geomout"}, + + {0} /* null-terminating sentinel */}, + bmo_symmetrize_exec, + 0 +}; + BMOpDefine *opdefines[] = { &bmo_automerge_def, &bmo_average_vert_facedata_def, @@ -1246,10 +1278,12 @@ BMOpDefine *opdefines[] = { &bmo_split_def, &bmo_split_edges_def, &bmo_subdivide_edges_def, + &bmo_symmetrize_def, &bmo_transform_def, &bmo_translate_def, &bmo_triangle_fill_def, &bmo_triangulate_def, + &bmo_unsubdivide_def, &bmo_weld_verts_def, &bmo_wireframe_def, diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h b/source/blender/bmesh/intern/bmesh_operator_api.h index 0674103162c..a2f4cdc8c6a 100644 --- a/source/blender/bmesh/intern/bmesh_operator_api.h +++ b/source/blender/bmesh/intern/bmesh_operator_api.h @@ -266,6 +266,16 @@ enum { DEL_ONLYTAGGED }; +typedef enum { + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_NEGATIVE_Z, + + BMO_SYMMETRIZE_POSITIVE_X, + BMO_SYMMETRIZE_POSITIVE_Y, + BMO_SYMMETRIZE_POSITIVE_Z, +} BMO_SymmDirection; + void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag); void BMO_op_flag_disable(BMesh *bm, BMOperator *op, const int op_flag); diff --git a/source/blender/bmesh/intern/bmesh_operators_private.h b/source/blender/bmesh/intern/bmesh_operators_private.h index dc1bdaa4689..d6135efe19a 100644 --- a/source/blender/bmesh/intern/bmesh_operators_private.h +++ b/source/blender/bmesh/intern/bmesh_operators_private.h @@ -96,10 +96,12 @@ void bmo_spin_exec(BMesh *bm, BMOperator *op); void bmo_split_edges_exec(BMesh *bm, BMOperator *op); void bmo_split_exec(BMesh *bm, BMOperator *op); void bmo_subdivide_edges_exec(BMesh *bm, BMOperator *op); +void bmo_symmetrize_exec(BMesh *bm, BMOperator *op); void bmo_transform_exec(BMesh *bm, BMOperator *op); void bmo_translate_exec(BMesh *bm, BMOperator *op); void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op); void bmo_triangulate_exec(BMesh *bm, BMOperator *op); +void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op); void bmo_weld_verts_exec(BMesh *bm, BMOperator *op); void bmo_wireframe_exec(BMesh *bm, BMOperator *op); diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c index d850eb34477..9520b0298d8 100644 --- a/source/blender/bmesh/intern/bmesh_queries.c +++ b/source/blender/bmesh/intern/bmesh_queries.c @@ -298,6 +298,14 @@ int BM_edge_in_face(BMFace *f, BMEdge *e) } /** + * Returns whether or not a given edge is is part of a given loop. + */ +int BM_edge_in_loop(BMEdge *e, BMLoop *l) +{ + return (l->e == e || l->prev->e == e); +} + +/** * Returns whether or not two vertices are in * a given edge */ @@ -316,6 +324,44 @@ BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v) } /** + * Given a edge and a loop (assumes the edge is manifold). returns + * the other faces loop, sharing the same vertex. + * + * <pre> + * +-------------------+ + * | | + * | | + * |l_other <-- return | + * +-------------------+ <-- A manifold edge between 2 faces + * |l e <-- edge | + * |^ <-------- loop | + * | | + * +-------------------+ + * </pre> + */ +BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l) +{ + BMLoop *l_other; + + BLI_assert(BM_edge_is_manifold(e)); + BLI_assert(BM_vert_in_edge(e, l->v)); + + l_other = (e->l == l) ? l->radial_next : l; + + if (l_other->v == l->v) { + /* pass */ + } + else if (l_other->next->v == l->v) { + l_other = l_other->next; + } + else { + BLI_assert(0); + } + + return l_other; +} + +/** * The function takes a vertex at the center of a fan and returns the opposite edge in the fan. * All edges in the fan must be manifold, otherwise return NULL. * @@ -1018,6 +1064,28 @@ BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2) } /** + * Returns an edge sharing the same vertices as this one. + * This isn't an invalid state but tools should clean up these cases before + * returning the mesh to the user. + */ +BMEdge *BM_edge_find_double(BMEdge *e) +{ + BMVert *v = e->v1; + BMVert *v_other = e->v2; + + BMEdge *e_iter; + + e_iter = e; + while ((e_iter = bmesh_disk_edge_next(e_iter, v)) != e) { + if (UNLIKELY(BM_vert_in_edge(e_iter, v_other))) { + return e_iter; + } + } + + return NULL; +} + +/** * Given a set of vertices \a varr, find out if * all those vertices overlap an existing face. * diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h index 36ffc296759..166b8a54f8a 100644 --- a/source/blender/bmesh/intern/bmesh_queries.h +++ b/source/blender/bmesh/intern/bmesh_queries.h @@ -31,6 +31,7 @@ int BM_vert_in_face(BMFace *f, BMVert *v); int BM_verts_in_face(BMesh *bm, BMFace *f, BMVert **varr, int len); int BM_edge_in_face(BMFace *f, BMEdge *e); +int BM_edge_in_loop(BMEdge *e, BMLoop *l); int BM_vert_in_edge(BMEdge *e, BMVert *v); int BM_verts_in_edge(BMVert *v1, BMVert *v2, BMEdge *e); @@ -39,6 +40,7 @@ float BM_edge_calc_length(BMEdge *e); int BM_edge_face_pair(BMEdge *e, BMFace **r_fa, BMFace **r_fb); int BM_edge_loop_pair(BMEdge *e, BMLoop **r_la, BMLoop **r_lb); BMVert *BM_edge_other_vert(BMEdge *e, BMVert *v); +BMLoop *BM_edge_other_loop(BMEdge *e, BMLoop *l); BMLoop *BM_face_other_edge_loop(BMFace *f, BMEdge *e, BMVert *v); BMLoop *BM_face_other_vert_loop(BMFace *f, BMVert *v_prev, BMVert *v); BMLoop *BM_loop_other_vert_loop(BMLoop *l, BMVert *v); @@ -72,6 +74,7 @@ BMLoop *BM_face_find_shortest_loop(BMFace *f); BMLoop *BM_face_find_longest_loop(BMFace *f); BMEdge *BM_edge_exists(BMVert *v1, BMVert *v2); +BMEdge *BM_edge_find_double(BMEdge *e); int BM_face_exists_overlap(BMesh *bm, BMVert **varr, int len, BMFace **r_existface); diff --git a/source/blender/bmesh/intern/bmesh_walkers_impl.c b/source/blender/bmesh/intern/bmesh_walkers_impl.c index a72bfe47127..225ea6c2ef6 100644 --- a/source/blender/bmesh/intern/bmesh_walkers_impl.c +++ b/source/blender/bmesh/intern/bmesh_walkers_impl.c @@ -499,7 +499,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker) BMEdge *e = lwalk->cur, *nexte = NULL; BMLoop *l; BMVert *v; - int i; + int i = 0; owalk = *lwalk; BMW_state_remove(walker); @@ -534,7 +534,7 @@ static void *bmw_LoopWalker_step(BMWalker *walker) } else if (l) { /* NORMAL EDGE WITH FACES */ int vert_edge_tot; - int stopi; + int stopi = 0; v = BM_edge_other_vert(e, lwalk->lastv); diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 10a9d511c77..e31df2e4444 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -233,7 +233,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op) } #if 0 - //a bit of cleaner code that, alas, doens't work. + /* a bit of cleaner code that, alas, doens't work. */ /* build edge tag */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BMO_elem_flag_test(bm, e->v1, BEVEL_FLAG) || BMO_elem_flag_test(bm, e->v2, BEVEL_FLAG)) { diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index 7191aa7a7b6..3dbc0d0a5eb 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -199,7 +199,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) { BMIter iter, liter; BMOIter siter; - BMFace *f1, *f2; + BMFace *f; BMLoop *l; BMEdge *e; BLI_array_declare(jedges); @@ -213,15 +213,16 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) int i, totedge; /* flag all edges of all input face */ - BMO_ITER (f1, &siter, bm, op, "faces", BM_FACE) { - BMO_elem_flag_enable(bm, f1, FACE_INPUT); - BM_ITER_ELEM (l, &liter, f1, BM_LOOPS_OF_FACE) { + BMO_ITER (f, &siter, bm, op, "faces", BM_FACE) { + BMO_elem_flag_enable(bm, f, FACE_INPUT); + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { BMO_elem_flag_enable(bm, l->e, EDGE_MARK); } } /* unflag edges that are invalid; e.g. aren't surrounded by triangle */ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMFace *f1, *f2; if (!BMO_elem_flag_test(bm, e, EDGE_MARK)) continue; @@ -300,6 +301,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) } BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + BMFace *f1, *f2; + if (!BMO_elem_flag_test(bm, e, EDGE_CHOSEN)) continue; @@ -310,6 +313,8 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op) BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BMO_elem_flag_test(bm, e, EDGE_MARK)) { + BMFace *f1, *f2; + /* ok, this edge wasn't merged, check if it's * in a 2-tri-pair island, and if so merg */ diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c new file mode 100644 index 00000000000..a428405fb8b --- /dev/null +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -0,0 +1,663 @@ +/* + * ***** 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): Nicholas Bishop + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_array.h" +#include "BLI_math.h" +#include "BLI_utildefines.h" + +#include "bmesh.h" +#include "intern/bmesh_operators_private.h" + +enum { + SYMM_OUTPUT_GEOM = (1 << 0) +}; + +/* Note: don't think there's much need to make these user-adjustable? */ +#define SYMM_AXIS_THRESHOLD 0.00002f +#define SYMM_VERT_THRESHOLD 0.00002f + +typedef enum { + /* Coordinate lies on the side being copied from */ + SYMM_SIDE_KEEP, + /* Coordinate lies on the side being copied from and within the + * axis threshold */ + SYMM_SIDE_AXIS, + /* Coordinate lies on the side being copied to */ + SYMM_SIDE_KILL +} SymmSide; + +typedef struct { + BMesh *bm; + BMOperator *op; + + int axis; + BMO_SymmDirection direction; + + /* Maps from input vertices to their mirrors. If the vertex + * doesn't have a mirror, it's not in this map. If the vertex is + * within the axis threshold, it's mapped to itself. */ + GHash *vert_symm_map; + + /* Edges that cross the symmetry plane and are asymmetric get + * split. This map goes from input edges to output vertices. If an + * edge is not split, it's not in this map. */ + GHash *edge_split_map; +} Symm; + +/* Return which side the coordinate lies on */ +static SymmSide symm_co_side(const Symm *symm, + const float *co) +{ + float comp = co[symm->axis]; + if (ELEM3(symm->direction, + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_NEGATIVE_Z)) + { + comp = -comp; + } + + if (comp >= 0) { + if (comp < SYMM_AXIS_THRESHOLD) + return SYMM_SIDE_AXIS; + else + return SYMM_SIDE_KEEP; + } + else + return SYMM_SIDE_KILL; +} + +/* Output vertices and the vert_map array */ +static void symm_verts_mirror(Symm *symm) +{ + BMOIter oiter; + BMVert *src_v, *dst_v; + + symm->vert_symm_map = BLI_ghash_ptr_new(AT); + + BMO_ITER (src_v, &oiter, symm->bm, symm->op, "input", BM_VERT) { + SymmSide side = symm_co_side(symm, src_v->co); + float co[3]; + + switch (side) { + case SYMM_SIDE_KEEP: + /* The vertex is outside the axis area; output its mirror */ + copy_v3_v3(co, src_v->co); + co[symm->axis] = -co[symm->axis]; + + dst_v = BM_vert_create(symm->bm, co, src_v); + BMO_elem_flag_enable(symm->bm, dst_v, SYMM_OUTPUT_GEOM); + BLI_ghash_insert(symm->vert_symm_map, src_v, dst_v); + break; + + case SYMM_SIDE_AXIS: + /* The vertex is within the axis area, snap to center */ + src_v->co[symm->axis] = 0; + /* Vertex isn't copied, map to itself */ + BLI_ghash_insert(symm->vert_symm_map, src_v, src_v); + break; + + case SYMM_SIDE_KILL: + /* The vertex does not lie in the half-space being + * copied from, nothing to do */ + break; + } + } +} + +static int symm_edge_crosses_axis(const Symm *symm, const BMEdge *e) +{ + const int sides[2] = {symm_co_side(symm, e->v1->co), + symm_co_side(symm, e->v2->co)}; + + return ((sides[0] != SYMM_SIDE_AXIS) && + (sides[1] != SYMM_SIDE_AXIS) && + (sides[0] != sides[1])); +} + +/* Output edge split vertices for asymmetric edges and the edge_splits + * mapping array */ +static void symm_split_asymmetric_edges(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + + symm->edge_split_map = BLI_ghash_ptr_new(AT); + + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + float flipped[3]; + + copy_v3_v3(flipped, e->v1->co); + flipped[symm->axis] = -flipped[symm->axis]; + + if (symm_edge_crosses_axis(symm, e) && + (!compare_v3v3(e->v2->co, flipped, SYMM_VERT_THRESHOLD))) + { + /* Endpoints lie on opposite sides and are asymmetric */ + + BMVert *v; + float lambda = 0, edge_dir[3], co[3]; + float plane_co[3][3][3] = { + /* axis == 0 */ + {{0, 0, 0}, {0, 1, 0}, {0, 0, 1}}, + /* axis == 1 */ + {{0, 0, 0}, {1, 0, 0}, {0, 0, 1}}, + /* axis == 2 */ + {{0, 0, 0}, {1, 0, 0}, {0, 1, 0}}, + }; + int r; + + /* Find intersection of edge with symmetry plane */ + sub_v3_v3v3(edge_dir, e->v2->co, e->v1->co); + normalize_v3(edge_dir); + r = isect_ray_plane_v3(e->v1->co, + edge_dir, + plane_co[symm->axis][0], + plane_co[symm->axis][1], + plane_co[symm->axis][2], + &lambda, TRUE); + BLI_assert(r); + + madd_v3_v3v3fl(co, e->v1->co, edge_dir, lambda); + co[symm->axis] = 0; + + /* Edge is asymmetric, split it with a new vertex */ + v = BM_vert_create(symm->bm, co, e->v1); + BMO_elem_flag_enable(symm->bm, v, SYMM_OUTPUT_GEOM); + BLI_ghash_insert(symm->edge_split_map, e, v); + } + } +} + +static void symm_mirror_edges(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + BMVert *v1 = NULL, *v2 = NULL; + BMEdge *e_new; + + v1 = BLI_ghash_lookup(symm->vert_symm_map, e->v1); + v2 = BLI_ghash_lookup(symm->vert_symm_map, e->v2); + + if (v1 && v2) { + e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + } + else if (v1 || v2) { + if (BLI_ghash_haskey(symm->edge_split_map, e)) { + BMVert *v_split = BLI_ghash_lookup(symm->edge_split_map, e); + + /* Output the keep side of the split edge */ + if (!v1) { + e_new = BM_edge_create(symm->bm, v_split, e->v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + v1 = v_split; + } + else { + e_new = BM_edge_create(symm->bm, e->v1, v_split, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + v2 = v_split; + } + + /* Output the kill side of the split edge */ + e_new = BM_edge_create(symm->bm, v1, v2, e, TRUE); + BMO_elem_flag_enable(symm->bm, e_new, SYMM_OUTPUT_GEOM); + } + } + } +} + +/****************************** SymmPoly ******************************/ + +typedef struct { + /* Indices into the source mvert array (or -1 if not in that array) */ + BMVert **src_verts; + /* Indices into the destination mvert array, these are vertices + * created by an edge split (-1 for vertices not created by edge + * split) */ + BMVert **edge_verts; + + /* Number of vertices in the polygon */ + int len; + + /* True only if none of the polygon's edges were split */ + int already_symmetric; +} SymmPoly; + +static void symm_poly_with_splits(const Symm *symm, + BMFace *f, + SymmPoly *out) +{ + BMIter iter; + BMLoop *l; + int i; + + /* Count vertices and check for edge splits */ + out->len = f->len; + out->already_symmetric = TRUE; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + if (BLI_ghash_haskey(symm->edge_split_map, l->e)) { + out->len++; + out->already_symmetric = FALSE; + } + } + + i = 0; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + BMVert *split = BLI_ghash_lookup(symm->edge_split_map, l->e); + + out->src_verts[i] = l->v; + out->edge_verts[i] = NULL; + i++; + + if (split) { + out->src_verts[i] = NULL; + out->edge_verts[i] = split; + i++; + } + } +} + +static const float *symm_poly_co(const SymmPoly *sp, int v) +{ + if (sp->src_verts[v]) + return sp->src_verts[v]->co; + else if (sp->edge_verts[v]) + return sp->edge_verts[v]->co; + else + return NULL; +} + +static SymmSide symm_poly_co_side(const Symm *symm, + const SymmPoly *sp, + int v) +{ + return symm_co_side(symm, symm_poly_co(sp, v)); +} + +/* Return the index of the vertex in the destination array at corner + * 'v' of the polygon, or -1 if not in that array */ +static BMVert *symm_poly_dst(const SymmPoly *sp, int v) +{ + if (sp->edge_verts[v]) + return sp->edge_verts[v]; + else if (sp->src_verts[v]) + return sp->src_verts[v]; + else + return NULL; +} + +/* Same as above, but returns the index of the mirror if available, or + * the same index if on the axis, or -1 otherwise */ +static BMVert *symm_poly_mirror_dst(const Symm *symm, + const SymmPoly *sp, + int v) +{ + if (sp->edge_verts[v]) + return sp->edge_verts[v]; + else if (sp->src_verts[v]) { + if (BLI_ghash_haskey(symm->vert_symm_map, sp->src_verts[v])) + return BLI_ghash_lookup(symm->vert_symm_map, sp->src_verts[v]); + else + return sp->src_verts[v]; + } + else + return NULL; +} + +static int symm_poly_next_crossing(const Symm *symm, + const SymmPoly *sp, + int start, + int *l1, + int *l2) +{ + int i; + + for (i = 0; i < sp->len; i++) { + (*l1) = (start + i) % sp->len; + (*l2) = ((*l1) + 1) % sp->len; + + if ((symm_poly_co_side(symm, sp, *l1) == SYMM_SIDE_KILL) ^ + (symm_poly_co_side(symm, sp, *l2) == SYMM_SIDE_KILL)) + { + return TRUE; + } + } + + BLI_assert(!"symm_poly_next_crossing failed"); + return FALSE; +} + +static BMFace *symm_face_create_v(BMesh *bm, BMVert **fv, BMEdge **fe, int len) +{ + BMFace *f_new; + int i; + + for (i = 0; i < len; i++) { + int j = (i + 1) % len; + fe[i] = BM_edge_exists(fv[i], fv[j]); + if (!fe[i]) { + fe[i] = BM_edge_create(bm, fv[i], fv[j], NULL, FALSE); + BMO_elem_flag_enable(bm, fe[i], SYMM_OUTPUT_GEOM); + } + } + f_new = BM_face_create(bm, fv, fe, len, TRUE); + BM_face_select_set(bm, f_new, TRUE); + BMO_elem_flag_enable(bm, f_new, SYMM_OUTPUT_GEOM); + return f_new; +} + +static void symm_mesh_output_poly_zero_splits(Symm *symm, + SymmPoly *sp, + BMVert **fv, + BMEdge **fe, + int segment_len, + int start) +{ + int i, j; + + j = 0; + + /* Output the keep side of the input polygon */ + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BLI_assert(sp->src_verts[offset]); + fv[j++] = sp->src_verts[offset]; + } + + /* Output the kill side of the polygon */ + for (i = segment_len - 1; i >= 0; i--) { + const int offset = (start + i) % sp->len; + + if (symm_poly_co_side(symm, sp, offset) == SYMM_SIDE_KEEP) { + BLI_assert(sp->src_verts[offset]); + fv[j++] = BLI_ghash_lookup(symm->vert_symm_map, + sp->src_verts[offset]); + } + } + + symm_face_create_v(symm->bm, fv, fe, j); +} + +static void symm_mesh_output_poly_with_splits(Symm *symm, + SymmPoly *sp, + BMVert **fv, + BMEdge **fe, + int segment_len, + int start) +{ + int i; + + /* Output the keep side of the input polygon */ + + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BMVert *v = symm_poly_dst(sp, offset); + + BLI_assert(v); + + fv[i] = v; + } + + symm_face_create_v(symm->bm, fv, fe, segment_len); + + /* Output the kill side of the input polygon */ + + for (i = 0; i < segment_len; i++) { + const int offset = (start + i) % sp->len; + BMVert *v = symm_poly_mirror_dst(symm, sp, offset); + + fv[segment_len - i - 1] = v; + + } + + symm_face_create_v(symm->bm, fv, fe, segment_len); +} + +static void symm_mirror_polygons(Symm *symm) +{ + BMOIter oiter; + BMFace *f; + BMVert **pv = NULL; + BMVert **fv = NULL; + BMEdge **fe = NULL; + BLI_array_declare(pv); + BLI_array_declare(fv); + BLI_array_declare(fe); + + BMO_ITER (f, &oiter, symm->bm, symm->op, "input", BM_FACE) { + BMIter iter; + BMLoop *l; + int mirror_all = TRUE, ignore_all = TRUE; + + /* Check if entire polygon can be mirrored or ignored */ + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + const SymmSide side = symm_co_side(symm, l->v->co); + if (side == SYMM_SIDE_KILL) + mirror_all = FALSE; + else if (side == SYMM_SIDE_KEEP) + ignore_all = FALSE; + } + + if (mirror_all) { + int i; + + /* Make a mirrored copy of the polygon */ + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, f->len); + BLI_array_grow_items(fe, f->len); + + i = f->len; + BM_ITER_ELEM (l, &iter, f, BM_LOOPS_OF_FACE) { + i--; + + if (symm_co_side(symm, l->v->co) == SYMM_SIDE_KEEP) + fv[i] = BLI_ghash_lookup(symm->vert_symm_map, l->v); + else + fv[i] = l->v; + } + + symm_face_create_v(symm->bm, fv, fe, f->len); + } + else if (ignore_all) { + BM_face_kill(symm->bm, f); + } + else { + SymmPoly sp; + int l1, l2, l3, l4; + int double_l2, double_l3; + int segment_len; + + BLI_array_empty(pv); + BLI_array_grow_items(pv, f->len * 4); + sp.src_verts = pv; + sp.edge_verts = pv + f->len * 2; + symm_poly_with_splits(symm, f, &sp); + + /* Find first loop edge crossing the axis */ + symm_poly_next_crossing(symm, &sp, 0, &l1, &l2); + + /* If crossing isn't kill to keep, find the next one */ + if (symm_poly_co_side(symm, &sp, l1) != SYMM_SIDE_KILL) { + symm_poly_next_crossing(symm, &sp, l2, &l1, &l2); + } + + /* Find next crossing (keep to kill) */ + symm_poly_next_crossing(symm, &sp, l2, &l3, &l4); + + if (l2 == l3) + segment_len = 0; + else if (l2 < l3) + segment_len = l3 - l2 + 1; + else + segment_len = (sp.len - l2 + 1) + l3; + + double_l2 = symm_poly_co_side(symm, &sp, l2) == SYMM_SIDE_KEEP; + double_l3 = symm_poly_co_side(symm, &sp, l3) == SYMM_SIDE_KEEP; + + /* Calculate number of new polygons/loops */ + if (segment_len == 0) { + } + else if (sp.already_symmetric) { + int new_loops; + + if (double_l2 && double_l3) + new_loops = segment_len * 2; + else if (!double_l2 && !double_l3) + new_loops = segment_len * 2 - 2; + else + new_loops = segment_len * 2 - 1; + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, new_loops); + BLI_array_grow_items(fe, new_loops); + + symm_mesh_output_poly_zero_splits(symm, &sp, + fv, fe, + segment_len, l2); + BM_face_kill(symm->bm, f); + } + else if (!double_l2 && !double_l3) { + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, segment_len); + BLI_array_grow_items(fe, segment_len); + + symm_mesh_output_poly_with_splits(symm, &sp, + fv, fe, + segment_len, + l2); + + BM_face_kill(symm->bm, f); + } + else { + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, segment_len); + BLI_array_grow_items(fe, segment_len); + + symm_mesh_output_poly_with_splits(symm, &sp, + fv, fe, + segment_len, + l2); + + BM_face_kill(symm->bm, f); + + /* Output bridge triangle */ + + BLI_array_empty(fv); + BLI_array_empty(fe); + BLI_array_grow_items(fv, 3); + BLI_array_grow_items(fe, 3); + + if (double_l2) { + fv[0] = symm_poly_dst(&sp, l2); + fv[1] = symm_poly_mirror_dst(symm, &sp, l2); + fv[2] = symm_poly_dst(&sp, l3); + } + else if (double_l3) { + fv[0] = symm_poly_dst(&sp, l3); + fv[1] = symm_poly_mirror_dst(symm, &sp, l3); + fv[2] = symm_poly_dst(&sp, l2); + } + + BLI_assert(fv[0] && fv[1] && fv[2]); + + symm_face_create_v(symm->bm, fv, fe, 3); + } + } + } + + BLI_array_free(pv); + BLI_array_free(fv); + BLI_array_free(fe); +} + +/* Remove unused edges and vertices from the side being copied to */ +static void symm_kill_unused(Symm *symm) +{ + BMOIter oiter; + BMEdge *e; + BMVert *v; + + /* Kill unused edges */ + BMO_ITER (e, &oiter, symm->bm, symm->op, "input", BM_EDGE) { + const int crosses = symm_edge_crosses_axis(symm, e); + const int symmetric = (crosses && + (!BLI_ghash_haskey(symm->edge_split_map, e))); + + if (((symm_co_side(symm, e->v1->co) == SYMM_SIDE_KILL) || + (symm_co_side(symm, e->v2->co) == SYMM_SIDE_KILL)) && + !symmetric) + { + /* The edge might be used by a face outside the input set */ + if (BM_edge_face_count(e) == 0) + BM_edge_kill(symm->bm, e); + } + } + + /* Kill unused vertices */ + BMO_ITER (v, &oiter, symm->bm, symm->op, "input", BM_VERT) { + if (symm_co_side(symm, v->co) == SYMM_SIDE_KILL) { + if (BM_vert_edge_count(v) == 0) + BM_vert_kill(symm->bm, v); + } + } +} + +void bmo_symmetrize_exec(BMesh *bm, BMOperator *op) +{ + Symm symm; + BMO_SymmDirection direction = BMO_slot_int_get(op, "direction"); + + symm.bm = bm; + symm.op = op; + symm.axis = (ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_X, + BMO_SYMMETRIZE_POSITIVE_X) ? 0 : + ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_Y, + BMO_SYMMETRIZE_POSITIVE_Y) ? 1 : + ELEM(direction, + BMO_SYMMETRIZE_NEGATIVE_Z, + BMO_SYMMETRIZE_POSITIVE_Z) ? 2 : 0); + symm.direction = direction; + + symm_verts_mirror(&symm); + symm_split_asymmetric_edges(&symm); + symm_mirror_edges(&symm); + symm_mirror_polygons(&symm); + symm_kill_unused(&symm); + + BLI_ghash_free(symm.vert_symm_map, NULL, NULL); + BLI_ghash_free(symm.edge_split_map, NULL, NULL); + + BMO_slot_buffer_from_enabled_flag(bm, op, "geomout", BM_ALL, + SYMM_OUTPUT_GEOM); +} diff --git a/source/blender/bmesh/operators/bmo_unsubdivide.c b/source/blender/bmesh/operators/bmo_unsubdivide.c new file mode 100644 index 00000000000..64b7151aee5 --- /dev/null +++ b/source/blender/bmesh/operators/bmo_unsubdivide.c @@ -0,0 +1,348 @@ +/* + * ***** 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): Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/bmesh/operators/bmo_unsubdivide.c + * \ingroup bmesh + */ + +#include "MEM_guardedalloc.h" + +#include "BLI_math.h" + +#include "bmesh.h" + +#include "intern/bmesh_operators_private.h" /* own include */ + + +static int bm_vert_dissolve_fan_test(BMVert *v) +{ + /* check if we should walk over these verts */ + BMIter iter; + BMEdge *e; + + unsigned int tot_edge = 0; + unsigned int tot_edge_boundary = 0; + unsigned int tot_edge_manifold = 0; + unsigned int tot_edge_wire = 0; + + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + if (BM_edge_is_boundary(e)) { + tot_edge_boundary++; + } + else if (BM_edge_is_manifold(e)) { + tot_edge_manifold++; + } + else if (BM_edge_is_wire(e)) { + tot_edge_wire++; + } + tot_edge++; + } + + if ((tot_edge == 4) && (tot_edge_boundary == 0) && (tot_edge_manifold == 4)) { + return TRUE; + } + else if ((tot_edge == 3) && (tot_edge_boundary == 0) && (tot_edge_manifold == 3)) { + return TRUE; + } + else if ((tot_edge == 3) && (tot_edge_boundary == 2) && (tot_edge_manifold == 1)) { + return TRUE; + } + else if ((tot_edge == 2) && (tot_edge_wire == 2)) { + return TRUE; + } + return FALSE; +} + +static int bm_vert_dissolve_fan(BMesh *bm, BMVert *v) +{ + /* collapse under 2 conditions. + * - vert connects to 4 manifold edges (and 4 faces). + * - vert connecrs to 1 manifold edge, 2 boundary edges (and 2 faces). + * + * This covers boundary verts of a quad grid and center verts. + * note that surrounding faces dont have to be quads. + */ + + BMIter iter; + BMEdge *e; + + unsigned int tot_loop = 0; + unsigned int tot_edge = 0; + unsigned int tot_edge_boundary = 0; + unsigned int tot_edge_manifold = 0; + unsigned int tot_edge_wire = 0; + + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + if (BM_edge_is_boundary(e)) { + tot_edge_boundary++; + } + else if (BM_edge_is_manifold(e)) { + tot_edge_manifold++; + } + else if (BM_edge_is_wire(e)) { + tot_edge_wire++; + } + tot_edge++; + } + + if (tot_edge == 2) { + /* check for 2 wire verts only */ + if (tot_edge_wire == 2) { + return (BM_vert_collapse_edge(bm, v->e, v, TRUE) != NULL); + } + } + else if (tot_edge == 4) { + /* check for 4 faces surrounding */ + if (tot_edge_boundary == 0 && tot_edge_manifold == 4) { + /* good to go! */ + tot_loop = 4; + } + } + else if (tot_edge == 3) { + /* check for 2 faces surrounding at a boundary */ + if (tot_edge_boundary == 2 && tot_edge_manifold == 1) { + /* good to go! */ + tot_loop = 2; + } + else if (tot_edge_boundary == 0 && tot_edge_manifold == 3) { + /* good to go! */ + tot_loop = 3; + } + } + + if (tot_loop) { + BMLoop *f_loop[4]; + unsigned int i; + + /* ensure there are exactly tot_loop loops */ + BLI_assert(BM_iter_at_index(bm, BM_LOOPS_OF_VERT, v, tot_loop) == NULL); + BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)f_loop, tot_loop); + + for (i = 0; i < tot_loop; i++) { + BMLoop *l = f_loop[i]; + if (l->f->len > 3) { + BLI_assert(l->prev->v != l->next->v); + BM_face_split(bm, l->f, l->prev->v, l->next->v, NULL, NULL, TRUE); + } + } + + return BM_vert_dissolve(bm, v); + } + + return FALSE; +} + +enum { + VERT_INDEX_DO_COLLAPSE = -1, + VERT_INDEX_INIT = 0, + VERT_INDEX_IGNORE = 1 +}; + +// #define USE_WALKER /* gives uneven results, disable for now */ +// #define USE_ALL_VERTS + +/* - BMVert.flag & BM_ELEM_TAG: shows we touched this vert + * - BMVert.index == -1: shows we will remove this vert + */ +void bmo_unsubdivide_exec(BMesh *bm, BMOperator *op) +{ +#ifdef USE_WALKER +# define ELE_VERT_TAG 1 +#else + BMVert **vert_seek_a = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); + BMVert **vert_seek_b = MEM_mallocN(sizeof(BMVert *) * bm->totvert, __func__); + unsigned vert_seek_a_tot = 0; + unsigned vert_seek_b_tot = 0; +#endif + + BMVert *v; + BMIter iter; + + const unsigned int offset = 0; + const unsigned int nth = 2; + + const int iterations = maxi(1, BMO_slot_int_get(op, "iterations")); + int iter_step; + +#ifdef USE_ALL_VERTS + (void)op; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_enable(v, BM_ELEM_TAG); + } +#else /* USE_ALL_VERTS */ + BMOpSlot *vinput = BMO_slot_get(op, "verts"); + BMVert **vinput_arr = (BMVert **)vinput->data.p; + int v_index; + + /* tag verts */ + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + BM_elem_flag_disable(v, BM_ELEM_TAG); + } + for (v_index = 0; v_index < vinput->len; v_index++) { + v = vinput_arr[v_index]; + BM_elem_flag_enable(v, BM_ELEM_TAG); + } +#endif /* USE_ALL_VERTS */ + + + for (iter_step = 0; iter_step < iterations; iter_step++) { + int iter_done; + + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG) && bm_vert_dissolve_fan_test(v)) { +#ifdef USE_WALKER + BMO_elem_flag_enable(bm, v, ELE_VERT_TAG); +#endif + BM_elem_index_set(v, VERT_INDEX_INIT); /* set_dirty! */ + } + else { + BM_elem_index_set(v, VERT_INDEX_IGNORE); /* set_dirty! */ + } + } + /* done with selecting tagged verts */ + + + /* main loop, keep tagging until we can't tag any more islands */ + while (TRUE) { +#ifdef USE_WALKER + BMWalker walker; +#else + unsigned int depth = 1; + unsigned int i; +#endif + BMVert *v_first = NULL; + BMVert *v; + + /* we could avoid iterating from the start each time */ + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (v->e && (BM_elem_index_get(v) == VERT_INDEX_INIT)) { +#ifdef USE_WALKER + if (BMO_elem_flag_test(bm, v, ELE_VERT_TAG)) +#endif + { + /* check again incase the topology changed */ + if (bm_vert_dissolve_fan_test(v)) { + v_first = v; + } + break; + } + } + } + if (v_first == NULL) { + break; + } + +#ifdef USE_WALKER + /* Walk over selected elements starting at active */ + BMW_init(&walker, bm, BMW_CONNECTED_VERTEX, + ELE_VERT_TAG, BMW_MASK_NOP, BMW_MASK_NOP, + BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */ + BMW_NIL_LAY); + + BLI_assert(walker.order == BMW_BREADTH_FIRST); + for (v = BMW_begin(&walker, v_first); v != NULL; v = BMW_step(&walker)) { + /* Deselect elements that aren't at "nth" depth from active */ + if (BM_elem_index_get(v) == VERT_INDEX_INIT) { + if ((offset + BMW_current_depth(&walker)) % nth) { + /* tag for removal */ + BM_elem_index_set(v, VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + } + else { + /* works better to allow these verts to be checked again */ + //BM_elem_index_set(v, VERT_INDEX_IGNORE); /* set_dirty! */ + } + } + } + BMW_end(&walker); +#else + + BM_elem_index_set(v_first, (offset + depth) % nth ? VERT_INDEX_IGNORE : VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + + vert_seek_b_tot = 0; + vert_seek_b[vert_seek_b_tot++] = v_first; + + while (TRUE) { + BMEdge *e; + + if ((offset + depth) % nth) { + vert_seek_a_tot = 0; + for (i = 0; i < vert_seek_b_tot; i++) { + v = vert_seek_b[i]; + BLI_assert(BM_elem_index_get(v) == VERT_INDEX_IGNORE); + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + BMVert *v_other = BM_edge_other_vert(e, v); + if (BM_elem_index_get(v_other) == VERT_INDEX_INIT) { + BM_elem_index_set(v_other, VERT_INDEX_DO_COLLAPSE); /* set_dirty! */ + vert_seek_a[vert_seek_a_tot++] = v_other; + } + } + } + if (vert_seek_a_tot == 0) { + break; + } + } + else { + vert_seek_b_tot = 0; + for (i = 0; i < vert_seek_a_tot; i++) { + v = vert_seek_a[i]; + BLI_assert(BM_elem_index_get(v) == VERT_INDEX_DO_COLLAPSE); + BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { + BMVert *v_other = BM_edge_other_vert(e, v); + if (BM_elem_index_get(v_other) == VERT_INDEX_INIT) { + BM_elem_index_set(v_other, VERT_INDEX_IGNORE); /* set_dirty! */ + vert_seek_b[vert_seek_b_tot++] = v_other; + } + } + } + if (vert_seek_b_tot == 0) { + break; + } + } + + depth++; + } +#endif /* USE_WALKER */ + + } + + /* now we tagged all verts -1 for removal, lets loop over and rebuild faces */ + iter_done = FALSE; + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + if (BM_elem_index_get(v) == VERT_INDEX_DO_COLLAPSE) { + iter_done |= bm_vert_dissolve_fan(bm, v); + } + } + + if (iter_done == FALSE) { + break; + } + } + + bm->elem_index_dirty |= BM_VERT; + +#ifndef USE_WALKER + MEM_freeN(vert_seek_a); + MEM_freeN(vert_seek_b); +#endif + +} + diff --git a/source/blender/bmesh/operators/bmo_utils.c b/source/blender/bmesh/operators/bmo_utils.c index 72e55b2700c..3d792205d08 100644 --- a/source/blender/bmesh/operators/bmo_utils.c +++ b/source/blender/bmesh/operators/bmo_utils.c @@ -1033,10 +1033,9 @@ void bmo_similar_verts_exec(BMesh *bm, BMOperator *op) void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op) { - BMOIter fs_iter; /* selected faces iterator */ - BMFace *fs; /* current face */ - BMIter l_iter; /* iteration loop */ - // int n; + BMOIter fs_iter; /* selected faces iterator */ + BMFace *fs; /* current face */ + BMIter l_iter; /* iteration loop */ int dir = BMO_slot_int_get(op, "dir"); @@ -1091,7 +1090,6 @@ void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op) } } } - } /**************************************************************************** * @@ -1140,10 +1138,9 @@ void bmo_reverse_uvs_exec(BMesh *bm, BMOperator *op) void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op) { - BMOIter fs_iter; /* selected faces iterator */ - BMFace *fs; /* current face */ - BMIter l_iter; /* iteration loop */ - // int n; + BMOIter fs_iter; /* selected faces iterator */ + BMFace *fs; /* current face */ + BMIter l_iter; /* iteration loop */ int dir = BMO_slot_int_get(op, "dir"); diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp index 7683ec1e9cd..bd7ad16dabd 100644 --- a/source/blender/collada/DocumentExporter.cpp +++ b/source/blender/collada/DocumentExporter.cpp @@ -160,7 +160,7 @@ void DocumentExporter::exportCurrentScene(Scene *sce) clear_global_id_map(); COLLADABU::NativeString native_filename = - COLLADABU::NativeString(std::string(this->export_settings->filepath)); + COLLADABU::NativeString(std::string(this->export_settings->filepath), COLLADABU::NativeString::ENCODING_UTF8); COLLADASW::StreamWriter sw(native_filename); fprintf(stdout, "Collada export: %s\n", this->export_settings->filepath); diff --git a/source/blender/compositor/intern/COM_ExecutionSystem.cpp b/source/blender/compositor/intern/COM_ExecutionSystem.cpp index a13717c9d86..57ff5c5c838 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystem.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystem.cpp @@ -25,6 +25,7 @@ #include <sstream> #include "PIL_time.h" +#include "BLI_utildefines.h" #include "BKE_node.h" #include "COM_Converter.h" @@ -50,7 +51,7 @@ ExecutionSystem::ExecutionSystem(RenderData *rd, bNodeTree *editingtree, bool re this->m_context.setbNodeTree(editingtree); this->m_context.setFastCalculation(fastcalculation); bNode *gnode; - for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = (bNode *)gnode->next) { + for (gnode = (bNode *)editingtree->nodes.first; gnode; gnode = gnode->next) { if (gnode->type == NODE_GROUP && gnode->typeinfo->group_edit_get(gnode)) { this->m_context.setActivegNode(gnode); break; @@ -240,12 +241,32 @@ void ExecutionSystem::addReadWriteBufferOperations(NodeOperation *operation) } } +#ifndef NDEBUG +/* if this fails, there are still connection to/from this node, + * which have not been properly relinked to operations! + */ +static void debug_check_node_connections(Node *node) +{ + for (int i = 0; i < node->getNumberOfInputSockets(); ++i) { + BLI_assert(!node->getInputSocket(i)->isConnected()); + } + for (int i = 0; i < node->getNumberOfOutputSockets(); ++i) { + BLI_assert(!node->getOutputSocket(i)->isConnected()); + } +} +#else +/* stub */ +#define debug_check_node_connections(node) +#endif + void ExecutionSystem::convertToOperations() { unsigned int index; for (index = 0; index < this->m_nodes.size(); index++) { Node *node = (Node *)this->m_nodes[index]; node->convertToOperations(this, &this->m_context); + + debug_check_node_connections(node); } for (index = 0; index < this->m_connections.size(); index++) { diff --git a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp index 33a5cafebbe..506bd42ace3 100644 --- a/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp +++ b/source/blender/compositor/intern/COM_ExecutionSystemHelper.cpp @@ -51,7 +51,7 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star while (node != NULL) { Node *nnode = addNode(nodes, node, isActiveGroup, system.getContext().isFastCalculation()); nnode->setbNodeGroup(groupnode); - node = (bNode *)node->next; + node = node->next; } NodeRange node_range(nodes.begin() + nodes_start, nodes.end()); @@ -60,7 +60,7 @@ void ExecutionSystemHelper::addbNodeTree(ExecutionSystem &system, int nodes_star bNodeLink *nodelink = (bNodeLink *)tree->links.first; while (nodelink != NULL) { addNodeLink(node_range, links, nodelink); - nodelink = (bNodeLink *)nodelink->next; + nodelink = nodelink->next; } /* Expand group nodes */ diff --git a/source/blender/compositor/intern/COM_Node.cpp b/source/blender/compositor/intern/COM_Node.cpp index 5922b0e6b08..300d7ef1952 100644 --- a/source/blender/compositor/intern/COM_Node.cpp +++ b/source/blender/compositor/intern/COM_Node.cpp @@ -51,7 +51,7 @@ Node::Node(bNode *editorNode, bool create_sockets): NodeBase() if (input->type == SOCK_VECTOR) dt = COM_DT_VECTOR; this->addInputSocket(dt, (InputSocketResizeMode)input->resizemode, input); - input = (bNodeSocket *)input->next; + input = input->next; } bNodeSocket *output = (bNodeSocket *)editorNode->outputs.first; while (output != NULL) { @@ -60,14 +60,14 @@ Node::Node(bNode *editorNode, bool create_sockets): NodeBase() if (output->type == SOCK_VECTOR) dt = COM_DT_VECTOR; this->addOutputSocket(dt, output); - output = (bNodeSocket *)output->next; + output = output->next; } } } void Node::addSetValueOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); SetValueOperation *operation = new SetValueOperation(); bNodeSocketValueFloat *val = (bNodeSocketValueFloat *)bSock->default_value; operation->setValue(val->value); @@ -114,7 +114,7 @@ SocketConnection *Node::addLink(ExecutionSystem *graph, OutputSocket *outputSock void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); SetColorOperation *operation = new SetColorOperation(); bNodeSocketValueRGBA *val = (bNodeSocketValueRGBA *)bSock->default_value; operation->setChannel1(val->value[0]); @@ -127,7 +127,7 @@ void Node::addSetColorOperation(ExecutionSystem *graph, InputSocket *inputsocket void Node::addSetVectorOperation(ExecutionSystem *graph, InputSocket *inputsocket, int editorNodeInputSocketIndex) { - bNodeSocket *bSock = (bNodeSocket *)this->getEditorInputSocket(editorNodeInputSocketIndex); + bNodeSocket *bSock = this->getEditorInputSocket(editorNodeInputSocketIndex); bNodeSocketValueVector *val = (bNodeSocketValueVector *)bSock->default_value; SetVectorOperation *operation = new SetVectorOperation(); operation->setX(val->value[0]); diff --git a/source/blender/compositor/intern/COM_Node.h b/source/blender/compositor/intern/COM_Node.h index e8fd936e749..468a95ed434 100644 --- a/source/blender/compositor/intern/COM_Node.h +++ b/source/blender/compositor/intern/COM_Node.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_Node_h -#define _COM_Node_h +#ifndef __COM_NODE_H__ +#define __COM_NODE_H__ #include "COM_NodeBase.h" #include "COM_InputSocket.h" @@ -152,4 +152,4 @@ protected: private: }; -#endif +#endif /* __COM_NODE_H__ */ diff --git a/source/blender/compositor/intern/COM_NodeBase.h b/source/blender/compositor/intern/COM_NodeBase.h index 64d669b5e9a..e386b5e08a0 100644 --- a/source/blender/compositor/intern/COM_NodeBase.h +++ b/source/blender/compositor/intern/COM_NodeBase.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_NodeBase_h -#define _COM_NodeBase_h +#ifndef __COM_NODEBASE_H__ +#define __COM_NODEBASE_H__ #include "COM_InputSocket.h" #include "COM_OutputSocket.h" @@ -166,4 +166,4 @@ protected: #endif }; -#endif +#endif /* __COM_NODEBASE_H__ */ diff --git a/source/blender/compositor/intern/COM_OpenCLDevice.cpp b/source/blender/compositor/intern/COM_OpenCLDevice.cpp index d23ed245844..d5da079c9fd 100644 --- a/source/blender/compositor/intern/COM_OpenCLDevice.cpp +++ b/source/blender/compositor/intern/COM_OpenCLDevice.cpp @@ -74,7 +74,7 @@ cl_mem OpenCLDevice::COM_clAttachMemoryBufferToKernelParameter(cl_kernel kernel, { cl_int error; - MemoryBuffer *result = (MemoryBuffer *)reader->getInputMemoryBuffer(inputMemoryBuffers); + MemoryBuffer *result = reader->getInputMemoryBuffer(inputMemoryBuffers); const cl_image_format imageFormat = { CL_RGBA, diff --git a/source/blender/compositor/nodes/COM_ChannelMatteNode.h b/source/blender/compositor/nodes/COM_ChannelMatteNode.h index 4efb06c9f87..29c6000a245 100644 --- a/source/blender/compositor/nodes/COM_ChannelMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChannelMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ChannelMatteNODE_H +#endif /* COM_ChannelMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ChromaMatteNode.h b/source/blender/compositor/nodes/COM_ChromaMatteNode.h index ddd350aab40..bf5302ccdbb 100644 --- a/source/blender/compositor/nodes/COM_ChromaMatteNode.h +++ b/source/blender/compositor/nodes/COM_ChromaMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ChromaMatteNODE_H +#endif /* COM_ChromaMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorBalanceNode.h b/source/blender/compositor/nodes/COM_ColorBalanceNode.h index cdad02fc831..30d22ef2e63 100644 --- a/source/blender/compositor/nodes/COM_ColorBalanceNode.h +++ b/source/blender/compositor/nodes/COM_ColorBalanceNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorBalanceNODE_H +#endif /* COM_ColorBalanceNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorMatteNode.h b/source/blender/compositor/nodes/COM_ColorMatteNode.h index 92a4fa79408..3386476bc85 100644 --- a/source/blender/compositor/nodes/COM_ColorMatteNode.h +++ b/source/blender/compositor/nodes/COM_ColorMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorMatteNODE_H +#endif /* COM_ColorMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorRampNode.h b/source/blender/compositor/nodes/COM_ColorRampNode.h index 6c256c09e68..3f00e1c2190 100644 --- a/source/blender/compositor/nodes/COM_ColorRampNode.h +++ b/source/blender/compositor/nodes/COM_ColorRampNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorRampNODE_H +#endif /* COM_ColorRampNODE_H */ diff --git a/source/blender/compositor/nodes/COM_ColorSpillNode.h b/source/blender/compositor/nodes/COM_ColorSpillNode.h index 1d976fc65ae..01722fac826 100644 --- a/source/blender/compositor/nodes/COM_ColorSpillNode.h +++ b/source/blender/compositor/nodes/COM_ColorSpillNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_ColorSpillNODE_H +#endif /* COM_ColorSpillNODE_H */ diff --git a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h index 191b7361c3c..0b571889571 100644 --- a/source/blender/compositor/nodes/COM_DifferenceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DifferenceMatteNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_DifferenceMatteNODE_H +#endif /* COM_DifferenceMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp index 5cfc29ecce2..0fb7ea7d264 100644 --- a/source/blender/compositor/nodes/COM_DilateErodeNode.cpp +++ b/source/blender/compositor/nodes/COM_DilateErodeNode.cpp @@ -79,7 +79,7 @@ void DilateErodeNode::convertToOperations(ExecutionSystem *graph, CompositorCont CompositorQuality quality = context->getQuality(); /* initialize node data */ - NodeBlurData *data = (NodeBlurData *)&this->m_alpha_blur; + NodeBlurData *data = &this->m_alpha_blur; memset(data, 0, sizeof(*data)); data->filtertype = R_FILTER_GAUSS; diff --git a/source/blender/compositor/nodes/COM_DistanceMatteNode.h b/source/blender/compositor/nodes/COM_DistanceMatteNode.h index 4e6682424e8..46ceae7c4f4 100644 --- a/source/blender/compositor/nodes/COM_DistanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_DistanceMatteNode.h @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_DistanceMatteNODE_H +#endif /* COM_DistanceMatteNODE_H */ diff --git a/source/blender/compositor/nodes/COM_FilterNode.h b/source/blender/compositor/nodes/COM_FilterNode.h index d65166944d8..9be3bb02494 100644 --- a/source/blender/compositor/nodes/COM_FilterNode.h +++ b/source/blender/compositor/nodes/COM_FilterNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_FilterNode_h_ -#define _COM_FilterNode_h_ +#ifndef __COM_FILTERNODE_H__ +#define __COM_FILTERNODE_H__ #include "COM_Node.h" @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_FilterNode_h_ +#endif /* __COM_FILTERNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_KeyingNode.cpp b/source/blender/compositor/nodes/COM_KeyingNode.cpp index 6bc9afba32c..51ea2913e65 100644 --- a/source/blender/compositor/nodes/COM_KeyingNode.cpp +++ b/source/blender/compositor/nodes/COM_KeyingNode.cpp @@ -151,7 +151,7 @@ OutputSocket *KeyingNode::setupFeather(ExecutionSystem *graph, CompositorContext CompositorQuality quality = context->getQuality(); /* initialize node data */ - NodeBlurData *data = (NodeBlurData *)&this->m_alpha_blur; + NodeBlurData *data = &this->m_alpha_blur; memset(data, 0, sizeof(*data)); data->filtertype = R_FILTER_GAUSS; diff --git a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h index 37f3c31113f..a71e68cf636 100644 --- a/source/blender/compositor/nodes/COM_LuminanceMatteNode.h +++ b/source/blender/compositor/nodes/COM_LuminanceMatteNode.h @@ -19,8 +19,8 @@ * Dalai Felinto */ -#ifndef _COM_LuminanceMatteNode_h_ -#define _COM_LuminanceMatteNode_h_ +#ifndef __COM_LUMINANCEMATTENODE_H__ +#define __COM_LUMINANCEMATTENODE_H__ #include "COM_Node.h" @@ -34,4 +34,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_LuminanceMatteNode_h_ +#endif /* __COM_LUMINANCEMATTENODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MapValueNode.h b/source/blender/compositor/nodes/COM_MapValueNode.h index 22aa5459ec0..bd8e3d08e9c 100644 --- a/source/blender/compositor/nodes/COM_MapValueNode.h +++ b/source/blender/compositor/nodes/COM_MapValueNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MapValueNode_h_ -#define _COM_MapValueNode_h_ +#ifndef __COM_MAPVALUENODE_H__ +#define __COM_MAPVALUENODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_MapValueNode_h_ +#endif /* __COM_MAPVALUENODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MaskNode.h b/source/blender/compositor/nodes/COM_MaskNode.h index cdd5d3c362e..9ef3e5deb50 100644 --- a/source/blender/compositor/nodes/COM_MaskNode.h +++ b/source/blender/compositor/nodes/COM_MaskNode.h @@ -21,8 +21,8 @@ * Sergey Sharybin */ -#ifndef _COM_MaskNode_h_ -#define _COM_MaskNode_h_ +#ifndef __COM_MASKNODE_H__ +#define __COM_MASKNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -38,4 +38,4 @@ public: }; -#endif // _COM_MaskNode_h_ +#endif /* __COM_MASKNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_MovieClipNode.h b/source/blender/compositor/nodes/COM_MovieClipNode.h index 52ea11ea8e9..2fb38860a34 100644 --- a/source/blender/compositor/nodes/COM_MovieClipNode.h +++ b/source/blender/compositor/nodes/COM_MovieClipNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_MovieClipNode_h_ -#define _COM_MovieClipNode_h_ +#ifndef __COM_MOVIECLIPNODE_H__ +#define __COM_MOVIECLIPNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -36,4 +36,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_MovieClipNode_h_ +#endif /* __COM_MOVIECLIPNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_NormalNode.h b/source/blender/compositor/nodes/COM_NormalNode.h index 660d90040bd..64d4e3a3656 100644 --- a/source/blender/compositor/nodes/COM_NormalNode.h +++ b/source/blender/compositor/nodes/COM_NormalNode.h @@ -35,4 +35,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // COM_NormalNODE_H +#endif /* COM_NormalNODE_H */ diff --git a/source/blender/compositor/nodes/COM_TransformNode.h b/source/blender/compositor/nodes/COM_TransformNode.h index 57a7a0229ec..666f2da775e 100644 --- a/source/blender/compositor/nodes/COM_TransformNode.h +++ b/source/blender/compositor/nodes/COM_TransformNode.h @@ -20,8 +20,8 @@ * Monique Dewanchand */ -#ifndef _COM_TransformNode_h_ -#define _COM_TransformNode_h_ +#ifndef __COM_TRANSFORMNODE_H__ +#define __COM_TRANSFORMNODE_H__ #include "COM_Node.h" #include "DNA_node_types.h" @@ -36,4 +36,4 @@ public: void convertToOperations(ExecutionSystem *graph, CompositorContext *context); }; -#endif // _COM_TransformNode_h_ +#endif /* __COM_TRANSFORMNODE_H__ */ diff --git a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp index 6bb873e0dec..a515bfc7f47 100644 --- a/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp +++ b/source/blender/compositor/nodes/COM_ViewLevelsNode.cpp @@ -24,6 +24,7 @@ #include "COM_ExecutionSystem.h" #include "COM_CalculateMeanOperation.h" #include "COM_CalculateStandardDeviationOperation.h" +#include "COM_SetValueOperation.h" ViewLevelsNode::ViewLevelsNode(bNode *editorNode) : Node(editorNode) { @@ -64,5 +65,18 @@ void ViewLevelsNode::convertToOperations(ExecutionSystem *graph, CompositorConte graph->addOperation(operation); } } + else { + SetValueOperation *meanOutput = new SetValueOperation(); + SetValueOperation *stdDevOutput = new SetValueOperation(); + + meanOutput->setValue(0.0f); + stdDevOutput->setValue(0.0f); + + this->getOutputSocket(0)->relinkConnections(meanOutput->getOutputSocket()); + this->getOutputSocket(1)->relinkConnections(stdDevOutput->getOutputSocket()); + + graph->addOperation(meanOutput); + graph->addOperation(stdDevOutput); + } } diff --git a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp index 88289f12ebb..f6b23f6afd2 100644 --- a/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp +++ b/source/blender/compositor/operations/COM_ConvertDepthToRadiusOperation.cpp @@ -64,8 +64,8 @@ void ConvertDepthToRadiusOperation::initExecution() this->m_inverseFocalDistance = 1.0f / focalDistance; this->m_aspect = (this->getWidth() > this->getHeight()) ? (this->getHeight() / (float)this->getWidth()) : (this->getWidth() / (float)this->getHeight()); this->m_aperture = 0.5f * (this->m_cam_lens / (this->m_aspect * cam_sensor)) / this->m_fStop; - float minsz = min(getWidth(), getHeight()); - this->m_dof_sp = (float)minsz / ((cam_sensor / 2.0f) / this->m_cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); + const float minsz = min(getWidth(), getHeight()); + this->m_dof_sp = minsz / ((cam_sensor / 2.0f) / this->m_cam_lens); // <- == aspect * MIN2(img->x, img->y) / tan(0.5f * fov); if (this->m_blurPostOperation) { m_blurPostOperation->setSigma(min(m_aperture * 128.0f, this->m_maxRadius)); diff --git a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp index 2b2928c98db..262252f7d8c 100644 --- a/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_FastGaussianBlurOperation.cpp @@ -128,8 +128,8 @@ void FastGaussianBlurOperation::IIR_gauss(MemoryBuffer *src, float sigma, unsign // XXX The YVV macro defined below explicitly expects sources of at least 3x3 pixels, // so just skiping blur along faulty direction if src's def is below that limit! - if (src_width < 3) xy &= ~(int) 1; - if (src_height < 3) xy &= ~(int) 2; + if (src_width < 3) xy &= ~1; + if (src_height < 3) xy &= ~2; if (xy < 1) return; // see "Recursive Gabor Filtering" by Young/VanVliet diff --git a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp index ace04237b29..c4f8b3a0ddb 100644 --- a/source/blender/compositor/operations/COM_GlareGhostOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareGhostOperation.cpp @@ -79,9 +79,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No sc = 2.13; isc = -0.97; for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { - v = (float)(y + 0.5f) / (float)gbuf->getHeight(); + v = ((float)y + 0.5f) / (float)gbuf->getHeight(); for (x = 0; x < gbuf->getWidth(); x++) { - u = (float)(x + 0.5f) / (float)gbuf->getWidth(); + u = ((float)x + 0.5f) / (float)gbuf->getWidth(); s = (u - 0.5f) * sc + 0.5f, t = (v - 0.5f) * sc + 0.5f; tbuf1->readCubic(c, s * gbuf->getWidth(), t * gbuf->getHeight()); sm = smoothMask(s, t); @@ -100,9 +100,9 @@ void GlareGhostOperation::generateGlare(float *data, MemoryBuffer *inputTile, No memset(tbuf1->getBuffer(), 0, tbuf1->getWidth() * tbuf1->getHeight() * COM_NUMBER_OF_CHANNELS * sizeof(float)); for (n = 1; n < settings->iter && (!breaked); n++) { for (y = 0; y < gbuf->getHeight() && (!breaked); y++) { - v = (float)(y + 0.5f) / (float)gbuf->getHeight(); + v = ((float)y + 0.5f) / (float)gbuf->getHeight(); for (x = 0; x < gbuf->getWidth(); x++) { - u = (float)(x + 0.5f) / (float)gbuf->getWidth(); + u = ((float)x + 0.5f) / (float)gbuf->getWidth(); tc[0] = tc[1] = tc[2] = 0.f; for (p = 0; p < 4; p++) { np = (n << 2) + p; diff --git a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp index 9125783c222..60d37fb8145 100644 --- a/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp +++ b/source/blender/compositor/operations/COM_GlareStreaksOperation.cpp @@ -81,11 +81,9 @@ void GlareStreaksOperation::generateGlare(float *data, MemoryBuffer *inputTile, float *sourcebuffer = tsrc->getBuffer(); float factor = 1.f / (float)(6 - settings->iter); - for (int i = 0; i < size4; i++) { - data[i] += sourcebuffer[i] * factor; - } - for (int i = 0; i < size; i++) { - data[i * 4 + 3] = 1.0f; + for (int i = 0; i < size4; i += 4) { + madd_v3_v3fl(&data[i], &sourcebuffer[i], factor); + data[i + 3] = 1.0f; } tdst->clear(); diff --git a/source/blender/compositor/operations/COM_MaskOperation.cpp b/source/blender/compositor/operations/COM_MaskOperation.cpp index 36b3f2023ae..ba1059c4eb5 100644 --- a/source/blender/compositor/operations/COM_MaskOperation.cpp +++ b/source/blender/compositor/operations/COM_MaskOperation.cpp @@ -73,7 +73,7 @@ void MaskOperation::initExecution() for (masklay = (MaskLayer *)mask_temp->masklayers.first; masklay; - masklay = (MaskLayer *)masklay->next) + masklay = masklay->next) { masklay_shape = BKE_mask_layer_shape_varify_frame(masklay, this->m_frame_number); BKE_mask_layer_shape_from_mask(masklay, masklay_shape); diff --git a/source/blender/compositor/operations/COM_MathBaseOperation.h b/source/blender/compositor/operations/COM_MathBaseOperation.h index b492d06a697..febfa9662c6 100644 --- a/source/blender/compositor/operations/COM_MathBaseOperation.h +++ b/source/blender/compositor/operations/COM_MathBaseOperation.h @@ -45,7 +45,7 @@ protected: */ MathBaseOperation(); - void clampIfNeeded(float *color); + void clampIfNeeded(float color[4]); public: /** * the inner loop of this program diff --git a/source/blender/compositor/operations/COM_MixBaseOperation.h b/source/blender/compositor/operations/COM_MixBaseOperation.h index 4b466d193d6..88d1d00c2bf 100644 --- a/source/blender/compositor/operations/COM_MixBaseOperation.h +++ b/source/blender/compositor/operations/COM_MixBaseOperation.h @@ -40,7 +40,7 @@ protected: bool m_valueAlphaMultiply; bool m_useClamp; - inline void clampIfNeeded(float *color) + inline void clampIfNeeded(float color[4]) { if (m_useClamp) { CLAMP(color[0], 0.0f, 1.0f); diff --git a/source/blender/compositor/operations/COM_MovieDistortionOperation.h b/source/blender/compositor/operations/COM_MovieDistortionOperation.h index f3eeb2f48ba..93cc555fdbc 100644 --- a/source/blender/compositor/operations/COM_MovieDistortionOperation.h +++ b/source/blender/compositor/operations/COM_MovieDistortionOperation.h @@ -115,10 +115,10 @@ public: if (!this->m_bufferCalculated[offset]) { //float overscan = 0.0f; - float w = (float)this->m_width /* / (1 + overscan) */; - float h = (float)this->m_height /* / (1 + overscan) */; - float aspx = (float)w / this->m_calibration_width; - float aspy = (float)h / this->m_calibration_height; + const float w = (float)this->m_width /* / (1 + overscan) */; + const float h = (float)this->m_height /* / (1 + overscan) */; + const float aspx = w / (float)this->m_calibration_width; + const float aspy = h / (float)this->m_calibration_height; float in[2]; float out[2]; diff --git a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp index 193ab669f40..fd9cc1fddcb 100644 --- a/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp +++ b/source/blender/compositor/operations/COM_ScreenLensDistortionOperation.cpp @@ -98,7 +98,7 @@ void ScreenLensDistortionOperation::executePixel(float output[4], int x, int y, const float sd = 1.0f / (float)ds; for (z = 0; z < ds; ++z) { - const float tz = ((float)z + (jit ? BLI_frand() : 0.5f)) * sd; + const float tz = (z + (jit ? BLI_frand() : 0.5f)) * sd; t = 1.0f - (this->m_kr4 + tz * this->m_drg) * uv_dot; d = 1.0f / (1.0f + sqrtf(t)); const float nx = (u * d + 0.5f) * width - 0.5f; @@ -116,7 +116,7 @@ void ScreenLensDistortionOperation::executePixel(float output[4], int x, int y, const float sd = 1.0f / (float)ds; for (z = 0; z < ds; ++z) { - const float tz = ((float)z + (jit ? BLI_frand() : 0.5f)) * sd; + const float tz = (z + (jit ? BLI_frand() : 0.5f)) * sd; t = 1.0f - (this->m_kg4 + tz * this->m_dgb) * uv_dot; d = 1.0f / (1.0f + sqrtf(t)); const float nx = (u * d + 0.5f) * width - 0.5f; diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp index 7ccc91072bc..b8e15934c30 100644 --- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp +++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp @@ -192,7 +192,7 @@ void VariableSizeBokehBlurOperation::executeOpenCL(OpenCLDevice *device, cl_int maxBlur; cl_float threshold = this->m_threshold; - MemoryBuffer *sizeMemoryBuffer = (MemoryBuffer *)this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers); + MemoryBuffer *sizeMemoryBuffer = this->m_inputSizeProgram->getInputMemoryBuffer(inputMemoryBuffers); const float max_dim = max(m_width, m_height); cl_float scalar = this->m_do_size_scale ? (max_dim / 100.0f) : 1.0f; diff --git a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp index d9ca131721f..55a001530ee 100644 --- a/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp +++ b/source/blender/compositor/operations/COM_ViewerBaseOperation.cpp @@ -107,7 +107,7 @@ void ViewerBaseOperation:: updateImage(rcti *rect) { IMB_partial_display_buffer_update(this->m_ibuf, this->m_outputBuffer, NULL, getWidth(), 0, 0, this->m_viewSettings, this->m_displaySettings, - rect->xmin, rect->ymin, rect->xmax, rect->ymax); + rect->xmin, rect->ymin, rect->xmax, rect->ymax, FALSE); WM_main_add_notifier(NC_WINDOW | ND_DRAW, NULL); } diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index eb7bc68ff8f..9b88c307cb6 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -994,6 +994,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) { @@ -1032,6 +1053,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/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index bc07bf091de..54c7f7ea30f 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -82,4 +82,4 @@ void ANIM_OT_driver_button_remove(struct wmOperatorType *ot); void ANIM_OT_copy_driver_button(struct wmOperatorType *ot); void ANIM_OT_paste_driver_button(struct wmOperatorType *ot); -#endif // __ANIM_INTERN_H__ +#endif /* __ANIM_INTERN_H__ */ diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index f2711ec3bb5..ca036a8540e 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -172,7 +172,7 @@ static void ANIM_OT_change_frame(wmOperatorType *ot) ot->poll = change_frame_poll; /* flags */ - ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO; + ot->flag = OPTYPE_BLOCKING | OPTYPE_UNDO | OPTYPE_GRAB_POINTER; /* rna */ RNA_def_int(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME); diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c index 672e11ac613..38f9119104b 100644 --- a/source/blender/editors/animation/drivers.c +++ b/source/blender/editors/animation/drivers.c @@ -147,7 +147,7 @@ short ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int ar RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not add Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -310,7 +310,7 @@ short ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int a RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not find Driver to copy, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -357,14 +357,14 @@ short ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not paste Driver, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not paste driver, as RNA path is invalid for the given ID (ID = %s, path = %s)", id->name, rna_path); return 0; } /* if the buffer is empty, cannot paste... */ if (channeldriver_copypaste_buf == NULL) { - BKE_report(reports, RPT_ERROR, "Paste Driver: No Driver to paste"); + BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste"); return 0; } diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c index 30e4d8570cb..a591b51b0b3 100644 --- a/source/blender/editors/animation/fmodifier_ui.c +++ b/source/blender/editors/animation/fmodifier_ui.c @@ -111,6 +111,7 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s uiBlock *block; uiBut *but; PointerRNA ptr; + short bwidth = width - 30; /* max button width */ /* init the RNA-pointer */ RNA_pointer_create(id, &RNA_FModifierFunctionGenerator, fcm, &ptr); @@ -119,10 +120,10 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s /* col = uiLayoutColumn(layout, TRUE); */ /* UNUSED */ block = uiLayoutGetBlock(layout); uiBlockBeginAlign(block); - but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, width - 30, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); + but = uiDefButR(block, MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); - - uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, width - 30, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); + + uiDefButR(block, TOG, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL); uiBlockEndAlign(block); /* now add settings for individual modes */ @@ -132,50 +133,62 @@ static void draw_modifier__generator(uiLayout *layout, ID *id, FModifier *fcm, s float *cp = NULL; char xval[32]; unsigned int i; + int maxXWidth; /* draw polynomial order selector */ row = uiLayoutRow(layout, FALSE); block = uiLayoutGetBlock(row); - but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 10, 0, width - 30, 19, + but = uiDefButI(block, NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 10, 0, bwidth, 20, &data->poly_order, 1, 100, 0, 0, TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)")); uiButSetFunc(but, validate_fmodifier_cb, fcm, NULL); + /* calculate maximum width of label for "x^n" labels */ + if (data->arraysize > 2) { + BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize); + maxXWidth = UI_GetStringWidth(xval) + 10; /* XXX: UI_GetStringWidth is not accurate */ + } + else { + /* basic size (just "x") */ + maxXWidth = 15; + } + /* draw controls for each coefficient and a + sign at end of row */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); cp = data->coefficients; for (i = 0; (i < data->arraysize) && (cp); i++, cp++) { - /* To align with first line */ + /* To align with first line... */ if (i) - uiDefBut(block, LABEL, 1, " ", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, " ", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, ""); else - uiDefBut(block, LABEL, 1, "y =", 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, "y =", 0, 0, 40, 20, NULL, 0.0, 0.0, 0, 0, ""); + /* coefficient */ - uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, 150, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, + uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth/2, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, TIP_("Coefficient for polynomial")); /* 'x' param (and '+' if necessary) */ if (i == 0) - strcpy(xval, ""); + BLI_strncpy(xval, "", sizeof(xval)); else if (i == 1) - strcpy(xval, "x"); + BLI_strncpy(xval, "x", sizeof(xval)); else - sprintf(xval, "x^%u", i); - uiDefBut(block, LABEL, 1, xval, 0, 0, 50, 20, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); + BLI_snprintf(xval, sizeof(xval), "x^%u", i); + uiDefBut(block, LABEL, 1, xval, 0, 0, maxXWidth, 20, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x")); if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) { - uiDefBut(block, LABEL, 1, "+", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, ""); + uiDefBut(block, LABEL, 1, "+", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, ""); /* next coefficient on a new row */ row = uiLayoutRow(layout, TRUE); block = uiLayoutGetBlock(row); } else { - /* For alignement in UI! */ - uiDefBut(block, LABEL, 1, " ", 0, 0, 30, 20, NULL, 0.0, 0.0, 0, 0, ""); + /* For alignment in UI! */ + uiDefBut(block, LABEL, 1, " ", 0, 0, 20, 20, NULL, 0.0, 0.0, 0, 0, ""); } } break; diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 0454e88e320..f0c5f063e57 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -43,6 +43,8 @@ #include "BLI_dynstr.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_anim_types.h" #include "DNA_armature_types.h" #include "DNA_constraint_types.h" @@ -787,14 +789,15 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p /* F-Curve not editable? */ if (fcurve_is_keyframable(fcu) == 0) { BKE_reportf(reports, RPT_ERROR, - "F-Curve with path = '%s' [%d] cannot be keyframed. Ensure that it is not locked or sampled. Also, try removing F-Modifiers", + "F-Curve with path = '%s' [%d] cannot be keyframed, ensure that it is not locked or sampled, " + "and try removing F-Modifiers", fcu->rna_path, fcu->array_index); return 0; } /* if no property given yet, try to validate from F-Curve info */ if ((ptr.id.data == NULL) && (ptr.data == NULL)) { - BKE_report(reports, RPT_ERROR, "No RNA-pointer available to retrieve values for keyframing from"); + BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from"); return 0; } if (prop == NULL) { @@ -803,10 +806,10 @@ short insert_keyframe_direct(ReportList *reports, PointerRNA ptr, PropertyRNA *p /* try to get property we should be affecting */ if ((RNA_path_resolve(&ptr, fcu->rna_path, &tmp_ptr, &prop) == 0) || (prop == NULL)) { /* property not found... */ - const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : "<No ID-Pointer>"; + const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : TIP_("<No ID pointer>"); BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", + "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", idname, fcu->rna_path); return 0; } @@ -906,15 +909,15 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou /* validate pointer first - exit if failure */ if (id == NULL) { - BKE_reportf(reports, RPT_ERROR, "No ID-block to insert keyframe in (Path = %s)", rna_path); + BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path); return 0; } RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", - (id) ? id->name : "<Missing ID-Block>", rna_path); + "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + (id) ? id->name : TIP_("<Missing ID block>"), rna_path); return 0; } @@ -927,7 +930,7 @@ short insert_keyframe(ReportList *reports, ID *id, bAction *act, const char grou if (act == NULL) { BKE_reportf(reports, RPT_ERROR, - "Could not insert keyframe, as this type does not support animation data (ID = %s, Path = %s)", + "Could not insert keyframe, as this type does not support animation data (ID = %s, path = %s)", id->name, rna_path); return 0; } @@ -997,14 +1000,16 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou /* sanity checks */ if (ELEM(NULL, id, adt)) { - BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from"); + BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from"); return 0; } /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { - BKE_reportf(reports, RPT_ERROR, "Could not delete keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path); + BKE_reportf(reports, RPT_ERROR, + "Could not delete keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + id->name, rna_path); return 0; } @@ -1023,7 +1028,7 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP); } else { - BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name); + BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s\n", id->name); return 0; } } @@ -1096,14 +1101,16 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha /* sanity checks */ if (ELEM(NULL, id, adt)) { - BKE_report(reports, RPT_ERROR, "No ID-Block and/Or AnimData to delete keyframe from"); + BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from"); return 0; } /* validate pointer first - exit if failure */ RNA_id_pointer_create(id, &id_ptr); if ((RNA_path_resolve(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { - BKE_reportf(reports, RPT_ERROR, "Could not clear keyframe, as RNA Path is invalid for the given ID (ID = %s, Path = %s)", id->name, rna_path); + BKE_reportf(reports, RPT_ERROR, + "Could not clear keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)", + id->name, rna_path); return 0; } @@ -1119,7 +1126,7 @@ static short clear_keyframe(ReportList *reports, ID *id, bAction *act, const cha act = adt->action; } else { - BKE_reportf(reports, RPT_ERROR, "No Action to delete keyframes from for ID = %s\n", id->name); + BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s\n", id->name); return 0; } } @@ -1222,30 +1229,30 @@ static int insert_key_exec(bContext *C, wmOperator *op) /* report failures */ if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No active keying set"); return OPERATOR_CANCELLED; } /* try to insert keyframes for the channels specified by KeyingSet */ success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra); if (G.debug & G_DEBUG) - BKE_reportf(op->reports, RPT_INFO, "KeyingSet '%s' - Successfully added %d Keyframes\n", ks->name, success); + BKE_reportf(op->reports, RPT_INFO, "Keying set '%s' - successfully added %d keyframes\n", ks->name, success); /* report failure or do updates? */ if (success == MODIFYKEY_INVALID_CONTEXT) { - BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set"); return OPERATOR_CANCELLED; } else if (success) { /* if the appropriate properties have been set, make a note that we've inserted something */ if (RNA_boolean_get(op->ptr, "confirm_success")) - BKE_reportf(op->reports, RPT_INFO, "Successfully added %d Keyframes for KeyingSet '%s'", success, ks->name); + BKE_reportf(op->reports, RPT_INFO, "Successfully added %d keyframes for keying set '%s'", success, ks->name); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } else - BKE_report(op->reports, RPT_WARNING, "Keying Set failed to insert any keyframes"); + BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes"); /* send updates */ DAG_ids_flush_update(bmain, 0); @@ -1389,19 +1396,19 @@ static int delete_key_exec(bContext *C, wmOperator *op) /* report failure or do updates? */ if (success == MODIFYKEY_INVALID_CONTEXT) { - BKE_report(op->reports, RPT_ERROR, "No suitable context info for active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set"); return OPERATOR_CANCELLED; } else if (success) { /* if the appropriate properties have been set, make a note that we've inserted something */ if (RNA_boolean_get(op->ptr, "confirm_success")) - BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d Keyframes for KeyingSet '%s'", success, ks->name); + BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", success, ks->name); /* send notifiers that keyframes have been changed */ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL); } else - BKE_report(op->reports, RPT_WARNING, "Keying Set failed to remove any keyframes"); + BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes"); /* send updates */ DAG_ids_flush_update(bmain, 0); @@ -1626,7 +1633,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op) else { if (G.debug & G_DEBUG) printf("Button Insert-Key: no path to property\n"); - BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property. Try using a Keying Set instead"); + BKE_report(op->reports, RPT_WARNING, "Failed to resolve path to property, try using a keying set instead"); } } else if (G.debug & G_DEBUG) { diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c index 04fd7f677b0..5844bd6708f 100644 --- a/source/blender/editors/animation/keyingsets.c +++ b/source/blender/editors/animation/keyingsets.c @@ -161,11 +161,11 @@ static int remove_active_keyingset_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove"); return OPERATOR_CANCELLED; } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot remove built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set"); return OPERATOR_CANCELLED; } else @@ -209,7 +209,7 @@ static int add_empty_ks_path_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to add empty path to"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to add empty path to"); return OPERATOR_CANCELLED; } else @@ -258,12 +258,12 @@ static int remove_active_ks_path_exec(bContext *C, wmOperator *op) ks->active_path--; } else { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set Path to remove"); + BKE_report(op->reports, RPT_ERROR, "No active keying set path to remove"); return OPERATOR_CANCELLED; } } else { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove a path from"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove a path from"); return OPERATOR_CANCELLED; } @@ -322,7 +322,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op) scene->active_keyingset = BLI_countlist(&scene->keyingsets); } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set"); return OPERATOR_CANCELLED; } else @@ -404,11 +404,11 @@ static int remove_keyingset_button_exec(bContext *C, wmOperator *op) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { - BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from"); + BKE_report(op->reports, RPT_ERROR, "No active keying set to remove property from"); return OPERATOR_CANCELLED; } else if (scene->active_keyingset < 0) { - BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set"); return OPERATOR_CANCELLED; } else @@ -947,7 +947,7 @@ int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSe /* skip path if no ID pointer is specified */ if (ksp->id == NULL) { BKE_reportf(reports, RPT_WARNING, - "Skipping path in Keying Set, as it has no ID (KS = '%s', Path = '%s'[%d])", + "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s'[%d])", ks->name, ksp->rna_path, ksp->array_index); continue; } diff --git a/source/blender/editors/armature/editarmature.c b/source/blender/editors/armature/editarmature.c index 707594ff590..8a75d07a678 100644 --- a/source/blender/editors/armature/editarmature.c +++ b/source/blender/editors/armature/editarmature.c @@ -654,17 +654,19 @@ static int apply_armature_pose2bones_exec(bContext *C, wmOperator *op) if (ob->type != OB_ARMATURE) return OPERATOR_CANCELLED; if (BKE_object_obdata_is_libdata(ob)) { - BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature"); //error_libdata(); + BKE_report(op->reports, RPT_ERROR, "Cannot apply pose to lib-linked armature"); /* error_libdata(); */ return OPERATOR_CANCELLED; } /* helpful warnings... */ /* TODO: add warnings to be careful about actions, applying deforms first, etc. */ if (ob->adt && ob->adt->action) - BKE_report(op->reports, RPT_WARNING, "Actions on this armature will be destroyed by this new rest pose as the transforms stored are relative to the old rest pose"); + BKE_report(op->reports, RPT_WARNING, + "Actions on this armature will be destroyed by this new rest pose as the " + "transforms stored are relative to the old rest pose"); /* Get editbones of active armature to alter */ - ED_armature_to_edit(ob); + ED_armature_to_edit(ob); /* get pose of active object and move it out of posemode */ pose = ob->pose; @@ -1591,7 +1593,8 @@ void ARMATURE_OT_select_linked(wmOperatorType *ot) /* does bones and points */ /* note that BONE ROOT only gets drawn for root bones (or without IK) */ -static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2], ListBase *edbo, int findunsel, int *selmask) +static EditBone *get_nearest_editbonepoint(ViewContext *vc, const int mval[2], + ListBase *edbo, int findunsel, int *selmask) { EditBone *ebone; rcti rect; @@ -2096,7 +2099,7 @@ static int armature_calc_roll_exec(bContext *C, wmOperator *op) } sub_v3_v3v3(nor, ebone->tail, ebone->head); - vec_roll_to_mat3(nor, ebone->roll, mat); + vec_roll_to_mat3(nor, ebone->roll, mat); copy_v3_v3(vec, mat[2]); } else { /* Axis */ @@ -2556,7 +2559,8 @@ void updateDuplicateSubtarget(EditBone *dupBone, ListBase *editbones, Object *ob } -EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones, Object *src_ob, Object *dst_ob) +EditBone *duplicateEditBoneObjects(EditBone *curBone, const char *name, ListBase *editbones, + Object *src_ob, Object *dst_ob) { EditBone *eBone = MEM_mallocN(sizeof(EditBone), "addup_editbone"); @@ -2965,7 +2969,7 @@ static int armature_fill_bones_exec(bContext *C, wmOperator *op) } } else { - // FIXME.. figure out a method for multiple bones + /* FIXME.. figure out a method for multiple bones */ BKE_reportf(op->reports, RPT_ERROR, "Too many points selected: %d\n", count); BLI_freelistN(&points); return OPERATOR_CANCELLED; @@ -3036,7 +3040,8 @@ static void bones_merge(Object *obedit, EditBone *start, EditBone *end, EditBone newbone->parent = start->parent; /* TODO, copy more things to the new bone */ - newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE | BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE); + newbone->flag = start->flag & (BONE_HINGE | BONE_NO_DEFORM | BONE_NO_SCALE | + BONE_NO_CYCLICOFFSET | BONE_NO_LOCAL_LOCATION | BONE_DONE); /* step 2a: reparent any side chains which may be parented to any bone in the chain of bones to merge * - potentially several tips for side chains leading to some tree exist... @@ -3357,12 +3362,17 @@ static int armature_extrude_exec(bContext *C, wmOperator *op) if (EBONE_VISIBLE(arm, ebone)) { /* we extrude per definition the tip */ do_extrude = FALSE; - if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) + if (ebone->flag & (BONE_TIPSEL | BONE_SELECTED)) { do_extrude = TRUE; + } else if (ebone->flag & BONE_ROOTSEL) { /* but, a bone with parent deselected we do the root... */ - if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) ; - else do_extrude = 2; + if (ebone->parent && (ebone->parent->flag & BONE_TIPSEL)) { + /* pass */ + } + else { + do_extrude = 2; + } } if (do_extrude) { @@ -3813,7 +3823,7 @@ static int armature_parent_set_exec(bContext *C, wmOperator *op) /* there must be an active bone */ if (actbone == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } else if (arm->flag & ARM_MIRROR_EDIT) { @@ -4207,7 +4217,7 @@ static int armature_select_similar_exec(bContext *C, wmOperator *op) /* Check for active bone */ if (ebone_act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } @@ -4399,7 +4409,7 @@ static int armature_align_bones_exec(bContext *C, wmOperator *op) /* there must be an active bone */ if (actbone == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Bone"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } else if (arm->flag & ARM_MIRROR_EDIT) { @@ -4476,7 +4486,8 @@ void ARMATURE_OT_align(wmOperatorType *ot) /* ***************** Pose tools ********************* */ -// XXX bone_looper is only to be used when we want to access settings (i.e. editability/visibility/selected) that context doesn't offer +/* XXX bone_looper is only to be used when we want to access settings + * (i.e. editability/visibility/selected) that context doesn't offer */ static int bone_looper(Object *ob, Bone *bone, void *data, int (*bone_func)(Object *, Bone *, void *)) { @@ -4506,7 +4517,8 @@ static int bone_looper(Object *ob, Bone *bone, void *data, /* called from editview.c, for mode-less pose selection */ /* assumes scene obact and basact is still on old situation */ -int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, short extend, short deselect, short toggle) +int ED_do_pose_selectbuffer(Scene *scene, Base *base, unsigned int *buffer, short hits, + short extend, short deselect, short toggle) { Object *ob = base->object; Bone *nearBone; @@ -4752,7 +4764,9 @@ static void add_vgroups__mapFunc(void *userData, int index, const float co[3], copy_v3_v3(verts[index], co); } -static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, float (*root)[3], float (*tip)[3], int *selected, float scale) +static void envelope_bone_weighting(Object *ob, Mesh *mesh, float (*verts)[3], int numbones, Bone **bonelist, + bDeformGroup **dgrouplist, bDeformGroup **dgroupflip, + float (*root)[3], float (*tip)[3], int *selected, float scale) { /* Create vertex group weights from envelopes */ @@ -5138,7 +5152,7 @@ static int pose_clear_transform_generic_exec(bContext *C, wmOperator *op, /* sanity checks */ if (ELEM(NULL, clear_func, default_ksName)) { - BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name"); + BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or keying set name"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/armature/editarmature_retarget.c b/source/blender/editors/armature/editarmature_retarget.c index fad06f0d020..196d03020e7 100644 --- a/source/blender/editors/armature/editarmature_retarget.c +++ b/source/blender/editors/armature/editarmature_retarget.c @@ -1962,7 +1962,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, ReebArcIterator arc_iter; BArcIterator *iter = (BArcIterator *)&arc_iter; RigEdge *edge; - EmbedBucket *bucket = NULL; ReebNode *node_start, *node_end; ReebArc *earc = iarc->link_mesh; float angle_weight = 1.0; // GET FROM CONTEXT @@ -1996,8 +1995,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, /* equal number of joints and potential position, just fill them in */ if (nb_joints == earc->bcount) { - int i; - /* init with first values */ for (i = 0; i < nb_joints; i++) { best_positions[i] = i + 1; @@ -2011,7 +2008,6 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, MemoNode *result; #endif float **positions_cache = MEM_callocN(sizeof(float *) * (nb_positions + 2), "positions cache"); - int i; positions_cache[0] = node_start->p; positions_cache[nb_positions + 1] = node_end->p; @@ -2053,7 +2049,7 @@ static void retargetArctoArcAggresive(bContext *C, RigGraph *rigg, RigArc *iarc, { float *no = NULL; if (i < nb_joints) { - bucket = IT_peek(iter, best_positions[i]); + EmbedBucket *bucket = IT_peek(iter, best_positions[i]); vec1 = bucket->p; no = bucket->no; } diff --git a/source/blender/editors/armature/editarmature_sketch.c b/source/blender/editors/armature/editarmature_sketch.c index 5ba4a232250..68d8a8d721e 100644 --- a/source/blender/editors/armature/editarmature_sketch.c +++ b/source/blender/editors/armature/editarmature_sketch.c @@ -646,7 +646,7 @@ static SK_Point *sk_snapPointStroke(bContext *C, SK_Stroke *stk, int mval[2], in short pval[2]; int pdist; - if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_global(ar, stk->points[i].p, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -682,7 +682,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, { copy_v3_v3(vec, bone->head); mul_m4_v3(ob->obmat, vec); - if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -699,7 +699,7 @@ static SK_Point *sk_snapPointArmature(bContext *C, Object *ob, ListBase *ebones, copy_v3_v3(vec, bone->tail); mul_m4_v3(ob->obmat, vec); - if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_noclip(ar, vec, pval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { pdist = ABS(pval[0] - mval[0]) + ABS(pval[1] - mval[1]); @@ -939,7 +939,7 @@ static void sk_projectDrawPoint(bContext *C, float vec[3], SK_Stroke *stk, SK_Dr initgrabz(ar->regiondata, fp[0], fp[1], fp[2]); /* method taken from editview.c - mouse_cursor() */ - if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_short_global(ar, fp, cval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { VECSUB2D(mval_f, cval, dd->mval); ED_view3d_win_to_delta(ar, mval_f, dvec); sub_v3_v3v3(vec, fp, dvec); @@ -1793,8 +1793,8 @@ int sk_detectMergeGesture(bContext *C, SK_Gesture *gest, SK_Sketch *UNUSED(sketc short start_val[2], end_val[2]; short dist; - if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_short_global(ar, gest->stk->points[0].p, start_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_short_global(ar, sk_lastStrokePoint(gest->stk)->p, end_val, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { dist = MAX2(ABS(start_val[0] - end_val[0]), ABS(start_val[1] - end_val[1])); diff --git a/source/blender/editors/armature/meshlaplacian.c b/source/blender/editors/armature/meshlaplacian.c index 522622ec5c4..82fef00b1e6 100644 --- a/source/blender/editors/armature/meshlaplacian.c +++ b/source/blender/editors/armature/meshlaplacian.c @@ -1221,7 +1221,7 @@ static void harmonic_ray_callback(void *userdata, int index, const BVHTreeRay *r else normal_quad_v3(no, face[0], face[1], face[2], face[3]); - dist = len_v3v3(ray->origin, co)/len_v3(isec->vec); + dist = len_v3v3(ray->origin, co) / len_v3(isec->vec); if (dist < hit->dist) { hit->index = index; hit->dist = dist; @@ -1254,8 +1254,10 @@ static MDefBoundIsect *meshdeform_ray_tree_intersect(MeshDeformBind *mdb, float hit.index = -1; hit.dist = FLT_MAX; - if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, 0.0, &hit, harmonic_ray_callback, data) != -1) { - len= isect_mdef.labda; + if (BLI_bvhtree_ray_cast(mdb->bvhtree, isect_mdef.start, isect_mdef.vec, + 0.0, &hit, harmonic_ray_callback, data) != -1) + { + len = isect_mdef.labda; isect_mdef.face = mface = mface1 + hit.index; /* create MDefBoundIsect */ diff --git a/source/blender/editors/armature/poseSlide.c b/source/blender/editors/armature/poseSlide.c index cdcb3ab4683..31398948b82 100644 --- a/source/blender/editors/armature/poseSlide.c +++ b/source/blender/editors/armature/poseSlide.c @@ -631,6 +631,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, wmEvent *evt) switch (evt->type) { case LEFTMOUSE: /* confirm */ + case RETKEY: { /* return to normal cursor and header status */ ED_area_headerprint(pso->sa, NULL); diff --git a/source/blender/editors/armature/poselib.c b/source/blender/editors/armature/poselib.c index eea7424c59a..a05a98c58ca 100644 --- a/source/blender/editors/armature/poselib.c +++ b/source/blender/editors/armature/poselib.c @@ -298,7 +298,7 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op) /* validate action */ if (act == NULL) { - BKE_report(op->reports, RPT_WARNING, "No Action to validate"); + BKE_report(op->reports, RPT_WARNING, "No action to validate"); return OPERATOR_CANCELLED; } @@ -547,7 +547,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } @@ -562,7 +562,7 @@ static int poselib_remove_exec(bContext *C, wmOperator *op) /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, marker_index); if (marker == NULL) { - BKE_reportf(op->reports, RPT_ERROR, "Invalid Pose specified %d", marker_index); + BKE_reportf(op->reports, RPT_ERROR, "Invalid pose specified %d", marker_index); return OPERATOR_CANCELLED; } @@ -628,14 +628,14 @@ static int poselib_rename_invoke(bContext *C, wmOperator *op, wmEvent *evt) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, act->active_marker - 1); if (marker == NULL) { - BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + BKE_report(op->reports, RPT_ERROR, "Invalid index for pose"); return OPERATOR_CANCELLED; } else { @@ -657,14 +657,14 @@ static int poselib_rename_exec(bContext *C, wmOperator *op) /* check if valid poselib */ if (act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have PoseLib data"); + BKE_report(op->reports, RPT_ERROR, "Object does not have pose lib data"); return OPERATOR_CANCELLED; } /* get index (and pointer) of pose to remove */ marker = BLI_findlink(&act->markers, RNA_int_get(op->ptr, "pose")); if (marker == NULL) { - BKE_report(op->reports, RPT_ERROR, "Invalid index for Pose"); + BKE_report(op->reports, RPT_ERROR, "Invalid index for pose"); return OPERATOR_CANCELLED; } @@ -1424,12 +1424,12 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op) /* check if valid poselib */ if (ELEM3(NULL, pld->ob, pld->pose, pld->arm)) { - BKE_report(op->reports, RPT_ERROR, "PoseLib is only for Armatures in PoseMode"); + BKE_report(op->reports, RPT_ERROR, "Pose lib is only for armatures in pose mode"); pld->state = PL_PREVIEW_ERROR; return; } if (pld->act == NULL) { - BKE_report(op->reports, RPT_ERROR, "Object doesn't have a valid PoseLib"); + BKE_report(op->reports, RPT_ERROR, "Object does not have a valid pose lib"); pld->state = PL_PREVIEW_ERROR; return; } @@ -1438,10 +1438,10 @@ static void poselib_preview_init_data(bContext *C, wmOperator *op) /* just use first one then... */ pld->marker = pld->act->markers.first; if (pose_index > -2) - BKE_report(op->reports, RPT_WARNING, "PoseLib had no active pose"); + BKE_report(op->reports, RPT_WARNING, "Pose lib had no active pose"); } else { - BKE_report(op->reports, RPT_ERROR, "PoseLib has no poses to preview/apply"); + BKE_report(op->reports, RPT_ERROR, "Pose lib has no poses to preview/apply"); pld->state = PL_PREVIEW_ERROR; return; } diff --git a/source/blender/editors/armature/poseobject.c b/source/blender/editors/armature/poseobject.c index 189b2e977c2..99de90bc9fa 100644 --- a/source/blender/editors/armature/poseobject.c +++ b/source/blender/editors/armature/poseobject.c @@ -105,7 +105,7 @@ void ED_armature_enter_posemode(bContext *C, Base *base) Object *ob = base->object; if (ob->id.lib) { - BKE_report(reports, RPT_WARNING, "Can't pose libdata"); + BKE_report(reports, RPT_WARNING, "Cannot pose libdata"); return; } @@ -1236,7 +1236,7 @@ static int pose_copy_exec(bContext *C, wmOperator *op) /* sanity checking */ if (ELEM(NULL, ob, ob->pose)) { - BKE_report(op->reports, RPT_ERROR, "No Pose to Copy"); + BKE_report(op->reports, RPT_ERROR, "No pose to copy"); return OPERATOR_CANCELLED; } @@ -1399,7 +1399,7 @@ void POSE_OT_group_remove(wmOperatorType *ot) /* identifiers */ ot->name = "Remove Bone Group"; ot->idname = "POSE_OT_group_remove"; - ot->description = "Removes the active bone group"; + ot->description = "Remove the active bone group"; /* api callbacks */ ot->exec = pose_group_remove_exec; @@ -1511,7 +1511,7 @@ void POSE_OT_group_assign(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_int(ot->srna, "type", 0, 0, 10, "Bone Group Index", "", 0, INT_MAX); + RNA_def_int(ot->srna, "type", 0, 0, INT_MAX, "Bone Group Index", "", 0, 10); } diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c index afd6bc4c4b5..874b31dd1ca 100644 --- a/source/blender/editors/curve/editcurve.c +++ b/source/blender/editors/curve/editcurve.c @@ -1579,8 +1579,9 @@ static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag) BPoint *bp, *bpn, *newbp; int a, b, newu, newv, sel; - if (obedit->type == OB_SURF) ; - else return OPERATOR_CANCELLED; + if (obedit->type != OB_SURF) { + return OPERATOR_CANCELLED; + } cu->lastsel = NULL; @@ -1593,8 +1594,12 @@ static int deleteflagNurb(bContext *C, wmOperator *UNUSED(op), int flag) a = nu->pntsu * nu->pntsv; while (a) { a--; - if (bp->f1 & flag) ; - else break; + if (bp->f1 & flag) { + /* pass */ + } + else { + break; + } bp++; } if (a == 0) { @@ -1715,8 +1720,12 @@ static short extrudeflagNurb(EditNurb *editnurb, int flag) bp = nu->bp; a = nu->pntsu; while (a) { - if (bp->f1 & flag) ; - else break; + if (bp->f1 & flag) { + /* pass */ + } + else { + break; + } bp++; a--; } @@ -3217,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; @@ -3239,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; @@ -3258,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; @@ -3762,20 +3771,28 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu /* first nurbs: u = resolu-1 selected */ - if (is_u_selected(nu1, nu1->pntsu - 1) ) ; + if (is_u_selected(nu1, nu1->pntsu - 1) ) { + /* pass */ + } else { /* For 2D curves blender uses (orderv = 0). It doesn't make any sense mathematically. */ /* but after rotating (orderu = 0) will be confusing. */ if (nu1->orderv == 0) nu1->orderv = 1; rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { rotate_direction_nurb(nu1); - if (is_u_selected(nu1, nu1->pntsu - 1)) ; + if (is_u_selected(nu1, nu1->pntsu - 1)) { + /* pass */ + } else { /* rotate again, now its OK! */ if (nu1->pntsv != 1) rotate_direction_nurb(nu1); @@ -3786,17 +3803,25 @@ static void merge_2_nurb(wmOperator *op, ListBase *editnurb, Nurb *nu1, Nurb *nu } /* 2nd nurbs: u = 0 selected */ - if (is_u_selected(nu2, 0) ) ; + if (is_u_selected(nu2, 0) ) { + /* pass */ + } else { if (nu2->orderv == 0) nu2->orderv = 1; rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { rotate_direction_nurb(nu2); - if (is_u_selected(nu2, 0)) ; + if (is_u_selected(nu2, 0)) { + /* pass */ + } else { /* rotate again, now its OK! */ if (nu1->pntsu == 1) rotate_direction_nurb(nu1); @@ -3892,15 +3917,27 @@ static int merge_nurb(bContext *C, wmOperator *op) /* resolution match, to avoid uv rotations */ if (nus1->nu->pntsv == 1) { - if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) ; - else ok = 0; + if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsu == nus2->nu->pntsv) { + /* pass */ + } + else { + ok = 0; + } } else if (nus2->nu->pntsv == 1) { - if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) ; - else ok = 0; + if (nus2->nu->pntsu == nus1->nu->pntsu || nus2->nu->pntsu == nus1->nu->pntsv) { + /* pass */ + } + else { + ok = 0; + } + } + else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) { + /* pass */ + } + else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) { + /* pass */ } - else if (nus1->nu->pntsu == nus2->nu->pntsu || nus1->nu->pntsv == nus2->nu->pntsv) ; - else if (nus1->nu->pntsu == nus2->nu->pntsv || nus1->nu->pntsv == nus2->nu->pntsu) ; else { ok = 0; } @@ -3949,8 +3986,12 @@ static int make_segment_exec(bContext *C, wmOperator *op) if (isNurbsel_count(cu, nu) == 1) { /* only 1 selected, not first or last, a little complex, but intuitive */ if (nu->pntsv == 1) { - if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) ; - else break; + if ( (nu->bp->f1 & SELECT) || (nu->bp[nu->pntsu - 1].f1 & SELECT)) { + /* pass */ + } + else { + break; + } } } } @@ -4380,7 +4421,7 @@ void CURVE_OT_spin(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; RNA_def_float_vector_xyz(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); } /***************** add vertex operator **********************/ @@ -5611,7 +5652,7 @@ void CURVE_OT_select_nth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX); + RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100); } /********************** add duplicate operator *********************/ @@ -5684,8 +5725,12 @@ static int delete_exec(bContext *C, wmOperator *op) a = nu->pntsu; if (a) { while (a) { - if (BEZSELECTED_HIDDENHANDLES(cu, bezt) ) ; - else break; + if (BEZSELECTED_HIDDENHANDLES(cu, bezt)) { + /* pass */ + } + else { + break; + } a--; bezt++; } @@ -5704,8 +5749,12 @@ static int delete_exec(bContext *C, wmOperator *op) a = nu->pntsu * nu->pntsv; if (a) { while (a) { - if (bp->f1 & SELECT) ; - else break; + if (bp->f1 & SELECT) { + /* pass */ + } + else { + break; + } a--; bp++; } @@ -6437,12 +6486,7 @@ Nurb *add_nurbs_primitive(bContext *C, Object *obedit, float mat[4][4], int type vec[0] = vec[1] = 0.0; vec[2] = -grid; - if (newob && (U.flag & USER_ADD_VIEWALIGNED) == 0) { - /* pass */ - } - else { - mul_mat3_m4_v3(mat, vec); - } + mul_mat3_m4_v3(mat, vec); translateflagNurb(editnurb, 1, vec); extrudeflagNurb(cu->editnurb, 1); @@ -6603,7 +6647,7 @@ static int curvesurf_prim_add(bContext *C, wmOperator *op, int type, int isSurf) if (newob && enter_editmode) ED_undo_push(C, "Enter Editmode"); - ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, TRUE); nu = add_nurbs_primitive(C, obedit, mat, type, newob); editnurb = object_editcurve_get(obedit); diff --git a/source/blender/editors/curve/editfont.c b/source/blender/editors/curve/editfont.c index b11d640256c..b379ce6e5cf 100644 --- a/source/blender/editors/curve/editfont.c +++ b/source/blender/editors/curve/editfont.c @@ -441,8 +441,9 @@ static void txt_add_object(bContext *C, TextLine *firstline, int totline, float obedit = BKE_object_add(scene, OB_FONT); base = scene->basact; - - ED_object_base_init_transform(C, base, NULL, rot); /* seems to assume view align ? TODO - look into this, could be an operator option */ + /* seems to assume view align ? TODO - look into this, could be an operator option */ + ED_object_base_init_transform(C, base, NULL, rot); + BKE_object_where_is_calc(scene, obedit); obedit->loc[0] += offset[0]; diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c index 5ff4ccbd126..3b26c46a410 100644 --- a/source/blender/editors/gpencil/drawgpencil.c +++ b/source/blender/editors/gpencil/drawgpencil.c @@ -149,7 +149,8 @@ static void gp_draw_stroke_buffer(tGPspoint *points, int totpoints, short thickn /* ----- Existing Strokes Drawing (3D and Point) ------ */ /* draw a given stroke - just a single dot (only one point) */ -static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag, int offsx, int offsy, int winx, int winy) +static void gp_draw_stroke_point(bGPDspoint *points, short thickness, short dflag, short sflag, + int offsx, int offsy, int winx, int winy) { /* draw point */ if (sflag & GP_STROKE_3DSPACE) { @@ -508,7 +509,8 @@ static void gp_draw_strokes(bGPDframe *gpf, int offsx, int offsy, int winx, int glDepthMask(0); glEnable(GL_DEPTH_TEST); - /* first arg is normally rv3d->dist, but this isn't available here and seems to work quite well without */ + /* first arg is normally rv3d->dist, but this isn't + * available here and seems to work quite well without */ bglPolygonOffset(1.0f, 1.0f); #if 0 glEnable(GL_POLYGON_OFFSET_LINE); @@ -579,7 +581,8 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, /* draw 'onionskins' (frame left + right) */ if (gpl->flag & GP_LAYER_ONIONSKIN) { - /* drawing method - only immediately surrounding (gstep = 0), or within a frame range on either side (gstep > 0)*/ + /* drawing method - only immediately surrounding (gstep = 0), + * or within a frame range on either side (gstep > 0)*/ if (gpl->gstep) { bGPDframe *gf; float fac; @@ -640,7 +643,8 @@ static void gp_draw_data(bGPdata *gpd, int offsx, int offsy, int winx, int winy, if (ED_gpencil_session_active() && (gpl->flag & GP_LAYER_ACTIVE) && (gpf->flag & GP_FRAME_PAINT)) { - /* Buffer stroke needs to be drawn with a different linestyle to help differentiate them from normal strokes. */ + /* Buffer stroke needs to be drawn with a different linestyle + * to help differentiate them from normal strokes. */ gp_draw_stroke_buffer(gpd->sbuffer, gpd->sbuffer_size, lthick, dflag, gpd->sbuffer_sflag); } } @@ -724,8 +728,8 @@ void draw_gpencil_2dimage(const bContext *C) } /* draw grease-pencil sketches to specified 2d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, second time with onlyv2d=0 for screen-aligned strokes - */ + * Note: this gets called twice - first time with onlyv2d=1 to draw 'canvas' strokes, + * second time with onlyv2d=0 for screen-aligned strokes */ void draw_gpencil_view2d(const bContext *C, short onlyv2d) { ScrArea *sa = CTX_wm_area(C); @@ -750,9 +754,8 @@ void draw_gpencil_view2d(const bContext *C, short onlyv2d) } /* draw grease-pencil sketches to specified 3d-view assuming that matrices are already set correctly - * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, second time with only3d=0 for screen-aligned strokes - */ - + * Note: this gets called twice - first time with only3d=1 to draw 3d-strokes, + * second time with only3d=0 for screen-aligned strokes */ void draw_gpencil_view3d(Scene *scene, View3D *v3d, ARegion *ar, short only3d) { bGPdata *gpd; diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c index de7c2c41a6d..e5afbdba50b 100644 --- a/source/blender/editors/gpencil/gpencil_paint.c +++ b/source/blender/editors/gpencil/gpencil_paint.c @@ -279,7 +279,7 @@ static void gp_stroke_convertcoords(tGPsdata *p, const int mval[2], float out[3] /* method taken from editview.c - mouse_cursor() */ /* TODO, use ED_view3d_project_float_global */ - if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(p->ar, rvec, mval_prj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { VECSUB2D(mval_f, mval_prj, mval); ED_view3d_win_to_delta(p->ar, mval_f, dvec); sub_v3_v3v3(out, rvec, dvec); @@ -395,8 +395,10 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure) pts = &gps->points[gps->totpoints - 1]; - /* special case for poly lines: normally, depth is needed only when creating new stroke from buffer, - * but poly lines are converting to stroke instantly, so initialize depth buffer before converting coordinates + /* special case for poly lines: normally, + * depth is needed only when creating new stroke from buffer, + * but poly lines are converting to stroke instantly, + * so initialize depth buffer before converting coordinates */ if (gpencil_project_check(p)) { View3D *v3d = p->sa->spacedata.first; @@ -785,13 +787,49 @@ 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, + int *r_x, int *r_y) +{ + int xyval[2]; + + if (gps->flag & GP_STROKE_3DSPACE) { + if (ED_view3d_project_int_global(ar, &pt->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { + *r_x = xyval[0]; + *r_y = xyval[1]; + } + else { + *r_x = V2D_IS_CLIPPED; + *r_y = V2D_IS_CLIPPED; + } + } + else if (gps->flag & GP_STROKE_2DSPACE) { + UI_view2d_view_to_region(v2d, pt->x, pt->y, r_x, r_y); + } + else { + if (subrect == NULL) { /* normal 3D view */ + *r_x = (int)(pt->x / 100 * ar->winx); + *r_y = (int)(pt->y / 100 * ar->winy); + } + else { /* camera view, use subrect */ + *r_x = (int)((pt->x / 100) * BLI_rctf_size_x(subrect)) + subrect->xmin; + *r_y = (int)((pt->y / 100) * BLI_rctf_size_y(subrect)) + subrect->ymin; + } + } +} + + /* eraser tool - evaluation per stroke */ // TODO: this could really do with some optimization (KD-Tree/BVH?) static void gp_stroke_eraser_dostroke(tGPsdata *p, @@ -800,7 +838,6 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, { bGPDspoint *pt1, *pt2; int x0 = 0, y0 = 0, x1 = 0, y1 = 0; - int xyval[2]; int i; if (gps->totpoints == 0) { @@ -810,33 +847,11 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, BLI_freelinkN(&gpf->strokes, gps); } else if (gps->totpoints == 1) { - /* get coordinates */ - if (gps->flag & GP_STROKE_3DSPACE) { - if (ED_view3d_project_int_global(p->ar, &gps->points->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x0 = xyval[0]; - y0 = xyval[1]; - } - else { - x0 = V2D_IS_CLIPPED; - y0 = V2D_IS_CLIPPED; - } - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region(p->v2d, gps->points->x, gps->points->y, &x0, &y0); - } - else { - if (p->subrect == NULL) { /* normal 3D view */ - x0 = (int)(gps->points->x / 100 * p->ar->winx); - y0 = (int)(gps->points->y / 100 * p->ar->winy); - } - else { /* camera view, use subrect */ - x0 = (int)((gps->points->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y0 = (int)((gps->points->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - } - } + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, gps->points, &x0, &y0); /* do boundbox check first */ - if (BLI_rcti_isect_pt(rect, x0, y0)) { + + if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) { /* only check if point is inside */ if (((x0 - mval[0]) * (x0 - mval[0]) + (y0 - mval[1]) * (y0 - mval[1])) <= rad * rad) { /* free stroke */ @@ -853,48 +868,13 @@ static void gp_stroke_eraser_dostroke(tGPsdata *p, /* get points to work with */ pt1 = gps->points + i; pt2 = gps->points + i + 1; - - /* get coordinates */ - if (gps->flag & GP_STROKE_3DSPACE) { - if (ED_view3d_project_int_global(p->ar, &pt1->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x0 = xyval[0]; - y0 = xyval[1]; - } - else { - x0 = V2D_IS_CLIPPED; - y0 = V2D_IS_CLIPPED; - } - if (ED_view3d_project_int_global(p->ar, &pt2->x, xyval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { - x1 = xyval[0]; - y1 = xyval[1]; - } - else { - x1 = V2D_IS_CLIPPED; - y1 = V2D_IS_CLIPPED; - } - } - else if (gps->flag & GP_STROKE_2DSPACE) { - UI_view2d_view_to_region(p->v2d, pt1->x, pt1->y, &x0, &y0); - - UI_view2d_view_to_region(p->v2d, pt2->x, pt2->y, &x1, &y1); - } - else { - if (p->subrect == NULL) { /* normal 3D view */ - x0 = (int)(pt1->x / 100 * p->ar->winx); - y0 = (int)(pt1->y / 100 * p->ar->winy); - x1 = (int)(pt2->x / 100 * p->ar->winx); - y1 = (int)(pt2->y / 100 * p->ar->winy); - } - else { /* camera view, use subrect */ - x0 = (int)((pt1->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y0 = (int)((pt1->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - x1 = (int)((pt2->x / 100) * BLI_rctf_size_x(p->subrect)) + p->subrect->xmin; - y1 = (int)((pt2->y / 100) * BLI_rctf_size_y(p->subrect)) + p->subrect->ymin; - } - } - + + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt1, &x0, &y0); + gp_point_to_xy(p->ar, p->v2d, p->subrect, gps, pt2, &x1, &y1); + /* check that point segment of the boundbox of the eraser stroke */ - if (BLI_rcti_isect_pt(rect, x0, y0) || BLI_rcti_isect_pt(rect, x1, y1)) { + if (((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(rect, x0, y0)) || + ((!ELEM(V2D_IS_CLIPPED, x1, y1)) && BLI_rcti_isect_pt(rect, x1, y1))) { /* check if point segment of stroke had anything to do with * eraser region (either within stroke painted, or on its lines) * - this assumes that linewidth is irrelevant @@ -1423,13 +1403,17 @@ static void gpencil_draw_status_indicators(tGPsdata *p) /* print status info */ switch (p->paintmode) { case GP_PAINTMODE_ERASER: - ED_area_headerprint(p->sa, "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase | ESC/Enter to end"); + ED_area_headerprint(p->sa, + "Grease Pencil Erase Session: Hold and drag LMB or RMB to erase |" + " ESC/Enter to end"); break; case GP_PAINTMODE_DRAW_STRAIGHT: - ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | ESC/Enter to end"); + ED_area_headerprint(p->sa, "Grease Pencil Line Session: Hold and drag LMB to draw | " + "ESC/Enter to end"); break; case GP_PAINTMODE_DRAW: - ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | ESC/Enter to end"); + ED_area_headerprint(p->sa, "Grease Pencil Freehand Session: Hold and drag LMB to draw | " + "ESC/Enter to end"); break; default: /* unhandled future cases */ @@ -1705,7 +1689,8 @@ static tGPsdata *gpencil_stroke_begin(bContext *C, wmOperator *op) //printf("\t\tGP - start stroke\n"); /* we may need to set up paint env again if we're resuming */ - /* XXX: watch it with the paintmode! in future, it'd be nice to allow changing paint-mode when in sketching-sessions */ + /* XXX: watch it with the paintmode! in future, + * it'd be nice to allow changing paint-mode when in sketching-sessions */ /* XXX: with tablet events, we may event want to check for eraser here, for nicer tablet support */ if (gp_session_initdata(C, p)) @@ -1889,7 +1874,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) case OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH: /* event doesn't need to be handled */ - //printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); +#if 0 + printf("unhandled event -> %d (mmb? = %d | mmv? = %d)\n", + event->type, event->type == MIDDLEMOUSE, event->type==MOUSEMOVE); +#endif break; } @@ -1900,10 +1888,10 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, wmEvent *event) /* ------------------------------- */ static EnumPropertyItem prop_gpencil_drawmodes[] = { - {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", ""}, - {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", ""}, - {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", ""}, - {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", ""}, + {GP_PAINTMODE_DRAW, "DRAW", 0, "Draw Freehand", "Draw freehand stroke(s)"}, + {GP_PAINTMODE_DRAW_STRAIGHT, "DRAW_STRAIGHT", 0, "Draw Straight Lines", "Draw straight line segment(s)"}, + {GP_PAINTMODE_DRAW_POLY, "DRAW_POLY", 0, "Draw Poly Line", "Click to place endpoints of straight line segments (connected)"}, + {GP_PAINTMODE_ERASER, "ERASER", 0, "Eraser", "Erase Grease Pencil strokes"}, {0, NULL, 0, NULL, NULL} }; @@ -1925,7 +1913,7 @@ void GPENCIL_OT_draw(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; /* settings for drawing */ - RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements"); + ot->prop = RNA_def_enum(ot->srna, "mode", prop_gpencil_drawmodes, 0, "Mode", "Way to interpret mouse movements"); RNA_def_collection_runtime(ot->srna, "stroke", &RNA_OperatorStrokeElement, "Stroke", ""); } diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index fbddd26c959..fba42a33f88 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -233,29 +233,29 @@ typedef enum eAnimFilter_Flags { /* Dopesheet only */ /* 'Scene' channels */ -#define SEL_SCEC(sce) ((sce->flag & SCE_DS_SELECTED)) -#define EXPANDED_SCEC(sce) ((sce->flag & SCE_DS_COLLAPSED) == 0) +#define SEL_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_SELECTED))) +#define EXPANDED_SCEC(sce) (CHECK_TYPE_INLINE(sce, Scene), ((sce->flag & SCE_DS_COLLAPSED) == 0)) /* 'Sub-Scene' channels (flags stored in Data block) */ -#define FILTER_WOR_SCED(wo) ((wo->flag & WO_DS_EXPAND)) +#define FILTER_WOR_SCED(wo) (CHECK_TYPE_INLINE(wo, World), (wo->flag & WO_DS_EXPAND)) #define FILTER_LS_SCED(linestyle) ((linestyle->flag & LS_DS_EXPAND)) /* 'Object' channels */ -#define SEL_OBJC(base) ((base->flag & SELECT)) -#define EXPANDED_OBJC(ob) ((ob->nlaflag & OB_ADS_COLLAPSED) == 0) +#define SEL_OBJC(base) (CHECK_TYPE_INLINE(base, Base), ((base->flag & SELECT))) +#define EXPANDED_OBJC(ob) (CHECK_TYPE_INLINE(ob, Object), ((ob->nlaflag & OB_ADS_COLLAPSED) == 0)) /* 'Sub-object' channels (flags stored in Data block) */ -#define FILTER_SKE_OBJD(key) ((key->flag & KEY_DS_EXPAND)) -#define FILTER_MAT_OBJD(ma) ((ma->flag & MA_DS_EXPAND)) -#define FILTER_LAM_OBJD(la) ((la->flag & LA_DS_EXPAND)) -#define FILTER_CAM_OBJD(ca) ((ca->flag & CAM_DS_EXPAND)) -#define FILTER_CUR_OBJD(cu) ((cu->flag & CU_DS_EXPAND)) -#define FILTER_PART_OBJD(part) ((part->flag & PART_DS_EXPAND)) -#define FILTER_MBALL_OBJD(mb) ((mb->flag2 & MB_DS_EXPAND)) -#define FILTER_ARM_OBJD(arm) ((arm->flag & ARM_DS_EXPAND)) -#define FILTER_MESH_OBJD(me) ((me->flag & ME_DS_EXPAND)) -#define FILTER_LATTICE_OBJD(lt) ((lt->flag & LT_DS_EXPAND)) -#define FILTER_SPK_OBJD(spk) ((spk->flag & SPK_DS_EXPAND)) +#define FILTER_SKE_OBJD(key) (CHECK_TYPE_INLINE(key, Key), ((key->flag & KEY_DS_EXPAND))) +#define FILTER_MAT_OBJD(ma) (CHECK_TYPE_INLINE(ma, Material), ((ma->flag & MA_DS_EXPAND))) +#define FILTER_LAM_OBJD(la) (CHECK_TYPE_INLINE(la, Lamp), ((la->flag & LA_DS_EXPAND))) +#define FILTER_CAM_OBJD(ca) (CHECK_TYPE_INLINE(ca, Camera), ((ca->flag & CAM_DS_EXPAND))) +#define FILTER_CUR_OBJD(cu) (CHECK_TYPE_INLINE(cu, Curve), ((cu->flag & CU_DS_EXPAND))) +#define FILTER_PART_OBJD(part) (CHECK_TYPE_INLINE(part, ParticleSettings), ((part->flag & PART_DS_EXPAND))) +#define FILTER_MBALL_OBJD(mb) (CHECK_TYPE_INLINE(mb, MetaBall), ((mb->flag2 & MB_DS_EXPAND))) +#define FILTER_ARM_OBJD(arm) (CHECK_TYPE_INLINE(arm, bArmature), ((arm->flag & ARM_DS_EXPAND))) +#define FILTER_MESH_OBJD(me) (CHECK_TYPE_INLINE(me, Mesh), ((me->flag & ME_DS_EXPAND))) +#define FILTER_LATTICE_OBJD(lt) (CHECK_TYPE_INLINE(lt, Lattice), ((lt->flag & LT_DS_EXPAND))) +#define FILTER_SPK_OBJD(spk) (CHECK_TYPE_INLINE(spk, Speaker), ((spk->flag & SPK_DS_EXPAND))) /* Variable use expanders */ -#define FILTER_NTREE_DATA(ntree) ((ntree->flag & NTREE_DS_EXPAND)) -#define FILTER_TEX_DATA(tex) ((tex->flag & TEX_DS_EXPAND)) +#define FILTER_NTREE_DATA(ntree) (CHECK_TYPE_INLINE(ntree, bNodeTree), ((ntree->flag & NTREE_DS_EXPAND))) +#define FILTER_TEX_DATA(tex) (CHECK_TYPE_INLINE(tex, Tex), ((tex->flag & TEX_DS_EXPAND))) /* 'Sub-object/Action' channels (flags stored in Action) */ #define SEL_ACTC(actc) ((actc->flag & ACT_SELECTED)) diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index b9996c87194..efd10f3cb6b 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -93,9 +93,18 @@ typedef struct EditBone { #define BONESEL_NOSEL (1 << 31) /* Indicates a negative number */ /* useful macros */ -#define EBONE_VISIBLE(arm, ebone) (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A)) +#define EBONE_VISIBLE(arm, ebone) ( \ + CHECK_TYPE_INLINE(arm, bArmature), \ + CHECK_TYPE_INLINE(ebone, EditBone), \ + (((arm)->layer & (ebone)->layer) && !((ebone)->flag & BONE_HIDDEN_A)) \ + ) + #define EBONE_SELECTABLE(arm, ebone) (EBONE_VISIBLE(arm, ebone) && !(ebone->flag & BONE_UNSELECTABLE)) -#define EBONE_EDITABLE(ebone) (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) + +#define EBONE_EDITABLE(ebone) ( \ + CHECK_TYPE_INLINE(ebone, EditBone), \ + (((ebone)->flag & BONE_SELECTED) && !((ebone)->flag & BONE_EDITMODE_LOCKED)) \ + ) /* used in bone_select_hierachy() */ #define BONE_SELECT_PARENT 0 diff --git a/source/blender/editors/include/ED_keyframes_draw.h b/source/blender/editors/include/ED_keyframes_draw.h index 8a65699f404..ffee46e30c6 100644 --- a/source/blender/editors/include/ED_keyframes_draw.h +++ b/source/blender/editors/include/ED_keyframes_draw.h @@ -157,4 +157,3 @@ short compare_ab_cfraPtr(void *node, void *data); short actkeyblock_is_valid(ActKeyBlock *ab, struct DLRBT_Tree *keys); #endif /* __ED_KEYFRAMES_DRAW_H__ */ - diff --git a/source/blender/editors/include/ED_mball.h b/source/blender/editors/include/ED_mball.h index 5ce6db97305..1321765588d 100644 --- a/source/blender/editors/include/ED_mball.h +++ b/source/blender/editors/include/ED_mball.h @@ -38,7 +38,7 @@ struct wmKeyConfig; void ED_operatortypes_metaball(void); void ED_keymap_metaball(struct wmKeyConfig *keyconf); -struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], int type, int newname); +struct MetaElem *add_metaball_primitive(struct bContext *C, struct Object *obedit, float mat[4][4], float dia, int type, int newname); int mouse_mball(struct bContext *C, const int mval[2], int extend, int deselect, int toggle); 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..d6ac9eb750d 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); @@ -123,7 +134,8 @@ void ED_object_location_from_view(struct bContext *C, float loc[3]); void ED_object_rotation_from_view(struct bContext *C, float rot[3]); void ED_object_base_init_transform(struct bContext *C, struct Base *base, const float loc[3], const float rot[3]); float ED_object_new_primitive_matrix(struct bContext *C, struct Object *editob, - const float loc[3], const float rot[3], float primmat[][4]); + const float loc[3], const float rot[3], float primmat[][4], + int apply_diameter); void ED_object_add_generic_props(struct wmOperatorType *ot, int do_editmode); int ED_object_add_generic_get_opts(struct bContext *C, struct wmOperator *op, float loc[3], float rot[3], @@ -183,7 +195,7 @@ 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); #ifdef __cplusplus diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index b81e08ed7ef..fc24f68f2d1 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -37,6 +37,7 @@ struct BMEdge; struct BMFace; struct BMVert; struct BPoint; +struct Base; struct BezTriple; struct BezTriple; struct BoundBox; @@ -50,9 +51,12 @@ struct Nurb; struct Object; struct RegionView3D; struct Scene; +struct ScrArea; struct View3D; struct ViewContext; struct bContext; +struct bPoseChannel; +struct bScreen; struct bglMats; struct rcti; struct wmOperator; @@ -80,24 +84,8 @@ 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); - -void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]); -void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]); -void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]); -void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]); -void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]); - -void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]); void ED_view3d_to_m4(float mat[][4], const float ofs[3], const float quat[4], const float dist); void ED_view3d_from_m4(float mat[][4], float ofs[3], float quat[4], float *dist); @@ -119,7 +107,7 @@ void ED_view3d_depth_tag_update(struct RegionView3D *rv3d); /* return values for ED_view3d_project_...() */ typedef enum { - V3D_PROJ_RET_SUCCESS = 0, + V3D_PROJ_RET_OK = 0, V3D_PROJ_RET_CLIP_NEAR = 1, /* can't avoid this when in perspective mode, (can't avoid) */ V3D_PROJ_RET_CLIP_BB = 2, /* bounding box clip - RV3D_CLIPPING */ V3D_PROJ_RET_CLIP_WIN = 3, /* outside window bounds */ @@ -133,50 +121,96 @@ 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) + + +/* view3d_iterators.c */ + +/* 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); +/* *** end iterators *** */ + + +/* view3d_project.c */ +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]); + +eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base); /* *** 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]); +int initgrabz(struct RegionView3D *rv3d, float x, float y, float z); +void ED_view3d_win_to_ray(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]); +void ED_view3d_global_to_vector(struct RegionView3D *rv3d, const float coord[3], float vec[3]); +void ED_view3d_win_to_3d(struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]); +void ED_view3d_win_to_delta(struct ARegion *ar, const float mval[2], float out[3]); +void ED_view3d_win_to_vector(struct ARegion *ar, const float mval[2], float out[3]); +void ED_view3d_win_to_segment_clip(struct ARegion *ar, struct View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]); +void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]); +void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z); + +/* end */ -/* Base's get their own function since its a common operation */ -eV3DProjStatus ED_view3d_project_base(struct ARegion *ar, struct Base *base); -void ED_view3d_unproject(struct bglMats *mats, float out[3], const float x, const float y, const float z); int ED_view3d_clip_range_get(struct View3D *v3d, struct RegionView3D *rv3d, float *clipsta, float *clipend); int ED_view3d_viewplane_get(struct View3D *v3d, struct RegionView3D *rv3d, int winxi, int winyi, struct rctf *viewplane, float *clipsta, float *clipend); -void ED_view3d_ob_project_mat_get(struct RegionView3D *v3d, struct Object *ob, float pmat[4][4]); 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 +225,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 +250,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/include/UI_icons.h b/source/blender/editors/include/UI_icons.h index ef7b8ed3a41..8f50edd1240 100644 --- a/source/blender/editors/include/UI_icons.h +++ b/source/blender/editors/include/UI_icons.h @@ -450,8 +450,8 @@ DEF_ICON(FORCE_CURVE) DEF_ICON(FORCE_BOID) DEF_ICON(FORCE_TURBULENCE) DEF_ICON(FORCE_DRAG) +DEF_ICON(FORCE_SMOKEFLOW) #ifndef DEF_ICON_BLANK_SKIP - DEF_ICON(BLANK672) DEF_ICON(BLANK673) DEF_ICON(BLANK674) DEF_ICON(BLANK675) diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 2c00e39766c..fcde4186778 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -1152,9 +1152,15 @@ static void ui_is_but_sel(uiBut *but, double *value) } } - if (is_push == 2) ; - else if (is_push == 1) but->flag |= UI_SELECT; - else but->flag &= ~UI_SELECT; + if (is_push == 2) { + /* pass */ + } + else if (is_push == 1) { + but->flag |= UI_SELECT; + } + else { + but->flag &= ~UI_SELECT; + } } static uiBut *ui_find_inlink(uiBlock *block, void *poin) @@ -1522,7 +1528,9 @@ void ui_set_but_val(uiBut *but, double value) * so leave this unset */ value = UI_BUT_VALUE_UNSET; } - else if (but->pointype == 0) ; + else if (but->pointype == 0) { + /* pass */ + } else if (but->type == HSVSLI) { float *fp, hsv[3]; @@ -1715,8 +1723,9 @@ void ui_get_but_string(uiBut *but, char *str, size_t maxlen) BLI_strncpy(str, but->poin, maxlen); return; } - else if (ui_but_anim_expression_get(but, str, maxlen)) - ; /* driver expression */ + else if (ui_but_anim_expression_get(but, str, maxlen)) { + /* driver expression */ + } else { /* number editing */ double value; @@ -2474,7 +2483,9 @@ static void ui_block_do_align_but(uiBut *first, short nr) if (rows > 0) { uiBut *bt = but; while (bt && bt->alignnr == nr) { - if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) break; + if (bt->next && bt->next->alignnr == nr && buts_are_horiz(bt, bt->next) == 0) { + break; + } bt = bt->next; } if (bt == NULL || bt->alignnr != nr) flag = UI_BUT_ALIGN_TOP | UI_BUT_ALIGN_RIGHT; @@ -2708,9 +2719,8 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, } /* keep track of UI_interface.h */ - if (ELEM7(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM)) ; - else if (ELEM(but->type, SCROLL, SEPR /* , FTPREVIEW */ )) ; - else if (but->type >= SEARCH_MENU) ; + if (ELEM9(but->type, BLOCK, BUT, LABEL, PULLDOWN, ROUNDBOX, LISTBOX, BUTM, SCROLL, SEPR /* , FTPREVIEW */)) {} + else if (but->type >= SEARCH_MENU) {} else but->flag |= UI_BUT_UNDO; BLI_addtail(&block->buttons, but); @@ -2744,7 +2754,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, const char *str, static uiBut *ui_def_but_rna(uiBlock *block, int type, int retval, const char *str, - int x, int y, short width, short height, + int x, int y, short width, short height, PointerRNA *ptr, PropertyRNA *prop, int index, float min, float max, float a1, float a2, const char *tip) { @@ -3863,12 +3873,41 @@ void uiButGetStrInfo(bContext *C, uiBut *but, int nbr, ...) } } else if (ELEM3(type, BUT_GET_RNAENUM_IDENTIFIER, BUT_GET_RNAENUM_LABEL, BUT_GET_RNAENUM_TIP)) { + PointerRNA *ptr = NULL; + PropertyRNA *prop = NULL; + int value = 0; + + /* get the enum property... */ if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) { + /* enum property */ + ptr = &but->rnapoin; + prop = but->rnaprop; + value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); + } + else if (but->optype) { + PointerRNA *opptr = uiButGetOperatorPtrRNA(but); + wmOperatorType *ot = but->optype; + + /* if the default property of the operator is enum and it is set, + * fetch the tooltip of the selected value so that "Snap" and "Mirror" + * operator menus in the Anim Editors will show tooltips for the different + * operations instead of the meaningless generic operator tooltip + */ + if (ot->prop && RNA_property_type(ot->prop) == PROP_ENUM) { + if (RNA_struct_contains_property(opptr, ot->prop)) { + ptr = opptr; + prop = ot->prop; + value = RNA_property_enum_get(opptr, ot->prop); + } + } + } + + /* get strings from matching enum item */ + if (ptr && prop) { if (!item) { int i; - int value = (but->type == ROW) ? (int)but->hardmax : (int)ui_get_but_val(but); - RNA_property_enum_items_gettexted(C, &but->rnapoin, but->rnaprop, &items, &totitems, &free_items); - + + RNA_property_enum_items_gettexted(C, ptr, prop, &items, &totitems, &free_items); for (i = 0, item = items; i < totitems; i++, item++) { if (item->identifier[0] && item->value == value) break; diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 60e4c2aa90f..c4440cf07ed 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -704,7 +704,9 @@ static int ui_but_mouse_inside_icon(uiBut *but, ARegion *ar, wmEvent *event) BLI_rcti_rctf_copy(&rect, &but->rect); - if (but->imb) ; /* use button size itself */ + if (but->imb) { + /* use button size itself */ + } else if (but->flag & UI_ICON_LEFT) { rect.xmax = rect.xmin + (BLI_rcti_size_y(&rect)); } @@ -1184,7 +1186,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, /* numeric value */ if (ELEM4(but->type, NUM, NUMABS, NUMSLI, HSVSLI)) { - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { ui_get_but_string(but, buf, sizeof(buf)); WM_clipboard_text_set(buf, 0); @@ -1205,7 +1209,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else if (but->type == COLOR) { float rgb[3]; - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { ui_get_but_vectorf(but, rgb); @@ -1234,7 +1240,9 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data, else if (ELEM3(but->type, TEX, IDPOIN, SEARCH_MENU)) { uiHandleButtonData *active_data = but->active; - if (but->poin == NULL && but->rnapoin.data == NULL) ; + if (but->poin == NULL && but->rnapoin.data == NULL) { + /* pass */ + } else if (mode == 'c') { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); BLI_strncpy(buf, active_data->str, UI_MAX_DRAW_STR); @@ -2297,7 +2305,9 @@ static int ui_do_but_TEX(bContext *C, uiBlock *block, uiBut *but, uiHandleButton { if (data->state == BUTTON_STATE_HIGHLIGHT) { if (ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN) && event->val == KM_PRESS) { - if (but->dt == UI_EMBOSSN && !event->ctrl) ; + if (but->dt == UI_EMBOSSN && !event->ctrl) { + /* pass */ + } else { button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING); return WM_UI_HANDLER_BREAK; @@ -6611,7 +6621,9 @@ static int ui_handle_menu_event(bContext *C, wmEvent *event, uiPopupBlockHandle } } - if (menu->menuretval) ; + if (menu->menuretval) { + /* pass */ + } else if (event->type == ESCKEY && event->val == KM_PRESS) { /* esc cancels this and all preceding menus */ menu->menuretval = UI_RETURN_CANCEL; @@ -6763,9 +6775,13 @@ static int ui_handle_menus_recursive(bContext *C, wmEvent *event, uiPopupBlockHa /* now handle events for our own menu */ if (retval == WM_UI_HANDLER_CONTINUE || event->type == TIMER) { if (submenu && submenu->menuretval) { + int do_ret_out_parent = (submenu->menuretval & UI_RETURN_OUT_PARENT); retval = ui_handle_menu_return_submenu(C, event, menu); - /* we may wan't to quit the submenu and handle the even in this menu */ - if ((retval == WM_UI_HANDLER_BREAK) && (submenu->menuretval & UI_RETURN_OUT_PARENT)) { + submenu = NULL; /* hint not to use this, it may be freed by call above */ + (void)submenu; + /* we may wan't to quit the submenu and handle the even in this menu, + * if its important to use it, check 'data->menu' first */ + if ((retval == WM_UI_HANDLER_BREAK) && do_ret_out_parent) { retval = ui_handle_menu_event(C, event, menu, level); } } diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c index 7a369019ac4..8e30b31f3fe 100644 --- a/source/blender/editors/interface/interface_layout.c +++ b/source/blender/editors/interface/interface_layout.c @@ -835,8 +835,9 @@ void uiItemsFullEnumO(uiLayout *layout, const char *opname, const char *propname bt = block->buttons.last; bt->flag = UI_TEXT_LEFT; } - else /* XXX bug here, collums draw bottom item badly */ + else { /* XXX bug here, colums draw bottom item badly */ uiItemS(column); + } } } @@ -2515,8 +2516,12 @@ static void ui_item_align(uiLayout *litem, short nr) if (!bitem->but->alignnr) bitem->but->alignnr = nr; } - else if (item->type == ITEM_LAYOUT_ABSOLUTE) ; - else if (item->type == ITEM_LAYOUT_OVERLAP) ; + else if (item->type == ITEM_LAYOUT_ABSOLUTE) { + /* pass */ + } + else if (item->type == ITEM_LAYOUT_OVERLAP) { + /* pass */ + } else if (item->type == ITEM_LAYOUT_BOX) { box = (uiLayoutItemBx *)item; box->roundbox->alignnr = nr; diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 1ee06b1ff64..017ffdcfb14 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -216,7 +216,7 @@ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3 /* set sample from accumulated values */ static void eyedropper_color_set_accum(bContext *C, Eyedropper *eye) { - float col[4]; + float col[3]; mul_v3_v3fl(col, eye->accum_col, 1.0f / (float)eye->accum_tot); eyedropper_color_set(C, eye, col); } @@ -807,8 +807,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, } if (text == NULL) { - BKE_reportf(op->reports, RPT_WARNING, - "file: '%s' can't be opened", filepath); + BKE_reportf(op->reports, RPT_WARNING, "File: '%s' can't be opened", filepath); return OPERATOR_CANCELLED; } else { @@ -820,8 +819,7 @@ static int editsource_text_edit(bContext *C, wmOperator *op, st->text = text; } else { - BKE_reportf(op->reports, RPT_INFO, - "See '%s' in the text editor", text->id.name + 2); + BKE_reportf(op->reports, RPT_INFO, "See '%s' in the text editor", text->id.name + 2); } txt_move_toline(text, line - 1, FALSE); @@ -857,8 +855,8 @@ static int editsource_exec(bContext *C, wmOperator *op) !BLI_ghashIterator_isDone(&ghi); BLI_ghashIterator_step(&ghi)) { - uiBut *but = BLI_ghashIterator_getKey(&ghi); - if (but && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but)) { + uiBut *but_key = BLI_ghashIterator_getKey(&ghi); + if (but_key && ui_editsource_uibut_match(&ui_editsource_info->but_orig, but_key)) { but_store = BLI_ghashIterator_getValue(&ghi); break; } @@ -872,14 +870,12 @@ static int editsource_exec(bContext *C, wmOperator *op) but_store->py_dbg_ln); } else { - BKE_report(op->reports, RPT_ERROR, - "Active button isn't from a script, cant edit source."); + BKE_report(op->reports, RPT_ERROR, "Active button isn't from a script, cant edit source"); ret = OPERATOR_CANCELLED; } } else { - BKE_report(op->reports, RPT_ERROR, - "Active button match can't be found."); + BKE_report(op->reports, RPT_ERROR, "Active button match can't be found"); ret = OPERATOR_CANCELLED; } @@ -978,19 +974,19 @@ static int edittranslation_exec(bContext *C, wmOperator *op) if (!BLI_is_dir(root)) { BKE_report(op->reports, RPT_ERROR, "Please set your User Preferences' \"Translation Branches " - "Directory\" path to a valid directory."); + "Directory\" path to a valid directory"); return OPERATOR_CANCELLED; } if (!WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0)) { BKE_reportf(op->reports, RPT_ERROR, "Could not find operator \"%s\"! Please enable ui_translate addon " - "in the User Preferences.", EDTSRC_I18N_OP_NAME); + "in the User Preferences", EDTSRC_I18N_OP_NAME); return OPERATOR_CANCELLED; } /* Try to find a valid po file for current language... */ edittranslation_find_po_file(root, uilng, popath, FILE_MAX); /* printf("po path: %s\n", popath);*/ if (popath[0] == '\0') { - BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s.", uilng, root); + BKE_reportf(op->reports, RPT_ERROR, "No valid po found for language '%s' under %s", uilng, root); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c index 4dafb4b2d4b..14cb1cbe85a 100644 --- a/source/blender/editors/interface/interface_regions.c +++ b/source/blender/editors/interface/interface_regions.c @@ -2674,14 +2674,18 @@ void uiPupMenuReports(bContext *C, ReportList *reports) ds = BLI_dynstr_new(); for (report = reports->list.first; report; report = report->next) { - if (report->type < reports->printlevel) - ; /* pass */ - else if (report->type >= RPT_ERROR) + if (report->type < reports->printlevel) { + /* pass */ + } + else if (report->type >= RPT_ERROR) { BLI_dynstr_appendf(ds, "Error %%i%d%%t|%s", ICON_ERROR, report->message); - else if (report->type >= RPT_WARNING) + } + else if (report->type >= RPT_WARNING) { BLI_dynstr_appendf(ds, "Warning %%i%d%%t|%s", ICON_ERROR, report->message); - else if (report->type >= RPT_INFO) + } + else if (report->type >= RPT_INFO) { BLI_dynstr_appendf(ds, "Info %%i%d%%t|%s", ICON_INFO, report->message); + } } str = BLI_dynstr_get_cstring(ds); diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c index 3fc20309264..3203237496f 100644 --- a/source/blender/editors/interface/interface_widgets.c +++ b/source/blender/editors/interface/interface_widgets.c @@ -891,8 +891,8 @@ static void widget_draw_icon(uiBut *but, BIFIconID icon, float alpha, rcti *rect /* calculate blend color */ if (ELEM4(but->type, TOG, ROW, TOGN, LISTROW)) { - if (but->flag & UI_SELECT) ; - else if (but->flag & UI_ACTIVE) ; + if (but->flag & UI_SELECT) {} + else if (but->flag & UI_ACTIVE) {} else alpha = 0.5f; } @@ -3094,14 +3094,10 @@ static int widget_roundbox_set(uiBut *but, rcti *rect) if (but->active) { int direction = ui_button_open_menu_direction(but); - if (direction == UI_TOP) - roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_TOP_LEFT); - else if (direction == UI_DOWN) - roundbox &= ~(UI_CNR_BOTTOM_RIGHT|UI_CNR_BOTTOM_LEFT); - else if (direction == UI_LEFT) - roundbox &= ~(UI_CNR_TOP_LEFT|UI_CNR_BOTTOM_LEFT); - else if (direction == UI_RIGHT) - roundbox &= ~(UI_CNR_TOP_RIGHT|UI_CNR_BOTTOM_RIGHT); + if (direction == UI_TOP) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_TOP_LEFT); + else if (direction == UI_DOWN) roundbox &= ~(UI_CNR_BOTTOM_RIGHT | UI_CNR_BOTTOM_LEFT); + else if (direction == UI_LEFT) roundbox &= ~(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT); + else if (direction == UI_RIGHT) roundbox &= ~(UI_CNR_TOP_RIGHT | UI_CNR_BOTTOM_RIGHT); } return roundbox; diff --git a/source/blender/editors/interface/view2d_ops.c b/source/blender/editors/interface/view2d_ops.c index 5ac20829480..12e04d392b4 100644 --- a/source/blender/editors/interface/view2d_ops.c +++ b/source/blender/editors/interface/view2d_ops.c @@ -827,6 +827,11 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) dx = RNA_float_get(op->ptr, "deltax"); dy = RNA_float_get(op->ptr, "deltay"); + if (U.uiflag & USER_ZOOM_INVERT) { + dx *= -1; + dy *= -1; + } + /* continuous zoom shouldn't move that fast... */ if (U.viewzoom == USER_ZOOM_CONT) { // XXX store this setting as RNA prop? double time = PIL_check_seconds_timer(); @@ -849,12 +854,12 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dx) - (mval_faci * dx); - v2d->cur.xmin += ofs - dx; - v2d->cur.xmax += ofs + dx; + v2d->cur.xmin += ofs + dx; + v2d->cur.xmax += ofs - dx; } else { - v2d->cur.xmin -= dx; - v2d->cur.xmax += dx; + v2d->cur.xmin += dx; + v2d->cur.xmax -= dx; } } } @@ -868,12 +873,12 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op) float mval_faci = 1.0f - mval_fac; float ofs = (mval_fac * dy) - (mval_faci * dy); - v2d->cur.ymin += ofs - dy; - v2d->cur.ymax += ofs + dy; + v2d->cur.ymin += ofs + dy; + v2d->cur.ymax += ofs - dy; } else { - v2d->cur.ymin -= dy; - v2d->cur.ymax += dy; + v2d->cur.ymin += dy; + v2d->cur.ymax -= dy; } } } @@ -1044,14 +1049,9 @@ static int view_zoomdrag_modal(bContext *C, wmOperator *op, wmEvent *event) } /* set transform amount, and add current deltas to stored total delta (for redo) */ - if (U.uiflag & USER_ZOOM_INVERT) { - RNA_float_set(op->ptr, "deltax", -dx); - RNA_float_set(op->ptr, "deltay", -dy); - } - else { - RNA_float_set(op->ptr, "deltax", dx); - RNA_float_set(op->ptr, "deltay", dy); - } + RNA_float_set(op->ptr, "deltax", dx); + RNA_float_set(op->ptr, "deltay", dy); + vzd->dx += dx; vzd->dy += dy; diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c index 0ec99325752..ba93206e63a 100644 --- a/source/blender/editors/io/io_collada.c +++ b/source/blender/editors/io/io_collada.c @@ -143,7 +143,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } else { - BKE_report(op->reports, RPT_WARNING, "Export file not created."); + BKE_report(op->reports, RPT_WARNING, "Export file not created"); return OPERATOR_CANCELLED; } } @@ -307,7 +307,7 @@ static int wm_collada_import_exec(bContext *C, wmOperator *op) RNA_string_get(op->ptr, "filepath", filename); if (collada_import(C, filename)) return OPERATOR_FINISHED; - BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document. Please see console for error log."); + BKE_report(op->reports, RPT_ERROR, "Errors found during parsing COLLADA document (see console for details)"); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c index a254a6a9278..e43c8a2b53b 100644 --- a/source/blender/editors/mask/mask_add.c +++ b/source/blender/editors/mask/mask_add.c @@ -46,6 +46,7 @@ #include "WM_types.h" #include "ED_mask.h" /* own include */ +#include "ED_screen.h" #include "RNA_access.h" #include "RNA_define.h" @@ -97,7 +98,7 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no &tot_diff_point); if (diff_points) { - int i, tot_point; + int j, tot_point; unsigned int tot_feather_point; float *feather_points = NULL, *points; @@ -114,26 +115,26 @@ static int find_nearest_diff_point(const bContext *C, Mask *mask, const float no tot_point = tot_diff_point; } - for (i = 0; i < tot_point - 1; i++) { + for (j = 0; j < tot_point - 1; j++) { float cur_dist, a[2], b[2]; - a[0] = points[2 * i] * scalex; - a[1] = points[2 * i + 1] * scaley; + a[0] = points[2 * j] * scalex; + a[1] = points[2 * j + 1] * scaley; - b[0] = points[2 * i + 2] * scalex; - b[1] = points[2 * i + 3] * scaley; + b[0] = points[2 * j + 2] * scalex; + b[1] = points[2 * j + 3] * scaley; cur_dist = dist_to_line_segment_v2(co, a, b); if (cur_dist < dist) { if (tangent) - sub_v2_v2v2(tangent, &diff_points[2 * i + 2], &diff_points[2 * i]); + sub_v2_v2v2(tangent, &diff_points[2 * j + 2], &diff_points[2 * j]); point_masklay = masklay; point_spline = spline; point = use_deform ? &spline->points[(cur_point - spline->points_deform)] : cur_point; dist = cur_dist; - u = (float)i / tot_point; + u = (float)j / tot_point; } } @@ -562,6 +563,11 @@ static int add_vertex_exec(bContext *C, wmOperator *op) float co[2]; + if (mask == NULL) { + /* if there's no active mask, create one */ + mask = ED_mask_new(C, NULL); + } + masklay = BKE_mask_layer_active(mask); if (masklay && masklay->restrictflag & (MASK_RESTRICT_VIEW | MASK_RESTRICT_SELECT)) { @@ -647,7 +653,7 @@ void MASK_OT_add_vertex(wmOperatorType *ot) /* api callbacks */ ot->exec = add_vertex_exec; ot->invoke = add_vertex_invoke; - ot->poll = ED_maskedit_mask_poll; + ot->poll = ED_operator_mask; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c index a60b771d179..490389c6d0c 100644 --- a/source/blender/editors/mask/mask_draw.c +++ b/source/blender/editors/mask/mask_draw.c @@ -20,6 +20,7 @@ * * * Contributor(s): Blender Foundation, + * Campbell Barton, * Sergey Sharybin * * ***** END GPL LICENSE BLOCK ***** @@ -41,7 +42,9 @@ #include "DNA_mask_types.h" #include "DNA_screen_types.h" #include "DNA_object_types.h" /* SELECT */ +#include "DNA_space_types.h" +#include "ED_clip.h" #include "ED_mask.h" /* own include */ #include "ED_space_api.h" #include "BIF_gl.h" @@ -120,13 +123,22 @@ static void draw_spline_parents(MaskLayer *UNUSED(masklay), MaskSpline *spline) } #endif +static void mask_point_undistort_pos(SpaceClip *sc, float r_co[2], float co[2]) +{ + BKE_mask_coord_to_movieclip(sc->clip, &sc->user, r_co, co); + ED_clip_point_undistorted_pos(sc, r_co, r_co); + BKE_mask_coord_from_movieclip(sc->clip, &sc->user, r_co, r_co); +} + /* return non-zero if spline is selected */ -static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, +static void draw_spline_points(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char UNUSED(draw_flag), const char draw_type) { const int is_spline_sel = (spline->flag & SELECT) && (masklay->restrictflag & MASK_RESTRICT_SELECT) == 0; unsigned char rgb_spline[4]; MaskSplinePoint *points_array = BKE_mask_spline_point_array(spline); + SpaceClip *sc = CTX_wm_space_clip(C); + int undistort = FALSE; int i, hsize, tot_feather_point; float (*feather_points)[2], (*fp)[2]; @@ -134,6 +146,9 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, if (!spline->tot_point) return; + if (sc) + undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; + /* TODO, add this to sequence editor */ hsize = 4; /* UI_GetThemeValuef(TH_HANDLE_VERTEX_SIZE); */ @@ -151,8 +166,14 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, int j; for (j = 0; j < point->tot_uw + 1; j++) { + float feather_point[2]; int sel = FALSE; + copy_v2_v2(feather_point, *fp); + + if (undistort) + mask_point_undistort_pos(sc, feather_point, feather_point); + if (j == 0) { sel = MASKPOINT_ISSEL_ANY(point); } @@ -171,7 +192,7 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, } glBegin(GL_POINTS); - glVertex2fv(*fp); + glVertex2fv(feather_point); glEnd(); fp++; @@ -188,11 +209,17 @@ static void draw_spline_points(MaskLayer *masklay, MaskSpline *spline, BezTriple *bezt = &point_deform->bezt; float handle[2]; - float *vert = bezt->vec[1]; + float vert[2]; int has_handle = BKE_mask_point_has_handle(point); + copy_v2_v2(vert, bezt->vec[1]); BKE_mask_point_handle(point_deform, handle); + if (undistort) { + mask_point_undistort_pos(sc, vert, vert); + mask_point_undistort_pos(sc, handle, handle); + } + /* draw handle segment */ if (has_handle) { @@ -265,7 +292,7 @@ static void mask_color_active_tint(unsigned char r_rgb[4], const unsigned char r } } -static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot_point, +static void mask_draw_curve_type(const bContext *C, MaskSpline *spline, float (*orig_points)[2], int tot_point, const short is_feather, const short is_smooth, const short is_active, const unsigned char rgb_spline[4], const char draw_type) { @@ -273,6 +300,22 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot const unsigned char rgb_black[4] = {0x00, 0x00, 0x00, 0xff}; // const unsigned char rgb_white[4] = {0xff, 0xff, 0xff, 0xff}; unsigned char rgb_tmp[4]; + SpaceClip *sc = CTX_wm_space_clip(C); + float (*points)[2] = orig_points; + + if (sc) { + int undistort = sc->clip && sc->user.render_flag & MCLIP_PROXY_RENDER_UNDISTORT; + + if (undistort) { + int i; + + points = MEM_callocN(2 * tot_point * sizeof(float), "undistorthed mask curve"); + + for (i = 0; i < tot_point; i++) { + mask_point_undistort_pos(sc, points[i], orig_points[i]); + } + } + } glEnableClientState(GL_VERTEX_ARRAY); glVertexPointer(2, GL_FLOAT, 0, points); @@ -347,8 +390,6 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot glVertexPointer(2, GL_FLOAT, 0, points); glDrawArrays(draw_method, 0, tot_point); - glDrawArrays(draw_method, 0, tot_point); - if (is_smooth == FALSE && is_feather) { glDisable(GL_BLEND); } @@ -358,9 +399,11 @@ static void mask_draw_curve_type(MaskSpline *spline, float (*points)[2], int tot glDisableClientState(GL_VERTEX_ARRAY); + if (points != orig_points) + MEM_freeN(points); } -static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, +static void draw_spline_curve(const bContext *C, MaskLayer *masklay, MaskSpline *spline, const char draw_flag, const char draw_type, const short is_active, int width, int height) @@ -395,7 +438,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, /* draw feather */ mask_spline_feather_color_get(masklay, spline, is_spline_sel, rgb_tmp); - mask_draw_curve_type(spline, feather_points, tot_feather_point, + mask_draw_curve_type(C, spline, feather_points, tot_feather_point, TRUE, is_smooth, is_active, rgb_tmp, draw_type); @@ -414,7 +457,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, } /* same as above */ - mask_draw_curve_type(spline, feather_points, tot_feather_point, + mask_draw_curve_type(C, spline, feather_points, tot_feather_point, TRUE, is_smooth, is_active, rgb_tmp, draw_type); } @@ -423,7 +466,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, /* draw main curve */ mask_spline_color_get(masklay, spline, is_spline_sel, rgb_tmp); - mask_draw_curve_type(spline, diff_points, tot_diff_point, + mask_draw_curve_type(C, spline, diff_points, tot_diff_point, FALSE, is_smooth, is_active, rgb_tmp, draw_type); MEM_freeN(diff_points); @@ -436,7 +479,7 @@ static void draw_spline_curve(MaskLayer *masklay, MaskSpline *spline, (void)draw_type; } -static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type, +static void draw_masklays(const bContext *C, Mask *mask, const char draw_flag,const char draw_type, int width, int height) { MaskLayer *masklay; @@ -453,13 +496,13 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type for (spline = masklay->splines.first; spline; spline = spline->next) { /* draw curve itself first... */ - draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height); + draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height); // draw_spline_parents(masklay, spline); if (!(masklay->restrictflag & MASK_RESTRICT_SELECT)) { /* ...and then handles over the curve so they're nicely visible */ - draw_spline_points(masklay, spline, draw_flag, draw_type); + draw_spline_points(C, masklay, spline, draw_flag, draw_type); } /* show undeform for testing */ @@ -467,9 +510,9 @@ static void draw_masklays(Mask *mask, const char draw_flag, const char draw_type void *back = spline->points_deform; spline->points_deform = NULL; - draw_spline_curve(masklay, spline, draw_flag, draw_type, is_active, width, height); + draw_spline_curve(C, masklay, spline, draw_flag, draw_type, is_active, width, height); // draw_spline_parents(masklay, spline); - draw_spline_points(masklay, spline, draw_flag, draw_type); + draw_spline_points(C, masklay, spline, draw_flag, draw_type); spline->points_deform = back; } } @@ -489,7 +532,7 @@ void ED_mask_draw(const bContext *C, ED_mask_get_size(sa, &width, &height); - draw_masklays(mask, draw_flag, draw_type, width, height); + draw_masklays(C, mask, draw_flag, draw_type, width, height); } /* sets up the opengl context. @@ -500,7 +543,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, const float aspx, const float aspy, const short do_scale_applied, const short do_post_draw, float stabmat[4][4], /* optional - only used by clip */ - const bContext *C /* optional - only used when do_post_draw is set */ + const bContext *C /* optional - only used when do_post_draw is set or called from clip editor */ ) { struct View2D *v2d = &ar->v2d; @@ -559,7 +602,7 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar, } /* draw! */ - draw_masklays(mask, draw_flag, draw_type, width, height); + draw_masklays(C, mask, draw_flag, draw_type, width, height); if (do_post_draw) { ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW); diff --git a/source/blender/editors/mask/mask_intern.h b/source/blender/editors/mask/mask_intern.h index ffd4afca182..fcfcfb237e9 100644 --- a/source/blender/editors/mask/mask_intern.h +++ b/source/blender/editors/mask/mask_intern.h @@ -33,6 +33,7 @@ #define __MASK_INTERN_H__ struct bContext; +struct Mask; struct wmEvent; struct wmOperatorType; @@ -43,6 +44,8 @@ void MASK_OT_add_vertex(struct wmOperatorType *ot); void MASK_OT_add_feather_vertex(struct wmOperatorType *ot); /* mask_ops.c */ +struct Mask *ED_mask_new(struct bContext *C, const char *name); + void MASK_OT_new(struct wmOperatorType *ot); void MASK_OT_layer_new(struct wmOperatorType *ot); void MASK_OT_layer_remove(struct wmOperatorType *ot); diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c index 88fbb91edfb..35f85f3faee 100644 --- a/source/blender/editors/mask/mask_ops.c +++ b/source/blender/editors/mask/mask_ops.c @@ -258,13 +258,10 @@ int ED_mask_feather_find_nearest(const bContext *C, Mask *mask, float normal_co[ /******************** create new mask *********************/ -static int mask_new_exec(bContext *C, wmOperator *op) +Mask *ED_mask_new(bContext *C, const char *name) { ScrArea *sa = CTX_wm_area(C); Mask *mask; - char name[MAX_ID_NAME - 2]; - - RNA_string_get(op->ptr, "name", name); mask = BKE_mask_new(name); @@ -290,6 +287,17 @@ static int mask_new_exec(bContext *C, wmOperator *op) } } + return mask; +} + +static int mask_new_exec(bContext *C, wmOperator *op) +{ + char name[MAX_ID_NAME - 2]; + + RNA_string_get(op->ptr, "name", name); + + ED_mask_new(C, name); + return OPERATOR_FINISHED; } @@ -483,15 +491,15 @@ static void *slide_point_customdata(bContext *C, wmOperator *op, wmEvent *event) customdata->uw = uw; if (uw) { - float co[2]; + float co_uw[2]; float weight_scalar = BKE_mask_point_weight_scalar(spline, point, uw->u); customdata->weight = uw->w; customdata->weight_scalar = weight_scalar; - BKE_mask_point_segment_co(spline, point, uw->u, co); + BKE_mask_point_segment_co(spline, point, uw->u, co_uw); BKE_mask_point_normal(spline, point, uw->u, customdata->no); - madd_v2_v2v2fl(customdata->feather, co, customdata->no, uw->w * weight_scalar); + madd_v2_v2v2fl(customdata->feather, co_uw, customdata->no, uw->w * weight_scalar); } else { BezTriple *bezt = &point->bezt; diff --git a/source/blender/editors/mask/mask_select.c b/source/blender/editors/mask/mask_select.c index 69cfdf4e51b..dc204909577 100644 --- a/source/blender/editors/mask/mask_select.c +++ b/source/blender/editors/mask/mask_select.c @@ -557,7 +557,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_mask(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index 246c323213c..9aa3f3633f3 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -21,6 +21,7 @@ set(INC ../include ../uvedit + ../../blenfont ../../blenkernel ../../blenlib ../../blenloader @@ -68,4 +69,8 @@ if(WITH_GAMEENGINE) ) endif() +if(WITH_INTERNATIONAL) + add_definitions(-DWITH_INTERNATIONAL) +endif() + blender_add_lib(bf_editor_mesh "${SRC}" "${INC}" "${INC_SYS}") diff --git a/source/blender/editors/mesh/SConscript b/source/blender/editors/mesh/SConscript index b3aba977b21..923bb3f9057 100644 --- a/source/blender/editors/mesh/SConscript +++ b/source/blender/editors/mesh/SConscript @@ -5,7 +5,7 @@ sources = env.Glob('*.c') defs = [] -incs = '../include ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' +incs = '../include ../../blenfont ../../blenlib ../../blenkernel ../../makesdna ../../imbuf' incs += ' ../../windowmanager #/intern/guardedalloc #/extern/glew/include' incs += ' ../../gpu ../../blenloader' incs += ' ../../makesrna ../../render/extern/include #/intern/elbeem/extern' @@ -24,4 +24,7 @@ if env['WITH_BF_GAMEENGINE']: else: sources.remove('mesh_navmesh.c') +if env['WITH_BF_INTERNATIONAL']: + defs.append('WITH_INTERNATIONAL') + env.BlenderLib ( 'bf_editors_mesh', sources, Split(incs), defs, libtype=['core'], priority=[45] ) diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c index 5fd848ccb13..429b2148894 100644 --- a/source/blender/editors/mesh/editface.c +++ b/source/blender/editors/mesh/editface.c @@ -214,7 +214,9 @@ static void select_linked_tfaces_with_seams(int mode, Mesh *me, unsigned int ind /* fill array by selection */ mp = me->mpoly; for (a = 0; a < me->totpoly; a++, mp++) { - if (mp->flag & ME_HIDE) ; + if (mp->flag & ME_HIDE) { + /* pass */ + } else if (mp->flag & ME_FACE_SEL) { hash_add_face(ehash, mp, me->mloop + mp->loopstart); linkflag[a] = 1; @@ -572,7 +574,9 @@ int do_paintface_box_select(ViewContext *vc, rcti *rect, int select, int extend) mpoly = me->mpoly; for (a = 1; a <= me->totpoly; a++, mpoly++) { if (selar[a]) { - if (mpoly->flag & ME_HIDE) ; + if (mpoly->flag & ME_HIDE) { + /* pass */ + } else { if (select) mpoly->flag |= ME_FACE_SEL; else mpoly->flag &= ~ME_FACE_SEL; diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 0cf4ac48bf7..99ed86d7a06 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -73,7 +73,7 @@ static Object *make_prim_init(bContext *C, const char *idname, *state = 1; } - *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, FALSE); return obedit; } @@ -200,7 +200,7 @@ static int add_primitive_circle_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_circle segments=%i diameter=%f cap_ends=%b cap_tris=%b mat=%m4", - RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), + RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius") * dia, cap_end, cap_tri, mat)) { return OPERATOR_CANCELLED; @@ -256,10 +256,10 @@ static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) em, op, "vertout", "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", RNA_int_get(op->ptr, "vertices"), - RNA_float_get(op->ptr, "radius"), - RNA_float_get(op->ptr, "radius"), + RNA_float_get(op->ptr, "radius") * dia, + RNA_float_get(op->ptr, "radius") * dia, cap_end, cap_tri, - RNA_float_get(op->ptr, "depth"), mat)) + RNA_float_get(op->ptr, "depth") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -315,8 +315,8 @@ static int add_primitive_cone_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf( em, op, "vertout", "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", - RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"), - RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat)) + RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1") * dia, + RNA_float_get(op->ptr, "radius2") * dia, cap_end, cap_tri, RNA_float_get(op->ptr, "depth") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -421,6 +421,10 @@ static int add_primitive_monkey_exec(bContext *C, wmOperator *op) rot[0] += (float)M_PI / 2.0f; obedit = make_prim_init(C, "Monkey", &dia, mat, &state, loc, rot, layer); + mat[0][0] *= dia; + mat[1][1] *= dia; + mat[2][2] *= dia; + em = BMEdit_FromObject(obedit); if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_monkey mat=%m4", mat)) { @@ -465,7 +469,7 @@ static int add_primitive_uvsphere_exec(bContext *C, wmOperator *op) if (!EDBM_op_call_and_selectf(em, op, "vertout", "create_uvsphere segments=%i revolutions=%i diameter=%f mat=%m4", RNA_int_get(op->ptr, "segments"), RNA_int_get(op->ptr, "ring_count"), - RNA_float_get(op->ptr, "size"), mat)) + RNA_float_get(op->ptr, "size") * dia, mat)) { return OPERATOR_CANCELLED; } @@ -517,7 +521,7 @@ static int add_primitive_icosphere_exec(bContext *C, wmOperator *op) em, op, "vertout", "create_icosphere subdivisions=%i diameter=%f mat=%m4", RNA_int_get(op->ptr, "subdivisions"), - RNA_float_get(op->ptr, "size"), mat)) + RNA_float_get(op->ptr, "size") * dia, mat)) { return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c index c249d764ac1..e84fa90fe5c 100644 --- a/source/blender/editors/mesh/editmesh_bvh.c +++ b/source/blender/editors/mesh/editmesh_bvh.c @@ -371,9 +371,9 @@ int BMBVH_VertVisible(BMBVHTree *tree, BMEdge *e, RegionView3D *r3d) } #endif -static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *hitout, BMEdge *e) +static BMFace *edge_ray_cast(BMBVHTree *tree, const float co[3], const float dir[3], float *r_hitout, BMEdge *e) { - BMFace *f = BMBVH_RayCast(tree, co, dir, hitout, NULL); + BMFace *f = BMBVH_RayCast(tree, co, dir, r_hitout, NULL); if (f && BM_edge_in_face(f, e)) return NULL; @@ -392,7 +392,7 @@ static void scale_point(float c1[3], const float p[3], const float s) int BMBVH_EdgeVisible(BMBVHTree *tree, BMEdge *e, ARegion *ar, View3D *v3d, Object *obedit) { BMFace *f; - float co1[3], co2[3], co3[3], dir1[4], dir2[4], dir3[4]; + float co1[3], co2[3], co3[3], dir1[3], dir2[3], dir3[3]; float origin[3], invmat[4][4]; float epsilon = 0.01f; float end[3]; 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_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 001d584416f..8fe2aa4b1a7 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -55,19 +55,59 @@ #include "mesh_intern.h" -/* helper to find edge for edge_rip */ -static float edbm_rip_rip_edgedist(ARegion *ar, float mat[][4], - const float co1[3], const float co2[3], const float mvalf[2]) +/** + * helper to find edge for edge_rip, + * + * \param inset is used so we get some useful distance + * when comparing multiple edges that meet at the same + * point and would result in teh same distance. + */ +#define INSET_DEFAULT 0.00001f +static float edbm_rip_edgedist(ARegion *ar, float mat[][4], + const float co1[3], const float co2[3], const float mvalf[2], + const float inset) { - float vec1[3], vec2[3]; + float vec1[2], vec2[2]; ED_view3d_project_float_v2_m4(ar, co1, vec1, mat); ED_view3d_project_float_v2_m4(ar, co2, vec2, mat); + if (inset != 0.0f) { + const float dist = inset / len_v2v2(vec1, vec2); + interp_v2_v2v2(vec1, vec1, vec2, dist); + interp_v2_v2v2(vec2, vec2, vec1, dist); + } + /* TODO: use dist_squared_to_line_segment_v2() looks like we only ever use for comparison */ return dist_to_line_segment_v2(mvalf, vec1, vec2); } +#if 0 +static float edbm_rip_linedist(ARegion *ar, float mat[][4], + const float co1[3], const float co2[3], const float mvalf[2]) +{ + float vec1[2], vec2[2]; + + ED_view3d_project_float_v2_m4(ar, co1, vec1, mat); + ED_view3d_project_float_v2_m4(ar, co2, vec2, mat); + + return dist_to_line_v2(mvalf, vec1, vec2); +} +#endif + +/* calculaters a point along the loop tangent which can be used to measure against edges */ +static void edbm_calc_loop_co(BMLoop *l, float l_mid_co[3]) +{ + BM_loop_calc_face_tangent(l, l_mid_co); + + /* scale to average of surrounding edge size, only needs to be approx, but should + * be roughly equivalent to the check below which uses the middle of the edge. */ + mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f); + + add_v3_v3(l_mid_co, l->v->co); +} + + static float edbm_rip_edge_side_measure(BMEdge *e, BMLoop *e_l, ARegion *ar, float projectMat[4][4], const float fmval[2]) @@ -237,7 +277,6 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm) uid_start = uid; while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) { - BM_elem_flag_disable(e, BM_ELEM_SMOOTH); v_step = BM_edge_other_vert((e_step = e), v_step); uid++; /* only different line */ tot++; @@ -254,7 +293,6 @@ static EdgeLoopPair *edbm_ripsel_looptag_helper(BMesh *bm) v_step = e_first->v1; while ((e = edbm_ripsel_edge_mark_step(v_step, uid))) { - BM_elem_flag_disable(e, BM_ELEM_SMOOTH); v_step = BM_edge_other_vert((e_step = e), v_step); uid--; /* only different line */ tot++; @@ -344,6 +382,145 @@ static void edbm_ripsel_deselect_helper(BMesh *bm, EdgeLoopPair *eloop_pairs, } /* --- end 'ripsel' selection handling code --- */ + +/* --- face-fill code --- */ +/** + * return an un-ordered array of loop pairs + * use for rebuilding face-fill + * + * \note the method currenly used fails for edges with 3+ face users and gives + * nasty holes in the mesh, there isnt a good way of knowing ahead of time + * which loops will be split apart (its possible to figure out but quite involved). + * So for now this is a known limitation of current rip-fill option. + */ + +typedef struct UnorderedLoopPair { + BMLoop *l_pair[2]; + char flag; +} UnorderedLoopPair; +enum { + ULP_FLIP_0 = (1 << 0), + ULP_FLIP_1 = (1 << 1) +}; + +static UnorderedLoopPair *edbm_tagged_loop_pairs_to_fill(BMesh *bm) +{ + BMIter iter; + BMEdge *e; + + unsigned int total_tag = 0; + /* count tags, could be pre-calculated */ + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + total_tag++; + } + } + + if (total_tag) { + UnorderedLoopPair *uloop_pairs = MEM_mallocN(total_tag * sizeof(UnorderedLoopPair), __func__); + UnorderedLoopPair *ulp = uloop_pairs; + + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + BMLoop *l1, *l2; + if (BM_edge_loop_pair(e, &l1, &l2)) { + BMVert *v_cmp = l1->e->v1; + ulp->flag = (((l1->v != v_cmp) ? ULP_FLIP_0 : 0) | + ((l2->v == v_cmp) ? ULP_FLIP_1 : 0)); + } + else { + ulp->flag = 0; + } + ulp->l_pair[0] = l1; + ulp->l_pair[1] = l2; + + ulp++; + } + } + + return uloop_pairs; + } + else { + return NULL; + } +} + +static void edbm_tagged_loop_pairs_do_fill_faces(BMesh *bm, UnorderedLoopPair *uloop_pairs) +{ + UnorderedLoopPair *ulp; + unsigned int total_tag = MEM_allocN_len(uloop_pairs) / sizeof(UnorderedLoopPair); + unsigned int i; + + for (i = 0, ulp = uloop_pairs; i < total_tag; i++, ulp++) { + if ((ulp->l_pair[0] && ulp->l_pair[1]) && + (ulp->l_pair[0]->e != ulp->l_pair[1]->e)) + { + /* time has come to make a face! */ + BMVert *v_shared = BM_edge_share_vert(ulp->l_pair[0]->e, ulp->l_pair[1]->e); + BMFace *f, *f_example = ulp->l_pair[0]->f; + BMLoop *l_iter; + BMVert *f_verts[4]; + + if (v_shared == NULL) { + /* quad */ + f_verts[0] = ulp->l_pair[0]->e->v1; + f_verts[1] = ulp->l_pair[1]->e->v1; + f_verts[2] = ulp->l_pair[1]->e->v2; + f_verts[3] = ulp->l_pair[0]->e->v2; + + if (ulp->flag & ULP_FLIP_0) { + SWAP(BMVert *, f_verts[0], f_verts[3]); + } + if (ulp->flag & ULP_FLIP_1) { + SWAP(BMVert *, f_verts[1], f_verts[2]); + } + } + else { + /* tri */ + f_verts[0] = v_shared; + f_verts[1] = BM_edge_other_vert(ulp->l_pair[0]->e, v_shared); + f_verts[2] = BM_edge_other_vert(ulp->l_pair[1]->e, v_shared); + f_verts[3] = NULL; + + /* don't use the flip flags */ + if (v_shared == ulp->l_pair[0]->v) { + SWAP(BMVert *, f_verts[0], f_verts[1]); + } + } + + /* face should never exist */ + BLI_assert(BM_face_exists(bm, f_verts, f_verts[3] ? 4 : 3, &f) == FALSE); + + f = BM_face_create_quad_tri_v(bm, f_verts, f_verts[3] ? 4 : 3, f_example, FALSE); + + l_iter = BM_FACE_FIRST_LOOP(f); + + if (f_verts[3]) { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); + } + else { + if (v_shared == f_verts[0]) { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]->next), l_iter); + } + else { + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]->next), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[0]->e, ulp->l_pair[0]), l_iter); l_iter = l_iter->next; + BM_elem_attrs_copy(bm, bm, BM_edge_other_loop(ulp->l_pair[1]->e, ulp->l_pair[1]), l_iter); + } + } + + } + } +} + +/* --- end 'face-fill' code --- */ + + static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op) { BMOperator bmop; @@ -366,6 +543,8 @@ static int edbm_rip_call_edgesplit(BMEditMesh *em, wmOperator *op) */ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) { + const int do_fill = RNA_boolean_get(op->ptr, "use_fill"); + UnorderedLoopPair *fill_uloop_pairs = NULL; Object *obedit = CTX_data_edit_object(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -388,7 +567,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat); /* find selected vert - same some time and check history first */ - if (BM_select_history_active_get(em->bm, &ese) && ese.htype == BM_VERT) { + if (BM_select_history_active_get(bm, &ese) && ese.htype == BM_VERT) { v = (BMVert *)ese.ele; } else { @@ -417,7 +596,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) totboundary_edge += (is_boundary != 0 || BM_edge_is_wire(e)); if (!BM_elem_flag_test(e, BM_ELEM_HIDDEN)) { if (is_boundary == FALSE && BM_edge_is_manifold(e)) { - d = edbm_rip_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval); + d = edbm_rip_edgedist(ar, projectMat, e->v1->co, e->v2->co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; e2 = e; @@ -426,6 +605,42 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) } } + /* if we are ripping a single vertex from 3 faces, + * then measure the distance to the face corner as well as the edge */ + if (BM_vert_face_count(v) == 3 && + BM_vert_edge_count(v) == 3) + { + BMEdge *e_all[3]; + BMLoop *l_all[3]; + int i1, i2; + + BM_iter_as_array(bm, BM_EDGES_OF_VERT, v, (void **)e_all, 3); + BM_iter_as_array(bm, BM_LOOPS_OF_VERT, v, (void **)l_all, 3); + + /* not do a loop similar to the one above, but test against loops */ + for (i1 = 0; i1 < 3; i1++) { + /* consider wire as boundary for this purpose, + * otherwise we can't a face away from a wire edge */ + float l_mid_co[3]; + l = l_all[i1]; + edbm_calc_loop_co(l, l_mid_co); + d = edbm_rip_edgedist(ar, projectMat, l->v->co, l_mid_co, fmval, INSET_DEFAULT); + + if (d < dist) { + dist = d; + + /* find the edge that is not in this loop */ + e2 = NULL; + for (i2 = 0; i2 < 3; i2++) { + if (!BM_edge_in_loop(e_all[i2], l)) { + e2 = e_all[i2]; + break; + } + } + BLI_assert(e2 != NULL); + } + } + } } /* should we go ahead with edge rip or do we need to do special case, split off vertex?: @@ -459,7 +674,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) int vi_best = 0; if (ese.ele) { - BM_select_history_remove(em->bm, ese.ele); + BM_select_history_remove(bm, ese.ele); } dist = FLT_MAX; @@ -473,14 +688,9 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) BM_ITER_ELEM (l, &iter, vout[i], BM_LOOPS_OF_VERT) { if (!BM_elem_flag_test(l->f, BM_ELEM_HIDDEN)) { float l_mid_co[3]; - BM_loop_calc_face_tangent(l, l_mid_co); + edbm_calc_loop_co(l, l_mid_co); - /* scale to average of surrounding edge size, only needs to be approx, but should - * be roughly equivalent to the check below which uses the middle of the edge. */ - mul_v3_fl(l_mid_co, (BM_edge_calc_length(l->e) + BM_edge_calc_length(l->prev->e)) / 2.0f); - add_v3_v3(l_mid_co, v->co); - - d = edbm_rip_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval); + d = edbm_rip_edgedist(ar, projectMat, v->co, l_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -496,7 +706,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) float e_mid_co[3]; mid_v3_v3v3(e_mid_co, e->v1->co, e->v2->co); - d = edbm_rip_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval); + d = edbm_rip_edgedist(ar, projectMat, v->co, e_mid_co, fmval, INSET_DEFAULT); if (d < dist) { dist = d; @@ -512,7 +722,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) BM_vert_select_set(bm, v, TRUE); if (ese.ele) { - BM_select_history_store(em->bm, v); + BM_select_history_store(bm, v); } /* splice all others back together */ @@ -543,39 +753,65 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } + /* *** Execute the split! *** */ + /* unlike edge split, for single vertex split we only use the operator in one of the cases + * but both allocate fill */ + /* rip two adjacent edges */ if (BM_edge_is_boundary(e2) || BM_vert_face_count(v) == 2) { + /* Don't run the edge split operator in this case */ + + BM_elem_flag_enable(e2, BM_ELEM_TAG); /* only for face-fill (we don't call the operator) */ + + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } + l = e2->l; ripvert = BM_face_vert_separate(bm, l->f, v); BLI_assert(ripvert); if (!ripvert) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); return OPERATOR_CANCELLED; } } - else if (BM_edge_is_manifold(e2)) { - l = e2->l; - e = BM_face_other_edge_loop(l->f, e2, v)->e; - BM_elem_flag_enable(e, BM_ELEM_TAG); + else { + if (BM_edge_is_manifold(e2)) { + l = e2->l; + e = BM_face_other_edge_loop(l->f, e2, v)->e; + BM_elem_flag_enable(e, BM_ELEM_TAG); + + l = e2->l->radial_next; + e = BM_face_other_edge_loop(l->f, e2, v)->e; + BM_elem_flag_enable(e, BM_ELEM_TAG); + } + else { + /* looks like there are no split edges, we could just return/report-error? - Campbell */ + } + + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } - l = e2->l->radial_next; - e = BM_face_other_edge_loop(l->f, e2, v)->e; - BM_elem_flag_enable(e, BM_ELEM_TAG); + if (!edbm_rip_call_edgesplit(em, op)) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); + return OPERATOR_CANCELLED; + } } dist = FLT_MAX; - if (!edbm_rip_call_edgesplit(em, op)) { - return OPERATOR_CANCELLED; - } - else { + { /* --- select which vert --- */ BMVert *v_best = NULL; float l_prev_co[3], l_next_co[3], l_corner_co[3]; float scale; dist = FLT_MAX; - BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { + BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { /* disable by default, re-enable winner at end */ BM_vert_select_set(bm, v, FALSE); @@ -593,7 +829,7 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) add_v3_v3v3(l_corner_co, l_prev_co, l_next_co); add_v3_v3(l_corner_co, l->v->co); - d = edbm_rip_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval); + d = edbm_rip_edgedist(ar, projectMat, l->v->co, l_corner_co, fmval, INSET_DEFAULT); if (d < dist) { v_best = v; dist = d; @@ -605,11 +841,17 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) if (v_best) { BM_vert_select_set(bm, v_best, TRUE); if (ese.ele) { - BM_select_history_store(em->bm, v_best); + BM_select_history_store(bm, v_best); } } } + if (do_fill && fill_uloop_pairs) { + edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs); + MEM_freeN(fill_uloop_pairs); + } + + if (totvert_orig == bm->totvert) { BKE_report(op->reports, RPT_ERROR, "No vertices could be ripped"); return OPERATOR_CANCELLED; @@ -623,6 +865,8 @@ static int edbm_rip_invoke__vert(bContext *C, wmOperator *op, wmEvent *event) */ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) { + const int do_fill = RNA_boolean_get(op->ptr, "use_fill"); + UnorderedLoopPair *fill_uloop_pairs = NULL; Object *obedit = CTX_data_edit_object(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); @@ -633,25 +877,25 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) BMEdge *e, *e2; BMVert *v; const int totedge_orig = bm->totedge; - int i; float projectMat[4][4], fmval[3] = {event->mval[0], event->mval[1]}; - int totedge; - int all_minifold; - EdgeLoopPair *eloop_pairs; ED_view3d_ob_project_mat_get(rv3d, obedit, projectMat); - /* important this runs on the original selection, before tempering with tagging */ + /* important this runs on the original selection, before tampering with tagging */ eloop_pairs = edbm_ripsel_looptag_helper(bm); /* expand edge selection */ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { + int all_manifold; + int totedge_manifold; /* manifold, visible edges */ + int i; + e2 = NULL; i = 0; - totedge = 0; - all_minifold = TRUE; + totedge_manifold = 0; + all_manifold = TRUE; BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) { if (!BM_edge_is_wire(e) && @@ -663,22 +907,25 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) e2 = e; i++; } - totedge++; + totedge_manifold++; } /** #BM_vert_other_disk_edge has no hidden checks so don't check hidden here */ - if ((all_minifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) { - all_minifold = FALSE; + if ((all_manifold == TRUE) && (BM_edge_is_manifold(e) == FALSE)) { + all_manifold = FALSE; } } /* single edge, extend */ if (i == 1 && e2->l) { - if ((totedge == 4) || (all_minifold == FALSE)) { + /* note: if the case of 3 edges has one change in loop stepping, + * if this becomes more involved we may be better off splitting + * the 3 edge case into its own else-if branch */ + if ((totedge_manifold == 4 || totedge_manifold == 3) || (all_manifold == FALSE)) { BMLoop *l_a = e2->l; BMLoop *l_b = l_a->radial_next; - /* find the best face to follow, this what the edge won't point away from + /* find the best face to follow, this way the edge won't point away from * the mouse when there are more then 4 (takes the shortest face fan around) */ l = (edbm_rip_edge_side_measure(e2, l_a, ar, projectMat, fmval) < edbm_rip_edge_side_measure(e2, l_b, ar, projectMat, fmval)) ? l_a : l_b; @@ -688,9 +935,12 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) * not crashing but adds duplicate edge. */ if (BM_edge_is_manifold(l->e)) { l = l->radial_next; - l = BM_face_other_edge_loop(l->f, l->e, v); + + if (totedge_manifold != 3) + l = BM_face_other_edge_loop(l->f, l->e, v); if (l) { + BLI_assert(!BM_elem_flag_test(l->e, BM_ELEM_TAG)); BM_elem_flag_enable(l->e, BM_ELEM_TAG); } } @@ -699,13 +949,20 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) e = BM_vert_other_disk_edge(v, e2); if (e) { + BLI_assert(!BM_elem_flag_test(e, BM_ELEM_TAG)); BM_elem_flag_enable(e, BM_ELEM_TAG); } } } } + /* keep directly before edgesplit */ + if (do_fill) { + fill_uloop_pairs = edbm_tagged_loop_pairs_to_fill(bm); + } + if (!edbm_rip_call_edgesplit(em, op)) { + if (fill_uloop_pairs) MEM_freeN(fill_uloop_pairs); return OPERATOR_CANCELLED; } @@ -718,6 +975,11 @@ static int edbm_rip_invoke__edge(bContext *C, wmOperator *op, wmEvent *event) ar, projectMat, fmval); MEM_freeN(eloop_pairs); + if (do_fill && fill_uloop_pairs) { + edbm_tagged_loop_pairs_do_fill_faces(bm, fill_uloop_pairs); + MEM_freeN(fill_uloop_pairs); + } + if (totedge_orig == bm->totedge) { BKE_report(op->reports, RPT_ERROR, "No edges could be ripped"); return OPERATOR_CANCELLED; @@ -740,7 +1002,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) int ret; /* running in face mode hardly makes sense, so convert to region loop and rip */ - if (em->bm->totfacesel) { + if (bm->totfacesel) { /* highly nifty but hard to support since the operator can fail and we're left * with modified selection */ // WM_operator_name_call(C, "MESH_OT_region_to_loop", WM_OP_INVOKE_DEFAULT, NULL); @@ -760,7 +1022,7 @@ static int edbm_rip_invoke(bContext *C, wmOperator *op, wmEvent *event) */ /* BM_ELEM_SELECT --> BM_ELEM_TAG */ - BM_ITER_MESH (e, &iter, em->bm, BM_EDGES_OF_MESH) { + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { BM_elem_flag_set(e, BM_ELEM_TAG, BM_elem_flag_test(e, BM_ELEM_SELECT)); } @@ -804,5 +1066,6 @@ void MESH_OT_rip(wmOperatorType *ot) /* to give to transform */ Transform_Properties(ot, P_PROPORTIONAL); - RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); + RNA_def_boolean(ot->srna, "mirror", FALSE, "Mirror Editing", ""); + RNA_def_boolean(ot->srna, "use_fill", FALSE, "Fill", "Fill the ripped region"); } diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index ae2d090fef3..bc792037443 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; @@ -1006,7 +1002,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); @@ -1061,11 +1057,11 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) /* We can't be sure this has already been set... */ ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); - if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, eed->v1->co, v1_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { length_1 = len_squared_v2v2(mvalf, v1_co); } - if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, eed->v2->co, v2_co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { length_2 = len_squared_v2v2(mvalf, v2_co); } #if 0 @@ -1092,7 +1088,7 @@ static void mouse_mesh_loop(bContext *C, int mval[2], short extend, short ring) float co[2], tdist; BM_face_calc_center_mean(f, cent); - if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(vc.ar, cent, co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { tdist = len_squared_v2v2(mvalf, co); if (tdist < best_dist) { /* printf("Best face: %p (%f)\n", f, tdist);*/ @@ -1399,7 +1395,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]; @@ -2179,11 +2175,19 @@ static void walker_deselect_nth(BMEditMesh *em, int nth, int offset, BMHeader *h BMW_FLAG_NOP, /* don't use BMW_FLAG_TEST_HIDDEN here since we want to desel all */ BMW_NIL_LAY); + /* use tag to avoid touching the same verts twice */ + BM_ITER_MESH (ele, &iter, bm, itertype) { + BM_elem_flag_disable(ele, BM_ELEM_TAG); + } + BLI_assert(walker.order == BMW_BREADTH_FIRST); for (ele = BMW_begin(&walker, h_act); ele != NULL; ele = BMW_step(&walker)) { - /* Deselect elements that aren't at "nth" depth from active */ - if ((offset + BMW_current_depth(&walker)) % nth) { - BM_elem_select_set(bm, ele, FALSE); + if (!BM_elem_flag_test(ele, BM_ELEM_TAG)) { + /* Deselect elements that aren't at "nth" depth from active */ + if ((offset + BMW_current_depth(&walker)) % nth) { + BM_elem_select_set(bm, ele, FALSE); + } + BM_elem_flag_enable(ele, BM_ELEM_TAG); } } BMW_end(&walker); @@ -2306,8 +2310,8 @@ void MESH_OT_select_nth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "nth", 2, 2, 100, "Nth Selection", "", 1, INT_MAX); - RNA_def_int(ot->srna, "offset", 0, 0, 100, "Offset", "", 0, INT_MAX); + RNA_def_int(ot->srna, "nth", 2, 2, INT_MAX, "Nth Selection", "", 2, 100); + RNA_def_int(ot->srna, "offset", 0, 0, INT_MAX, "Offset", "", 0, 100); } void em_setup_viewcontext(bContext *C, ViewContext *vc) diff --git a/source/blender/editors/mesh/editmesh_slide.c b/source/blender/editors/mesh/editmesh_slide.c index e42b95c6013..d370b5a881e 100644 --- a/source/blender/editors/mesh/editmesh_slide.c +++ b/source/blender/editors/mesh/editmesh_slide.c @@ -34,6 +34,8 @@ #include "BLI_array.h" #include "BLI_math.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_report.h" #include "BKE_tessmesh.h" @@ -113,11 +115,11 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Custom data */ VertexSlideOp *vso; - const char *header_str = "Vertex Slide: Hover over an edge and left-click to select slide edge. " - "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap&Merge"; + const char *header_str = TIP_("Vertex Slide: Hover over an edge and left-click to select slide edge. " + "Left-Shift: Midpoint Snap, Left-Alt: Snap, Left-Ctrl: Snap & Merge"); if (!obedit) { - BKE_report(op->reports, RPT_ERROR, "Vertex Slide Error: Not object in context"); + BKE_report(op->reports, RPT_ERROR, "Vertex slide error: no object in context"); return FALSE; } @@ -126,7 +128,7 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Is there a starting vertex ? */ if (ese == NULL || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex"); return FALSE; } @@ -177,7 +179,7 @@ static int vtx_slide_init(bContext *C, wmOperator *op) /* Init frame */ if (!vtx_slide_set_frame(vso)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide: Can't find starting vertex!"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: cannot find starting vertex!"); vtx_slide_exit(C, op); return FALSE; } @@ -390,8 +392,8 @@ static BMEdge *vtx_slide_nrst_in_frame(VertexSlideOp *vso, const float mval[2]) mul_v3_m4v3(v2_proj, vso->obj->obmat, edge->v2->co); /* we could use ED_view3d_project_float_object here, but for now dont since we dont have the context */ - if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vso->active_region, v1_proj, v1_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_global(vso->active_region, v2_proj, v2_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { const float dist = dist_to_line_segment_v2(mval, v1_proj, v2_proj); if (dist < min_dist) { @@ -409,7 +411,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); @@ -458,8 +461,8 @@ static void vtx_slide_update(VertexSlideOp *vso, wmEvent *event) mul_v3_m4v3(start_vtx_proj, vso->obj->obmat, vso->start_vtx->co); mul_v3_m4v3(edge_other_proj, vso->obj->obmat, other->co); - if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || - (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vso->active_region, edge_other_proj, edge_other_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) || + (ED_view3d_project_float_global(vso->active_region, start_vtx_proj, start_vtx_proj, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK)) { /* not much we can do here */ return; @@ -718,7 +721,7 @@ static int edbm_vertex_slide_exec_ex(bContext *C, wmOperator *op, const int do_u /* Is there a starting vertex ? */ if ((ese == NULL) || (ese->htype != BM_VERT && ese->htype != BM_EDGE)) { - BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex Slide Error: Select a (single) vertex"); + BKE_report(op->reports, RPT_ERROR_INVALID_INPUT, "Vertex slide error: select a (single) vertex"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index d73e7d81b9f..ee615093c86 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -41,7 +41,9 @@ #include "RNA_define.h" #include "RNA_access.h" +#include "BLI_array.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_math.h" #include "BLI_rand.h" @@ -49,6 +51,7 @@ #include "BKE_context.h" #include "BKE_cdderivedmesh.h" #include "BKE_depsgraph.h" +#include "BKE_mesh.h" #include "BKE_object.h" #include "BKE_report.h" #include "BKE_texture.h" @@ -72,6 +75,8 @@ #include "mesh_intern.h" +#define MVAL_PIXEL_MARGIN 5.0f + /* allow accumulated normals to form a new direction but don't * accept direct opposite directions else they will cancel each other out */ static void add_normal_aligned(float nor[3], const float add[3]) @@ -153,6 +158,51 @@ void MESH_OT_subdivide(wmOperatorType *ot) } +static int edbm_unsubdivide_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMOperator bmop; + + int iterations = RNA_int_get(op->ptr, "iterations"); + + EDBM_op_init(em, &bmop, op, + "unsubdivide verts=%hv iterations=%i", BM_ELEM_SELECT, iterations); + + BMO_op_exec(em->bm, &bmop); + + if (!EDBM_op_finish(em, &bmop, op, TRUE)) { + return 0; + } + + if ((em->selectmode & SCE_SELECT_VERTEX) == 0) { + EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); /* need to flush vert->face first */ + } + EDBM_selectmode_flush(em); + + EDBM_update_generic(C, em, TRUE); + + return OPERATOR_FINISHED; +} + +void MESH_OT_unsubdivide(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Un-Subdivide"; + ot->description = "UnSubdivide selected edges & faces"; + ot->idname = "MESH_OT_unsubdivide"; + + /* api callbacks */ + ot->exec = edbm_unsubdivide_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_int(ot->srna, "iterations", 2, 1, INT_MAX, "Iterations", "Number of times to unsubdivide", 1, 100); +} + void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) { Object *obedit = em->ob; @@ -165,7 +215,7 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { float mval[2], co_proj[3], no_dummy[3]; int dist_dummy; - if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(ar, eve->co, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (snapObjectsContext(C, mval, &dist_dummy, co_proj, no_dummy, SNAP_NOT_OBEDIT)) { mul_v3_m4v3(eve->co, obedit->imat, co_proj); } @@ -429,8 +479,8 @@ void MESH_OT_extrude_repeat(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* props */ - RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, 100.0f, "Offset", "", 0.0f, FLT_MAX); - RNA_def_int(ot->srna, "steps", 10, 0, 180, "Steps", "", 0, INT_MAX); + RNA_def_float(ot->srna, "offset", 2.0f, 0.0f, FLT_MAX, "Offset", "", 0.0f, 100.0f); + RNA_def_int(ot->srna, "steps", 10, 0, INT_MAX, "Steps", "", 0, 180); } /* generic extern called extruder */ @@ -765,10 +815,10 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, wmEvent done = FALSE; BM_ITER_MESH (eed, &iter, vc.em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - float co1[3], co2[3]; + float co1[2], co2[2]; - if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_object(vc.ar, eed->v1->co, co1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_object(vc.ar, eed->v2->co, co2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { /* 2D rotate by 90d while adding. * (x, y) = (y, -x) @@ -1215,11 +1265,14 @@ static int edbm_vert_connect(bContext *C, wmOperator *op) if (!EDBM_op_finish(em, &bmop, op, TRUE)) { return OPERATOR_CANCELLED; } + else { + EDBM_selectmode_flush(em); /* so newly created edges get the selection state from the vertex */ EDBM_update_generic(C, em, TRUE); return len ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } +} void MESH_OT_vert_connect(wmOperatorType *ot) { @@ -1607,7 +1660,7 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "repeat", 1, 1, 100, "Number of times to smooth the mesh", "", 1, INT_MAX); + RNA_def_int(ot->srna, "repeat", 1, 1, 1000, "Number of times to smooth the mesh", "", 1, 100); RNA_def_boolean(ot->srna, "xaxis", 1, "X-Axis", "Smooth along the X axis"); RNA_def_boolean(ot->srna, "yaxis", 1, "Y-Axis", "Smooth along the Y axis"); RNA_def_boolean(ot->srna, "zaxis", 1, "Z-Axis", "Smooth along the Z axis"); @@ -2080,7 +2133,7 @@ static int edbm_remove_doubles_exec(bContext *C, wmOperator *op) } count = totvert_orig - em->bm->totvert; - BKE_reportf(op->reports, RPT_INFO, "Removed %d vert%s", count, (count == 1) ? "ex" : "ices"); + BKE_reportf(op->reports, RPT_INFO, "Removed %d vertices", count); EDBM_update_generic(C, em, TRUE); @@ -2165,7 +2218,7 @@ static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) } if (svert == NULL || evert == NULL) { - BKE_report(op->reports, RPT_WARNING, "Path Selection requires that two vertices be selected"); + BKE_report(op->reports, RPT_WARNING, "Path selection requires two vertices to be selected"); return OPERATOR_CANCELLED; } @@ -2772,7 +2825,7 @@ static int edbm_knife_cut_exec(bContext *C, wmOperator *op) screen_vert_coords = sco = MEM_mallocN(bm->totvert * sizeof(float) * 2, __func__); BM_ITER_MESH_INDEX (bv, &iter, bm, BM_VERTS_OF_MESH, i) { - if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_object(ar, bv->co, *sco, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { copy_v2_fl(*sco, FLT_MAX); /* set error value */ } BM_elem_index_set(bv, i); /* set_ok */ @@ -3078,7 +3131,7 @@ static int edbm_separate_exec(bContext *C, wmOperator *op) } else { if (type == 0) { - BKE_report(op->reports, RPT_ERROR, "Selecton not supported in object mode"); + BKE_report(op->reports, RPT_ERROR, "Selection not supported in object mode"); return OPERATOR_CANCELLED; } @@ -3542,7 +3595,7 @@ void MESH_OT_spin(wmOperatorType *ot) RNA_def_float(ot->srna, "degrees", 90.0f, -FLT_MAX, FLT_MAX, "Degrees", "Degrees", -360.0f, 360.0f); RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); } @@ -3666,8 +3719,8 @@ void MESH_OT_screw(wmOperatorType *ot) RNA_def_float_vector(ot->srna, "center", 3, NULL, -FLT_MAX, FLT_MAX, "Center", "Center in global view space", -FLT_MAX, FLT_MAX); - RNA_def_float_vector(ot->srna, "axis", 3, NULL, -1.0f, 1.0f, - "Axis", "Axis in global view space", -FLT_MAX, FLT_MAX); + RNA_def_float_vector(ot->srna, "axis", 3, NULL, -FLT_MAX, FLT_MAX, + "Axis", "Axis in global view space", -1.0f, 1.0f); } static int edbm_select_by_number_vertices_exec(bContext *C, wmOperator *op) @@ -3851,8 +3904,8 @@ static void sort_bmelem_flag(Scene *scene, Object *ob, char *pblock[3] = {NULL, NULL, NULL}, *pb; BMElemSort *sblock[3] = {NULL, NULL, NULL}, *sb; int *map[3] = {NULL, NULL, NULL}, *mp; - int totelem[3] = {0, 0, 0}, tot; - int affected[3] = {0, 0, 0}, aff; + int totelem[3] = {0, 0, 0}; + int affected[3] = {0, 0, 0}; int i, j; if (!(types && flag && action)) @@ -4227,8 +4280,8 @@ static void sort_bmelem_flag(Scene *scene, Object *ob, if (pb && sb && !map[j]) { char *p_blk; BMElemSort *s_blk; - tot = totelem[j]; - aff = affected[j]; + int tot = totelem[j]; + int aff = affected[j]; qsort(sb, aff, sizeof(BMElemSort), bmelemsort_comp); @@ -4277,7 +4330,7 @@ static int edbm_sort_elements_exec(bContext *C, wmOperator *op) if (ELEM(action, SRT_VIEW_ZAXIS, SRT_VIEW_XAXIS)) { if (rv3d == NULL) { - BKE_report(op->reports, RPT_ERROR, "View not found, can't sort by view axis"); + BKE_report(op->reports, RPT_ERROR, "View not found, cannot sort by view axis"); return OPERATOR_CANCELLED; } } @@ -4465,6 +4518,7 @@ typedef struct { int li; int mcenter[2]; float initial_length; + float pixel_size; /* use when mouse input is interpreted as spatial distance */ int is_modal; NumInput num_input; float shift_factor; /* The current factor when shift is pressed. Negative when shift not active. */ @@ -4662,8 +4716,10 @@ static int edbm_bevel_exec(bContext *C, wmOperator *op) static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) { /* TODO make modal keymap (see fly mode) */ + RegionView3D *rv3d = CTX_wm_region_view3d(C); BevelData *opdata; float mlen[2]; + float center_3d[3]; if (!edbm_bevel_init(C, op, TRUE)) { return OPERATOR_CANCELLED; @@ -4672,7 +4728,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) opdata = op->customdata; /* initialize mouse values */ - if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; @@ -4680,6 +4736,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); + opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; edbm_bevel_update_header(op, C); @@ -4693,6 +4750,44 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_RUNNING_MODAL; } +static float edbm_bevel_mval_factor(wmOperator *op, wmEvent *event) +{ + BevelData *opdata = op->customdata; + int use_dist = RNA_boolean_get(op->ptr, "use_dist"); + float mdiff[2]; + float factor; + + mdiff[0] = opdata->mcenter[0] - event->mval[0]; + mdiff[1] = opdata->mcenter[1] - event->mval[1]; + + if (use_dist) { + factor = ((len_v2(mdiff) - MVAL_PIXEL_MARGIN) - opdata->initial_length) * opdata->pixel_size; + } + else { + factor = (len_v2(mdiff) - MVAL_PIXEL_MARGIN) / opdata->initial_length; + factor = factor - 1.0f; /* a different kind of buffer where nothing happens */ + } + + /* Fake shift-transform... */ + if (event->shift) { + if (opdata->shift_factor < 0.0f) + opdata->shift_factor = RNA_float_get(op->ptr, "percent"); + factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; + } + else if (opdata->shift_factor >= 0.0f) + opdata->shift_factor = -1.0f; + + /* clamp differently based on distance/factor */ + if (use_dist) { + if (factor < 0.0f) factor = 0.0f; + } + else { + CLAMP(factor, 0.0f, 1.0f); + } + + return factor; +} + static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) { BevelData *opdata = op->customdata; @@ -4720,25 +4815,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) case MOUSEMOVE: if (!hasNumInput(&opdata->num_input)) { - float factor; - float mdiff[2]; - - mdiff[0] = opdata->mcenter[0] - event->mval[0]; - mdiff[1] = opdata->mcenter[1] - event->mval[1]; - - factor = opdata->initial_length / -len_v2(mdiff) + 1.0f; - - /* Fake shift-transform... */ - if (event->shift) { - if (opdata->shift_factor < 0.0f) - opdata->shift_factor = RNA_float_get(op->ptr, "percent"); - factor = (factor - opdata->shift_factor) * 0.1f + opdata->shift_factor; - } - else if (opdata->shift_factor >= 0.0f) - opdata->shift_factor = -1.0f; - - CLAMP(factor, 0.0f, 1.0f); - + const float factor = edbm_bevel_mval_factor(op, event); RNA_float_set(op->ptr, "percent", factor); edbm_bevel_calc(C, op); @@ -4768,6 +4845,11 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, wmEvent *event) int use_dist = RNA_boolean_get(op->ptr, "use_dist"); RNA_boolean_set(op->ptr, "use_dist", !use_dist); + { + const float factor = edbm_bevel_mval_factor(op, event); + RNA_float_set(op->ptr, "percent", factor); + } + edbm_bevel_calc(C, op); edbm_bevel_update_header(op, C); } @@ -4794,6 +4876,7 @@ void MESH_OT_bevel(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; + /* take note, used as a factor _and_ a distance depending on 'use_dist' */ RNA_def_float(ot->srna, "percent", 0.0f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f); /* XXX, disabled for 2.63 release, needs to work much better without overlap before we can give to users. */ /* RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8); */ @@ -4858,8 +4941,9 @@ typedef struct { float old_depth; int mcenter[2]; int modify_depth; - int is_modal; float initial_length; + float pixel_size; /* use when mouse input is interpreted as spatial distance */ + int is_modal; int shift; float shift_amount; BMBackup backup; @@ -5025,15 +5109,17 @@ static int edbm_inset_exec(bContext *C, wmOperator *op) static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) { + RegionView3D *rv3d = CTX_wm_region_view3d(C); InsetData *opdata; float mlen[2]; + float center_3d[3]; edbm_inset_init(C, op, TRUE); opdata = op->customdata; /* initialize mouse values */ - if (!calculateTransformCenter(C, V3D_CENTROID, NULL, opdata->mcenter)) { + if (!calculateTransformCenter(C, V3D_CENTROID, center_3d, opdata->mcenter)) { /* in this case the tool will likely do nothing, * ideally this will never happen and should be checked for above */ opdata->mcenter[0] = opdata->mcenter[1] = 0; @@ -5041,6 +5127,7 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, wmEvent *event) mlen[0] = opdata->mcenter[0] - event->mval[0]; mlen[1] = opdata->mcenter[1] - event->mval[1]; opdata->initial_length = len_v2(mlen); + opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f; edbm_inset_calc(C, op); @@ -5090,9 +5177,9 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, wmEvent *event) mdiff[1] = opdata->mcenter[1] - event->mval[1]; if (opdata->modify_depth) - amount = opdata->old_depth + opdata->initial_length / len_v2(mdiff) - 1.0f; + amount = opdata->old_depth + ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); else - amount = opdata->old_thickness - opdata->initial_length / len_v2(mdiff) + 1.0f; + amount = opdata->old_thickness - ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); /* Fake shift-transform... */ if (opdata->shift) @@ -5393,6 +5480,57 @@ void MESH_OT_convex_hull(wmOperatorType *ot) join_triangle_props(ot); } +static int mesh_symmetrize_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMOperator bmop; + + EDBM_op_init(em, &bmop, op, "symmetrize input=%hvef direction=%i", + BM_ELEM_SELECT, RNA_enum_get(op->ptr, "direction")); + BMO_op_exec(em->bm, &bmop); + + if (!EDBM_op_finish(em, &bmop, op, TRUE)) { + return OPERATOR_CANCELLED; + } + else { + EDBM_update_generic(C, em, TRUE); + EDBM_selectmode_flush(em); + return OPERATOR_FINISHED; + } +} + +void MESH_OT_symmetrize(struct wmOperatorType *ot) +{ + static EnumPropertyItem axis_direction_items[] = { + {BMO_SYMMETRIZE_NEGATIVE_X, "NEGATIVE_X", 0, "-X to +X", ""}, + {BMO_SYMMETRIZE_POSITIVE_X, "POSITIVE_X", 0, "+X to -X", ""}, + + {BMO_SYMMETRIZE_NEGATIVE_Y, "NEGATIVE_Y", 0, "-Y to +Y", ""}, + {BMO_SYMMETRIZE_POSITIVE_Y, "POSITIVE_Y", 0, "+Y to -Y", ""}, + + {BMO_SYMMETRIZE_NEGATIVE_Z, "NEGATIVE_Z", 0, "-Z to +Z", ""}, + {BMO_SYMMETRIZE_POSITIVE_Z, "POSITIVE_Z", 0, "+Z to -Z", ""}, + {0, NULL, 0, NULL, NULL}, + }; + + /* identifiers */ + ot->name = "Symmetrize"; + ot->description = "Enforce symmetry (both form and topological) across an axis"; + ot->idname = "MESH_OT_symmetrize"; + + /* api callbacks */ + ot->exec = mesh_symmetrize_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + ot->prop = RNA_def_enum(ot->srna, "direction", axis_direction_items, + BMO_SYMMETRIZE_NEGATIVE_X, + "Direction", "Which sides to copy from and to"); +} + static int edbm_mark_freestyle_edge(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 735492cb553..4adf37a14c3 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -593,7 +593,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) /* Check context */ if (base == NULL || base->object->type != OB_MESH) { - BKE_report(op->reports, RPT_ERROR, "Not an Object or Mesh"); + BKE_report(op->reports, RPT_ERROR, "Not an object or mesh"); return OPERATOR_CANCELLED; } @@ -610,7 +610,7 @@ static int drop_named_image_invoke(bContext *C, wmOperator *op, wmEvent *event) } if (!ima) { - BKE_report(op->reports, RPT_ERROR, "Not an Image"); + BKE_report(op->reports, RPT_ERROR, "Not an image"); return OPERATOR_CANCELLED; } @@ -1124,7 +1124,7 @@ static void mesh_remove_faces(Mesh *mesh, int len) void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, int faces) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add geometry in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add geometry in edit mode"); return; } @@ -1140,12 +1140,12 @@ void ED_mesh_geometry_add(Mesh *mesh, ReportList *reports, int verts, int edges, void ED_mesh_tessfaces_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessfaces in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessfaces in edit mode"); return; } if (mesh->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessfaces to a mesh that already has polygons"); + BKE_report(reports, RPT_ERROR, "Cannot add tessfaces to a mesh that already has polygons"); return; } @@ -1155,7 +1155,7 @@ void ED_mesh_tessfaces_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add edges in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add edges in edit mode"); return; } @@ -1165,7 +1165,7 @@ void ED_mesh_edges_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add vertices in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot add vertices in edit mode"); return; } @@ -1175,11 +1175,11 @@ void ED_mesh_vertices_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove faces in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove faces in edit mode"); return; } else if (count > mesh->totface) { - BKE_report(reports, RPT_ERROR, "Can't remove more faces than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more faces than the mesh contains"); return; } @@ -1189,11 +1189,11 @@ void ED_mesh_faces_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove edges in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove edges in edit mode"); return; } else if (count > mesh->totedge) { - BKE_report(reports, RPT_ERROR, "Can't remove more edges than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more edges than the mesh contains"); return; } @@ -1203,11 +1203,11 @@ void ED_mesh_edges_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't remove vertices in edit mode"); + BKE_report(reports, RPT_ERROR, "Cannot remove vertices in edit mode"); return; } else if (count > mesh->totvert) { - BKE_report(reports, RPT_ERROR, "Can't remove more vertices than the mesh contains"); + BKE_report(reports, RPT_ERROR, "Cannot remove more vertices than the mesh contains"); return; } @@ -1217,7 +1217,7 @@ void ED_mesh_vertices_remove(Mesh *mesh, ReportList *reports, int count) void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add loops in edit mode."); + BKE_report(reports, RPT_ERROR, "Cannot add loops in edit mode"); return; } @@ -1227,7 +1227,7 @@ void ED_mesh_loops_add(Mesh *mesh, ReportList *reports, int count) void ED_mesh_polys_add(Mesh *mesh, ReportList *reports, int count) { if (mesh->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add polys in edit mode."); + BKE_report(reports, RPT_ERROR, "Cannot add polygons in edit mode"); return; } diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index b68c1836992..835b1ccd52d 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -145,6 +145,7 @@ extern struct EnumPropertyItem *corner_type_items; void MESH_OT_merge(struct wmOperatorType *ot); void MESH_OT_subdivide(struct wmOperatorType *ot); +void MESH_OT_unsubdivide(struct wmOperatorType *ot); void MESH_OT_remove_doubles(struct wmOperatorType *ot); void MESH_OT_spin(struct wmOperatorType *ot); void MESH_OT_screw(struct wmOperatorType *ot); @@ -216,6 +217,8 @@ void MESH_OT_vert_slide(struct wmOperatorType *ot); void MESH_OT_convex_hull(struct wmOperatorType *ot); +void MESH_OT_symmetrize(struct wmOperatorType *ot); + /* ******************* mesh_navmesh.c */ void MESH_OT_navmesh_make(struct wmOperatorType *ot); void MESH_OT_navmesh_face_copy(struct wmOperatorType *ot); @@ -223,5 +226,4 @@ void MESH_OT_navmesh_face_add(struct wmOperatorType *ot); void MESH_OT_navmesh_reset(struct wmOperatorType *ot); void MESH_OT_navmesh_clear(struct wmOperatorType *ot); -#endif // __MESH_INTERN_H__ - +#endif /* __MESH_INTERN_H__ */ diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index ccf91958e08..d06142d2654 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -74,6 +74,7 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_normals_make_consistent); WM_operatortype_append(MESH_OT_merge); WM_operatortype_append(MESH_OT_subdivide); + WM_operatortype_append(MESH_OT_unsubdivide); WM_operatortype_append(MESH_OT_faces_select_linked_flat); WM_operatortype_append(MESH_OT_edges_select_sharp); WM_operatortype_append(MESH_OT_primitive_plane_add); @@ -168,6 +169,8 @@ void ED_operatortypes_mesh(void) WM_operatortype_append(MESH_OT_convex_hull); + WM_operatortype_append(MESH_OT_symmetrize); + #ifdef WITH_GAMEENGINE WM_operatortype_append(MESH_OT_navmesh_make); WM_operatortype_append(MESH_OT_navmesh_face_copy); @@ -211,7 +214,17 @@ void ED_operatormacros_mesh(void) ot = WM_operatortype_append_macro("MESH_OT_rip_move", "Rip", "Rip polygons and move the result", OPTYPE_UNDO | OPTYPE_REGISTER); - WM_operatortype_macro_define(ot, "MESH_OT_rip"); + otmacro = WM_operatortype_macro_define(ot, "MESH_OT_rip"); + RNA_boolean_set(otmacro->ptr, "use_fill", FALSE); + otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); + RNA_enum_set(otmacro->ptr, "proportional", 0); + RNA_boolean_set(otmacro->ptr, "mirror", FALSE); + + /* annoying we can't pass 'use_fill' through the macro */ + ot = WM_operatortype_append_macro("MESH_OT_rip_move_fill", "Rip Fill", "Rip-fill polygons and move the result", + OPTYPE_UNDO | OPTYPE_REGISTER); + otmacro = WM_operatortype_macro_define(ot, "MESH_OT_rip"); + RNA_boolean_set(otmacro->ptr, "use_fill", TRUE); otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate"); RNA_enum_set(otmacro->ptr, "proportional", 0); RNA_boolean_set(otmacro->ptr, "mirror", FALSE); @@ -326,6 +339,8 @@ void ED_keymap_mesh(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "MESH_OT_tris_convert_to_quads", JKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "MESH_OT_rip_move", VKEY, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "MESH_OT_rip_move_fill", VKEY, KM_PRESS, KM_ALT, 0); + WM_keymap_add_item(keymap, "MESH_OT_merge", MKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "TRANSFORM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 42d82fff38e..d8793505608 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -113,7 +113,7 @@ int join_mesh_exec(bContext *C, wmOperator *op) CustomData vdata, edata, fdata, ldata, pdata; if (scene->obedit) { - BKE_report(op->reports, RPT_WARNING, "Cant join while in editmode"); + BKE_report(op->reports, RPT_WARNING, "Cannot join while in editmode"); return OPERATOR_CANCELLED; } @@ -161,8 +161,8 @@ int join_mesh_exec(bContext *C, wmOperator *op) } if (totvert > MESH_MAX_VERTS) { - BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is " STRINGIFY(MESH_MAX_VERTS), totvert); - return OPERATOR_CANCELLED; + BKE_reportf(op->reports, RPT_WARNING, "Joining results in %d vertices, limit is %ld", totvert, MESH_MAX_VERTS); + return OPERATOR_CANCELLED; } /* new material indices and material array */ @@ -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 { @@ -1237,7 +1237,7 @@ int ED_mesh_pick_face_vert(bContext *C, Mesh *me, Object *ob, const int mval[2], const int v_idx = me->mloop[mp->loopstart + fidx].v; dm->getVertCo(dm, v_idx, co); mul_m4_v3(ob->obmat, co); - if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(ar, co, sco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { len = len_squared_v2v2(mval_f, sco); if (len < len_best) { len_best = len; @@ -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/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index e9063687506..b9018914633 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -98,7 +98,7 @@ void load_editMball(Object *UNUSED(obedit)) } /* Add metaelem primitive to metaball object (which is in edit mode) */ -MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], int type, int UNUSED(newname)) +MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[4][4], float dia, int type, int UNUSED(newname)) { MetaBall *mball = (MetaBall *)obedit->data; MetaElem *ml; @@ -111,6 +111,7 @@ MetaElem *add_metaball_primitive(bContext *UNUSED(C), Object *obedit, float mat[ } ml = BKE_mball_element_add(mball, type); + ml->rad *= dia; copy_v3_v3(&ml->x, mat[3]); ml->flag |= SELECT; diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index 43a32cd662e..9a2915a5d55 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -136,6 +136,7 @@ static EnumPropertyItem field_type_items[] = { {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", ""}, {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", ""}, + {PFIELD_SMOKEFLOW, "SMOKE", ICON_FORCE_SMOKEFLOW, "Smoke Flow", ""}, {0, NULL, 0, NULL, NULL} }; @@ -185,7 +186,8 @@ void ED_object_base_init_transform(bContext *C, Base *base, const float loc[3], /* Uses context to figure out transform for primitive. * Returns standard diameter. */ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, - const float loc[3], const float rot[3], float primmat[][4]) + const float loc[3], const float rot[3], float primmat[][4], + int apply_diameter) { Scene *scene = CTX_data_scene(C); View3D *v3d = CTX_wm_view3d(C); @@ -208,8 +210,17 @@ float ED_object_new_primitive_matrix(bContext *C, Object *obedit, invert_m3_m3(imat, mat); mul_m3_v3(imat, primmat[3]); - if (v3d) - return ED_view3d_grid_scale(scene, v3d, NULL); + if (v3d) { + float dia = ED_view3d_grid_scale(scene, v3d, NULL); + + if (apply_diameter) { + primmat[0][0] *= dia; + primmat[1][1] *= dia; + primmat[2][2] *= dia; + } + + return dia; + } return 1.0f; } @@ -356,7 +367,7 @@ Object *ED_object_add_type(bContext *C, int type, const float loc[3], const floa Scene *scene = CTX_data_scene(C); Object *ob; - /* For as long scene has editmode... */ + /* for as long scene has editmode... */ if (CTX_data_edit_object(C)) ED_object_exit_editmode(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); /* freedata, and undo */ @@ -441,7 +452,7 @@ static int effector_add_exec(bContext *C, wmOperator *op) rename_id(&ob->id, "CurveGuide"); ((Curve *)ob->data)->flag |= CU_PATH | CU_3D; ED_object_enter_editmode(C, 0); - ED_object_new_primitive_matrix(C, ob, loc, rot, mat); + ED_object_new_primitive_matrix(C, ob, loc, rot, mat, FALSE); BLI_addtail(object_editcurve_get(ob), add_nurbs_primitive(C, ob, mat, CU_NURBS | CU_PRIM_PATH, 1)); if (!enter_editmode) ED_object_exit_editmode(C, EM_FREEDATA); @@ -546,6 +557,7 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) unsigned int layer; float loc[3], rot[3]; float mat[4][4]; + float dia; if (!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL)) return OPERATOR_CANCELLED; @@ -557,9 +569,9 @@ static int object_metaball_add_exec(bContext *C, wmOperator *op) else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); - ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); + dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, FALSE); - add_metaball_primitive(C, obedit, mat, RNA_enum_get(op->ptr, "type"), newob); + add_metaball_primitive(C, obedit, mat, dia, RNA_enum_get(op->ptr, "type"), newob); /* userdef */ if (newob && !enter_editmode) { diff --git a/source/blender/editors/object/object_bake.c b/source/blender/editors/object/object_bake.c index 6d124377821..bc5d289d04c 100644 --- a/source/blender/editors/object/object_bake.c +++ b/source/blender/editors/object/object_bake.c @@ -900,7 +900,7 @@ static void finish_images(MultiresBakeRender *bkr) RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, bkr->bake_filter); - ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID;; + ibuf->userflags |= IB_BITMAPDIRTY | IB_DISPLAY_BUFFER_INVALID; if (ibuf->rect_float) ibuf->userflags |= IB_RECT_INVALID; @@ -937,7 +937,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) ob = base->object; if (ob->type != OB_MESH) { - BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh"); + BKE_report(op->reports, RPT_ERROR, "Baking of multires data only works with an active mesh object"); ok = 0; break; @@ -985,7 +985,7 @@ static int multiresbake_check(bContext *C, wmOperator *op) ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); if (!ibuf) { - BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer"); + BKE_report(op->reports, RPT_ERROR, "Baking should happen to image with image buffer"); ok = 0; } @@ -1366,20 +1366,23 @@ static void finish_bake_internal(BakeRender *bkr) if (bkr->prev_r_raytrace == 0) bkr->scene->r.mode &= ~R_RAYTRACE; - /* force OpenGL reload and mipmap recalc */ for (ima = G.main->image.first; ima; ima = ima->id.next) { ImBuf *ibuf = BKE_image_get_ibuf(ima, NULL); - if (bkr->result == BAKE_RESULT_OK) { - if (ima->ok == IMA_OK_LOADED) { - if (ibuf) { - if (ibuf->userflags & IB_BITMAPDIRTY) { - ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; - GPU_free_image(ima); - imb_freemipmapImBuf(ibuf); - } + /* some of the images could have been changed during bake, + * so recreate mipmaps regardless bake result status + */ + if (ima->ok == IMA_OK_LOADED) { + if (ibuf) { + if (ibuf->userflags & IB_BITMAPDIRTY) { + GPU_free_image(ima); + imb_freemipmapImBuf(ibuf); } + + /* invalidate display buffers for changed images */ + if (ibuf->userflags & IB_BITMAPDIRTY) + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } } diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 56f2426b1b0..80993d6cca7 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -853,7 +853,7 @@ static int childof_clear_inverse_exec(bContext *C, wmOperator *op) bChildOfConstraint *data = (con) ? (bChildOfConstraint *)con->data : NULL; if (data == NULL) { - BKE_report(op->reports, RPT_ERROR, "Childof constraint not found"); + BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found"); return OPERATOR_CANCELLED; } @@ -1073,7 +1073,7 @@ static int objectsolver_clear_inverse_exec(bContext *C, wmOperator *op) bObjectSolverConstraint *data = (con) ? (bObjectSolverConstraint *)con->data : NULL; if (data == NULL) { - BKE_report(op->reports, RPT_ERROR, "Childof constraint not found"); + BKE_report(op->reports, RPT_ERROR, "Child Of constraint not found"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_hook.c b/source/blender/editors/object/object_hook.c index a6afe6b2d04..8bc249974f2 100644 --- a/source/blender/editors/object/object_hook.c +++ b/source/blender/editors/object/object_hook.c @@ -442,7 +442,7 @@ static int add_hook_object(Main *bmain, Scene *scene, Object *obedit, Object *ob ok = object_hook_index_array(scene, obedit, &tot, &indexar, name, cent); if (!ok) { - BKE_report(reports, RPT_ERROR, "Requires selected vertices or active Vertex Group"); + BKE_report(reports, RPT_ERROR, "Requires selected vertices or active vertex group"); return FALSE; } diff --git a/source/blender/editors/object/object_intern.h b/source/blender/editors/object/object_intern.h index 4c83f6ef2ce..0be9c92897e 100644 --- a/source/blender/editors/object/object_intern.h +++ b/source/blender/editors/object/object_intern.h @@ -138,6 +138,7 @@ void OBJECT_OT_hook_recenter(struct wmOperatorType *ot); /* object_lattice.c */ void LATTICE_OT_select_all(struct wmOperatorType *ot); void LATTICE_OT_make_regular(struct wmOperatorType *ot); +void LATTICE_OT_flip(struct wmOperatorType *ot); /* object_group.c */ void GROUP_OT_create(struct wmOperatorType *ot); @@ -204,6 +205,7 @@ void OBJECT_OT_vertex_group_remove_from(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_select(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_deselect(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_linked(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_transfer_weight(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy_to_selected(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_copy(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_normalize(struct wmOperatorType *ot); @@ -214,6 +216,7 @@ void OBJECT_OT_vertex_group_fix(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_invert(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_blend(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_clean(struct wmOperatorType *ot); +void OBJECT_OT_vertex_group_limit_total(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_mirror(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_set_active(struct wmOperatorType *ot); void OBJECT_OT_vertex_group_sort(struct wmOperatorType *ot); diff --git a/source/blender/editors/object/object_lattice.c b/source/blender/editors/object/object_lattice.c index 1f7be0bf9a6..ac9c4f7adee 100644 --- a/source/blender/editors/object/object_lattice.c +++ b/source/blender/editors/object/object_lattice.c @@ -46,6 +46,7 @@ #include "DNA_scene_types.h" #include "RNA_access.h" +#include "RNA_define.h" #include "BKE_context.h" #include "BKE_depsgraph.h" @@ -167,7 +168,7 @@ void load_editLatt(Object *obedit) } } -/************************** Operators *************************/ +/************************** Select All Operator *************************/ void ED_setflagsLatt(Object *obedit, int flag) { @@ -254,6 +255,8 @@ void LATTICE_OT_select_all(wmOperatorType *ot) WM_operator_properties_select_all(ot); } +/************************** Make Regular Operator *************************/ + static int make_regular_poll(bContext *C) { Object *ob; @@ -300,18 +303,265 @@ void LATTICE_OT_make_regular(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +/************************** Flip Verts Operator *************************/ + +/* flipping options */ +typedef enum eLattice_FlipAxes { + LATTICE_FLIP_U = 0, + LATTICE_FLIP_V = 1, + LATTICE_FLIP_W = 2 +} eLattice_FlipAxes; + +/* Helper macro for accessing item at index (u, v, w) + * < lt: (Lattice) + * < U: (int) u-axis coordinate of point + * < V: (int) v-axis coordinate of point + * < W: (int) w-axis coordinate of point + * < dimU: (int) number of points per row or number of columns (U-Axis) + * < dimV: (int) number of rows (V-Axis) + * > returns: (BPoint *) pointer to BPoint at this index + */ +#define LATTICE_PT(lt, U, V, W, dimU, dimV) \ + ( (lt)->def + \ + ((dimU) * (dimV)) * (W) + \ + (dimU) * (V) + \ + (U) \ + ) + +/* Flip midpoint value so that relative distances between midpoint and neighbour-pair is maintained + * ! Assumes that uvw <=> xyz (i.e. axis-aligned index-axes with coordinate-axes) + * - Helper for lattice_flip_exec() + */ +static void lattice_flip_point_value(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) +{ + BPoint *bp; + float diff; + + /* just the point in the middle (unpaired) */ + bp = LATTICE_PT(lt, u, v, w, lt->pntsu, lt->pntsv); + + /* flip over axis */ + diff = mid - bp->vec[axis]; + bp->vec[axis] = mid + diff; +} + +/* Swap pairs of lattice points along a specified axis + * - Helper for lattice_flip_exec() + */ +static void lattice_swap_point_pairs(Lattice *lt, int u, int v, int w, float mid, eLattice_FlipAxes axis) +{ + BPoint *bpA, *bpB; + + int numU = lt->pntsu; + int numV = lt->pntsv; + int numW = lt->pntsw; + + int u0 = u, u1 = u; + int v0 = v, v1 = v; + int w0 = w, w1 = w; + + /* get pair index by just overriding the relevant pair-value + * - "-1" else buffer overflow + */ + switch (axis) { + case LATTICE_FLIP_U: + u1 = numU - u - 1; + break; + case LATTICE_FLIP_V: + v1 = numV - v - 1; + break; + case LATTICE_FLIP_W: + w1 = numW - w - 1; + break; + } + + /* get points to operate on */ + bpA = LATTICE_PT(lt, u0, v0, w0, numU, numV); + bpB = LATTICE_PT(lt, u1, v1, w1, numU, numV); + + /* Swap all coordinates, so that flipped coordinates belong to + * the indices on the correct side of the lattice. + * + * Coords: (-2 4) |0| (3 4) --> (3 4) |0| (-2 4) + * Indices: (0,L) (1,R) --> (0,L) (1,R) + */ + swap_v3_v3(bpA->vec, bpB->vec); + + /* However, we need to mirror the coordinate values on the axis we're dealing with, + * otherwise we'd have effectively only rotated the points around. If we don't do this, + * we'd just be reimplementing the naive mirroring algorithm, which causes unwanted deforms + * such as flipped normals, etc. + * + * Coords: (3 4) |0| (-2 4) --\ + * \-> (-3 4) |0| (2 4) + * Indices: (0,L) (1,R) --> (0,L) (1,R) + */ + lattice_flip_point_value(lt, u0, v0, w0, mid, axis); + lattice_flip_point_value(lt, u1, v1, w1, mid, axis); +} + +static int lattice_flip_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + Lattice *lt; + + eLattice_FlipAxes axis = RNA_enum_get(op->ptr, "axis"); + int numU, numV, numW; + int totP; + + float mid = 0.0f; + short isOdd = 0; + + /* get lattice - we need the "edit lattice" from the lattice... confusing... */ + lt = (Lattice *)obedit->data; + lt = lt->editlatt->latt; + + numU = lt->pntsu; + numV = lt->pntsv; + numW = lt->pntsw; + totP = numU * numV * numW; + + /* First Pass: determine midpoint - used for flipping center verts if there are odd number of points on axis */ + switch (axis) { + case LATTICE_FLIP_U: + isOdd = numU & 1; + break; + case LATTICE_FLIP_V: + isOdd = numV & 1; + break; + case LATTICE_FLIP_W: + isOdd = numW & 1; + break; + + default: + printf("lattice_flip(): Unknown flipping axis (%d)\n", axis); + return OPERATOR_CANCELLED; + } + + if (isOdd) { + BPoint *bp; + float avgInv = 1.0f / (float)totP; + int i; + + /* midpoint calculation - assuming that u/v/w are axis-aligned */ + for (i = 0, bp = lt->def; i < totP; i++, bp++) { + mid += bp->vec[axis] * avgInv; + } + } + + /* Second Pass: swap pairs of vertices per axis, assuming they are all sorted */ + switch (axis) { + case LATTICE_FLIP_U: + { + int u, v, w; + + /* v/w strips - front to back, top to bottom */ + for (w = 0; w < numW; w++) { + for (v = 0; v < numV; v++) { + /* swap coordinates of pairs of vertices on u */ + for (u = 0; u < (numU / 2); u++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip u-coordinate of midpoint (i.e. unpaired point on u) */ + if (isOdd) { + u = (numU / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + case LATTICE_FLIP_V: + { + int u, v, w; + + /* u/w strips - front to back, left to right */ + for (w = 0; w < numW; w++) { + for (u = 0; u < numU; u++) { + /* swap coordinates of pairs of vertices on v */ + for (v = 0; v < (numV / 2); v++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip v-coordinate of midpoint (i.e. unpaired point on v) */ + if (isOdd) { + v = (numV / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + case LATTICE_FLIP_W: + { + int u, v, w; + + for (v = 0; v < numV; v++) { + for (u = 0; u < numU; u++) { + /* swap coordinates of pairs of vertices on w */ + for (w = 0; w < (numW / 2); w++) { + lattice_swap_point_pairs(lt, u, v, w, mid, axis); + } + + /* flip w-coordinate of midpoint (i.e. unpaired point on w) */ + if (isOdd) { + w = (numW / 2); + lattice_flip_point_value(lt, u, v, w, mid, axis); + } + } + } + } + break; + + default: /* shouldn't happen, but just in case */ + break; + } + + /* updates */ + DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + +void LATTICE_OT_flip(wmOperatorType *ot) +{ + static EnumPropertyItem flip_items[] = { + {LATTICE_FLIP_U, "U", 0, "U (X) Axis", ""}, + {LATTICE_FLIP_V, "V", 0, "V (Y) Axis", ""}, + {LATTICE_FLIP_W, "W", 0, "W (Z) Axis", ""}, + {0, NULL, 0, NULL, NULL}}; + + /* identifiers */ + ot->name = "Flip (Distortion Free)"; + ot->description = "Mirror all control points without inverting the lattice deform"; + ot->idname = "LATTICE_OT_flip"; + + /* api callbacks */ + ot->poll = ED_operator_editlattice; + ot->invoke = WM_menu_invoke; + ot->exec = lattice_flip_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "axis", flip_items, LATTICE_FLIP_U, "Flip Axis", "Coordinates along this axis get flipped"); +} + /****************************** 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 +572,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 +591,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_modifier.c b/source/blender/editors/object/object_modifier.c index d75ef78fc4c..02070506937 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -1242,7 +1242,7 @@ static int multires_reshape_exec(bContext *C, wmOperator *op) CTX_DATA_END; if (!secondob) { - BKE_report(op->reports, RPT_ERROR, "Second selected mesh object require to copy shape from"); + BKE_report(op->reports, RPT_ERROR, "Second selected mesh object required to copy shape from"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/object/object_ops.c b/source/blender/editors/object/object_ops.c index fa40d579e2b..b6d3594c826 100644 --- a/source/blender/editors/object/object_ops.c +++ b/source/blender/editors/object/object_ops.c @@ -178,6 +178,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_select); WM_operatortype_append(OBJECT_OT_vertex_group_deselect); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_linked); + WM_operatortype_append(OBJECT_OT_vertex_group_transfer_weight); WM_operatortype_append(OBJECT_OT_vertex_group_copy_to_selected); WM_operatortype_append(OBJECT_OT_vertex_group_copy); WM_operatortype_append(OBJECT_OT_vertex_group_normalize); @@ -188,6 +189,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(OBJECT_OT_vertex_group_levels); WM_operatortype_append(OBJECT_OT_vertex_group_blend); WM_operatortype_append(OBJECT_OT_vertex_group_clean); + WM_operatortype_append(OBJECT_OT_vertex_group_limit_total); WM_operatortype_append(OBJECT_OT_vertex_group_mirror); WM_operatortype_append(OBJECT_OT_vertex_group_set_active); WM_operatortype_append(OBJECT_OT_vertex_group_sort); @@ -209,6 +211,7 @@ void ED_operatortypes_object(void) WM_operatortype_append(LATTICE_OT_select_all); WM_operatortype_append(LATTICE_OT_make_regular); + WM_operatortype_append(LATTICE_OT_flip); WM_operatortype_append(OBJECT_OT_group_add); WM_operatortype_append(OBJECT_OT_group_link); @@ -422,6 +425,8 @@ void ED_keymap_object(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "OBJECT_OT_vertex_parent_set", PKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "LATTICE_OT_flip", FKEY, KM_PRESS, KM_CTRL, 0); + /* menus */ WM_keymap_add_menu(keymap, "VIEW3D_MT_hook", HKEY, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index 446c0a51ed5..447ba29e203 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -423,29 +423,92 @@ void OBJECT_OT_proxy_make(wmOperatorType *ot) /********************** Clear Parent Operator ******************* */ +typedef enum eObClearParentTypes { + CLEAR_PARENT_ALL = 0, + CLEAR_PARENT_KEEP_TRANSFORM, + CLEAR_PARENT_INVERSE +} eObClearParentTypes; + EnumPropertyItem prop_clear_parent_types[] = { - {0, "CLEAR", 0, "Clear Parent", ""}, - {1, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, - {2, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, + {CLEAR_PARENT_ALL, "CLEAR", 0, "Clear Parent", ""}, + {CLEAR_PARENT_KEEP_TRANSFORM, "CLEAR_KEEP_TRANSFORM", 0, "Clear and Keep Transformation", ""}, + {CLEAR_PARENT_INVERSE, "CLEAR_INVERSE", 0, "Clear Parent Inverse", ""}, {0, NULL, 0, NULL, NULL} }; -void ED_object_parent_clear(Object *ob, int type) +/* Helper for ED_object_parent_clear() - Remove deform-modifiers associated with parent */ +static void object_remove_parent_deform_modifiers(Object *ob, const Object *par) { + if (ELEM3(par->type, OB_ARMATURE, OB_LATTICE, OB_CURVE)) { + ModifierData *md, *mdn; + + /* assume that we only need to remove the first instance of matching deform modifier here */ + for (md = ob->modifiers.first; md; md = mdn) { + short free = FALSE; + + mdn = md->next; + + /* need to match types (modifier + parent) and references */ + if ((md->type == eModifierType_Armature) && (par->type == OB_ARMATURE)) { + ArmatureModifierData *amd = (ArmatureModifierData *)md; + if (amd->object == par) { + free = TRUE; + } + } + else if ((md->type == eModifierType_Lattice) && (par->type == OB_LATTICE)) { + LatticeModifierData *lmd = (LatticeModifierData *)md; + if (lmd->object == par) { + free = TRUE; + } + } + else if ((md->type == eModifierType_Curve) && (par->type == OB_CURVE)) { + CurveModifierData *cmd = (CurveModifierData *)md; + if (cmd->object == par) { + free = TRUE; + } + } + + /* free modifier if match */ + if (free) { + BLI_remlink(&ob->modifiers, md); + modifier_free(md); + } + } + } +} +void ED_object_parent_clear(Object *ob, int type) +{ if (ob->parent == NULL) return; + + switch (type) { + case CLEAR_PARENT_ALL: + { + /* for deformers, remove corresponding modifiers to prevent a large number of modifiers building up */ + object_remove_parent_deform_modifiers(ob, ob->parent); + + /* clear parenting relationship completely */ + ob->parent = NULL; + } + break; - if (type == 0) { - ob->parent = NULL; - } - else if (type == 1) { - ob->parent = NULL; - BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); - } - else if (type == 2) - unit_m4(ob->parentinv); + case CLEAR_PARENT_KEEP_TRANSFORM: + { + /* remove parent, and apply the parented transform result as object's local transforms */ + ob->parent = NULL; + BKE_object_apply_mat4(ob, ob->obmat, TRUE, FALSE); + } + break; + case CLEAR_PARENT_INVERSE: + { + /* object stays parented, but the parent inverse (i.e. offset from parent to retain binding state) is cleared */ + unit_m4(ob->parentinv); + } + break; + } + ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME; } @@ -606,23 +669,38 @@ int ED_object_parent_set(ReportList *reports, Main *bmain, Scene *scene, Object ob->partype = PAROBJECT; /* note, dna define, not operator property */ //ob->partype= PARSKEL; /* note, dna define, not operator property */ - /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses */ + /* BUT, to keep the deforms, we need a modifier, and then we need to set the object that it uses + * - We need to ensure that the modifier we're adding doesn't already exist, so we check this by + * assuming that the parent is selected too... + */ // XXX currently this should only happen for meshes, curves, surfaces, and lattices - this stuff isn't available for metas yet if (ELEM5(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { ModifierData *md; switch (partype) { case PAR_CURVE: /* curve deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); - ((CurveModifierData *)md)->object = par; + if ( modifiers_isDeformedByCurve(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Curve); + if (md) { + ((CurveModifierData *)md)->object = par; + } + } break; case PAR_LATTICE: /* lattice deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); - ((LatticeModifierData *)md)->object = par; + if (modifiers_isDeformedByLattice(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Lattice); + if (md) { + ((LatticeModifierData *)md)->object = par; + } + } break; default: /* armature deform */ - md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); - ((ArmatureModifierData *)md)->object = par; + if (modifiers_isDeformedByArmature(ob) != par) { + md = ED_object_modifier_add(reports, bmain, scene, ob, NULL, eModifierType_Armature); + if (md) { + ((ArmatureModifierData *)md)->object = par; + } + } break; } } diff --git a/source/blender/editors/object/object_shapekey.c b/source/blender/editors/object/object_shapekey.c index cfd4945688b..86a55a9b278 100644 --- a/source/blender/editors/object/object_shapekey.c +++ b/source/blender/editors/object/object_shapekey.c @@ -162,15 +162,15 @@ static int object_shape_key_mirror(bContext *C, Object *ob) kb = BLI_findlink(&key->block, ob->shapenr - 1); if (kb) { - int i1, i2; - float *fp1, *fp2; - float tvec[3]; char *tag_elem = MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror"); if (ob->type == OB_MESH) { Mesh *me = ob->data; MVert *mv; + int i1, i2; + float *fp1, *fp2; + float tvec[3]; mesh_octree_table(ob, NULL, NULL, 's'); diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c index 9129d651d4d..4c95884a51a 100644 --- a/source/blender/editors/object/object_transform.c +++ b/source/blender/editors/object/object_transform.c @@ -217,7 +217,7 @@ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op, /* sanity checks */ if (ELEM(NULL, clear_func, default_ksName)) { - BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name"); + BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform function or Keying Set Name"); return OPERATOR_CANCELLED; } @@ -381,8 +381,8 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); - float rsmat[3][3], tmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; - int a, change = 1; + float rsmat[3][3], obmat[3][3], iobmat[3][3], mat[4][4], scale; + int change = 1; /* first check if we can execute */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) @@ -417,7 +417,8 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo cu = ob->data; if (!(cu->flag & CU_3D) && (apply_rot || apply_loc)) { - BKE_report(reports, RPT_ERROR, "Neither rotation nor location could be applied to a 2d curve, doing nothing"); + BKE_report(reports, RPT_ERROR, + "Neither rotation nor location could be applied to a 2D curve, doing nothing"); change = 0; } if (cu->key) { @@ -464,6 +465,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo copy_v3_v3(mat[3], ob->loc); if (!(apply_scale && apply_rot)) { + float tmat[3][3]; /* correct for scale and rotation that is still applied */ BKE_object_to_mat3(ob, obmat); invert_m3_m3(iobmat, obmat); @@ -476,6 +478,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo if (ob->type == OB_MESH) { Mesh *me = ob->data; MVert *mvert; + int a; if (apply_scale) multiresModifier_scale_disp(scene, ob); @@ -518,6 +521,7 @@ static int apply_objects_internal(bContext *C, ReportList *reports, int apply_lo Nurb *nu; BPoint *bp; BezTriple *bezt; + int a; scale = mat3_to_scale(rsmat); @@ -896,6 +900,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* offset other selected objects */ if (do_inverse_offset && (centermode != GEOMETRY_TO_ORIGIN)) { + CollectionPointerLink *ctx_link_other; + /* was the object data modified * note: the functions above must set 'cent' */ copy_v3_v3(centn, cent); @@ -910,8 +916,16 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ignore_parent_tx(bmain, scene, ob); /* other users? */ - CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) + //CTX_DATA_BEGIN (C, Object *, ob_other, selected_editable_objects) + //{ + + /* use existing context looper */ + for (ctx_link_other = ctx_data_list.first; + ctx_link_other; + ctx_link_other = ctx_link_other->next) { + Object *ob_other = ctx_link_other->ptr.data; + if ((ob_other->flag & OB_DONE) == 0 && ((ob->data && (ob->data == ob_other->data)) || (ob->dup_group == ob_other->dup_group && @@ -931,7 +945,7 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) ignore_parent_tx(bmain, scene, ob_other); } } - CTX_DATA_END; + //CTX_DATA_END; } } } @@ -948,9 +962,9 @@ static int object_origin_set_exec(bContext *C, wmOperator *op) /* Warn if any errors occurred */ if (tot_lib_error + tot_multiuser_arm_error) { - BKE_reportf(op->reports, RPT_WARNING, "%i Object(s) Not Centered, %i Changed:", tot_lib_error + tot_multiuser_arm_error, tot_change); + BKE_reportf(op->reports, RPT_WARNING, "%i object(s) not centered, %i changed:", tot_lib_error + tot_multiuser_arm_error, tot_change); if (tot_lib_error) - BKE_reportf(op->reports, RPT_WARNING, "|%i linked library objects", tot_lib_error); + BKE_reportf(op->reports, RPT_WARNING, "|%i linked library object(s)", tot_lib_error); if (tot_multiuser_arm_error) BKE_reportf(op->reports, RPT_WARNING, "|%i multiuser armature object(s)", tot_multiuser_arm_error); } @@ -962,8 +976,10 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) { static EnumPropertyItem prop_set_center_types[] = { {GEOMETRY_TO_ORIGIN, "GEOMETRY_ORIGIN", 0, "Geometry to Origin", "Move object geometry to object origin"}, - {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry", "Move object origin to center of object geometry"}, - {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor", "Move object origin to position of the 3d cursor"}, + {ORIGIN_TO_GEOMETRY, "ORIGIN_GEOMETRY", 0, "Origin to Geometry", + "Move object origin to center of object geometry"}, + {ORIGIN_TO_CURSOR, "ORIGIN_CURSOR", 0, "Origin to 3D Cursor", + "Move object origin to position of the 3D cursor"}, {0, NULL, 0, NULL, NULL} }; @@ -975,7 +991,7 @@ void OBJECT_OT_origin_set(wmOperatorType *ot) /* identifiers */ ot->name = "Set Origin"; - ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3d cursor"; + ot->description = "Set the object's origin, by either moving the data, or set to center of data, or use 3D cursor"; ot->idname = "OBJECT_OT_origin_set"; /* api callbacks */ diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index b31d2b8b076..1be09847ef2 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -20,7 +20,7 @@ * * The Original Code is: all of this file. * - * Contributor(s): none yet. + * Contributor(s): Ove M Henriksen. * * ***** END GPL LICENSE BLOCK ***** */ @@ -29,7 +29,6 @@ * \ingroup edobj */ - #include <string.h> #include <stddef.h> #include <math.h> @@ -83,6 +82,19 @@ static void vgroup_delete_edit_mode(Object *ob, bDeformGroup *defgroup); static void vgroup_delete_object_mode(Object *ob, bDeformGroup *dg); static void vgroup_delete_all(Object *ob); +static int vertex_group_use_vert_sel(Object *ob) +{ + if (ob->mode == OB_MODE_EDIT) { + return TRUE; + } + else if (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) { + return TRUE; + } + else { + return FALSE; + } +} + static Lattice *vgroup_edit_lattice(Object *ob) { Lattice *lt = ob->data; @@ -377,6 +389,332 @@ int ED_vgroup_copy_array(Object *ob, Object *ob_from) return 1; } +/***********************Start weight transfer (WT)*********************************/ + +typedef enum WT_VertexGroupMode { + WT_REPLACE_ACTIVE_VERTEX_GROUP = 1, + WT_REPLACE_ALL_VERTEX_GROUPS = 2 +} WT_VertexGroupMode; + +typedef enum WT_Method { + WT_BY_INDEX = 1, + WT_BY_NEAREST_VERTEX = 2, + WT_BY_NEAREST_FACE = 3, + WT_BY_NEAREST_VERTEX_IN_FACE = 4 +} WT_Method; + +typedef enum WT_ReplaceMode { + WT_REPLACE_ALL_WEIGHTS = 1, + WT_REPLACE_EMPTY_WEIGHTS = 2, +} WT_ReplaceMode; + +static EnumPropertyItem WT_vertex_group_mode_item[] = { + {WT_REPLACE_ACTIVE_VERTEX_GROUP, "WT_REPLACE_ACTIVE_VERTEX_GROUP", 1, "Active", "Transfer active vertex group from selected to active mesh."}, + {WT_REPLACE_ALL_VERTEX_GROUPS, "WT_REPLACE_ALL_VERTEX_GROUPS", 1, "All", "Transfer all vertex groups from selected to active mesh."}, + {0, NULL, 0, NULL, NULL} +}; + +static EnumPropertyItem WT_method_item[] = { + {WT_BY_INDEX, "WT_BY_INDEX", 1, "Vertex index", "Copy for identical meshes."}, + {WT_BY_NEAREST_VERTEX, "WT_BY_NEAREST_VERTEX", 1, "Nearest vertex", "Copy weight from closest vertex."}, + {WT_BY_NEAREST_FACE, "WT_BY_NEAREST_FACE", 1, "Nearest face", "Barycentric interpolation from nearest face."}, + {WT_BY_NEAREST_VERTEX_IN_FACE, "WT_BY_NEAREST_VERTEX_IN_FACE", 1, "Nearest vertex in face", "Copy weight from closest vertex in nearest face."}, + {0, NULL, 0, NULL, NULL} +}; + +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."}, + {0, NULL, 0, NULL, NULL} +}; + +/*copy weight*/ +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: + *r_weight_dst = weight_src; + break; + + case WT_REPLACE_EMPTY_WEIGHTS: + if (*r_weight_dst == 0.0f) { + *r_weight_dst = weight_src; + } + break; + + default: + BLI_assert(0); + break; + } +} + +/* could be exposed externally */ +static int ed_vgroup_transfer_weight(Object *ob_dst, Object *ob_src, bDeformGroup *dg_src, Scene *scene, + WT_Method method, WT_ReplaceMode replace_mode, wmOperator *op) +{ + bDeformGroup *dg_dst; + Mesh *me_dst, *me_src; + DerivedMesh *dmesh_src; + BVHTreeFromMesh tree_mesh_vertices_src, tree_mesh_faces_src = {NULL}; + MDeformVert **dv_array_src, **dv_array_dst, **dv_src, **dv_dst; + MVert *mv_dst, *mv_src; + MFace *mface_src, *mf; + BVHTreeNearest nearest; + MDeformWeight *dw_dst, *dw_src; + 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)) { + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_src->name)); + ED_vgroup_add_name(ob_dst, dg_src->name); + } + + /* get destination deformgroup */ + dg_dst = defgroup_find_name(ob_dst, dg_src->name); + + /* get meshes */ + dmesh_src = mesh_get_derived_deform(scene, ob_src, CD_MASK_BAREMESH); + me_dst = ob_dst->data; + me_src = ob_src->data; + + /* sanity check */ + if (!me_src->dvert) { + BKE_report(op->reports, RPT_ERROR, "Transfer failed (source mesh does not have any vertex groups)"); + return 0; + } + + /* create data in memory when nothing there */ + if (!me_dst->dvert) ED_vgroup_data_create(ob_dst->data); + + /* 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, use_vert_sel); + + /* get indexes of vertex groups */ + index_src = BLI_findindex(&ob_src->defbase, dg_src); + index_dst = BLI_findindex(&ob_dst->defbase, dg_dst); + + /* get vertices */ + mv_dst = me_dst->mvert; + mv_src = dmesh_src->getVertArray(dmesh_src); + + /* prepare transformation matrix */ + invert_m4_m4(ob_src->imat, ob_src->obmat); + mult_m4_m4m4(tmp_mat, ob_src->imat, ob_dst->obmat); + + /* clear weights */ + if (replace_mode == WT_REPLACE_ALL_WEIGHTS) { + 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); + } + } + + switch (method) { + + case WT_BY_INDEX: + /* check if indices are matching, delete and return if not */ + if (ob_dst == ob_src || dv_tot_dst == 0 || dv_tot_dst != dv_tot_src || + dv_array_src == NULL || dv_array_dst == NULL) + { + ED_vgroup_delete(ob_dst, defgroup_find_name(ob_dst, dg_dst->name)); + if (dv_array_src) MEM_freeN(dv_array_src); + if (dv_array_dst) MEM_freeN(dv_array_dst); + dmesh_src->release(dmesh_src); + BKE_report(op->reports, RPT_ERROR, "Transfer failed (indices are not matching)"); + return 0; + } + + /* 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++, 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(&dw_dst->weight, dw_src->weight, replace_mode); + } + } + break; + + case WT_BY_NEAREST_VERTEX: + /* make node tree */ + bvhtree_from_mesh_verts(&tree_mesh_vertices_src, dmesh_src, FLT_EPSILON, 2, 6); + + /* 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. */ + nearest.index = -1; + + /* transform into target space */ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /* node tree accelerated search for closest vetex */ + BLI_bvhtree_find_nearest(tree_mesh_vertices_src.tree, tmp_co, + &nearest, tree_mesh_vertices_src.nearest_callback, &tree_mesh_vertices_src); + + /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + 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(&dw_dst->weight, dw_src->weight, replace_mode); + } + } + + /* free memory */ + free_bvhtree_from_mesh(&tree_mesh_vertices_src); + break; + + case WT_BY_NEAREST_FACE: + /* get faces */ + DM_ensure_tessface(dmesh_src); + mface_src = dmesh_src->getTessFaceArray(dmesh_src); + + /* make node tree */ + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); + + /* 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. */ + nearest.index = -1; + + /* transform into target space */ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /* node tree accelerated search for closest face */ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + index_nearest = nearest.index; + + /* project onto face */ + mf = &mface_src[index_nearest]; + normal_tri_v3(normal, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co); + project_v3_plane(tmp_co, normal, mv_src[mf->v1].co); + + /* interpolate weights over face*/ + f_index = mf->v4 ? 3 : 2; + if (f_index == 3) { + interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, mv_src[mf->v4].co, tmp_co); + } + else { + interp_weights_face_v3(tmp_weight, mv_src[mf->v1].co, mv_src[mf->v2].co, mv_src[mf->v3].co, NULL, tmp_co); + } + + /* get weights from face*/ + weight = 0; + do { + v_index = (&mf->v1)[f_index]; + weight += tmp_weight[f_index] * defvert_find_weight(dv_array_src[v_index], index_src); + } while (f_index--); + + /* 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(&dw_dst->weight, weight, replace_mode); + } + } + + /* free memory */ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + break; + + case WT_BY_NEAREST_VERTEX_IN_FACE: + /* get faces */ + DM_ensure_tessface(dmesh_src); + mface_src = dmesh_src->getTessFaceArray(dmesh_src); + + /* make node tree */ + bvhtree_from_mesh_faces(&tree_mesh_faces_src, dmesh_src, FLT_EPSILON, 2, 6); + + /* 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. */ + nearest.index = -1; + + /* transform into target space */ + mul_v3_m4v3(tmp_co, tmp_mat, mv_dst->co); + + /* node tree accelerated search for closest face */ + BLI_bvhtree_find_nearest(tree_mesh_faces_src.tree, tmp_co, + &nearest, tree_mesh_faces_src.nearest_callback, &tree_mesh_faces_src); + index_nearest = nearest.index; + + /* get distances */ + mf = &mface_src[index_nearest]; + dist_v1 = len_squared_v3v3(tmp_co, mv_src[mf->v1].co); + dist_v2 = len_squared_v3v3(tmp_co, mv_src[mf->v2].co); + dist_v3 = len_squared_v3v3(tmp_co, mv_src[mf->v3].co); + + /* get closest vertex */ + f_index = mf->v4 ? 3 : 2; + if (dist_v1 < dist_v2 && dist_v1 < dist_v3) index_nearest_vertex = mf->v1; + else if (dist_v2 < dist_v3) index_nearest_vertex = mf->v2; + else index_nearest_vertex = mf->v3; + if (f_index == 3) { + dist_v4 = len_squared_v3v3(tmp_co, mv_src[mf->v4].co); + if (dist_v4 < dist_v1 && dist_v4 < dist_v2 && dist_v4 < dist_v3) { + index_nearest_vertex = mf->v4; + } + } + + /* copy weight that are not NULL including weight value 0. Existing target weights are overwritten prior to this in relevant cases. */ + 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(&dw_dst->weight, dw_src->weight, replace_mode); + } + } + + /* free memory */ + free_bvhtree_from_mesh(&tree_mesh_faces_src); + break; + + default: + BLI_assert(0); + break; + } + + /*free memory*/ + if (dv_array_src) MEM_freeN(dv_array_src); + if (dv_array_dst) MEM_freeN(dv_array_dst); + dmesh_src->release(dmesh_src); + + return 1; +} + +/***********************End weight transfer (WT)***********************************/ /* for Mesh in Object mode */ /* allows editmode for Lattice */ @@ -580,7 +918,6 @@ void ED_vgroup_select_by_name(Object *ob, const char *name) static void vgroup_select_verts(Object *ob, int select) { const int def_nr = ob->actdef - 1; - MDeformVert *dv; if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -596,7 +933,7 @@ static void vgroup_select_verts(Object *ob, int select) BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (!BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) { - dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); + MDeformVert *dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); if (defvert_find_index(dv, def_nr)) { BM_vert_select_set(em->bm, eve, select); } @@ -633,6 +970,7 @@ static void vgroup_select_verts(Object *ob, int select) Lattice *lt = vgroup_edit_lattice(ob); if (lt->dvert) { + MDeformVert *dv; BPoint *bp; int a, tot; @@ -704,7 +1042,7 @@ static void vgroup_normalize(Object *ob) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1109,7 +1447,7 @@ static void vgroup_levels(Object *ob, float offset, float gain) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1143,7 +1481,7 @@ static void vgroup_normalize_all(Object *ob, int lock_active) int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (lock_active && !BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1221,7 +1559,7 @@ static void vgroup_invert(Object *ob, const short auto_assign, const short auto_ MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1389,13 +1727,119 @@ static void vgroup_blend(Object *ob, const float fac) } } +static int inv_cmp_mdef_vert_weights(const void *a1, const void *a2) +{ + /* qsort sorts in ascending order. We want descending order to save a memcopy + * so this compare function is inverted from the standard greater than comparison qsort needs. + * A normal compare function is called with two pointer arguments and should return an integer less than, equal to, + * or greater than zero corresponding to whether its first argument is considered less than, equal to, + * or greater than its second argument. This does the opposite. */ + const struct MDeformWeight *dw1 = a1, *dw2 = a2; + + if (dw1->weight < dw2->weight) return 1; + else if (dw1->weight > dw2->weight) return -1; + else if (&dw1 < &dw2) return 1; /* compare addresses so we have a stable sort algorithm */ + else return -1; +} + +/* Used for limiting the number of influencing bones per vertex when exporting + * skinned meshes. if all_deform_weights is True, limit all deform modifiers + * to max_weights regardless of type, otherwise, only limit the number of influencing bones per vertex*/ +static int vertex_group_limit_total(Object *ob, + const int max_weights, + const int all_deform_weights) +{ + MDeformVert *dv, **dvert_array = NULL; + int i, dvert_tot = 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); + int is_change = FALSE; + + ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); + + if (dvert_array) { + int defbase_tot = BLI_countlist(&ob->defbase); + const char *vgroup_validmap = (all_deform_weights == FALSE) ? + BKE_objdef_validmap_get(ob, defbase_tot) : + NULL; + int num_to_drop = 0; + + /* only the active group */ + for (i = 0; i < dvert_tot; i++) { + + /* in case its not selected */ + if (!(dv = dvert_array[i])) { + continue; + } + + if (all_deform_weights) { + /* keep only the largest weights, discarding the rest + * qsort will put array in descending order because of invCompare function */ + num_to_drop = dv->totweight - max_weights; + if (num_to_drop > 0) { + qsort(dv->dw, dv->totweight, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights); + dv->dw = MEM_reallocN(dv->dw, sizeof(MDeformWeight) * max_weights); + dv->totweight = max_weights; + is_change = TRUE; + } + } + else { + MDeformWeight *dw_temp; + int bone_count = 0, non_bone_count = 0; + int j; + /* only consider vgroups with bone modifiers attached (in vgroup_validmap) */ + + num_to_drop = dv->totweight - max_weights; + + /* first check if we even need to test further */ + if (num_to_drop > 0) { + /* re-pack dw array so that non-bone weights are first, bone-weighted verts at end + * sort the tail, then copy only the truncated array back to dv->dw */ + dw_temp = MEM_mallocN(sizeof(MDeformWeight) * (dv->totweight), __func__); + bone_count = 0; non_bone_count = 0; + for (j = 0; j < dv->totweight; j++) { + BLI_assert(dv->dw[j].def_nr < defbase_tot); + if (!vgroup_validmap[(dv->dw[j]).def_nr]) { + dw_temp[non_bone_count] = dv->dw[j]; + non_bone_count += 1; + } + else { + dw_temp[dv->totweight - 1 - bone_count] = dv->dw[j]; + bone_count += 1; + } + } + BLI_assert(bone_count + non_bone_count == dv->totweight); + num_to_drop = bone_count - max_weights; + if (num_to_drop > 0) { + qsort(&dw_temp[non_bone_count], bone_count, sizeof(MDeformWeight), inv_cmp_mdef_vert_weights); + dv->totweight -= num_to_drop; + /* Do we want to clean/normalize here? */ + MEM_freeN(dv->dw); + dv->dw = MEM_reallocN(dw_temp, sizeof(MDeformWeight) * dv->totweight); + is_change = TRUE; + } + else { + MEM_freeN(dw_temp); + } + } + } + } + MEM_freeN(dvert_array); + + if (vgroup_validmap) { + MEM_freeN((void *)vgroup_validmap); + } + } + + return is_change; +} + static void vgroup_clean(Object *ob, const float epsilon, int keep_single) { MDeformWeight *dw; MDeformVert *dv, **dvert_array = NULL; int i, dvert_tot = 0; const int def_nr = ob->actdef - 1; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); if (!BLI_findlink(&ob->defbase, def_nr)) { return; @@ -1431,7 +1875,7 @@ static void vgroup_clean_all(Object *ob, const float epsilon, const int keep_sin { MDeformVert **dvert_array = NULL; int i, dvert_tot = 0; - const int use_vert_sel = (ob->type == OB_MESH && ((Mesh *)ob->data)->editflag & ME_EDIT_VERT_SEL) != 0; + const int use_vert_sel = vertex_group_use_vert_sel(ob); ED_vgroup_give_parray(ob->data, &dvert_array, &dvert_tot, use_vert_sel); @@ -2007,7 +2451,6 @@ static void vgroup_delete_all(Object *ob) /* only in editmode */ static void vgroup_assign_verts(Object *ob, const float weight) { - MDeformVert *dv; const int def_nr = ob->actdef - 1; if (!BLI_findlink(&ob->defbase, def_nr)) @@ -2027,6 +2470,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) /* Go through the list of editverts and assign them */ BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { + MDeformVert *dv; MDeformWeight *dw; dv = CustomData_bmesh_get(&em->bm->vdata, eve->head.data, CD_MDEFORMVERT); /* can be NULL */ dw = defvert_verify_index(dv, def_nr); @@ -2061,6 +2505,7 @@ static void vgroup_assign_verts(Object *ob, const float weight) } else if (ob->type == OB_LATTICE) { Lattice *lt = vgroup_edit_lattice(ob); + MDeformVert *dv; BPoint *bp; int a, tot; @@ -2665,6 +3110,47 @@ void OBJECT_OT_vertex_group_clean(wmOperatorType *ot) "Keep verts assigned to at least one group when cleaning"); } +static int vertex_group_limit_total_exec(bContext *C, wmOperator *op) +{ + Object *ob = ED_object_context(C); + + const int limit = RNA_int_get(op->ptr, "limit"); + const int all_deform_weights = RNA_boolean_get(op->ptr, "all_deform_weights"); + + if (vertex_group_limit_total(ob, limit, all_deform_weights)) { + + DAG_id_tag_update(&ob->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob->data); + + return OPERATOR_FINISHED; + } + else { + BKE_report(op->reports, RPT_WARNING, "No vertex groups limited"); + + /* note, would normally return cancelled, except we want the redo + * UI to show up for users to change */ + return OPERATOR_FINISHED; + } +} + +void OBJECT_OT_vertex_group_limit_total(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Limit Number of Weights per Vertex"; + ot->idname = "OBJECT_OT_vertex_group_limit_total"; + ot->description = "Limits deform weights associated with a vertex to a specified number by removing lowest weights"; + + /* api callbacks */ + ot->poll = vertex_group_poll; + ot->exec = vertex_group_limit_total_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_int(ot->srna, "limit", 4, 1, 32, "Limit", "Maximum number of deform weights", 1, 32); + RNA_def_boolean(ot->srna, "all_deform_weights", FALSE, "All Deform Weights", "Cull all deform weights, not just bones"); +} static int vertex_group_mirror_exec(bContext *C, wmOperator *op) { @@ -2762,14 +3248,13 @@ static int vertex_group_copy_to_selected_exec(bContext *C, wmOperator *op) if ((change == 0 && fail == 0) || fail) { BKE_reportf(op->reports, RPT_ERROR, - "Copy to VGroups to Selected warning done %d, failed %d, object data must have matching indices", + "Copy VGroups to Selected warning, %d done, %d failed (object data must have matching indices)", change, fail); } return OPERATOR_FINISHED; } - void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) { /* identifiers */ @@ -2785,6 +3270,86 @@ void OBJECT_OT_vertex_group_copy_to_selected(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } +static int vertex_group_transfer_weight_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *ob_act = CTX_data_active_object(C); + bDeformGroup *dg_src; + int fail = 0; + + WT_VertexGroupMode vertex_group_mode = RNA_enum_get(op->ptr, "WT_vertex_group_mode"); + WT_Method method = RNA_enum_get(op->ptr, "WT_method"); + WT_ReplaceMode replace_mode = RNA_enum_get(op->ptr, "WT_replace_mode"); + + /* Macro to loop through selected objects and perform operation depending on function, option and method */ + CTX_DATA_BEGIN (C, Object *, ob_slc, selected_editable_objects) + { + + if (ob_act != ob_slc && ob_slc->defbase.first) { + switch (vertex_group_mode) { + + case WT_REPLACE_ACTIVE_VERTEX_GROUP: + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, + BLI_findlink(&ob_slc->defbase, ob_slc->actdef - 1), + scene, method, replace_mode, op)) + { + fail++; + } + break; + + case WT_REPLACE_ALL_VERTEX_GROUPS: + for (dg_src = ob_slc->defbase.first; dg_src; dg_src = dg_src->next) { + if (!ed_vgroup_transfer_weight(ob_act, ob_slc, + dg_src, scene, method, replace_mode, op)) + { + fail++; + } + } + break; + + default: + BLI_assert(0); + break; + } + } + } + + /* Event notifiers for correct display of data */ + DAG_id_tag_update(&ob_slc->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob_slc); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, ob_slc->data); + + CTX_DATA_END; + + if (fail != 0) { + return OPERATOR_CANCELLED; + } + else { + return OPERATOR_FINISHED; + } +} + +/* transfers weight from active to selected */ +void OBJECT_OT_vertex_group_transfer_weight(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Transfer Weights"; + ot->idname = "OBJECT_OT_vertex_group_transfer_weight"; + ot->description = "Transfer weight paint to active from selected mesh"; + + /* api callbacks */ + ot->poll = vertex_group_poll; + ot->exec = vertex_group_transfer_weight_exec; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "WT_vertex_group_mode", WT_vertex_group_mode_item, 1, "Group", ""); + ot->prop = RNA_def_enum(ot->srna, "WT_method", WT_method_item, 3, "Method", ""); + ot->prop = RNA_def_enum(ot->srna, "WT_replace_mode", WT_replace_mode_item, 1, "Replace", ""); +} + static EnumPropertyItem vgroup_items[] = { {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 70fe87e5c01..467ad5c6ff9 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -73,9 +73,9 @@ static int surface_slot_add_exec(bContext *C, wmOperator *UNUSED(op)) /* set preview for this surface only and set active */ canvas->active_sur = 0; - for (surface=surface->prev; surface; surface=surface->prev) { - surface->flags &= ~MOD_DPAINT_PREVIEW; - canvas->active_sur++; + for (surface = surface->prev; surface; surface = surface->prev) { + surface->flags &= ~MOD_DPAINT_PREVIEW; + canvas->active_sur++; } return OPERATOR_FINISHED; @@ -94,26 +94,26 @@ void DPAINT_OT_surface_slot_add(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) { DynamicPaintModifierData *pmd = NULL; - Object *cObject = ED_object_context(C); + Object *obj_ctx = ED_object_context(C); DynamicPaintCanvasSettings *canvas; DynamicPaintSurface *surface; - int id=0; + int id = 0; /* Make sure we're dealing with a canvas */ - pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint); + pmd = (DynamicPaintModifierData *)modifiers_findByType(obj_ctx, eModifierType_DynamicPaint); if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED; canvas = pmd->canvas; surface = canvas->surfaces.first; /* find active surface and remove it */ - for (; surface; surface=surface->next) { + for (; surface; surface = surface->next) { if (id == canvas->active_sur) { canvas->active_sur -= 1; dynamicPaint_freeSurface(surface); @@ -123,8 +123,8 @@ static int surface_slot_remove_exec(bContext *C, wmOperator *UNUSED(op)) } dynamicPaint_resetPreview(canvas); - DAG_id_tag_update(&cObject->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject); + DAG_id_tag_update(&obj_ctx->id, OB_RECALC_DATA); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, obj_ctx); return OPERATOR_FINISHED; } @@ -142,7 +142,7 @@ void DPAINT_OT_surface_slot_remove(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } static int type_toggle_exec(bContext *C, wmOperator *op) @@ -151,7 +151,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op) Object *cObject = ED_object_context(C); Scene *scene = CTX_data_scene(C); DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(cObject, eModifierType_DynamicPaint); - int type= RNA_enum_get(op->ptr, "type"); + int type = RNA_enum_get(op->ptr, "type"); if (!pmd) return OPERATOR_CANCELLED; @@ -170,7 +170,7 @@ static int type_toggle_exec(bContext *C, wmOperator *op) /* update dependency */ DAG_id_tag_update(&cObject->id, OB_RECALC_DATA); - WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, cObject); + WM_event_add_notifier(C, NC_OBJECT | ND_MODIFIER, cObject); DAG_scene_sort(CTX_data_main(C), scene); return OPERATOR_FINISHED; @@ -190,10 +190,10 @@ void DPAINT_OT_type_toggle(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - prop= RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", ""); + prop = RNA_def_enum(ot->srna, "type", prop_dynamicpaint_type_items, MOD_DYNAMICPAINT_TYPE_CANVAS, "Type", ""); ot->prop = prop; } @@ -203,7 +203,7 @@ static int output_toggle_exec(bContext *C, wmOperator *op) Scene *scene = CTX_data_scene(C); DynamicPaintSurface *surface; DynamicPaintModifierData *pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); - int output= RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */ + int output = RNA_enum_get(op->ptr, "output"); /* currently only 1/0 */ if (!pmd || !pmd->canvas) return OPERATOR_CANCELLED; surface = get_activeSurface(pmd->canvas); @@ -258,7 +258,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot) ot->poll = ED_operator_object_active_editable; /* flags */ - ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO; + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ ot->prop = RNA_def_enum(ot->srna, "output", prop_output_toggle_types, 0, "Output Toggle", ""); @@ -274,7 +274,7 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot) static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surface, Object *cObject) { DynamicPaintCanvasSettings *canvas = surface->canvas; - Scene *scene= CTX_data_scene(C); + Scene *scene = CTX_data_scene(C); wmWindow *win = CTX_wm_window(C); int frame = 1; int frames; @@ -291,7 +291,7 @@ static int dynamicPaint_bakeImageSequence(bContext *C, DynamicPaintSurface *surf if (!dynamicPaint_createUVSurface(surface)) return 0; /* Loop through selected frames */ - for (frame=surface->start_frame; frame<=surface->end_frame; frame++) { + for (frame = surface->start_frame; frame <= surface->end_frame; frame++) { float progress = (frame - surface->start_frame) / (float)frames * 100; surface->current_frame = frame; @@ -346,7 +346,6 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) Object *ob = ED_object_context(C); int status = 0; double timer = PIL_check_seconds_timer(); - char result_str[80]; DynamicPaintSurface *surface; /* @@ -354,14 +353,14 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) */ pmd = (DynamicPaintModifierData *)modifiers_findByType(ob, eModifierType_DynamicPaint); if (!pmd) { - BKE_report(op->reports, RPT_ERROR, "Bake Failed: No Dynamic Paint modifier found."); + BKE_report(op->reports, RPT_ERROR, "Bake failed: no Dynamic Paint modifier found"); return 0; } /* Make sure we're dealing with a canvas */ canvas = pmd->canvas; if (!canvas) { - BKE_report(op->reports, RPT_ERROR, "Bake Failed: Invalid Canvas."); + BKE_report(op->reports, RPT_ERROR, "Bake failed: invalid canvas"); return 0; } surface = get_activeSurface(canvas); @@ -381,23 +380,20 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) /* Bake was successful: * Report for ended bake and how long it took */ if (status) { - /* Format time string */ + /* Format time string */ char time_str[30]; double time = PIL_check_seconds_timer() - timer; BLI_timestr(time, time_str); /* Show bake info */ - BLI_snprintf(result_str, sizeof(result_str), "Bake Complete! (%s)", time_str); - BKE_report(op->reports, RPT_INFO, result_str); + BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%s)", time_str); } else { - if (strlen(canvas->error)) { /* If an error occured */ - BLI_snprintf(result_str, sizeof(result_str), "Bake Failed: %s", canvas->error); - BKE_report(op->reports, RPT_ERROR, result_str); + if (strlen(canvas->error)) { /* If an error occurred */ + BKE_reportf(op->reports, RPT_ERROR, "Bake failed: %s", canvas->error); } - else { /* User canceled the bake */ - BLI_strncpy(result_str, "Baking Cancelled!", sizeof(result_str)); - BKE_report(op->reports, RPT_WARNING, result_str); + else { /* User canceled the bake */ + BKE_report(op->reports, RPT_WARNING, "Baking canceled!"); } } diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index ee2b5e08520..7343a44470a 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -411,7 +411,7 @@ static int key_test_depth(PEData *data, const float co[3], const int screen_co[2 /* used to calculate here but all callers have the screen_co already, so pass as arg */ #if 0 if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -448,7 +448,7 @@ static int key_inside_circle(PEData *data, float rad, const float co[3], float * int screen_co[2]; /* TODO, should this check V3D_PROJ_TEST_CLIP_BB too? */ - if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -473,7 +473,7 @@ static int key_inside_rect(PEData *data, const float co[3]) { int screen_co[2]; - if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(data->vc.ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) != V3D_PROJ_RET_OK) { return 0; } @@ -1665,7 +1665,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short LOOP_KEYS { copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && key_test_depth(&data, co, screen_co)) { @@ -1685,7 +1685,7 @@ int PE_lasso_select(bContext *C, const int mcords[][2], const short moves, short copy_v3_v3(co, key->co); mul_m4_v3(mat, co); - if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) && + if ((ED_view3d_project_int_global(ar, co, screen_co, V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) && BLI_lasso_is_point_inside(mcords, moves, screen_co[0], screen_co[1], IS_CLIPPED) && key_test_depth(&data, co, screen_co)) { @@ -2414,7 +2414,7 @@ static int remove_doubles_exec(bContext *C, wmOperator *op) if (totremoved == 0) return OPERATOR_CANCELLED; - BKE_reportf(op->reports, RPT_INFO, "Remove %d double particles", totremoved); + BKE_reportf(op->reports, RPT_INFO, "Removed %d double particles", totremoved); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_PARTICLE|NA_EDITED, ob); @@ -2797,7 +2797,7 @@ static void brush_cut(PEData *data, int pa_index) if (edit->points[pa_index].flag & PEP_HIDE) return; - if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) + if (ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) return; rad2= data->rad * data->rad; @@ -2822,7 +2822,7 @@ static void brush_cut(PEData *data, int pa_index) /* calculate path time closest to root that was inside the circle */ for (k=1, key++; k<=keys; k++, key++) { - if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) || + if ((ED_view3d_project_int_global(ar, key->co, screen_co, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) || key_test_depth(data, key->co, screen_co) == 0) { x0 = (float)screen_co[0]; @@ -3989,7 +3989,9 @@ void PE_undo_step(Scene *scene, int step) } else if (step==1) { - if (edit->curundo==NULL || edit->curundo->prev==NULL); + if (edit->curundo==NULL || edit->curundo->prev==NULL) { + /* pass */ + } else { if (G.debug & G_DEBUG) printf("undo %s\n", edit->curundo->name); edit->curundo= edit->curundo->prev; @@ -3999,7 +4001,9 @@ void PE_undo_step(Scene *scene, int step) else { /* curundo has to remain current situation! */ - if (edit->curundo==NULL || edit->curundo->next==NULL); + if (edit->curundo==NULL || edit->curundo->next==NULL) { + /* pass */ + } else { get_PTCacheUndo(edit, edit->curundo->next); edit->curundo= edit->curundo->next; diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c index 218ae628d3f..bbce94b6215 100644 --- a/source/blender/editors/physics/physics_pointcache.c +++ b/source/blender/editors/physics/physics_pointcache.c @@ -325,9 +325,9 @@ static int ptcache_add_new_exec(bContext *C, wmOperator *UNUSED(op)) for (pid=pidlist.first; pid; pid=pid->next) { if (pid->cache == cache) { - PointCache *cache = BKE_ptcache_add(pid->ptcaches); - cache->step = pid->default_step; - *(pid->cache_ptr) = cache; + PointCache *cache_new = BKE_ptcache_add(pid->ptcaches); + cache_new->step = pid->default_step; + *(pid->cache_ptr) = cache_new; break; } } diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index c08ea2b6429..b61280f14ce 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -80,7 +80,6 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat float *rectf = NULL; int ymin, ymax, xmin, xmax; int rymin, rxmin; - /* unsigned char *rectc; */ /* UNUSED */ /* if renrect argument, we only refresh scanlines */ if (renrect) { @@ -143,11 +142,10 @@ void image_buffer_rect_update(Scene *scene, RenderResult *rr, ImBuf *ibuf, volat imb_addrectImBuf(ibuf); rectf += 4 * (rr->rectx * ymin + xmin); - /* rectc = (unsigned char *)(ibuf->rect + ibuf->x * rymin + rxmin); */ /* UNUSED */ IMB_partial_display_buffer_update(ibuf, rectf, NULL, rr->rectx, rxmin, rymin, &scene->view_settings, &scene->display_settings, - rxmin, rymin, rxmin + xmax, rymin + ymax); + rxmin, rymin, rxmin + xmax, rymin + ymax, TRUE); } /* ****************************** render invoking ***************** */ diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 85ae923f881..1d0e5bb6d44 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -342,7 +342,7 @@ static int screen_opengl_render_init(bContext *C, wmOperator *op) ofs = GPU_offscreen_create(sizex, sizey, err_out); if (!ofs) { - BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer, %s", err_out); + BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer, %s", err_out); return 0; } diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c index 817067422af..694d2302fbd 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); } @@ -818,7 +809,7 @@ static void shader_preview_free(void *customdata) /* get rid of copied world */ BLI_remlink(&pr_main->world, sp->worldcopy); - BKE_world_free_ex(sp->worldcopy, FALSE); + BKE_world_free_ex(sp->worldcopy, TRUE); /* [#32865] - we need to unlink the texture copies, unlike for materials */ properties = IDP_GetProperties((ID *)sp->worldcopy, FALSE); if (properties) { diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c index b1b27e1424a..ebbdc90ab04 100644 --- a/source/blender/editors/render/render_shading.c +++ b/source/blender/editors/render/render_shading.c @@ -1362,7 +1362,11 @@ void TEXTURE_OT_envmap_save(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER; /* no undo since this doesnt modify the env-map */ /* properties */ - prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, "File layout", "Flat array describing the X,Y position of each cube face in the output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] (use -1 to skip a face)", 0.0f, 0.0f); + prop = RNA_def_float_array(ot->srna, "layout", 12, default_envmap_layout, 0.0f, 0.0f, + "File layout", + "Flat array describing the X,Y position of each cube face in the output image, " + "where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " + "(use -1 to skip a face)", 0.0f, 0.0f); RNA_def_property_flag(prop, PROP_HIDDEN); WM_operator_properties_filesel(ot, FOLDERFILE | IMAGEFILE | MOVIEFILE, FILE_SPECIAL, FILE_SAVE, diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c index 08ccf37265b..5b1c03f65df 100644 --- a/source/blender/editors/render/render_update.c +++ b/source/blender/editors/render/render_update.c @@ -74,12 +74,19 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) bScreen *sc; ScrArea *sa; ARegion *ar; + static int recursive_check = FALSE; /* don't do this render engine update if we're updating the scene from * other threads doing e.g. rendering or baking jobs */ if (!BLI_thread_is_main()) return; + /* don't call this recursively for frame updates */ + if(recursive_check) + return; + + recursive_check = TRUE; + C = CTX_create(); CTX_data_main_set(C, bmain); CTX_data_scene_set(C, scene); @@ -114,6 +121,8 @@ void ED_render_scene_update(Main *bmain, Scene *scene, int updated) } CTX_free(C); + + recursive_check = FALSE; } void ED_render_engine_area_exit(ScrArea *sa) @@ -224,8 +233,12 @@ static void material_changed(Main *bmain, Material *ma) /* find node materials using this */ for (parent = bmain->mat.first; parent; parent = parent->id.next) { - if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) ; - else continue; + if (parent->use_nodes && parent->nodetree && nodes_use_material(parent->nodetree, ma)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&parent->id)); @@ -247,9 +260,15 @@ static void texture_changed(Main *bmain, Tex *tex) /* find materials */ for (ma = bmain->mat.first; ma; ma = ma->id.next) { - if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) ; - else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) ; - else continue; + if (mtex_use_tex(ma->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (ma->use_nodes && ma->nodetree && nodes_use_tex(ma->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&ma->id)); @@ -259,18 +278,30 @@ static void texture_changed(Main *bmain, Tex *tex) /* find lamps */ for (la = bmain->lamp.first; la; la = la->id.next) { - if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) ; - else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) ; - else continue; + if (mtex_use_tex(la->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (la->nodetree && nodes_use_tex(la->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&la->id)); } /* find worlds */ for (wo = bmain->world.first; wo; wo = wo->id.next) { - if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) ; - else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) ; - else continue; + if (mtex_use_tex(wo->mtex, MAX_MTEX, tex)) { + /* pass */ + } + else if (wo->nodetree && nodes_use_tex(wo->nodetree, tex)) { + /* pass */ + } + else { + continue; + } BKE_icon_changed(BKE_icon_getid(&wo->id)); } diff --git a/source/blender/editors/screen/area.c b/source/blender/editors/screen/area.c index 01a5304451a..ad9b0f61eb1 100644 --- a/source/blender/editors/screen/area.c +++ b/source/blender/editors/screen/area.c @@ -407,8 +407,12 @@ void region_scissor_winrct(ARegion *ar, rcti *winrct) ar = ar->prev; if (BLI_rcti_isect(winrct, &ar->winrct, NULL)) { - if (ar->flag & RGN_FLAG_HIDDEN) ; - else if (ar->alignment & RGN_SPLIT_PREV) ; + if (ar->flag & RGN_FLAG_HIDDEN) { + /* pass */ + } + else if (ar->alignment & RGN_SPLIT_PREV) { + /* pass */ + } else if (ar->alignment == RGN_OVERLAP_LEFT) { winrct->xmin = ar->winrct.xmax + 1; } @@ -935,20 +939,25 @@ static void region_rect_recursive(ScrArea *sa, ARegion *ar, rcti *remainder, int /* prefsize, for header we stick to exception */ prefsizex = ar->sizex ? ar->sizex : ar->type->prefsizex; - if (ar->regiontype == RGN_TYPE_HEADER) + if (ar->regiontype == RGN_TYPE_HEADER) { prefsizey = ar->type->prefsizey; + } else if (ar->regiontype == RGN_TYPE_UI && sa->spacetype == SPACE_FILE) { prefsizey = UI_UNIT_Y * 2 + (UI_UNIT_Y / 2); } - else + else { prefsizey = ar->sizey ? ar->sizey : ar->type->prefsizey; - - /* hidden is user flag */ - if (ar->flag & RGN_FLAG_HIDDEN) ; - /* XXX floating area region, not handled yet here */ - else if (alignment == RGN_ALIGN_FLOAT) ; - /* remainder is too small for any usage */ + } + + + if (ar->flag & RGN_FLAG_HIDDEN) { + /* hidden is user flag */ + } + else if (alignment == RGN_ALIGN_FLOAT) { + /* XXX floating area region, not handled yet here */ + } else if (rct_fits(remainder, 'v', 1) < 0 || rct_fits(remainder, 'h', 1) < 0) { + /* remainder is too small for any usage */ ar->flag |= RGN_FLAG_TOO_SMALL; } else if (alignment == RGN_ALIGN_NONE) { @@ -1517,7 +1526,7 @@ int ED_area_header_switchbutton(const bContext *C, uiBlock *block, int yco) but = uiDefIconTextButC(block, ICONTEXTROW, 0, ICON_VIEW3D, editortype_pup(), xco, yco, UI_UNIT_X + 10, UI_UNIT_Y, &(sa->butspacetype), 1.0, SPACEICONMAX, 0, 0, - TIP_("Display current editor type (click for menu of available types)")); + TIP_("Display current editor type (click for a menu of available types)")); uiButSetFunc(but, spacefunc, NULL, NULL); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ 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/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 6120229190d..5e23a144408 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -322,8 +322,8 @@ static int project_brush_radius(ViewContext *vc, add_v3_v3v3(offset, location, ortho); /* project the center of the brush, and the tangent point to the view onto the screen */ - if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) && - (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS)) + if ((ED_view3d_project_float_global(vc->ar, location, p1, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) && + (ED_view3d_project_float_global(vc->ar, offset, p2, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK)) { /* the distance between these points is the size of the projected brush in pixels */ return len_v2v2(p1, p2); @@ -340,7 +340,6 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, { Scene *scene = CTX_data_scene(C); Paint *paint = paint_get_active_from_context(C); - Brush *brush = paint_brush(paint); float window[2]; int hit; @@ -350,6 +349,7 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, if (vc->obact->sculpt && vc->obact->sculpt->pbvh && sculpt_stroke_get_location(C, location, window)) { + Brush *brush = paint_brush(paint); *pixel_radius = project_brush_radius(vc, BKE_brush_unprojected_radius_get(scene, brush), diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index c6aaae6b879..34ff5efacc9 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -2554,7 +2554,6 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i float (*outset_uv)[2] = ps->faceSeamUVs[face_index]; float insetCos[4][3]; /* inset face coords. NOTE!!! ScreenSace for ortho, Worldspace in prespective view */ - float fac; float *vCoSS[4]; /* vertex screenspace coords */ float bucket_clip_edges[2][2]; /* store the screenspace coords of the face, clipped by the bucket's screen aligned rectangle */ @@ -2636,6 +2635,7 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i /* test we're inside uvspace bucket and triangle bounds */ if (isect_point_quad_v2(uv, seam_subsection[0], seam_subsection[1], seam_subsection[2], seam_subsection[3])) { + float fac; /* We need to find the closest point along the face edge, * getting the screen_px_from_*** wont work because our actual location @@ -2670,9 +2670,9 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i #if 1 /* get the UV on the line since we want to copy the pixels from there for bleeding */ float uv_close[2]; - float fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]); - if (fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]); - else if (fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]); + float uv_fac = closest_to_line_v2(uv_close, uv, tf_uv_pxoffset[fidx1], tf_uv_pxoffset[fidx2]); + if (uv_fac < 0.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx1]); + else if (uv_fac > 1.0f) copy_v2_v2(uv_close, tf_uv_pxoffset[fidx2]); if (side) { barycentric_weights_v2(tf_uv_pxoffset[0], tf_uv_pxoffset[2], tf_uv_pxoffset[3], uv_close, w); @@ -2683,16 +2683,16 @@ static void project_paint_face_init(const ProjPaintState *ps, const int thread_i #else /* this is buggy with quads, don't use for now */ /* Cheat, we know where we are along the edge so work out the weights from that */ - fac = fac1 + (fac * (fac2 - fac1)); + uv_fac = fac1 + (uv_fac * (fac2 - fac1)); w[0] = w[1] = w[2] = 0.0; if (side) { - w[fidx1 ? fidx1 - 1 : 0] = 1.0f - fac; - w[fidx2 ? fidx2 - 1 : 0] = fac; + w[fidx1 ? fidx1 - 1 : 0] = 1.0f - uv_fac; + w[fidx2 ? fidx2 - 1 : 0] = uv_fac; } else { - w[fidx1] = 1.0f - fac; - w[fidx2] = fac; + w[fidx1] = 1.0f - uv_fac; + w[fidx2] = uv_fac; } #endif } @@ -4249,7 +4249,7 @@ static void imapaint_image_update(Scene *scene, SpaceImage *sima, Image *image, IMB_partial_display_buffer_update(ibuf, ibuf->rect_float, (unsigned char *) ibuf->rect, ibuf->x, 0, 0, &scene->view_settings, &scene->display_settings, imapaintpartial.x1, imapaintpartial.y1, - imapaintpartial.x2, imapaintpartial.y2); + imapaintpartial.x2, imapaintpartial.y2, FALSE); } else { ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; @@ -5890,7 +5890,7 @@ static int texture_paint_image_from_view_exec(bContext *C, wmOperator *op) if (!ibuf) { /* Mostly happens when OpenGL offscreen buffer was failed to create, */ /* but could be other reasons. Should be handled in the future. nazgul */ - BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL offscreen buffer: %s", err_out); + BKE_reportf(op->reports, RPT_ERROR, "Failed to create OpenGL off-screen buffer: %s", err_out); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 794e7755636..162e2fa15d6 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -51,7 +51,7 @@ struct wmOperator; struct wmOperatorType; /* paint_stroke.c */ -typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], float mouse[2]); +typedef int (*StrokeGetLocation)(struct bContext *C, float location[3], const float mouse[2]); typedef int (*StrokeTestStart)(struct bContext *C, struct wmOperator *op, const float mouse[2]); typedef void (*StrokeUpdateStep)(struct bContext *C, struct PaintStroke *stroke, struct PointerRNA *itemptr); typedef void (*StrokeDone)(const struct bContext *C, struct PaintStroke *stroke); diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index 7fabaf7f23d..2ae24db7c33 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -139,13 +139,13 @@ static float event_tablet_data(wmEvent *event, int *pen_flip) } /* Put the location of the next stroke dot into the stroke RNA and apply it to the mesh */ -static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, float mouse_in[2]) +static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *event, const float mouse_in[2]) { Scene *scene = CTX_data_scene(C); Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); PaintStroke *stroke = op->customdata; - float mouse[3]; + float mouse_out[2]; PointerRNA itemptr; float location[3]; float pressure; @@ -159,24 +159,24 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev if (stroke->vc.obact->sculpt) { float delta[2]; - BKE_brush_jitter_pos(scene, brush, mouse_in, mouse); + BKE_brush_jitter_pos(scene, brush, mouse_in, mouse_out); /* XXX: meh, this is round about because * BKE_brush_jitter_pos isn't written in the best way to * be reused here */ if (brush->flag & BRUSH_JITTER_PRESSURE) { - sub_v2_v2v2(delta, mouse, mouse_in); + sub_v2_v2v2(delta, mouse_out, mouse_in); mul_v2_fl(delta, pressure); - add_v2_v2v2(mouse, mouse_in, delta); + add_v2_v2v2(mouse_out, mouse_in, delta); } } else { - copy_v2_v2(mouse, mouse_in); + copy_v2_v2(mouse_out, mouse_in); } /* TODO: can remove the if statement once all modes have this */ if (stroke->get_location) - stroke->get_location(C, location, mouse); + stroke->get_location(C, location, mouse_out); else zero_v3(location); @@ -184,12 +184,11 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent *ev RNA_collection_add(op->ptr, "stroke", &itemptr); RNA_float_set_array(&itemptr, "location", location); - RNA_float_set_array(&itemptr, "mouse", mouse); + RNA_float_set_array(&itemptr, "mouse", mouse_out); RNA_boolean_set(&itemptr, "pen_flip", pen_flip); RNA_float_set(&itemptr, "pressure", pressure); - stroke->last_mouse_position[0] = mouse[0]; - stroke->last_mouse_position[1] = mouse[1]; + copy_v2_v2(stroke->last_mouse_position, mouse_out); stroke->update_step(C, stroke, &itemptr); } diff --git a/source/blender/editors/sculpt_paint/paint_undo.c b/source/blender/editors/sculpt_paint/paint_undo.c index f5b9aa742c6..e406d4f5c3b 100644 --- a/source/blender/editors/sculpt_paint/paint_undo.c +++ b/source/blender/editors/sculpt_paint/paint_undo.c @@ -152,7 +152,9 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char * UndoElem *undo; if (step == 1) { - if (stack->current == NULL) ; + if (stack->current == NULL) { + /* pass */ + } else { if (!name || strcmp(stack->current->name, name) == 0) { if (G.debug & G_DEBUG_WM) { @@ -165,7 +167,9 @@ static int undo_stack_step(bContext *C, UndoStack *stack, int step, const char * } } else if (step == -1) { - if ((stack->current != NULL && stack->current->next == NULL) || stack->elems.first == NULL) ; + if ((stack->current != NULL && stack->current->next == NULL) || stack->elems.first == NULL) { + /* pass */ + } else { if (!name || strcmp(stack->current->name, name) == 0) { undo = (stack->current && stack->current->next) ? stack->current->next : stack->elems.first; @@ -254,7 +258,9 @@ int ED_undo_paint_valid(int type, const char *name) else return 0; - if (stack->current == NULL) ; + if (stack->current == NULL) { + /* pass */ + } else { if (name && strcmp(stack->current->name, name) == 0) return 1; diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 5a79368ac49..bb931dd1ff2 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -848,7 +848,7 @@ static float calc_vp_strength_dl(VPaint *vp, ViewContext *vc, const float vert_n { float vertco[2]; - if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(vc->ar, vert_nor, vertco, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { float delta[2]; float dist_squared; @@ -1535,7 +1535,6 @@ static void enforce_locks(MDeformVert *odv, MDeformVert *ndv, } else { /* reset the weights */ - unsigned int i; MDeformWeight *dw_old = odv->dw; MDeformWeight *dw_new = ndv->dw; @@ -2049,7 +2048,6 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU Object *ob = CTX_data_active_object(C); struct WPaintData *wpd; Mesh *me; - bDeformGroup *dg; float mat[4][4], imat[4][4]; @@ -2098,12 +2096,14 @@ static int wpaint_stroke_test_start(bContext *C, wmOperator *op, const float UNU return FALSE; } - /* check if we are attempting to paint onto a locked vertex group, - * and other options disallow it from doing anything useful */ - dg = BLI_findlink(&ob->defbase, (ob->actdef - 1)); - if (dg->flag & DG_LOCK_WEIGHT) { - BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting"); - return FALSE; + { + /* check if we are attempting to paint onto a locked vertex group, + * and other options disallow it from doing anything useful */ + bDeformGroup *dg = BLI_findlink(&ob->defbase, (ob->actdef - 1)); + if (dg->flag & DG_LOCK_WEIGHT) { + BKE_report(op->reports, RPT_WARNING, "Active group is locked, aborting"); + return FALSE; + } } /* ALLOCATIONS! no return after this line */ diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 3d3e86d2acb..092ec32e724 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -3536,8 +3536,6 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, StrokeCache *cache = ss->cache; Brush *brush = paint_brush(&sd->paint); - int dx, dy; - /* RNA_float_get_array(ptr, "location", cache->traced_location); */ if (cache->first_time || @@ -3606,8 +3604,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, if (brush->flag & BRUSH_ANCHORED) { int hit = 0; - dx = cache->mouse[0] - cache->initial_mouse[0]; - dy = cache->mouse[1] - cache->initial_mouse[1]; + const float dx = cache->mouse[0] - cache->initial_mouse[0]; + const float dy = cache->mouse[1] - cache->initial_mouse[1]; sd->anchored_size = cache->pixel_radius = sqrt(dx * dx + dy * dy); @@ -3617,8 +3615,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, float halfway[2]; float out[3]; - halfway[0] = (float)dx * 0.5f + cache->initial_mouse[0]; - halfway[1] = (float)dy * 0.5f + cache->initial_mouse[1]; + halfway[0] = dx * 0.5f + cache->initial_mouse[0]; + halfway[1] = dy * 0.5f + cache->initial_mouse[1]; if (sculpt_stroke_get_location(C, out, halfway)) { copy_v3_v3(sd->anchored_location, out); @@ -3665,8 +3663,8 @@ static void sculpt_update_cache_variants(bContext *C, Sculpt *sd, Object *ob, sculpt_update_brush_delta(sd, ob, brush); if (brush->sculpt_tool == SCULPT_TOOL_ROTATE) { - dx = cache->mouse[0] - cache->initial_mouse[0]; - dy = cache->mouse[1] - cache->initial_mouse[1]; + const float dx = cache->mouse[0] - cache->initial_mouse[0]; + const float dy = cache->mouse[1] - cache->initial_mouse[1]; cache->vertex_rotation = -atan2f(dx, dy) * cache->bstrength; @@ -3738,7 +3736,7 @@ static void sculpt_raycast_cb(PBVHNode *node, void *data_v, float *tmin) * (This allows us to ignore the GL depth buffer) * Returns 0 if the ray doesn't hit the mesh, non-zero otherwise */ -int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]) +int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]) { ViewContext vc; Object *ob; diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 0852378974e..acb906e4a91 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -65,7 +65,7 @@ void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct void free_sculptsession_deformMats(struct SculptSession *ss); /* Stroke */ -int sculpt_stroke_get_location(bContext *C, float out[3], float mouse[2]); +int sculpt_stroke_get_location(bContext *C, float out[3], const float mouse[2]); /* Undo */ diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c index 7635f85a37e..eeb297b7f57 100644 --- a/source/blender/editors/space_action/action_edit.c +++ b/source/blender/editors/space_action/action_edit.c @@ -976,8 +976,8 @@ void ACTION_OT_sample(wmOperatorType *ot) /* defines for set extrapolation-type for selected keyframes tool */ static EnumPropertyItem prop_actkeys_expo_types[] = { - {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""}, - {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""}, + {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"}, + {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"}, {MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"}, {CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"}, @@ -1353,9 +1353,9 @@ static int actkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) void ACTION_OT_frame_jump(wmOperatorType *ot) { /* identifiers */ - ot->name = "Jump to Frame"; + ot->name = "Jump to Keyframes"; ot->idname = "ACTION_OT_frame_jump"; - ot->description = "Set the current frame to the average frame of the selected keyframes"; + ot->description = "Set the current frame to the average frame value of selected keyframes"; /* api callbacks */ ot->exec = actkeys_framejump_exec; @@ -1369,10 +1369,14 @@ void ACTION_OT_frame_jump(wmOperatorType *ot) /* defines for snap keyframes tool */ static EnumPropertyItem prop_actkeys_snap_types[] = { - {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", ""}, - {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry? - {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry? - {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""}, + {ACTKEYS_SNAP_CFRA, "CFRA", 0, "Current frame", + "Snap selected keyframes to the current frame"}, + {ACTKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", + "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"}, + {ACTKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", + "Snap selected keyframes to the nearest second"}, + {ACTKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", + "Snap selected keyframes to the nearest marker"}, {0, NULL, 0, NULL, NULL} }; @@ -1473,9 +1477,12 @@ void ACTION_OT_snap(wmOperatorType *ot) /* defines for mirror keyframes tool */ static EnumPropertyItem prop_actkeys_mirror_types[] = { - {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", ""}, - {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""}, - {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""}, + {ACTKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", + "Flip times of selected keyframes using the current frame as the mirror line"}, + {ACTKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", + "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"}, + {ACTKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", + "Flip times of selected keyframes using the first selected marker as the reference point"}, {0, NULL, 0, NULL, NULL} }; @@ -1497,12 +1504,8 @@ static void mirror_action_keys(bAnimContext *ac, short mode) /* for 'first selected marker' mode, need to find first selected marker first! */ // XXX should this be made into a helper func in the API? if (mode == ACTKEYS_MIRROR_MARKER) { - TimeMarker *marker = NULL; + TimeMarker *marker = ED_markers_get_first_selected(ac->markers); - /* find first selected marker */ - marker = ED_markers_get_first_selected(ac->markers); - - /* store marker's time (if available) */ if (marker) ked.f1 = (float)marker->frame; else diff --git a/source/blender/editors/space_action/action_ops.c b/source/blender/editors/space_action/action_ops.c index e4a161e3e22..cca71bb1331 100644 --- a/source/blender/editors/space_action/action_ops.c +++ b/source/blender/editors/space_action/action_ops.c @@ -168,9 +168,8 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* action_edit.c */ - /* snap - current frame to selected keys */ - // TODO: maybe since this is called jump, we're better to have it on <something>-J? - WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + /* jump to selected keyframes */ + WM_keymap_add_item(keymap, "ACTION_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0); /* menu + single-step transform */ WM_keymap_add_item(keymap, "ACTION_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_buttons/buttons_context.c b/source/blender/editors/space_buttons/buttons_context.c index c41d2521ee8..7e232a02536 100644 --- a/source/blender/editors/space_buttons/buttons_context.c +++ b/source/blender/editors/space_buttons/buttons_context.c @@ -900,7 +900,7 @@ int buttons_context(const bContext *C, const char *member, bContextDataResult *r } else { /* get settings from active particle system instead */ - PointerRNA *ptr = get_pointer_type(path, &RNA_ParticleSystem); + ptr = get_pointer_type(path, &RNA_ParticleSystem); if (ptr && ptr->data) { ParticleSettings *part = ((ParticleSystem *)ptr->data)->part; diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index c8cf69e3e17..9a7284de660 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -207,7 +207,7 @@ static int file_browse_invoke(bContext *C, wmOperator *op, wmEvent *event) * user-prefs exception - campbell */ if (RNA_struct_find_property(op->ptr, "relative_path")) { if (!RNA_struct_property_is_set(op->ptr, "relative_path")) { - /* annoying exception!, if were dealign with the user prefs, default relative to be off */ + /* annoying exception!, if were dealing with the user prefs, default relative to be off */ RNA_boolean_set(op->ptr, "relative_path", U.flag & USER_RELPATHS && (ptr.data != &U)); } } diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 5e940df2a30..d7936c1e2e8 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -117,6 +117,7 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc int *points, totseg, i, a; float sfra = SFRA, efra = EFRA, framelen = ar->winx / (efra - sfra + 1); MovieTracking *tracking = &clip->tracking; + MovieTrackingObject *act_object = BKE_tracking_object_get_active(tracking); MovieTrackingTrack *act_track = BKE_tracking_track_get_active(&clip->tracking); MovieTrackingReconstruction *reconstruction = BKE_tracking_get_active_reconstruction(tracking); @@ -218,8 +219,8 @@ static void draw_movieclip_cache(SpaceClip *sc, ARegion *ar, MovieClip *clip, Sc /* solver keyframes */ glColor4ub(175, 255, 0, 255); - draw_keyframe(tracking->settings.keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); - draw_keyframe(tracking->settings.keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); + draw_keyframe(act_object->keyframe1 + clip->start_frame - 1, CFRA, sfra, framelen, 2); + draw_keyframe(act_object->keyframe2 + clip->start_frame - 1, CFRA, sfra, framelen, 2); /* movie clip animation */ if ((sc->mode == SC_MODE_MASKEDIT) && sc->mask_info.mask) { diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 167353e7cb7..b495ca32813 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -44,6 +44,7 @@ #include "BLI_utildefines.h" #include "BLI_math.h" +#include "BLI_string.h" #include "BLI_rect.h" #include "GPU_extensions.h" @@ -692,7 +693,7 @@ int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf, const unsign context->start_frame = clip->start_frame; context->frame_offset = clip->frame_offset; - strcpy(context->colorspace, clip->colorspace_settings.name); + BLI_strncpy(context->colorspace, clip->colorspace_settings.name, sizeof(context->colorspace)); } else { /* displaying exactly the same image which was loaded t oa texture, diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 5c338f3e6f1..37eb0bcb7c1 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -41,6 +41,8 @@ #include "BLI_math.h" #include "BLI_rect.h" +#include "BLF_translation.h" + #include "BKE_context.h" #include "BKE_global.h" #include "BKE_report.h" @@ -180,7 +182,7 @@ static int open_exec(bContext *C, wmOperator *op) BLI_join_dirfile(str, sizeof(str), dir_only, file_only); } else { - BKE_reportf(op->reports, RPT_ERROR, "No files selected to be opened"); + BKE_report(op->reports, RPT_ERROR, "No files selected to be opened"); return OPERATOR_CANCELLED; } @@ -195,8 +197,8 @@ static int open_exec(bContext *C, wmOperator *op) if (op->customdata) MEM_freeN(op->customdata); - BKE_reportf(op->reports, RPT_ERROR, "Can't read: \"%s\", %s.", str, - errno ? strerror(errno) : "Unsupported movie clip format"); + BKE_reportf(op->reports, RPT_ERROR, "Can't read \"%s\": %s", str, + errno ? strerror(errno) : TIP_("Unsupported movie clip format")); return OPERATOR_CANCELLED; } @@ -514,9 +516,14 @@ static int view_zoom_exec(bContext *C, wmOperator *op) static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) { if (event->type == MOUSEZOOM) { - float factor; + float delta, factor; + + delta = event->x - event->prevx + event->y - event->prevy; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; - factor = 1.0f + (event->x - event->prevx + event->y - event->prevy) / 300.0f; + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sclip_zoom_set_factor_exec(C, event, factor); @@ -533,11 +540,16 @@ static int view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) static int view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) { ViewZoomData *vpd = op->customdata; - float factor; + float delta, factor; switch (event->type) { case MOUSEMOVE: - factor = 1.0f + (vpd->x - event->x + vpd->y - event->y) / 300.0f; + delta = event->x - vpd->x + event->y - vpd->y; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sclip_zoom_set(C, vpd->zoom * factor, vpd->location); ED_region_tag_redraw(CTX_wm_region(C)); @@ -579,7 +591,7 @@ void CLIP_OT_view_zoom(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_POINTER; /* properties */ - RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX); } @@ -700,7 +712,7 @@ void CLIP_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = ED_space_clip_view_clip_poll; /* properties */ - RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c index 97f7d7bf132..c061125b4d5 100644 --- a/source/blender/editors/space_clip/tracking_ops.c +++ b/source/blender/editors/space_clip/tracking_ops.c @@ -154,7 +154,7 @@ void CLIP_OT_add_marker(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; /* properties */ - RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MIN, FLT_MAX, + RNA_def_float_vector(ot->srna, "location", 2, NULL, -FLT_MAX, FLT_MAX, "Location", "Location of marker on frame", -1.0f, 1.0f); } @@ -1343,7 +1343,6 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op MovieClip *clip = ED_space_clip_get_clip(sc); Scene *scene = CTX_data_scene(C); MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &clip->tracking.settings; MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); int width, height; @@ -1359,7 +1358,7 @@ static int solve_camera_initjob(bContext *C, SolveCameraJob *scj, wmOperator *op scj->user = sc->user; scj->context = BKE_tracking_reconstruction_context_new(tracking, object, - settings->keyframe1, settings->keyframe2, width, height); + object->keyframe1, object->keyframe2, width, height); tracking->stats = MEM_callocN(sizeof(MovieTrackingStats), "solve camera stats"); @@ -1401,7 +1400,7 @@ static void solve_camera_freejob(void *scv) if (!solved) BKE_report(scj->reports, RPT_WARNING, "Some data failed to reconstruct, see console for details"); else - BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error %.3f", tracking->reconstruction.error); + BKE_reportf(scj->reports, RPT_INFO, "Average re-projection error: %.3f", tracking->reconstruction.error); /* set currently solved clip as active for scene */ if (scene->clip) @@ -2767,7 +2766,7 @@ static int join_tracks_exec(bContext *C, wmOperator *op) next = track->next; if (TRACK_VIEW_SELECTED(sc, track) && track != act_track) { - BKE_tracking_tracks_join(act_track, track); + BKE_tracking_tracks_join(tracking, act_track, track); if (tracking->stabilization.rot_track == track) tracking->stabilization.rot_track = act_track; @@ -2859,14 +2858,14 @@ static int set_solver_keyframe_exec(bContext *C, wmOperator *op) SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); MovieTracking *tracking = &clip->tracking; - MovieTrackingSettings *settings = &tracking->settings; + MovieTrackingObject *object = BKE_tracking_object_get_active(tracking); int keyframe = RNA_enum_get(op->ptr, "keyframe"); int framenr = BKE_movieclip_remap_scene_to_clip_frame(clip, sc->user.framenr); if (keyframe == 0) - settings->keyframe1 = framenr; + object->keyframe1 = framenr; else - settings->keyframe2 = framenr; + object->keyframe2 = framenr; WM_event_add_notifier(C, NC_MOVIECLIP | ND_DISPLAY, clip); diff --git a/source/blender/editors/space_clip/tracking_select.c b/source/blender/editors/space_clip/tracking_select.c index 4f62d3fdc2f..feb523237ba 100644 --- a/source/blender/editors/space_clip/tracking_select.c +++ b/source/blender/editors/space_clip/tracking_select.c @@ -291,7 +291,6 @@ static int select_invoke(bContext *C, wmOperator *op, wmEvent *event) MovieTrackingTrack *track = tracking_marker_check_slide(C, event, NULL, NULL, NULL); if (track) { - SpaceClip *sc = CTX_wm_space_clip(C); MovieClip *clip = ED_space_clip_get_clip(sc); clip->tracking.act_track = track; @@ -477,7 +476,7 @@ static int clip_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_marker(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_console/console_draw.c b/source/blender/editors/space_console/console_draw.c index 4c2f0ac73d4..c4a5c2a0154 100644 --- a/source/blender/editors/space_console/console_draw.c +++ b/source/blender/editors/space_console/console_draw.c @@ -94,12 +94,14 @@ void console_scrollback_prompt_begin(struct SpaceConsole *sc, ConsoleLine *cl_du { /* fake the edit line being in the scroll buffer */ ConsoleLine *cl = sc->history.last; + int prompt_len = strlen(sc->prompt); + cl_dummy->type = CONSOLE_LINE_INPUT; - cl_dummy->len = cl_dummy->len_alloc = strlen(sc->prompt) + cl->len; + cl_dummy->len = prompt_len + cl->len; cl_dummy->len_alloc = cl_dummy->len + 1; cl_dummy->line = MEM_mallocN(cl_dummy->len_alloc, "cl_dummy"); - memcpy(cl_dummy->line, sc->prompt, (cl_dummy->len_alloc - cl->len)); - memcpy(cl_dummy->line + ((cl_dummy->len_alloc - cl->len)) - 1, cl->line, cl->len + 1); + memcpy(cl_dummy->line, sc->prompt, prompt_len); + memcpy(cl_dummy->line + prompt_len, cl->line, cl->len + 1); BLI_addtail(&sc->scrollback, cl_dummy); } void console_scrollback_prompt_end(struct SpaceConsole *sc, ConsoleLine *cl_dummy) @@ -158,12 +160,13 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha const ConsoleLine *cl = (ConsoleLine *)sc->history.last; const int prompt_len = strlen(sc->prompt); const int cursor_loc = cl->cursor + prompt_len; + const int line_len = cl->len + prompt_len; int xy[2] = {CONSOLE_DRAW_MARGIN, CONSOLE_DRAW_MARGIN}; int pen[2]; xy[1] += tvc->lheight / 6; /* account for wrapping */ - if (cl->len < tvc->console_width) { + if (line_len < tvc->console_width) { /* simple case, no wrapping */ pen[0] = tvc->cwidth * cursor_loc; pen[1] = -2; @@ -171,7 +174,7 @@ static int console_textview_line_color(struct TextViewContext *tvc, unsigned cha else { /* wrap */ pen[0] = tvc->cwidth * (cursor_loc % tvc->console_width); - pen[1] = -2 + (((cl->len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight); + pen[1] = -2 + (((line_len / tvc->console_width) - (cursor_loc / tvc->console_width)) * tvc->lheight); } /* cursor */ diff --git a/source/blender/editors/space_console/console_ops.c b/source/blender/editors/space_console/console_ops.c index 7efcbcceb3c..ecd9e316cef 100644 --- a/source/blender/editors/space_console/console_ops.c +++ b/source/blender/editors/space_console/console_ops.c @@ -580,7 +580,7 @@ static int console_delete_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } else { - console_select_offset(sc, -1); + console_select_offset(sc, -stride); } console_textview_update_rect(sc, ar); diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c index fcbeb064e4d..7a364eb8685 100644 --- a/source/blender/editors/space_file/file_ops.c +++ b/source/blender/editors/space_file/file_ops.c @@ -307,7 +307,7 @@ void FILE_OT_select_border(wmOperatorType *ot) ot->poll = ED_operator_file_active; ot->cancel = WM_border_select_cancel; - /* rna */ + /* properties */ WM_operator_properties_gesture_border(ot, 1); } @@ -347,6 +347,8 @@ static int file_select_invoke(bContext *C, wmOperator *op, wmEvent *event) void FILE_OT_select(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Activate/Select File"; ot->description = "Activate/select file"; @@ -356,10 +358,13 @@ void FILE_OT_select(wmOperatorType *ot) ot->invoke = file_select_invoke; ot->poll = ED_operator_file_active; - /* rna */ - RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first"); - RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection"); - RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it"); + /* properties */ + prop = RNA_def_boolean(ot->srna, "extend", FALSE, "Extend", "Extend selection instead of deselecting everything first"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "fill", FALSE, "Fill", "Select everything beginning with the last selection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); + prop = RNA_def_boolean(ot->srna, "open", TRUE, "Open", "Open a directory when selecting it"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int file_select_all_exec(bContext *C, wmOperator *UNUSED(op)) @@ -404,9 +409,7 @@ void FILE_OT_select_all_toggle(wmOperatorType *ot) ot->exec = file_select_all_exec; ot->poll = ED_operator_file_active; - /* rna */ - - + /* properties */ } /* ---------- BOOKMARKS ----------- */ @@ -432,6 +435,8 @@ static int bookmark_select_exec(bContext *C, wmOperator *op) void FILE_OT_select_bookmark(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Select Directory"; ot->description = "Select a bookmarked directory"; @@ -441,7 +446,9 @@ void FILE_OT_select_bookmark(wmOperatorType *ot) ot->exec = bookmark_select_exec; ot->poll = ED_operator_file_active; - RNA_def_string(ot->srna, "dir", "", 256, "Dir", ""); + /* properties */ + prop = RNA_def_string(ot->srna, "dir", "", FILE_MAXDIR, "Dir", ""); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int bookmark_add_exec(bContext *C, wmOperator *UNUSED(op)) @@ -498,6 +505,8 @@ static int bookmark_delete_exec(bContext *C, wmOperator *op) void FILE_OT_delete_bookmark(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Delete Bookmark"; ot->description = "Delete selected bookmark"; @@ -507,7 +516,9 @@ void FILE_OT_delete_bookmark(wmOperatorType *ot) ot->exec = bookmark_delete_exec; ot->poll = ED_operator_file_active; - RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000); + /* properties */ + prop = RNA_def_int(ot->srna, "index", -1, -1, 20000, "Index", "", -1, 20000); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int reset_recent_exec(bContext *C, wmOperator *UNUSED(op)) @@ -819,7 +830,8 @@ void FILE_OT_execute(struct wmOperatorType *ot) /* api callbacks */ ot->exec = file_exec; ot->poll = file_operator_poll; - + + /* properties */ prop = RNA_def_boolean(ot->srna, "need_active", 0, "Need Active", "Only execute if there's an active selected file in the file list"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); @@ -1123,6 +1135,8 @@ int file_directory_new_exec(bContext *C, wmOperator *op) void FILE_OT_directory_new(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Create New Directory"; ot->description = "Create a new directory"; @@ -1133,7 +1147,8 @@ void FILE_OT_directory_new(struct wmOperatorType *ot) ot->exec = file_directory_new_exec; ot->poll = ED_operator_file_active; /* <- important, handler is on window level */ - RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); + prop = RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Name of new directory"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 699cb9b4feb..1408e8b801b 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -748,7 +748,9 @@ static int file_is_blend_backup(const char *str) a = strlen(str); b = 7; - if (a == 0 || b >= a) ; + if (a == 0 || b >= a) { + /* pass */ + } else { char *loc; @@ -1224,11 +1226,12 @@ void filelist_from_main(struct FileList *filelist) if (ok) { if (!filelist->hide_dot || id->name[2] != '.') { memset(files, 0, sizeof(struct direntry)); - if (id->lib == NULL) + if (id->lib == NULL) { files->relname = BLI_strdup(id->name + 2); + } else { - files->relname = MEM_mallocN(FILE_MAX + 32, "filename for lib"); - sprintf(files->relname, "%s | %s", id->lib->name, id->name + 2); + files->relname = MEM_mallocN(FILE_MAX + (MAX_ID_NAME - 2), "filename for lib"); + BLI_snprintf(files->relname, FILE_MAX + (MAX_ID_NAME - 2) + 3, "%s | %s", id->lib->name, id->name + 2); } files->type |= S_IFREG; #if 0 // XXXXX TODO show the selection status of the objects @@ -1238,7 +1241,7 @@ void filelist_from_main(struct FileList *filelist) } else if (idcode == ID_SCE) { if ( ((Scene *)id)->r.scemode & R_BG_RENDER) files->selflag |= SELECTED_FILE; - } + } } #endif files->nr = totbl + 1; @@ -1247,10 +1250,10 @@ void filelist_from_main(struct FileList *filelist) if (idcode == ID_MA || idcode == ID_TE || idcode == ID_LA || idcode == ID_WO || idcode == ID_IM) { files->flags |= IMAGEFILE; } - if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us); - else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us); - else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us); - else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us); + if (id->lib && fake) BLI_snprintf(files->extra, sizeof(files->extra), "LF %d", id->us); + else if (id->lib) BLI_snprintf(files->extra, sizeof(files->extra), "L %d", id->us); + else if (fake) BLI_snprintf(files->extra, sizeof(files->extra), "F %d", id->us); + else BLI_snprintf(files->extra, sizeof(files->extra), " %d", id->us); if (id->lib) { if (totlib == 0) firstlib = files; diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index 0d56b02e086..3e8f6f1c7fc 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -148,6 +148,7 @@ static void graph_panel_view(const bContext *C, Panel *pa) row = uiLayoutSplit(sub, 0.7f, TRUE); uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE); uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA); + row = uiLayoutSplit(sub, 0.7f, TRUE); uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE); uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE); @@ -308,44 +309,43 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) * - we use the button-versions of the calls so that we can attach special update handlers * and unit conversion magic that cannot be achieved using a purely RNA-approach */ - // XXX: col = uiLayoutColumn(layout, TRUE); /* keyframe itself */ { uiItemL(col, IFACE_("Key:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, IFACE_("Value"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); uiButSetUnitType(but, unit); } - + /* previous handle - only if previous was Bezier interpolation */ if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) { uiItemL(col, IFACE_("Left Handle:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); uiButSetUnitType(but, unit); } - + /* next handle - only if current is Bezier interpolation */ if (bezt->ipo == BEZT_IPO_BEZ) { uiItemL(col, IFACE_("Right Handle:"), ICON_NONE); - + but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); - + but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL); uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); @@ -437,7 +437,7 @@ static void driver_update_flags_cb(bContext *UNUSED(C), void *fcu_v, void *UNUSE ChannelDriver *driver = fcu->driver; /* clear invalid flags */ - fcu->flag &= ~FCURVE_DISABLED; // XXX? + fcu->flag &= ~FCURVE_DISABLED; driver->flag &= ~DRIVER_FLAG_INVALID; } @@ -467,7 +467,6 @@ static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVa uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:")); /* Target Property */ - // TODO: make this less technical... if (dtar->id) { PointerRNA root_ptr; @@ -630,12 +629,12 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) - uiItemL(col, IFACE_("ERROR: invalid Python expression"), ICON_ERROR); + uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_ERROR); } else { /* errors? */ if (driver->flag & DRIVER_FLAG_INVALID) - uiItemL(col, IFACE_("ERROR: invalid target channel(s)"), ICON_ERROR); + uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR); } col = uiLayoutColumn(pa->layout, TRUE); @@ -706,15 +705,15 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) graph_panel_driverVar__transChan(box, ale->id, dvar); break; } - + /* value of variable */ if (driver->flag & DRIVER_FLAG_SHOWDEBUG) { char valBuf[32]; - + box = uiLayoutBox(col); row = uiLayoutRow(box, TRUE); uiItemL(row, IFACE_("Value:"), ICON_NONE); - + BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval); uiItemL(row, valBuf, ICON_NONE); } @@ -724,8 +723,8 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) MEM_freeN(ale); } -/* ******************* f-modifiers ******************************** */ -/* all the drawing code is in editors/animation/fmodifier_ui.c */ +/* ******************* F-Modifiers ******************************** */ +/* All the drawing code is in editors/animation/fmodifier_ui.c */ #define B_FMODIFIER_REDRAW 20 @@ -757,7 +756,9 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) row = uiLayoutRow(pa->layout, FALSE); block = uiLayoutGetBlock(row); - // XXX for now, this will be a operator button which calls a 'add modifier' operator + /* this is an operator button which calls a 'add modifier' operator... + * a menu might be nicer but would be tricky as we need some custom filtering + */ uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 10, 0, 150, 20, TIP_("Adds a new F-Curve Modifier for the active F-Curve")); diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index 7107a6a2369..30ec32ec0aa 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -1309,8 +1309,8 @@ void GRAPH_OT_sample(wmOperatorType *ot) /* defines for set extrapolation-type for selected keyframes tool */ static EnumPropertyItem prop_graphkeys_expo_types[] = { - {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", ""}, - {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", ""}, + {FCURVE_EXTRAPOLATE_CONSTANT, "CONSTANT", 0, "Constant Extrapolation", "Values on endpoint keyframes are held"}, + {FCURVE_EXTRAPOLATE_LINEAR, "LINEAR", 0, "Linear Extrapolation", "Straight-line slope of end segments are extended past the endpoint keyframes"}, {MAKE_CYCLIC_EXPO, "MAKE_CYCLIC", 0, "Make Cyclic (F-Modifier)", "Add Cycles F-Modifier if one doesn't exist already"}, {CLEAR_CYCLIC_EXPO, "CLEAR_CYCLIC", 0, "Clear Cyclic (F-Modifier)", "Remove Cycles F-Modifier if not needed anymore"}, @@ -1808,9 +1808,9 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) void GRAPH_OT_frame_jump(wmOperatorType *ot) { /* identifiers */ - ot->name = "Jump to Frame"; + ot->name = "Jump to Keyframes"; ot->idname = "GRAPH_OT_frame_jump"; - ot->description = "Set the current frame to the average frame of the selected keyframes"; + ot->description = "Place the cursor on the midpoint of selected keyframes"; /* api callbacks */ ot->exec = graphkeys_framejump_exec; @@ -1824,12 +1824,18 @@ void GRAPH_OT_frame_jump(wmOperatorType *ot) /* defines for snap keyframes tool */ static EnumPropertyItem prop_graphkeys_snap_types[] = { - {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame", ""}, - {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", ""}, - {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", ""}, // XXX as single entry? - {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", ""}, // XXX as single entry? - {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", ""}, - {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles", ""}, + {GRAPHKEYS_SNAP_CFRA, "CFRA", 0, "Current Frame", + "Snap selected keyframes to the current frame"}, + {GRAPHKEYS_SNAP_VALUE, "VALUE", 0, "Cursor Value", + "Set values of selected keyframes to the cursor value (Y/Horizontal component)"}, + {GRAPHKEYS_SNAP_NEAREST_FRAME, "NEAREST_FRAME", 0, "Nearest Frame", + "Snap selected keyframes to the nearest (whole) frame (use to fix accidental sub-frame offsets)"}, + {GRAPHKEYS_SNAP_NEAREST_SECOND, "NEAREST_SECOND", 0, "Nearest Second", + "Snap selected keyframes to the nearest second"}, + {GRAPHKEYS_SNAP_NEAREST_MARKER, "NEAREST_MARKER", 0, "Nearest Marker", + "Snap selected keyframes to the nearest marker"}, + {GRAPHKEYS_SNAP_HORIZONTAL, "HORIZONTAL", 0, "Flatten Handles", + "Flatten handles for a smoother transition"}, {0, NULL, 0, NULL, NULL} }; @@ -1932,11 +1938,16 @@ void GRAPH_OT_snap(wmOperatorType *ot) /* defines for mirror keyframes tool */ static EnumPropertyItem prop_graphkeys_mirror_types[] = { - {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame", ""}, - {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value", ""}, - {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", ""}, - {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""}, - {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""}, + {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current Frame", + "Flip times of selected keyframes using the current frame as the mirror line"}, + {GRAPHKEYS_MIRROR_VALUE, "VALUE", 0, "By Values over Cursor Value", + "Flip values of selected keyframes using the cursor value (Y/Horizontal component) as the mirror line"}, + {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", + "Flip times of selected keyframes, effectively reversing the order they appear in"}, + {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", + "Flip values of selected keyframes (i.e. negative values become positive, and vice versa)"}, + {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", + "Flip times of selected keyframes using the first selected marker as the reference point"}, {0, NULL, 0, NULL, NULL} }; diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 08b13b49f55..9b031c015a9 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -346,9 +346,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* graph_edit.c */ - /* snap - current frame to selected keys */ - // TODO: maybe since this is called jump, we're better to have it on <something>-J? - WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0); + /* jump to selected keyframes */ + WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", GKEY, KM_PRESS, KM_CTRL, 0); /* menu + single-step transform */ WM_keymap_add_item(keymap, "GRAPH_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0); diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c index 4f57b2249d1..4793f995d98 100644 --- a/source/blender/editors/space_image/image_ops.c +++ b/source/blender/editors/space_image/image_ops.c @@ -430,11 +430,16 @@ static int image_view_zoom_invoke(bContext *C, wmOperator *op, wmEvent *event) if (event->type == MOUSEZOOM) { SpaceImage *sima = CTX_wm_space_image(C); ARegion *ar = CTX_wm_region(C); - float factor, location[2]; + float delta, factor, location[2]; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &location[0], &location[1]); - factor = 1.0f + (event->x - event->prevx + event->y - event->prevy) / 300.0f; + delta = event->x - event->prevx + event->y - event->prevy; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sima_zoom_set(sima, ar, sima->zoom * factor, location); ED_region_tag_redraw(CTX_wm_region(C)); @@ -452,11 +457,16 @@ static int image_view_zoom_modal(bContext *C, wmOperator *op, wmEvent *event) SpaceImage *sima = CTX_wm_space_image(C); ARegion *ar = CTX_wm_region(C); ViewZoomData *vpd = op->customdata; - float factor; + float delta, factor; switch (event->type) { case MOUSEMOVE: - factor = 1.0f + (vpd->x - event->x + vpd->y - event->y) / 300.0f; + delta = event->x - vpd->x + event->y - vpd->y; + + if (U.uiflag & USER_ZOOM_INVERT) + delta *= -1; + + factor = 1.0f + delta / 300.0f; RNA_float_set(op->ptr, "factor", factor); sima_zoom_set(sima, ar, vpd->zoom * factor, vpd->location); ED_region_tag_redraw(CTX_wm_region(C)); @@ -496,7 +506,7 @@ void IMAGE_OT_view_zoom(wmOperatorType *ot) ot->flag = OPTYPE_BLOCKING; /* properties */ - RNA_def_float(ot->srna, "factor", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "factor", 0.0f, -FLT_MAX, FLT_MAX, "Factor", "Zoom factor, values higher than 1.0 zoom in, lower values zoom out", -FLT_MAX, FLT_MAX); } @@ -800,7 +810,7 @@ void IMAGE_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = space_image_main_area_poll; /* properties */ - RNA_def_float(ot->srna, "ratio", 0.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 0.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } @@ -1259,8 +1269,7 @@ static void save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI BKE_image_release_renderresult(scene, ima); } else { - if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) - { + if (BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, &simopts->im_format, save_copy)) { ok = TRUE; } } @@ -1549,7 +1558,7 @@ static int image_save_sequence_exec(bContext *C, wmOperator *op) BLI_strncpy(di, ibuf->name, FILE_MAX); BLI_splitdirstring(di, fi); - BKE_reportf(op->reports, RPT_INFO, "%d Image(s) will be saved in %s", tot, di); + BKE_reportf(op->reports, RPT_INFO, "%d image(s) will be saved in %s", tot, di); for (ibuf = sima->image->ibufs.first; ibuf; ibuf = ibuf->next) { if (ibuf->userflags & IB_BITMAPDIRTY) { diff --git a/source/blender/editors/space_image/space_image.c b/source/blender/editors/space_image/space_image.c index 31cb6d91889..7f53f378042 100644 --- a/source/blender/editors/space_image/space_image.c +++ b/source/blender/editors/space_image/space_image.c @@ -414,8 +414,9 @@ static void image_refresh(const bContext *C, ScrArea *sa) /* don't need to check for pin here, see above */ sima->image = tf->tpage; - if (sima->flag & SI_EDITTILE) ; - else sima->curtile = tf->tile; + if ((sima->flag & SI_EDITTILE) == 0) { + sima->curtile = tf->tile; + } } } } diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c index 805ff1794c9..bb2d55fa0f6 100644 --- a/source/blender/editors/space_info/info_ops.c +++ b/source/blender/editors/space_info/info_ops.c @@ -124,7 +124,7 @@ static const EnumPropertyItem unpack_all_method_items[] = { {PF_WRITE_LOCAL, "WRITE_LOCAL", 0, "Write files to current directory (overwrite existing files)", ""}, {PF_USE_ORIGINAL, "USE_ORIGINAL", 0, "Use files in original location (create when necessary)", ""}, {PF_WRITE_ORIGINAL, "WRITE_ORIGINAL", 0, "Write files to original location (overwrite existing files)", ""}, - {PF_KEEP, "KEEP", 0, "Disable AutoPack, keep all packed files", ""}, + {PF_KEEP, "KEEP", 0, "Disable Auto-pack, keep all packed files", ""}, /* {PF_ASK, "ASK", 0, "Ask for each file", ""}, */ {0, NULL, 0, NULL, NULL}}; @@ -150,7 +150,7 @@ static int unpack_all_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event) count = countPackedFiles(bmain); if (!count) { - BKE_report(op->reports, RPT_WARNING, "No packed files. Autopack disabled"); + BKE_report(op->reports, RPT_WARNING, "No packed files (auto-pack disabled)"); G.fileflags &= ~G_AUTOPACK; return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_info/textview.c b/source/blender/editors/space_info/textview.c index 4ba196276da..cfab2542756 100644 --- a/source/blender/editors/space_info/textview.c +++ b/source/blender/editors/space_info/textview.c @@ -128,7 +128,7 @@ static int console_draw_string(ConsoleDrawContext *cdc, const char *str, int str return 1; } - if (str_len > cdc->console_width) { /* wrap? */ + if (tot_lines > 1) { /* wrap? */ const int initial_offset = ((tot_lines - 1) * cdc->console_width); const char *line_stride = str + initial_offset; /* advance to the last line and draw it first */ diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c index 92f014fd804..5c8e7e99a8c 100644 --- a/source/blender/editors/space_nla/nla_draw.c +++ b/source/blender/editors/space_nla/nla_draw.c @@ -849,8 +849,6 @@ static void draw_nla_channel_list_gl(bAnimContext *ac, ListBase *anim_data, View /* draw NLA-action line 'status-icons' - only when there's an action */ if ((ale->type == ANIMTYPE_NLAACTION) && (ale->data)) { - AnimData *adt = ale->adt; - offset += 16; /* now draw some indicator icons */ diff --git a/source/blender/editors/space_nla/nla_edit.c b/source/blender/editors/space_nla/nla_edit.c index 950060dde5f..e0e5007aff0 100644 --- a/source/blender/editors/space_nla/nla_edit.c +++ b/source/blender/editors/space_nla/nla_edit.c @@ -121,7 +121,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op) /* if no blocks, popup error? */ if (anim_data.first == NULL) { - BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for"); + BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for"); return OPERATOR_CANCELLED; } @@ -147,7 +147,7 @@ static int nlaedit_enable_tweakmode_exec(bContext *C, wmOperator *op) WM_event_add_notifier(C, NC_ANIMATION | ND_NLA_ACTCHANGE, NULL); } else { - BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweakmode on"); + BKE_report(op->reports, RPT_ERROR, "No active strip(s) to enter tweak mode on"); return OPERATOR_CANCELLED; } @@ -190,7 +190,7 @@ static int nlaedit_disable_tweakmode_exec(bContext *C, wmOperator *op) /* if no blocks, popup error? */ if (anim_data.first == NULL) { - BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweakmode for"); + BKE_report(op->reports, RPT_ERROR, "No AnimData blocks to enter tweak mode for"); return OPERATOR_CANCELLED; } @@ -405,7 +405,9 @@ static int nlaedit_add_actionclip_exec(bContext *C, wmOperator *op) else if (act->idroot == 0) { /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */ BKE_reportf(op->reports, RPT_WARNING, - "Action '%s' does not specify what datablocks it can be used on. Try setting the 'ID Root Type' setting from the Datablocks Editor for this Action to avoid future problems", + "Action '%s' does not specify what datablocks it can be used on " + "(try setting the 'ID Root Type' setting from the Datablocks Editor " + "for this Action to avoid future problems)", act->id.name + 2); } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index 470f82195a4..67508f2087a 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -3098,7 +3098,6 @@ void draw_nodespace_back_pix(const bContext *C, ARegion *ar, SpaceNode *snode) void *lock; ImBuf *ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock); if (ibuf) { - SpaceNode *snode = CTX_wm_space_node(C); float x, y; unsigned char *display_buffer; void *cache_handle; diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index 64a8d96a74f..f0afc647ed5 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -1935,7 +1935,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) bNodeTree *ntree = snode->edittree; bNode *gnode = node_tree_get_editgroup(snode->nodetree); float gnode_x = 0.0f, gnode_y = 0.0f; - bNode *node, *new_node; + bNode *node; bNodeLink *link, *newlink; ED_preview_kill_jobs(C); @@ -1950,6 +1950,7 @@ static int node_clipboard_copy_exec(bContext *C, wmOperator *UNUSED(op)) for (node = ntree->nodes.first; node; node = node->next) { if (node->flag & SELECT) { + bNode *new_node; new_node = nodeCopyNode(NULL, node); BKE_node_clipboard_add_node(new_node); } diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c index b76cc05af5c..19a678a9c6e 100644 --- a/source/blender/editors/space_node/node_group.c +++ b/source/blender/editors/space_node/node_group.c @@ -583,7 +583,7 @@ static int node_group_ungroup_exec(bContext *C, wmOperator *op) ntreeUpdateTree(snode->nodetree); } else { - BKE_report(op->reports, RPT_WARNING, "Can't ungroup"); + BKE_report(op->reports, RPT_WARNING, "Cannot ungroup"); return OPERATOR_CANCELLED; } @@ -755,13 +755,13 @@ static int node_group_separate_exec(bContext *C, wmOperator *op) switch (type) { case NODE_GS_COPY: if (!node_group_separate_selected(snode->nodetree, gnode, 1)) { - BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes"); return OPERATOR_CANCELLED; } break; case NODE_GS_MOVE: if (!node_group_separate_selected(snode->nodetree, gnode, 0)) { - BKE_report(op->reports, RPT_WARNING, "Can't separate nodes"); + BKE_report(op->reports, RPT_WARNING, "Cannot separate nodes"); return OPERATOR_CANCELLED; } break; @@ -1036,7 +1036,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op) int type = RNA_enum_get(op->ptr, "type"); if (snode->edittree != snode->nodetree) { - BKE_report(op->reports, RPT_WARNING, "Can not add a new Group in a Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot add a new group in a group"); return OPERATOR_CANCELLED; } @@ -1049,7 +1049,7 @@ static int node_group_make_exec(bContext *C, wmOperator *op) } if (gnode) { - BKE_report(op->reports, RPT_WARNING, "Can not add RenderLayer in a Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot add a Render Layers node in a group"); return OPERATOR_CANCELLED; } } @@ -1062,21 +1062,21 @@ static int node_group_make_exec(bContext *C, wmOperator *op) gnode = node_group_make_from_selected(snode->nodetree); } else { - BKE_report(op->reports, RPT_WARNING, "Can not make Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot make group"); return OPERATOR_CANCELLED; } break; case NODE_GM_INSERT: gnode = nodeGetActive(snode->nodetree); if (!gnode || gnode->type != NODE_GROUP) { - BKE_report(op->reports, RPT_WARNING, "No active Group node"); + BKE_report(op->reports, RPT_WARNING, "No active group node"); return OPERATOR_CANCELLED; } if (node_group_make_test(snode->nodetree, gnode)) { node_group_make_insert_selected(snode->nodetree, gnode); } else { - BKE_report(op->reports, RPT_WARNING, "Can not insert into Group"); + BKE_report(op->reports, RPT_WARNING, "Cannot insert into group"); return OPERATOR_CANCELLED; } break; diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index b0916a50c37..a3efa15c54a 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -593,7 +593,7 @@ static int node_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); do_lasso_select_node(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_node/node_templates.c b/source/blender/editors/space_node/node_templates.c index 3d93a6c14a1..42480c0c2d9 100644 --- a/source/blender/editors/space_node/node_templates.c +++ b/source/blender/editors/space_node/node_templates.c @@ -147,7 +147,7 @@ static void node_socket_remove(Main *bmain, bNodeTree *ntree, bNode *node_to, bN static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_to, bNodeSocket *sock_to, bNodeTemplate *ntemp, int sock_num) { bNode *node_from; - bNodeSocket *sock_from; + bNodeSocket *sock_from_tmp; bNode *node_prev = NULL; /* unlink existing node */ @@ -183,8 +183,8 @@ static void node_socket_add_replace(Main *bmain, bNodeTree *ntree, bNode *node_t nodeSetActive(ntree, node_from); /* add link */ - sock_from = BLI_findlink(&node_from->outputs, sock_num); - nodeAddLink(ntree, node_from, sock_from, node_to, sock_to); + sock_from_tmp = BLI_findlink(&node_from->outputs, sock_num); + nodeAddLink(ntree, node_from, sock_from_tmp, node_to, sock_to); /* copy input sockets from previous node */ if (node_prev && node_from != node_prev) { diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c index b70d66f60b4..76d1357a83c 100644 --- a/source/blender/editors/space_node/space_node.c +++ b/source/blender/editors/space_node/space_node.c @@ -254,6 +254,15 @@ static void node_area_listener(ScrArea *sa, wmNotifier *wmn) } } break; + + case NC_MOVIECLIP: + if (wmn->action == NA_EDITED) { + if (type == NTREE_COMPOSIT) { + if (nodeUpdateID(snode->nodetree, wmn->reference)) + ED_area_tag_refresh(sa); + } + } + break; } } diff --git a/source/blender/editors/space_outliner/outliner_draw.c b/source/blender/editors/space_outliner/outliner_draw.c index a05588495e9..d2e47427b94 100644 --- a/source/blender/editors/space_outliner/outliner_draw.c +++ b/source/blender/editors/space_outliner/outliner_draw.c @@ -783,7 +783,9 @@ static void outliner_draw_keymapbuts(uiBlock *block, ARegion *ar, SpaceOops *soo wmKeyMapItem *kmi = te->directdata; /* modal map? */ - if (kmi->propvalue) ; + if (kmi->propvalue) { + /* pass */ + } else { uiDefBlockBut(block, operator_search_menu, kmi, "", xstart, (int)te->ys + 1, butw1, UI_UNIT_Y - 1, "Assign new Operator"); } @@ -1409,11 +1411,15 @@ static void outliner_draw_tree_element(bContext *C, uiBlock *block, Scene *scene /* closed item, we draw the icons, not when it's a scene, or master-server list though */ if (!TSELEM_OPEN(tselem, soops)) { if (te->subtree.first) { - if (tselem->type == 0 && te->idcode == ID_SCE) ; - else if (tselem->type != TSE_R_LAYER) { /* this tree element always has same amount of branches, so don't draw */ + if (tselem->type == 0 && te->idcode == ID_SCE) { + /* pass */ + } + else if (tselem->type != TSE_R_LAYER) { + /* this tree element always has same amount of branches, so don't draw */ + int tempx = startx + offsx; - // divider + /* divider */ UI_ThemeColorShade(TH_BACK, -40); glRecti(tempx - 10, *starty + 4, tempx - 8, *starty + UI_UNIT_Y - 4); @@ -1525,7 +1531,7 @@ static void outliner_draw_tree(bContext *C, uiBlock *block, Scene *scene, ARegio { TreeElement *te; int starty, startx; - float col[4]; + float col[3]; glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // only once diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c index 2ec23091019..8f059b0a735 100644 --- a/source/blender/editors/space_outliner/outliner_edit.c +++ b/source/blender/editors/space_outliner/outliner_edit.c @@ -368,12 +368,14 @@ void group_toggle_visibility_cb(bContext *UNUSED(C), Scene *scene, TreeElement * static int outliner_toggle_visibility_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); ARegion *ar = CTX_wm_region(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_visibility_cb); + DAG_id_type_tag(bmain, ID_OB); WM_event_add_notifier(C, NC_SCENE | ND_OB_VISIBLE, scene); ED_region_tag_redraw(ar); @@ -464,11 +466,13 @@ void group_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElemen static int outliner_toggle_renderability_exec(bContext *C, wmOperator *UNUSED(op)) { + Main *bmain = CTX_data_main(C); SpaceOops *soops = CTX_wm_space_outliner(C); Scene *scene = CTX_data_scene(C); outliner_do_object_operation(C, scene, soops, &soops->tree, object_toggle_renderability_cb); + DAG_id_type_tag(bmain, ID_OB); WM_event_add_notifier(C, NC_SCENE | ND_OB_RENDER, scene); return OPERATOR_FINISHED; @@ -1340,7 +1344,7 @@ static int outliner_keyingset_additems_exec(bContext *C, wmOperator *op) /* check for invalid states */ if (ks == NULL) { - BKE_report(op->reports, RPT_ERROR, "Operation requires an Active Keying Set"); + BKE_report(op->reports, RPT_ERROR, "Operation requires an active keying set"); return OPERATOR_CANCELLED; } if (soutliner == NULL) diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c index bf76fdda61e..e4cd971dbd5 100644 --- a/source/blender/editors/space_outliner/outliner_tools.c +++ b/source/blender/editors/space_outliner/outliner_tools.c @@ -811,7 +811,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) ED_undo_push(C, "Unlink world"); break; default: - BKE_report(op->reports, RPT_WARNING, "Not Yet"); + BKE_report(op->reports, RPT_WARNING, "Not yet"); break; } } @@ -844,7 +844,7 @@ static int outliner_id_operation_exec(bContext *C, wmOperator *op) break; default: - BKE_report(op->reports, RPT_WARNING, "Not Yet"); + BKE_report(op->reports, RPT_WARNING, "Not yet"); break; } } @@ -980,9 +980,9 @@ static int outliner_action_set_exec(bContext *C, wmOperator *op) else if (act->idroot == 0) { /* hopefully in this case (i.e. library of userless actions), the user knows what they're doing... */ BKE_reportf(op->reports, RPT_WARNING, - "Action '%s' does not specify what datablocks it can be used on. " - "Try setting the 'ID Root Type' setting from the Datablocks Editor " - "for this Action to avoid future problems", + "Action '%s' does not specify what datablocks it can be used on " + "(try setting the 'ID Root Type' setting from the Datablocks Editor " + "for this Action to avoid future problems)", act->id.name + 2); } @@ -1160,37 +1160,49 @@ static int outliner_data_operation_exec(bContext *C, wmOperator *op) event = RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); - if (datalevel == TSE_POSE_CHANNEL) { - if (event > 0) { + if (event <= 0) + return OPERATOR_CANCELLED; + + switch (datalevel) { + case TSE_POSE_CHANNEL: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, pchan_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "PoseChannel operation"); } - } - else if (datalevel == TSE_BONE) { - if (event > 0) { + break; + + case TSE_BONE: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, bone_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "Bone operation"); } - } - else if (datalevel == TSE_EBONE) { - if (event > 0) { + break; + + case TSE_EBONE: + { outliner_do_data_operation(soops, datalevel, event, &soops->tree, ebone_cb, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_POSE, NULL); ED_undo_push(C, "EditBone operation"); } - } - else if (datalevel == TSE_SEQUENCE) { - if (event > 0) { + break; + + case TSE_SEQUENCE: + { Scene *scene = CTX_data_scene(C); outliner_do_data_operation(soops, datalevel, event, &soops->tree, sequence_cb, scene); } - } - else if (datalevel == TSE_RNA_STRUCT) { - if (event == 5) { - outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C); - } + break; + + case TSE_RNA_STRUCT: + if (event == 5) { + outliner_do_data_operation(soops, datalevel, event, &soops->tree, data_select_linked_cb, C); + } + break; + + default: + break; } return OPERATOR_FINISHED; @@ -1262,12 +1274,15 @@ static int do_outliner_operation_event(bContext *C, Scene *scene, ARegion *ar, S else { if (datalevel == TSE_ANIM_DATA) WM_operator_name_call(C, "OUTLINER_OT_animdata_operation", WM_OP_INVOKE_REGION_WIN, NULL); - else if (datalevel == TSE_DRIVER_BASE) - /* do nothing... no special ops needed yet */; - else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) - /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/; - else + else if (datalevel == TSE_DRIVER_BASE) { + /* do nothing... no special ops needed yet */ + } + else if (ELEM3(datalevel, TSE_R_LAYER_BASE, TSE_R_LAYER, TSE_R_PASS)) { + /*WM_operator_name_call(C, "OUTLINER_OT_renderdata_operation", WM_OP_INVOKE_REGION_WIN, NULL)*/ + } + else { WM_operator_name_call(C, "OUTLINER_OT_data_operation", WM_OP_INVOKE_REGION_WIN, NULL); + } } } @@ -1289,11 +1304,13 @@ static int outliner_operation(bContext *C, wmOperator *UNUSED(op), wmEvent *even SpaceOops *soops = CTX_wm_space_outliner(C); TreeElement *te; float fmval[2]; - + UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], fmval, fmval + 1); for (te = soops->tree.first; te; te = te->next) { - if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) break; + if (do_outliner_operation_event(C, scene, ar, soops, te, event, fmval)) { + break; + } } return OPERATOR_FINISHED; diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c index 3e1ce1fea6e..ef0542130ea 100644 --- a/source/blender/editors/space_outliner/outliner_tree.c +++ b/source/blender/editors/space_outliner/outliner_tree.c @@ -769,7 +769,9 @@ static void outliner_add_id_contents(SpaceOops *soops, TreeElement *te, TreeStor else { /* do not extend Armature when we have posemode */ tselem = TREESTORE(te->parent); - if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) ; + if (GS(tselem->id->name) == ID_OB && ((Object *)tselem->id)->mode & OB_MODE_POSE) { + /* pass */ + } else { Bone *curBone; for (curBone = arm->bonebase.first; curBone; curBone = curBone->next) { @@ -811,9 +813,15 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i te->parent = parent; te->index = index; // for data arays - if (ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) ; - else if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) ; - else if (type == TSE_ANIM_DATA) ; + if (ELEM3(type, TSE_SEQUENCE, TSE_SEQ_STRIP, TSE_SEQUENCE_DUP)) { + /* pass */ + } + else if (ELEM3(type, TSE_RNA_STRUCT, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM)) { + /* pass */ + } + else if (type == TSE_ANIM_DATA) { + /* pass */ + } else { te->name = id->name + 2; // default, can be overridden by Library or non-ID data te->idcode = GS(id->name); @@ -1055,8 +1063,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i if (key[0]) { wmOperatorType *ot = NULL; - if (kmi->propvalue) ; - else ot = WM_operatortype_find(kmi->idname, 0); + if (kmi->propvalue) { + /* pass */ + } + else { + ot = WM_operatortype_find(kmi->idname, 0); + } if (ot || kmi->propvalue) { TreeElement *ten = outliner_add_element(soops, &te->subtree, kmi, te, TSE_KEYMAP_ITEM, a); diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c index 204930e82a6..82d08be4da2 100644 --- a/source/blender/editors/space_sequencer/sequencer_edit.c +++ b/source/blender/editors/space_sequencer/sequencer_edit.c @@ -579,7 +579,9 @@ static Sequence *del_seq_find_replace_recurs(Scene *scene, Sequence *seq) seq2 = del_seq_find_replace_recurs(scene, seq->seq2); seq3 = del_seq_find_replace_recurs(scene, seq->seq3); - if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) ; + if (seq1 == seq->seq1 && seq2 == seq->seq2 && seq3 == seq->seq3) { + /* pass */ + } else if (seq1 || seq2 || seq3) { seq->seq1 = (seq1) ? seq1 : (seq2) ? seq2 : seq3; seq->seq2 = (seq2) ? seq2 : (seq1) ? seq1 : seq3; @@ -1572,7 +1574,7 @@ static int apply_unique_name_cb(Sequence *seq, void *arg_pt) Scene *scene = (Scene *)arg_pt; char name[sizeof(seq->name) - 2]; - strcpy(name, seq->name + 2); + BLI_strncpy_utf8(name, seq->name + 2, sizeof(name)); BKE_sequence_base_unique_name_recursive(&scene->ed->seqbase, seq); BKE_sequencer_dupe_animdata(scene, name, seq->name + 2); return 1; @@ -1851,7 +1853,7 @@ void SEQUENCER_OT_images_separate(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_int(ot->srna, "length", 1, 1, 1000, "Length", "Length of each frame", 1, INT_MAX); + RNA_def_int(ot->srna, "length", 1, 1, INT_MAX, "Length", "Length of each frame", 1, 1000); } @@ -2186,7 +2188,7 @@ void SEQUENCER_OT_view_zoom_ratio(wmOperatorType *ot) ot->poll = ED_operator_sequencer_active; /* properties */ - RNA_def_float(ot->srna, "ratio", 1.0f, 0.0f, FLT_MAX, + RNA_def_float(ot->srna, "ratio", 1.0f, -FLT_MAX, FLT_MAX, "Ratio", "Zoom ratio, 1.0 is 1:1, higher is zoomed in, lower is zoomed out", -FLT_MAX, FLT_MAX); } @@ -2618,7 +2620,6 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) { Scene *scene = CTX_data_scene(C); Editing *ed = BKE_sequencer_editing_get(scene, FALSE); - Sequence *seq; ListBase nseqbase = {NULL, NULL}; @@ -2654,8 +2655,11 @@ static int sequencer_copy_exec(bContext *C, wmOperator *op) seqbase_clipboard_frame = scene->r.cfra; /* Need to remove anything that references the current scene */ - for (seq = seqbase_clipboard.first; seq; seq = seq->next) { - seq_copy_del_sound(scene, seq); + { + Sequence *seq; + for (seq = seqbase_clipboard.first; seq; seq = seq->next) { + seq_copy_del_sound(scene, seq); + } } return OPERATOR_FINISHED; @@ -2738,7 +2742,7 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op) const char *error_msg; if (BKE_sequencer_active_get_pair(scene, &seq_act, &seq_other) == 0) { - BKE_report(op->reports, RPT_ERROR, "Must select 2 strips"); + BKE_report(op->reports, RPT_ERROR, "Please select two strips"); return OPERATOR_CANCELLED; } diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index 5111d20b8ee..a68524fcdd6 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -1741,6 +1741,7 @@ void draw_text_main(SpaceText *st, ARegion *ar) char linenr[12]; int i, x, y, winx, linecount = 0, lineno = 0; int wraplinecount = 0, wrap_skip = 0; + int margin_column_x; if (st->lheight) st->viewlines = (int)ar->winy / st->lheight; else st->viewlines = 0; @@ -1845,10 +1846,14 @@ void draw_text_main(SpaceText *st, ARegion *ar) if (st->flags & ST_SHOW_MARGIN) { UI_ThemeColor(TH_HILITE); - glBegin(GL_LINES); - glVertex2i(x + st->cwidth * st->margin_column, 0); - glVertex2i(x + st->cwidth * st->margin_column, ar->winy - 2); - glEnd(); + margin_column_x = x + st->cwidth * (st->margin_column - st->left); + + if (margin_column_x >= x) { + glBegin(GL_LINES); + glVertex2i(margin_column_x, 0); + glVertex2i(margin_column_x, ar->winy - 2); + glEnd(); + } } /* draw other stuff */ diff --git a/source/blender/editors/space_text/text_ops.c b/source/blender/editors/space_text/text_ops.c index 75b8e2f218d..b2fb16ff7fe 100644 --- a/source/blender/editors/space_text/text_ops.c +++ b/source/blender/editors/space_text/text_ops.c @@ -3352,7 +3352,7 @@ void TEXT_OT_to_3d_object(wmOperatorType *ot) /* identifiers */ ot->name = "To 3D Object"; ot->idname = "TEXT_OT_to_3d_object"; - ot->description = "Create 3d text object from active text data block"; + ot->description = "Create 3D text object from active text data block"; /* api callbacks */ ot->exec = text_to_3d_object_exec; diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 1bba237ed5c..35dd88c3209 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -51,7 +51,9 @@ set(SRC view3d_edit.c view3d_fly.c view3d_header.c + view3d_iterators.c view3d_ops.c + view3d_project.c view3d_select.c view3d_snap.c view3d_toolbar.c diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c index ecce12b8cba..31df13343ce 100644 --- a/source/blender/editors/space_view3d/drawarmature.c +++ b/source/blender/editors/space_view3d/drawarmature.c @@ -2226,9 +2226,16 @@ static void draw_ebones(View3D *v3d, ARegion *ar, Object *ob, const short dt) } /* restore */ - if (index != -1) glLoadName(-1); - if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) ; - else if (dt > OB_WIRE) bglPolygonOffset(rv3d->dist, 0.0f); + if (index != -1) { + glLoadName(-1); + } + + if (ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) { + /* pass */ + } + else if (dt > OB_WIRE) { + bglPolygonOffset(rv3d->dist, 0.0f); + } /* finally names and axes */ if (arm->flag & (ARM_DRAWNAMES | ARM_DRAWAXES)) { diff --git a/source/blender/editors/space_view3d/drawmesh.c b/source/blender/editors/space_view3d/drawmesh.c index e4c21a9c2c8..cded7bbbdfc 100644 --- a/source/blender/editors/space_view3d/drawmesh.c +++ b/source/blender/editors/space_view3d/drawmesh.c @@ -533,8 +533,7 @@ static void update_tface_color_layer(DerivedMesh *dm) } else { float col[3]; - Material *ma = give_current_material(Gtexdraw.ob, mface[i].mat_nr + 1); - + if (ma) { if (Gtexdraw.color_profile) linearrgb_to_srgb_v3_v3(col, &ma->r); else copy_v3_v3(col, &ma->r); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index df04cc33e71..ec54ae09fd2 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 */ @@ -784,10 +745,10 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa mul_m4_v3(mat, vos->vec); if (ED_view3d_project_short_ex(ar, - (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, - (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, - vos->vec, vos->sco, - V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_SUCCESS) + (vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob, + (vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0, + vos->vec, vos->sco, + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { tot++; } @@ -858,7 +819,9 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, int depth_write, floa if (depth_write) { if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } - else glDepthMask(1); + else { + glDepthMask(1); + } glMatrixMode(GL_PROJECTION); glPopMatrix(); @@ -900,7 +863,7 @@ static void drawcube(void) glEnd(); } -/* draws a cube on given the scaling of the cube, assuming that +/* draws a cube on given the scaling of the cube, assuming that * all required matrices have been set (used for drawing empties) */ static void drawcube_size(float size) @@ -1284,8 +1247,10 @@ static void drawlamp(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *base, glVertex3fv(tvec); glEnd(); } - else circ(0.0, 0.0, fabsf(z)); - + else { + circ(0.0, 0.0, fabsf(z)); + } + /* draw the circle/square representing spotbl */ if (la->type == LA_SPOT) { float spotblcirc = fabs(z) * (1 - pow(la->spotblend, 2)); @@ -1429,7 +1394,7 @@ static void draw_limit_line(float sta, float end, unsigned int col) glVertex3f(0.0, 0.0, -end); glEnd(); glPointSize(1.0); -} +} /* yafray: draw camera focus point (cross, similar to aqsis code in tuhopuu) */ @@ -1870,29 +1835,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_SUCCESS) - { - 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 +1921,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_SUCCESS) { - 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,286 +1949,9 @@ 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_SUCCESS) { - return; - } - if (ED_view3d_project_int_object(data->vc.ar, v1co, screen_co_b, flag) != V3D_PROJ_RET_SUCCESS) { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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_SUCCESS) - { - 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, +/* First section is all the "simple" draw routines, * ones that just pass some sort of primitive to GL, * with perhaps various options to control lighting, * color, etc. @@ -2568,7 +2186,7 @@ static DMDrawOption draw_dm_edges_sel__setDrawOptions(void *userData, int index) return DM_DRAW_OPTION_SKIP; } } -static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, +static void draw_dm_edges_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *actCol, BMEdge *eed_act) { drawDMEdgesSel_userData data; @@ -2590,7 +2208,7 @@ static DMDrawOption draw_dm_edges__setDrawOptions(void *userData, int index) return DM_DRAW_OPTION_NORMAL; } -static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) +static void draw_dm_edges(BMEditMesh *em, DerivedMesh *dm) { dm->drawMappedEdges(dm, draw_dm_edges__setDrawOptions, em); } @@ -2729,7 +2347,7 @@ static int draw_dm_faces_sel__compareDrawOptions(void *userData, int index, int } /* also draws the active face */ -static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, +static void draw_dm_faces_sel(BMEditMesh *em, DerivedMesh *dm, unsigned char *baseCol, unsigned char *selCol, unsigned char *markCol, unsigned char *actCol, BMFace *efa_act) { drawDMFacesSel_userData data; @@ -2827,9 +2445,9 @@ static void draw_dm_bweights(BMEditMesh *em, Scene *scene, DerivedMesh *dm) /* EditMesh drawing routines*/ -static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, +static void draw_em_fancy_verts(Scene *scene, View3D *v3d, Object *obedit, BMEditMesh *em, DerivedMesh *cageDM, BMVert *eve_act, - RegionView3D *rv3d) + RegionView3D *rv3d) { ToolSettings *ts = scene->toolsettings; int sel; @@ -2949,7 +2567,7 @@ static void draw_em_fancy_edges(BMEditMesh *em, Scene *scene, View3D *v3d, glEnable(GL_DEPTH_TEST); } } -} +} static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitSettings *unit) { @@ -3214,7 +2832,7 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, if (ese->type == BM_FACE) { efa_act = (BMFace *)ese->data; } - else + else #endif if (ese->htype == BM_EDGE) { eed_act = (BMEdge *)ese->ele; @@ -3397,13 +3015,12 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) { - if ((v3d->transp == FALSE) && /* not when we draw the transparent pass */ (ob->mode & OB_MODE_ALL_PAINT) == FALSE) /* not when painting (its distracting) - campbell */ { glLineWidth(UI_GetThemeValuef(TH_OUTLINE_WIDTH) * 2.0f); glDepthMask(0); - + /* if transparent, we cannot draw the edges for solid select... edges have no material info. * drawFacesSolid() doesn't draw the transparent faces */ if (ob->dtx & OB_DRAWTRANSP) { @@ -5896,7 +5513,7 @@ static void drawspiral(const float cent[3], float rad, float tmat[][4], int star glEnd(); } -/* draws a circle on x-z plane given the scaling of the circle, assuming that +/* draws a circle on x-z plane given the scaling of the circle, assuming that * all required matrices have been set (used for drawing empties) */ static void drawcircle_size(float size) @@ -7041,72 +6658,76 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short } /* only draw domains */ - if (smd->domain && smd->domain->fluid) { - if (CFRA < smd->domain->point_cache[0]->startframe) { - /* don't show smoke before simulation starts, this could be made an option in the future */ - } - else if (!smd->domain->wt || !(smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { -// #if 0 - smd->domain->tex = NULL; - GPU_create_smoke(smd, 0); - draw_volume(ar, smd->domain->tex, - smd->domain->p0, smd->domain->p1, - smd->domain->res, smd->domain->dx, - smd->domain->tex_shadow); - GPU_free_smoke(smd); -// #endif -#if 0 - int x, y, z; - float *density = smoke_get_density(smd->domain->fluid); + if (smd->domain) { + SmokeDomainSettings *sds = smd->domain; + float p0[3], p1[3], viewnormal[3]; + BoundBox bb; - glLoadMatrixf(rv3d->viewmat); - // glMultMatrixf(ob->obmat); + glLoadMatrixf(rv3d->viewmat); + glMultMatrixf(ob->obmat); - if (col || (ob->flag & SELECT)) cpack(0xFFFFFF); - glDepthMask(GL_FALSE); - glEnable(GL_BLEND); - + /* draw adaptive domain bounds */ + if (sds->flags & MOD_SMOKE_ADAPTIVE_DOMAIN) { + /* draw domain max bounds */ + VECSUBFAC(p0, sds->p0, sds->cell_size, sds->adapt_res); + VECADDFAC(p1, sds->p1, sds->cell_size, sds->adapt_res); + BKE_boundbox_init_from_minmax(&bb, p0, p1); + draw_box(bb.vec); - // glPointSize(3.0); - bglBegin(GL_POINTS); + /* draw base resolution bounds */ +#if 0 + BKE_boundbox_init_from_minmax(&bb, sds->p0, sds->p1); + draw_box(bb.vec); +#endif + } - for (x = 0; x < smd->domain->res[0]; x++) { - for (y = 0; y < smd->domain->res[1]; y++) { - for (z = 0; z < smd->domain->res[2]; z++) { - float tmp[3]; - int index = smoke_get_index(x, smd->domain->res[0], y, smd->domain->res[1], z); - - if (density[index] > FLT_EPSILON) { - float color[3]; - copy_v3_v3(tmp, smd->domain->p0); - tmp[0] += smd->domain->dx * x + smd->domain->dx * 0.5; - tmp[1] += smd->domain->dx * y + smd->domain->dx * 0.5; - tmp[2] += smd->domain->dx * z + smd->domain->dx * 0.5; - color[0] = color[1] = color[2] = density[index]; - glColor3fv(color); - bglVertex3fv(tmp); - } - } - } + /* don't show smoke before simulation starts, this could be made an option in the future */ + if (smd->domain->fluid && CFRA >= smd->domain->point_cache[0]->startframe) { + + // get view vector + copy_v3_v3(viewnormal, rv3d->viewinv[2]); + mul_mat3_m4_v3(ob->imat, viewnormal); + normalize_v3(viewnormal); + + /* set dynamic boundaries to draw the volume */ + p0[0] = sds->p0[0] + sds->cell_size[0] * sds->res_min[0] + sds->obj_shift_f[0]; + p0[1] = sds->p0[1] + sds->cell_size[1] * sds->res_min[1] + sds->obj_shift_f[1]; + p0[2] = sds->p0[2] + sds->cell_size[2] * sds->res_min[2] + sds->obj_shift_f[2]; + p1[0] = sds->p0[0] + sds->cell_size[0] * sds->res_max[0] + sds->obj_shift_f[0]; + p1[1] = sds->p0[1] + sds->cell_size[1] * sds->res_max[1] + sds->obj_shift_f[1]; + p1[2] = sds->p0[2] + sds->cell_size[2] * sds->res_max[2] + sds->obj_shift_f[2]; + + /* scale cube to global space to equalize volume slicing on all axises + * (its scaled back before drawing) */ + mul_v3_v3(p0, ob->size); + mul_v3_v3(p1, ob->size); + + if (!sds->wt || !(sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { + smd->domain->tex = NULL; + GPU_create_smoke(smd, 0); + draw_smoke_volume(sds, ob, sds->tex, + p0, p1, + sds->res, sds->dx, sds->scale * sds->maxres, + viewnormal, sds->tex_shadow, sds->tex_flame); + GPU_free_smoke(smd); + } + else if (sds->wt && (sds->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { + sds->tex = NULL; + GPU_create_smoke(smd, 1); + draw_smoke_volume(sds, ob, sds->tex, + p0, p1, + sds->res_wt, sds->dx, sds->scale * sds->maxres, + viewnormal, sds->tex_shadow, sds->tex_flame); + GPU_free_smoke(smd); } - bglEnd(); - glPointSize(1.0); - - glMultMatrixf(ob->obmat); - glDisable(GL_BLEND); - glDepthMask(GL_TRUE); - if (col) cpack(col); + /* smoke debug render */ +#ifdef SMOKE_DEBUG_VELOCITY + draw_smoke_velocity(smd->domain, ob); +#endif +#ifdef SMOKE_DEBUG_HEAT + draw_smoke_heat(smd->domain, ob); #endif - } - else if (smd->domain->wt && (smd->domain->viewsettings & MOD_SMOKE_VIEW_SHOWBIG)) { - smd->domain->tex = NULL; - GPU_create_smoke(smd, 1); - draw_volume(ar, smd->domain->tex, - smd->domain->p0, smd->domain->p1, - smd->domain->res_wt, smd->domain->dx_wt, - smd->domain->tex_shadow); - GPU_free_smoke(smd); } } } @@ -7368,7 +6989,7 @@ static void bbs_mesh_verts(BMEditMesh *em, DerivedMesh *dm, int offset) dm->foreachMappedVert(dm, bbs_mesh_verts__mapFunc, ptrs); bglEnd(); glPointSize(1.0); -} +} static DMDrawOption bbs_mesh_wire__setDrawOptions(void *userData, int index) { @@ -7388,7 +7009,7 @@ static void bbs_mesh_wire(BMEditMesh *em, DerivedMesh *dm, int offset) { void *ptrs[2] = {(void *)(intptr_t) offset, em}; dm->drawMappedEdges(dm, bbs_mesh_wire__setDrawOptions, ptrs); -} +} static DMDrawOption bbs_mesh_solid__setSolidDrawOptions(void *userData, int index) { @@ -7567,7 +7188,7 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec /* assumes all matrices/etc set OK */ /* helper function for drawing object instances - meshes */ -static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, +static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob, const short dt, int outline) { Mesh *me = ob->data; diff --git a/source/blender/editors/space_view3d/drawvolume.c b/source/blender/editors/space_view3d/drawvolume.c index 2c2d4039225..ebb48960b80 100644 --- a/source/blender/editors/space_view3d/drawvolume.c +++ b/source/blender/editors/space_view3d/drawvolume.c @@ -36,6 +36,7 @@ #include "DNA_scene_types.h" #include "DNA_screen_types.h" +#include "DNA_smoke_types.h" #include "DNA_view3d_types.h" #include "BLI_utildefines.h" @@ -132,7 +133,7 @@ static int intersect_edges(float *points, float a, float b, float c, float d, fl int i; float t; int numpoints = 0; - + for (i = 0; i < 12; i++) { t = -(a * edges[i][0][0] + b * edges[i][0][1] + c * edges[i][0][2] + d) / (a * edges[i][1][0] + b * edges[i][1][1] + c * edges[i][1][2]); @@ -156,12 +157,12 @@ static int convex(const float p0[3], const float up[3], const float a[3], const return dot_v3v3(up, tmp) >= 0; } -void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int res[3], float dx, GPUTexture *tex_shadow) +void draw_smoke_volume(SmokeDomainSettings *sds, Object *ob, + GPUTexture *tex, float min[3], float max[3], + int res[3], float dx, float UNUSED(base_scale), float viewnormal[3], + GPUTexture *tex_shadow, GPUTexture *tex_flame) { - RegionView3D *rv3d = ar->regiondata; - - float viewnormal[3]; - int i, j, n, good_index; + int i, j, k, n, good_index; float d /*, d0 */ /* UNUSED */, dd, ds; float *points = NULL; int numpoints = 0; @@ -193,25 +194,76 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r {{-1.0f, 1.0f, -1.0f}, {2.0f, 0.0f, 0.0f}} }; + unsigned char *spec_data; + float *spec_pixels; + GPUTexture *tex_spec; + /* Fragment program to calculate the view3d of smoke */ - /* using 2 textures, density and shadow */ - const char *text = "!!ARBfp1.0\n" - "PARAM dx = program.local[0];\n" - "PARAM darkness = program.local[1];\n" - "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" - "TEMP temp, shadow, value;\n" - "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" - "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" - "MUL value, temp, darkness;\n" - "MUL value, value, dx;\n" - "MUL value, value, f;\n" - "EX2 temp, -value.r;\n" - "SUB temp.a, 1.0, temp.r;\n" - "MUL temp.r, temp.r, shadow.r;\n" - "MUL temp.g, temp.g, shadow.r;\n" - "MUL temp.b, temp.b, shadow.r;\n" - "MOV result.color, temp;\n" - "END\n"; + /* using 4 textures, density, shadow, flame and flame spectrum */ + const char *shader_basic = + "!!ARBfp1.0\n" + "PARAM dx = program.local[0];\n" + "PARAM darkness = program.local[1];\n" + "PARAM render = program.local[2];\n" + "PARAM f = {1.442695041, 1.442695041, 1.442695041, 0.01};\n" + "TEMP temp, shadow, flame, spec, value;\n" + "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" + "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" + "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" + "TEX spec, flame.r, texture[3], 1D;\n" + /* calculate shading factor from density */ + "MUL value.r, temp.a, darkness.a;\n" + "MUL value.r, value.r, dx.r;\n" + "MUL value.r, value.r, f.r;\n" + "EX2 temp, -value.r;\n" + /* alpha */ + "SUB temp.a, 1.0, temp.r;\n" + /* shade colors */ + "MUL temp.r, temp.r, shadow.r;\n" + "MUL temp.g, temp.g, shadow.r;\n" + "MUL temp.b, temp.b, shadow.r;\n" + "MUL temp.r, temp.r, darkness.r;\n" + "MUL temp.g, temp.g, darkness.g;\n" + "MUL temp.b, temp.b, darkness.b;\n" + /* for now this just replace smoke shading if rendering fire */ + "CMP result.color, render.r, temp, spec;\n" + "END\n"; + + /* color shader */ + const char *shader_color = + "!!ARBfp1.0\n" + "PARAM dx = program.local[0];\n" + "PARAM darkness = program.local[1];\n" + "PARAM render = program.local[2];\n" + "PARAM f = {1.442695041, 1.442695041, 1.442695041, 1.442695041};\n" + "TEMP temp, shadow, flame, spec, value;\n" + "TEX temp, fragment.texcoord[0], texture[0], 3D;\n" + "TEX shadow, fragment.texcoord[0], texture[1], 3D;\n" + "TEX flame, fragment.texcoord[0], texture[2], 3D;\n" + "TEX spec, flame.r, texture[3], 1D;\n" + /* unpremultiply volume texture */ + "RCP value.r, temp.a;\n" + "MUL temp.r, temp.r, value.r;\n" + "MUL temp.g, temp.g, value.r;\n" + "MUL temp.b, temp.b, value.r;\n" + /* calculate shading factor from density */ + "MUL value.r, temp.a, darkness.a;\n" + "MUL value.r, value.r, dx.r;\n" + "MUL value.r, value.r, f.r;\n" + "EX2 value.r, -value.r;\n" + /* alpha */ + "SUB temp.a, 1.0, value.r;\n" + /* shade colors */ + "MUL temp.r, temp.r, shadow.r;\n" + "MUL temp.g, temp.g, shadow.r;\n" + "MUL temp.b, temp.b, shadow.r;\n" + "MUL temp.r, temp.r, value.r;\n" + "MUL temp.g, temp.g, value.r;\n" + "MUL temp.b, temp.b, value.r;\n" + /* for now this just replace smoke shading if rendering fire */ + "CMP result.color, render.r, temp, spec;\n" + "END\n"; + GLuint prog; @@ -223,6 +275,33 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r } tstart(); + /* generate flame spectrum texture */ + #define SPEC_WIDTH 256 + #define FIRE_THRESH 7 + #define MAX_FIRE_ALPHA 0.06f + #define FULL_ON_FIRE 100 + spec_data = malloc(SPEC_WIDTH * 4 * sizeof(unsigned char)); + flame_get_spectrum(spec_data, SPEC_WIDTH, 1500, 3000); + spec_pixels = malloc(SPEC_WIDTH * 4 * 16 * 16 * sizeof(float)); + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + for (k = 0; k < SPEC_WIDTH; k++) { + int index = (j * SPEC_WIDTH * 16 + i * SPEC_WIDTH + k) * 4; + if (k >= FIRE_THRESH) { + spec_pixels[index] = ((float)spec_data[k * 4]) / 255.0f; + spec_pixels[index + 1] = ((float)spec_data[k * 4 + 1]) / 255.0f; + spec_pixels[index + 2] = ((float)spec_data[k * 4 + 2]) / 255.0f; + spec_pixels[index + 3] = MAX_FIRE_ALPHA * ( + (k > FULL_ON_FIRE) ? 1.0f : (k - FIRE_THRESH) / ((float)FULL_ON_FIRE - FIRE_THRESH)); + } + else { + spec_pixels[index] = spec_pixels[index + 1] = spec_pixels[index + 2] = spec_pixels[index + 3] = 0.0f; + } + } + } + } + + tex_spec = GPU_texture_create_1D(SPEC_WIDTH, spec_pixels, NULL); sub_v3_v3v3(size, max, min); @@ -296,32 +375,17 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r glGetBooleanv(GL_BLEND, (GLboolean *)&gl_blend); glGetBooleanv(GL_DEPTH_TEST, (GLboolean *)&gl_depth); - glLoadMatrixf(rv3d->viewmat); - // glMultMatrixf(ob->obmat); - glDepthMask(GL_FALSE); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - -#if 0 - printf("Viewinv:\n"); - printf("%f, %f, %f\n", rv3d->viewinv[0][0], rv3d->viewinv[0][1], rv3d->viewinv[0][2]); - printf("%f, %f, %f\n", rv3d->viewinv[1][0], rv3d->viewinv[1][1], rv3d->viewinv[1][2]); - printf("%f, %f, %f\n", rv3d->viewinv[2][0], rv3d->viewinv[2][1], rv3d->viewinv[2][2]); -#endif - - /* get view vector */ - copy_v3_v3(viewnormal, rv3d->viewinv[2]); - normalize_v3(viewnormal); /* find cube vertex that is closest to the viewer */ for (i = 0; i < 8; i++) { float x, y, z; - x = cv[i][0] - viewnormal[0]*size[0]*0.5f; - y = cv[i][1] - viewnormal[1]*size[1]*0.5f; - z = cv[i][2] - viewnormal[2]*size[2]*0.5f; + x = cv[i][0] - viewnormal[0] * size[0] * 0.5f; + y = cv[i][1] - viewnormal[1] * size[1] * 0.5f; + z = cv[i][2] - viewnormal[2] * size[2] * 0.5f; if ((x >= min[0]) && (x <= max[0]) && (y >= min[1]) && (y <= max[1]) && @@ -344,12 +408,19 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r glGenProgramsARB(1, &prog); glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, prog); - glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(text), text); + /* set shader */ + if (sds->active_fields & SM_ACTIVE_COLORS) + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_color), shader_color); + else + glProgramStringARB(GL_FRAGMENT_PROGRAM_ARB, GL_PROGRAM_FORMAT_ASCII_ARB, (GLsizei)strlen(shader_basic), shader_basic); /* cell spacing */ glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 0, dx, dx, dx, 1.0); /* custom parameter for smoke style (higher = thicker) */ - glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 7.0, 7.0, 7.0, 1.0); + if (sds->active_fields & SM_ACTIVE_COLORS) + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, 1.0, 1.0, 1.0, 10.0); + else + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 1, sds->active_color[0], sds->active_color[1], sds->active_color[2], 10.0); } else printf("Your gfx card does not support 3D View smoke drawing.\n"); @@ -360,6 +431,11 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r else printf("No volume shadow\n"); + if (tex_flame) { + GPU_texture_bind(tex_flame, 2); + GPU_texture_bind(tex_spec, 3); + } + if (!GPU_non_power_of_two_support()) { cor[0] = (float)res[0] / (float)power_of_2_max_i(res[0]); cor[1] = (float)res[1] / (float)power_of_2_max_i(res[1]); @@ -373,7 +449,7 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r /* d0 = (viewnormal[0]*cv[i][0] + viewnormal[1]*cv[i][1] + viewnormal[2]*cv[i][2]); */ /* UNUSED */ ds = (ABS(viewnormal[0]) * size[0] + ABS(viewnormal[1]) * size[1] + ABS(viewnormal[2]) * size[2]); - dd = ds / 96.f; + dd = MAX3(sds->global_size[0], sds->global_size[1], sds->global_size[2]) / 128.f; n = 0; good_index = i; @@ -416,14 +492,29 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r } } - // printf("numpoints: %d\n", numpoints); + /* render fire slice */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, 1.0, 0.0, 0.0, 0.0); + glBegin(GL_POLYGON); + glColor3f(1.0, 1.0, 1.0); + for (i = 0; i < numpoints; i++) { + glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], + (points[i * 3 + 1] - min[1]) * cor[1] / size[1], + (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); + glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); + } + glEnd(); + + /* render smoke slice */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glProgramLocalParameter4fARB(GL_FRAGMENT_PROGRAM_ARB, 2, -1.0, 0.0, 0.0, 0.0); glBegin(GL_POLYGON); glColor3f(1.0, 1.0, 1.0); for (i = 0; i < numpoints; i++) { glTexCoord3d((points[i * 3 + 0] - min[0]) * cor[0] / size[0], (points[i * 3 + 1] - min[1]) * cor[1] / size[1], (points[i * 3 + 2] - min[2]) * cor[2] / size[2]); - glVertex3f(points[i * 3 + 0], points[i * 3 + 1], points[i * 3 + 2]); + glVertex3f(points[i * 3 + 0] / ob->size[0], points[i * 3 + 1] / ob->size[1], points[i * 3 + 2] / ob->size[2]); } glEnd(); } @@ -436,6 +527,14 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r if (tex_shadow) GPU_texture_unbind(tex_shadow); GPU_texture_unbind(tex); + if (tex_flame) { + GPU_texture_unbind(tex_flame); + GPU_texture_unbind(tex_spec); + } + GPU_texture_free(tex_spec); + + free(spec_data); + free(spec_pixels); if (GLEW_ARB_fragment_program) { glDisable(GL_FRAGMENT_PROGRAM_ARB); @@ -451,6 +550,109 @@ void draw_volume(ARegion *ar, GPUTexture *tex, float min[3], float max[3], int r if (gl_depth) { glEnable(GL_DEPTH_TEST); - glDepthMask(GL_TRUE); + glDepthMask(GL_TRUE); } } + +#ifdef SMOKE_DEBUG_VELOCITY +void draw_smoke_velocity(SmokeDomainSettings *domain, Object *ob) +{ + float x, y, z; + float x0, y0, z0; + int *base_res = domain->base_res; + int *res = domain->res; + int *res_min = domain->res_min; + int *res_max = domain->res_max; + float *vel_x = smoke_get_velocity_x(domain->fluid); + float *vel_y = smoke_get_velocity_y(domain->fluid); + float *vel_z = smoke_get_velocity_z(domain->fluid); + + float min[3]; + float *cell_size = domain->cell_size; + float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f; + float vf = domain->scale / 16.f * 2.f; /* velocity factor */ + + glLineWidth(1.0f); + + /* set first position so that it doesn't jump when domain moves */ + x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size); + y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size); + z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size); + if (x0 < res_min[0]) x0 += step_size; + if (y0 < res_min[1]) y0 += step_size; + if (z0 < res_min[2]) z0 += step_size; + add_v3_v3v3(min, domain->p0, domain->obj_shift_f); + + for (x = floor(x0); x < res_max[0]; x += step_size) + for (y = floor(y0); y < res_max[1]; y += step_size) + for (z = floor(z0); z < res_max[2]; z += step_size) { + int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1]; + + float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]}; + float vel = sqrtf(vel_x[index] * vel_x[index] + vel_y[index] * vel_y[index] + vel_z[index] * vel_z[index]); + + /* draw heat as scaled "arrows" */ + if (vel >= 0.01f) { + float col_g = 1.0f - vel; + CLAMP(col_g, 0.0f, 1.0f); + glColor3f(1.0f, col_g, 0.0f); + glPointSize(10.0f * vel); + + glBegin(GL_LINES); + glVertex3f(pos[0], pos[1], pos[2]); + glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); + glEnd(); + glBegin(GL_POINTS); + glVertex3f(pos[0] + vel_x[index] * vf, pos[1] + vel_y[index] * vf, pos[2] + vel_z[index] * vf); + glEnd(); + } + } +} +#endif + +#ifdef SMOKE_DEBUG_HEAT +void draw_smoke_heat(SmokeDomainSettings *domain, Object *ob) +{ + float x, y, z; + float x0, y0, z0; + int *base_res = domain->base_res; + int *res = domain->res; + int *res_min = domain->res_min; + int *res_max = domain->res_max; + float *heat = smoke_get_heat(domain->fluid); + + float min[3]; + float *cell_size = domain->cell_size; + float step_size = ((float)MAX3(base_res[0], base_res[1], base_res[2])) / 16.f; + float vf = domain->scale / 16.f * 2.f; /* velocity factor */ + + /* set first position so that it doesn't jump when domain moves */ + x0 = res_min[0] + fmod(-(float)domain->shift[0] + res_min[0], step_size); + y0 = res_min[1] + fmod(-(float)domain->shift[1] + res_min[1], step_size); + z0 = res_min[2] + fmod(-(float)domain->shift[2] + res_min[2], step_size); + if (x0 < res_min[0]) x0 += step_size; + if (y0 < res_min[1]) y0 += step_size; + if (z0 < res_min[2]) z0 += step_size; + add_v3_v3v3(min, domain->p0, domain->obj_shift_f); + + for (x = floor(x0); x < res_max[0]; x += step_size) + for (y = floor(y0); y < res_max[1]; y += step_size) + for (z = floor(z0); z < res_max[2]; z += step_size) { + int index = (floor(x) - res_min[0]) + (floor(y) - res_min[1]) * res[0] + (floor(z) - res_min[2]) * res[0] * res[1]; + + float pos[3] = {min[0] + ((float)x + 0.5f) * cell_size[0], min[1] + ((float)y + 0.5f) * cell_size[1], min[2] + ((float)z + 0.5f) * cell_size[2]}; + + /* draw heat as different sized points */ + if (heat[index] >= 0.01f) { + float col_gb = 1.0f - heat[index]; + CLAMP(col_gb, 0.0f, 1.0f); + glColor3f(1.0f, col_gb, col_gb); + glPointSize(24.0f * heat[index]); + + glBegin(GL_POINTS); + glVertex3f(pos[0], pos[1], pos[2]); + glEnd(); + } + } +} +#endif diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index c8aca5674a4..9755c7d1b7c 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -86,13 +86,15 @@ #define B_REDR 2 #define B_OBJECTPANELMEDIAN 1008 +#define NBR_TRANSFORM_PROPERTIES 7 + /* temporary struct for storing transform properties */ typedef struct { float ob_eul[4]; /* used for quat too... */ float ob_scale[3]; /* need temp space due to linked values */ float ob_dims[3]; short link_scale; - float ve_median[9]; + float ve_median[NBR_TRANSFORM_PROPERTIES]; int curdef; float *defweightp; } TransformProperties; @@ -131,17 +133,38 @@ static float compute_scale_factor(const float ve_median, const float median) /* is used for both read and write... */ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float lim) { +/* Get rid of those ugly magic numbers, even in a single func they become confusing! */ +/* Location, common to all. */ +/* XXX Those two *must* remain contiguous (used as array)! */ +#define LOC_X 0 +#define LOC_Y 1 +#define LOC_Z 2 +/* Meshes... */ +#define M_CREASE 3 +#define M_WEIGHT 4 +/* XXX Those two *must* remain contiguous (used as array)! */ +#define M_SKIN_X 5 +#define M_SKIN_Y 6 +/* Curves... */ +#define C_BWEIGHT 3 +#define C_WEIGHT 4 +#define C_RADIUS 5 +#define C_TILT 6 +/*Lattice... */ +#define L_WEIGHT 4 + uiBlock *block = (layout) ? uiLayoutAbsoluteBlock(layout) : NULL; MDeformVert *dvert = NULL; TransformProperties *tfp; - float median[9], ve_median[9]; - int tot, totw, totweight, totedge, totradius, totskinradius; + float median[NBR_TRANSFORM_PROPERTIES], ve_median[NBR_TRANSFORM_PROPERTIES]; + int tot, totedgedata, totcurvedata, totlattdata, totskinradius, totcurvebweight; + int meshdata = FALSE; char defstr[320]; - PointerRNA radius_ptr; + PointerRNA data_ptr; - median[0] = median[1] = median[2] = median[3] = median[4] = median[5] = median[6] = median[7] = median[8] = 0.0; - tot = totw = totweight = totedge = totradius = totskinradius = 0; - defstr[0] = 0; + fill_vn_fl(median, NBR_TRANSFORM_PROPERTIES, 0.0f); + tot = totedgedata = totcurvedata = totlattdata = totskinradius = totcurvebweight = 0; + defstr[0] = '\0'; /* make sure we got storage */ if (v3d->properties_storage == NULL) @@ -162,11 +185,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float evedef = eve; tot++; - add_v3_v3(median, eve->co); + add_v3_v3(&median[LOC_X], eve->co); vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); if (vs) { - add_v2_v2(median + 7, vs->radius); /* Third val not used currently. */ + add_v2_v2(&median[M_SKIN_X], vs->radius); /* Third val not used currently. */ totskinradius++; } } @@ -176,12 +199,12 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { float *f; - totedge++; + totedgedata++; f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_CREASE); - median[3] += f ? *f : 0.0f; + median[M_CREASE] += f ? *f : 0.0f; f = (float *)CustomData_bmesh_get(&bm->edata, eed->head.data, CD_BWEIGHT); - median[6] += f ? *f : 0.0f; + median[M_WEIGHT] += f ? *f : 0.0f; } } @@ -211,6 +234,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float tfp->defweightp = &dvert->dw[0].weight; } } + + meshdata = totedgedata || totskinradius; } else if (ob->type == OB_CURVE || ob->type == OB_SURF) { Curve *cu = ob->data; @@ -229,22 +254,24 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu; while (a--) { if (bezt->f2 & SELECT) { - add_v3_v3(median, bezt->vec[1]); + add_v3_v3(&median[LOC_X], bezt->vec[1]); tot++; - median[4] += bezt->weight; - totweight++; - median[5] += bezt->radius; - totradius++; - selp = bezt; - seltype = &RNA_BezierSplinePoint; + median[C_WEIGHT] += bezt->weight; + median[C_RADIUS] += bezt->radius; + median[C_TILT] += bezt->alfa; + if (!totcurvedata) { /* I.e. first time... */ + selp = bezt; + seltype = &RNA_BezierSplinePoint; + } + totcurvedata++; } else { if (bezt->f1 & SELECT) { - add_v3_v3(median, bezt->vec[0]); + add_v3_v3(&median[LOC_X], bezt->vec[0]); tot++; } if (bezt->f3 & SELECT) { - add_v3_v3(median, bezt->vec[2]); + add_v3_v3(&median[LOC_X], bezt->vec[2]); tot++; } } @@ -256,16 +283,18 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu * nu->pntsv; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(median, bp->vec); - median[3] += bp->vec[3]; - totw++; + add_v3_v3(&median[LOC_X], bp->vec); + median[C_BWEIGHT] += bp->vec[3]; + totcurvebweight++; tot++; - median[4] += bp->weight; - totweight++; - median[5] += bp->radius; - totradius++; - selp = bp; - seltype = &RNA_SplinePoint; + median[C_WEIGHT] += bp->weight; + median[C_RADIUS] += bp->radius; + median[C_TILT] += bp->alfa; + if (!totcurvedata) { /* I.e. first time... */ + selp = bp; + seltype = &RNA_SplinePoint; + } + totcurvedata++; } bp++; } @@ -273,84 +302,102 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float nu = nu->next; } - if (totradius == 1) - RNA_pointer_create(&cu->id, seltype, selp, &radius_ptr); + if (totcurvedata == 1) + RNA_pointer_create(&cu->id, seltype, selp, &data_ptr); } else if (ob->type == OB_LATTICE) { Lattice *lt = ob->data; BPoint *bp; int a; + StructRNA *seltype = NULL; + void *selp = NULL; a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; bp = lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(median, bp->vec); + add_v3_v3(&median[LOC_X], bp->vec); tot++; - median[4] += bp->weight; - totweight++; + median[L_WEIGHT] += bp->weight; + if (!totlattdata) { /* I.e. first time... */ + selp = bp; + seltype = &RNA_LatticePoint; + } + totlattdata++; } bp++; } + + if (totlattdata == 1) + RNA_pointer_create(<->id, seltype, selp, &data_ptr); } if (tot == 0) { uiDefBut(block, LABEL, 0, IFACE_("Nothing selected"), 0, 130, 200, 20, NULL, 0, 0, 0, 0, ""); return; } - median[0] /= (float)tot; - median[1] /= (float)tot; - median[2] /= (float)tot; - if (totedge) { - median[3] /= (float)totedge; - median[6] /= (float)totedge; - } - else if (totw) - median[3] /= (float)totw; - if (totweight) - median[4] /= (float)totweight; - if (totradius) - median[5] /= (float)totradius; - if (totskinradius) { - median[7] /= (float)totskinradius; - median[8] /= (float)totskinradius; - } + /* Location, X/Y/Z */ + mul_v3_fl(&median[LOC_X], 1.0f / (float)tot); if (v3d->flag & V3D_GLOBAL_STATS) - mul_m4_v3(ob->obmat, median); + mul_m4_v3(ob->obmat, &median[LOC_X]); + + if (meshdata) { + if (totedgedata) { + median[M_CREASE] /= (float)totedgedata; + median[M_WEIGHT] /= (float)totedgedata; + } + if (totskinradius) { + median[M_SKIN_X] /= (float)totskinradius; + median[M_SKIN_Y] /= (float)totskinradius; + } + } + else if (totcurvedata) { + median[C_WEIGHT] /= (float)totcurvedata; + median[C_RADIUS] /= (float)totcurvedata; + median[C_TILT] /= (float)totcurvedata; + if (totcurvebweight) + median[C_BWEIGHT] /= (float)totcurvebweight; + } + else if (totlattdata) + median[L_WEIGHT] /= (float)totlattdata; if (block) { /* buttons */ uiBut *but; int yi = 200; const int buth = 20 * UI_DPI_ICON_FAC; const int but_margin = 2; + const char *c; memcpy(tfp->ve_median, median, sizeof(tfp->ve_median)); uiBlockBeginAlign(block); if (tot == 1) { - uiDefBut(block, LABEL, 0, IFACE_("Vertex:"), 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); - } - else { - uiDefBut(block, LABEL, 0, IFACE_("Median:"), 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); + if (totcurvedata) /* Curve */ + c = IFACE_("Control Point:"); + else /* Mesh or lattice */ + c = IFACE_("Vertex:"); } + else + c = IFACE_("Median:"); + uiDefBut(block, LABEL, 0, c, 0, yi -= buth, 200, buth, NULL, 0, 0, 0, 0, ""); uiBlockBeginAlign(block); /* Should be no need to translate these. */ but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "X:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[0]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_X]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Y:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[1]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_Y]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "Z:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[2]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); + &(tfp->ve_median[LOC_Z]), -lim, lim, 10, RNA_TRANSLATION_PREC_DEFAULT, ""); uiButSetUnitType(but, PROP_UNIT_LENGTH); - if (totw == tot) { + if (totcurvebweight == tot) { uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, "W:", 0, yi -= buth, 200, buth, - &(tfp->ve_median[3]), 0.01, 100.0, 1, 3, ""); + &(tfp->ve_median[C_BWEIGHT]), 0.01, 100.0, 1, 3, ""); } uiBlockBeginAlign(block); @@ -362,60 +409,60 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float &v3d->flag, 0, 0, 0, 0, "Displays local values"); uiBlockEndAlign(block); - if (totweight == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); + /* Meshes... */ + if (meshdata) { + if (totedgedata) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Crease:") : IFACE_("Mean Crease:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_CREASE]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totedgedata == 1 ? IFACE_("Bevel Weight:") : IFACE_("Mean Bevel Weight:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + } + if (totskinradius) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totskinradius == 1 ? IFACE_("Radius X:") : IFACE_("Mean Radius X:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_SKIN_X]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier")); + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, + totskinradius == 1 ? IFACE_("Radius Y:") : IFACE_("Mean Radius Y:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[M_SKIN_Y]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier")); + } } - else if (totweight > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), - 0, yi -= buth, 200, buth, - &(tfp->ve_median[4]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); + /* Curve... */ + else if (totcurvedata == 1) { + uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); + uiDefButR(block, NUM, 0, "Radius", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "radius", 0, 0.0, 100.0, 1, 3, NULL); + uiDefButR(block, NUM, 0, "Tilt", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "tilt", 0, -M_PI * 2.0f, M_PI * 2.0f, 1, 3, NULL); } - - if (totradius == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius:"), + else if (totcurvedata > 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); - } - else if (totradius > 1) { + &(tfp->ve_median[C_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[5]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); + &(tfp->ve_median[C_RADIUS]), 0.0, 100.0, 1, 3, TIP_("Radius of curve control points")); + but = uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Tilt:"), + 0, yi -= buth + but_margin, 200, buth, + &(tfp->ve_median[C_TILT]), -M_PI * 2.0f, M_PI * 2.0f, 1, 3, + TIP_("Tilt of curve control points")); + uiButSetUnitType(but, PROP_UNIT_ROTATION); } - - if (totskinradius == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius X:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("X radius used by Skin modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Radius Y:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Y radius used by Skin modifier")); + /* Lattice... */ + else if (totlattdata == 1) { + uiDefButR(block, NUM, 0, "Weight", 0, yi -= buth + but_margin, 200, buth, + &data_ptr, "weight_softbody", 0, 0.0, 1.0, 1, 3, NULL); } - else if (totskinradius > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius X:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[7]), 0.0, 100.0, 1, 3, TIP_("Median X radius used by Skin modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Radius Y:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[8]), 0.0, 100.0, 1, 3, TIP_("Median Y radius used by Skin modifier")); - } - - if (totedge == 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Crease:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Bevel Weight:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); - } - else if (totedge > 1) { - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Crease:"), - 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[3]), 0.0, 1.0, 1, 3, TIP_("Weight used by SubSurf modifier")); - uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Bevel Weight:"), + else if (totlattdata > 1) { + uiDefButF(block, NUM, B_OBJECTPANELMEDIAN, IFACE_("Mean Weight:"), 0, yi -= buth + but_margin, 200, buth, - &(tfp->ve_median[6]), 0.0, 1.0, 1, 3, TIP_("Weight used by Bevel modifier")); + &(tfp->ve_median[L_WEIGHT]), 0.0, 1.0, 1, 3, TIP_("Weight used for SoftBody Goal")); } uiBlockEndAlign(block); @@ -423,42 +470,40 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } else { /* apply */ + int i; + memcpy(ve_median, tfp->ve_median, sizeof(tfp->ve_median)); if (v3d->flag & V3D_GLOBAL_STATS) { invert_m4_m4(ob->imat, ob->obmat); - mul_m4_v3(ob->imat, median); - mul_m4_v3(ob->imat, ve_median); + mul_m4_v3(ob->imat, &median[LOC_X]); + mul_m4_v3(ob->imat, &ve_median[LOC_X]); } - sub_v3_v3v3(median, ve_median, median); - median[3] = ve_median[3] - median[3]; - median[4] = ve_median[4] - median[4]; - median[5] = ve_median[5] - median[5]; - median[6] = ve_median[6] - median[6]; - median[7] = ve_median[7] - median[7]; - median[8] = ve_median[8] - median[8]; + i = NBR_TRANSFORM_PROPERTIES; + while (i--) + median[i] = ve_median[i] - median[i]; if (ob->type == OB_MESH) { Mesh *me = ob->data; BMEditMesh *em = me->edit_btmesh; BMesh *bm = em->bm; - BMVert *eve; BMIter iter; - if (len_v3(median) > 0.000001f) { + if (len_v3(&median[LOC_X]) > 0.000001f) { + BMVert *eve; BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { - add_v3_v3(eve->co, median); + add_v3_v3(eve->co, &median[LOC_X]); } } EDBM_mesh_normals_update(em); } - if (median[3] != 0.0f) { + if (median[M_CREASE] != 0.0f) { BMEdge *eed; - const float sca = compute_scale_factor(ve_median[3], median[3]); + const float sca = compute_scale_factor(ve_median[M_CREASE], median[M_CREASE]); if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { @@ -494,9 +539,9 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - if (median[6] != 0.0f) { + if (median[M_WEIGHT] != 0.0f) { BMEdge *eed; - const float sca = compute_scale_factor(ve_median[6], median[6]); + const float sca = compute_scale_factor(ve_median[M_WEIGHT], median[M_WEIGHT]); if (ELEM(sca, 0.0f, 1.0f)) { BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) { @@ -532,11 +577,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - if (median[7] != 0.0f) { + if (median[M_SKIN_X] != 0.0f) { BMVert *eve; /* That one is not clamped to [0.0, 1.0]. */ - float sca = ve_median[7]; - if (ve_median[7] - median[7] == 0.0f) { + float sca = ve_median[M_SKIN_X]; + if (ve_median[M_SKIN_X] - median[M_SKIN_X] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -546,7 +591,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } else { - sca /= (ve_median[7] - median[7]); + sca /= (ve_median[M_SKIN_X] - median[M_SKIN_X]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -556,11 +601,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } } - if (median[8] != 0.0f) { + if (median[M_SKIN_Y] != 0.0f) { BMVert *eve; /* That one is not clamped to [0.0, 1.0]. */ - float sca = ve_median[8]; - if (ve_median[8] - median[8] == 0.0f) { + float sca = ve_median[M_SKIN_Y]; + if (ve_median[M_SKIN_Y] - median[M_SKIN_Y] == 0.0f) { BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -570,7 +615,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } else { - sca /= (ve_median[8] - median[8]); + sca /= (ve_median[M_SKIN_Y] - median[M_SKIN_Y]); BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) { MVertSkin *vs = (MVertSkin *)CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MVERT_SKIN); @@ -589,7 +634,7 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float BezTriple *bezt; int a; ListBase *nurbs = BKE_curve_editNurbs_get(cu); - const float scale_w = compute_scale_factor(ve_median[4], median[4]); + const float scale_w = compute_scale_factor(ve_median[C_WEIGHT], median[C_WEIGHT]); nu = nurbs->first; while (nu) { @@ -598,11 +643,11 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu; while (a--) { if (bezt->f2 & SELECT) { - add_v3_v3(bezt->vec[0], median); - add_v3_v3(bezt->vec[1], median); - add_v3_v3(bezt->vec[2], median); + add_v3_v3(bezt->vec[0], &median[LOC_X]); + add_v3_v3(bezt->vec[1], &median[LOC_X]); + add_v3_v3(bezt->vec[2], &median[LOC_X]); - if (median[4] != 0.0f) { + if (median[C_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bezt->weight = scale_w; } @@ -613,14 +658,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - bezt->radius += median[5]; + bezt->radius += median[C_RADIUS]; + bezt->alfa += median[C_TILT]; } else { if (bezt->f1 & SELECT) { - add_v3_v3(bezt->vec[0], median); + add_v3_v3(bezt->vec[0], &median[LOC_X]); } if (bezt->f3 & SELECT) { - add_v3_v3(bezt->vec[2], median); + add_v3_v3(bezt->vec[2], &median[LOC_X]); } } bezt++; @@ -631,10 +677,10 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float a = nu->pntsu * nu->pntsv; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(bp->vec, median); - bp->vec[3] += median[3]; + add_v3_v3(bp->vec, &median[LOC_X]); + bp->vec[3] += median[C_BWEIGHT]; - if (median[4] != 0.0f) { + if (median[C_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bp->weight = scale_w; } @@ -645,7 +691,8 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float } } - bp->radius += median[5]; + bp->radius += median[C_RADIUS]; + bp->alfa += median[C_TILT]; } bp++; } @@ -660,15 +707,15 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float Lattice *lt = ob->data; BPoint *bp; int a; - const float scale_w = compute_scale_factor(ve_median[4], median[4]); + const float scale_w = compute_scale_factor(ve_median[L_WEIGHT], median[L_WEIGHT]); a = lt->editlatt->latt->pntsu * lt->editlatt->latt->pntsv * lt->editlatt->latt->pntsw; bp = lt->editlatt->latt->def; while (a--) { if (bp->f1 & SELECT) { - add_v3_v3(bp->vec, median); + add_v3_v3(bp->vec, &median[LOC_X]); - if (median[4] != 0.0f) { + if (median[L_WEIGHT] != 0.0f) { if (ELEM(scale_w, 0.0f, 1.0f)) { bp->weight = scale_w; } @@ -685,7 +732,28 @@ static void v3d_editvertex_buts(uiLayout *layout, View3D *v3d, Object *ob, float /* ED_undo_push(C, "Transform properties"); */ } + +/* Clean up! */ +/* Location, common to all. */ +#undef LOC_X +#undef LOC_Y +#undef LOC_Z +/* Meshes (and lattice)... */ +#undef M_CREASE +#undef M_WEIGHT +#undef M_SKIN_X +#undef M_SKIN_Y +/* Curves... */ +#undef C_BWEIGHT +#undef C_WEIGHT +#undef C_RADIUS +#undef C_TILT +/* Lattice... */ +#undef L_WEIGHT } +#undef NBR_TRANSFORM_PROPERTIES + + #define B_VGRP_PNL_COPY 1 #define B_VGRP_PNL_NORMALIZE 2 #define B_VGRP_PNL_EDIT_SINGLE 8 /* or greater */ @@ -1161,7 +1229,6 @@ static void view3d_panel_object(const bContext *C, Panel *pa) uiBlockSetHandleFunc(block, do_view3d_region_buttons, NULL); col = uiLayoutColumn(pa->layout, FALSE); - /* row = uiLayoutRow(col, FALSE); */ /* UNUSED */ RNA_id_pointer_create(&ob->id, &obptr); if (ob == obedit) { diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index ca768f2ef17..8e1b0716136 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -355,7 +355,9 @@ static void drawgrid(UnitSettings *unit, ARegion *ar, View3D *v3d, const char ** if (dx < GRID_MIN_PX_D) { rv3d->gridview *= sublines; dx *= sublines; - if (dx < GRID_MIN_PX_D) ; + if (dx < GRID_MIN_PX_D) { + /* pass */ + } else { UI_ThemeColor(TH_GRID); drawgrid_draw(ar, wx, wy, x, y, dx); @@ -556,7 +558,7 @@ static void drawcursor(Scene *scene, ARegion *ar, View3D *v3d) int co[2]; /* we don't want the clipping for cursor */ - if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, give_cursor(scene, v3d), co, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { setlinestyle(0); cpack(0xFF); circ((float)co[0], (float)co[1], 10.0); @@ -1460,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; @@ -1498,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; } @@ -2854,6 +2856,12 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw engine->tile_x = ceil(ar->winx / (float)scene->r.xparts); engine->tile_y = ceil(ar->winy / (float)scene->r.yparts); + /* clamp small tile sizes to prevent inefficient threading utilization + * the same happens for final renders as well + */ + engine->tile_x = MAX2(engine->tile_x, 64); + engine->tile_y = MAX2(engine->tile_x, 64); + type->view_update(engine, C); rv3d->render_engine = engine; @@ -2870,12 +2878,20 @@ static int view3d_main_area_draw_engine(const bContext *C, ARegion *ar, int draw rctf viewborder; rcti cliprct; - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &viewborder, FALSE); - cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); - cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); - cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); - cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + cliprct.xmin = viewborder.xmin + scene->r.border.xmin * BLI_rctf_size_x(&viewborder); + cliprct.ymin = viewborder.ymin + scene->r.border.ymin * BLI_rctf_size_y(&viewborder); + cliprct.xmax = viewborder.xmin + scene->r.border.xmax * BLI_rctf_size_x(&viewborder); + cliprct.ymax = viewborder.ymin + scene->r.border.ymax * BLI_rctf_size_y(&viewborder); + } + else { + cliprct.xmin = v3d->render_border.xmin * ar->winx; + cliprct.xmax = v3d->render_border.xmax * ar->winx; + cliprct.ymin = v3d->render_border.ymin * ar->winy; + cliprct.ymax = v3d->render_border.ymax * ar->winy; + } cliprct.xmin += ar->winrct.xmin; cliprct.xmax += ar->winrct.xmin; @@ -3121,8 +3137,20 @@ static void view3d_main_area_draw_info(const bContext *C, ARegion *ar, const cha Object *ob; - if (rv3d->persp == RV3D_CAMOB) + if (rv3d->persp == RV3D_CAMOB) { drawviewborder(scene, ar, v3d); + } + else if (v3d->flag2 & V3D_RENDER_BORDER) { + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + setlinestyle(3); + cpack(0x4040FF); + + glRectf(v3d->render_border.xmin * ar->winx, v3d->render_border.ymin * ar->winy, + v3d->render_border.xmax * ar->winx, v3d->render_border.ymax * ar->winy); + + setlinestyle(0); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + } if ((v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { /* draw grease-pencil stuff - needed to get paint-buffer shown too (since it's 2D) */ @@ -3172,7 +3200,12 @@ void view3d_main_area_draw(const bContext *C, ARegion *ar) View3D *v3d = CTX_wm_view3d(C); RegionView3D *rv3d = CTX_wm_region_view3d(C); const char *grid_unit = NULL; - int draw_border = (rv3d->persp == RV3D_CAMOB && (scene->r.mode & R_BORDER)); + int draw_border = FALSE; + + if (rv3d->persp == RV3D_CAMOB) + draw_border = scene->r.mode & R_BORDER; + else + draw_border = v3d->flag2 & V3D_RENDER_BORDER; /* draw viewport using opengl */ if (v3d->drawtype != OB_RENDER || !view3d_main_area_do_render_draw(C) || draw_border) { diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c index 735f7b5ea4a..96264081f10 100644 --- a/source/blender/editors/space_view3d/view3d_edit.c +++ b/source/blender/editors/space_view3d/view3d_edit.c @@ -929,18 +929,6 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, wmEvent *event) } } -static int view3d_camera_active_poll(bContext *C) -{ - if (ED_operator_view3d_active(C)) { - RegionView3D *rv3d = CTX_wm_region_view3d(C); - if (rv3d && rv3d->persp == RV3D_CAMOB) { - return 1; - } - } - - return 0; -} - /* test for unlocked camera view in quad view */ static int view3d_camera_user_poll(bContext *C) { @@ -966,7 +954,6 @@ static int viewrotate_cancel(bContext *C, wmOperator *op) void VIEW3D_OT_rotate(wmOperatorType *ot) { - /* identifiers */ ot->name = "Rotate view"; ot->description = "Rotate the view"; @@ -1637,7 +1624,7 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, const short viewzoom, if (use_cam_zoom) { float delta; delta = (x - vod->origx + y - vod->origy) / 10.0f; - vod->rv3d->camzoom = vod->camzoom0 + (zoom_invert ? delta : -delta); + vod->rv3d->camzoom = vod->camzoom0 + (zoom_invert ? -delta : delta); CLAMP(vod->rv3d->camzoom, RV3D_CAMZOOM_MIN, RV3D_CAMZOOM_MAX); } @@ -1692,11 +1679,11 @@ static void viewzoom_apply(ViewOpsData *vod, int x, int y, const short viewzoom, if (use_cam_zoom) { /* zfac is ignored in this case, see below */ #if 0 - zfac = vod->camzoom0 * (2.0f * ((len2 / len1) - 1.0f) + 1.0f) / vod->rv3d->camzoom; + zfac = vod->camzoom0 * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->camzoom; #endif } else { - zfac = vod->dist0 * (2.0f * ((len2 / len1) - 1.0f) + 1.0f) / vod->rv3d->dist; + zfac = vod->dist0 * (2.0f * ((len1 / len2) - 1.0f) + 1.0f) / vod->rv3d->dist; } } @@ -1889,12 +1876,12 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, wmEvent *event) if (U.uiflag & USER_ZOOM_HORIZ) { vod->origx = vod->oldx = event->x; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, FALSE); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); } else { /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */ vod->origy = vod->oldy = vod->origy + event->x - event->prevx; - viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, FALSE); + viewzoom_apply(vod, event->prevx, event->prevy, USER_ZOOM_DOLLY, (U.uiflag & USER_ZOOM_INVERT) == 0); } ED_view3d_depth_tag_update(vod->rv3d); @@ -1972,7 +1959,7 @@ static void viewdolly_apply(ViewOpsData *vod, int x, int y, const short zoom_inv if (zoom_invert) SWAP(float, len1, len2); - zfac = 1.0f + ((len2 - len1) * 0.01f * vod->rv3d->dist); + zfac = 1.0f + ((len1 - len2) * 0.01f * vod->rv3d->dist); } if (zfac != 1.0f) @@ -2108,13 +2095,13 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, wmEvent *event) if (U.uiflag & USER_ZOOM_HORIZ) { vod->origx = vod->oldx = event->x; - viewdolly_apply(vod, event->prevx, event->prevy, FALSE); + viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0); } else { /* Set y move = x move as MOUSEZOOM uses only x axis to pass magnification value */ vod->origy = vod->oldy = vod->origy + event->x - event->prevx; - viewdolly_apply(vod, event->prevx, event->prevy, FALSE); + viewdolly_apply(vod, event->prevx, event->prevy, (U.uiflag & USER_ZOOM_INVERT) == 0); } ED_view3d_depth_tag_update(vod->rv3d); @@ -2179,21 +2166,98 @@ void VIEW3D_OT_dolly(wmOperatorType *ot) RNA_def_int(ot->srna, "my", 0, 0, INT_MAX, "Zoom Position Y", "", 0, INT_MAX); } +static void view3d_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 */ +} + +/* same as view3d_from_minmax but for all regions (except cameras) */ +static void view3d_from_minmax_multi(bContext *C, View3D *v3d, + const float min[3], const float max[3], + const int ok_dist) +{ + ScrArea *sa = CTX_wm_area(C); + ARegion *ar; + for (ar = sa->regionbase.first; ar; ar = ar->next) { + if (ar->regiontype == RGN_TYPE_WINDOW) { + RegionView3D *rv3d = ar->regiondata; + /* when using all regions, don't jump out of camera view, + * but _do_ allow locked cameras to be moved */ + if ((rv3d->persp != RV3D_CAMOB) || ED_view3d_camera_lock_check(v3d, rv3d)) { + view3d_from_minmax(C, v3d, ar, min, max, ok_dist); + } + } + } +} static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in 2.4x */ { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); Scene *scene = CTX_data_scene(C); Base *base; float *curs; - const short skip_camera = ED_view3d_camera_lock_check(v3d, rv3d); - + const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); + const short skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) || + /* any one of the regions may be locked */ + (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA)); int center = RNA_boolean_get(op->ptr, "center"); - float size, min[3], max[3], afm[3]; + float min[3], max[3]; int ok = 1, onedone = FALSE; if (center) { @@ -2230,37 +2294,16 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in return OPERATOR_FINISHED; } - sub_v3_v3v3(afm, max, min); - size = 0.7f * MAX3(afm[0], afm[1], afm[2]); - if (size == 0.0f) ok = 0; - - if (ok) { - float new_dist; - float new_ofs[3]; - - new_dist = size; - new_ofs[0] = -(min[0] + max[0]) / 2.0f; - new_ofs[1] = -(min[1] + max[1]) / 2.0f; - new_ofs[2] = -(min[2] + max[2]) / 2.0f; - - /* 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, &new_dist, NULL); - } - else { - view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, &new_dist, NULL); - } + if (ok == 0) { + return OPERATOR_FINISHED; } -// XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); - WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, v3d); + if (use_all_regions) { + view3d_from_minmax_multi(C, v3d, min, max, TRUE); + } + else { + view3d_from_minmax(C, v3d, ar, min, max, TRUE); + } return OPERATOR_FINISHED; } @@ -2268,6 +2311,8 @@ static int view3d_all_exec(bContext *C, wmOperator *op) /* was view3d_home() in void VIEW3D_OT_view_all(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "View All"; ot->description = "View all objects in scene"; @@ -2280,25 +2325,25 @@ void VIEW3D_OT_view_all(wmOperatorType *ot) /* flags */ ot->flag = 0; + prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); RNA_def_boolean(ot->srna, "center", 0, "Center", ""); } /* like a localview without local!, was centerview() in 2.4x */ -static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) +static int viewselected_exec(bContext *C, wmOperator *op) { ARegion *ar = CTX_wm_region(C); View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = CTX_wm_region_view3d(C); 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; + const short use_all_regions = RNA_boolean_get(op->ptr, "use_all_regions"); + const short skip_camera = (ED_view3d_camera_lock_check(v3d, ar->regiondata) || + /* any one of the regions may be locked */ + (use_all_regions && v3d->flag2 & V3D_LOCK_CAMERA)); INIT_MINMAX(min, max); @@ -2369,54 +2414,17 @@ 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 (ok == 0) { + return OPERATOR_FINISHED; } - 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); + if (use_all_regions) { + view3d_from_minmax_multi(C, v3d, min, max, ok_dist); } else { - view3d_smooth_view(C, v3d, ar, NULL, NULL, new_ofs, NULL, ok_dist ? &new_dist : NULL, NULL); + view3d_from_minmax(C, v3d, ar, min, max, ok_dist); } - /* smooth view does viewlock RV3D_BOXVIEW copy */ - // XXX BIF_view3d_previewrender_signal(curarea, PR_DBASE|PR_DISPRECT); return OPERATOR_FINISHED; @@ -2424,6 +2432,7 @@ static int viewselected_exec(bContext *C, wmOperator *UNUSED(op)) void VIEW3D_OT_view_selected(wmOperatorType *ot) { + PropertyRNA *prop; /* identifiers */ ot->name = "View Selected"; @@ -2436,6 +2445,10 @@ void VIEW3D_OT_view_selected(wmOperatorType *ot) /* flags */ ot->flag = 0; + + /* rna later */ + prop = RNA_def_boolean(ot->srna, "use_all_regions", 0, "All Regions", "View selected for all regions"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static int view_lock_clear_exec(bContext *C, wmOperator *UNUSED(op)) @@ -2608,42 +2621,71 @@ static int render_border_exec(bContext *C, wmOperator *op) View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); RegionView3D *rv3d = ED_view3d_context_rv3d(C); + Scene *scene = CTX_data_scene(C); rcti rect; - rctf vb; + rctf vb, border; + + int camera_only = RNA_boolean_get(op->ptr, "camera_only"); + + if (camera_only && rv3d->persp != RV3D_CAMOB) + return OPERATOR_PASS_THROUGH; /* get border select values using rna */ WM_operator_properties_border_to_rcti(op, &rect); /* calculate range */ - ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); - scene->r.border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb); - scene->r.border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb); - scene->r.border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb); - scene->r.border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb); + if (rv3d->persp == RV3D_CAMOB) { + ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &vb, FALSE); + } + else { + vb.xmin = 0; + vb.ymin = 0; + vb.xmax = ar->winx; + vb.ymax = ar->winy; + } + + border.xmin = ((float)rect.xmin - vb.xmin) / BLI_rctf_size_x(&vb); + border.ymin = ((float)rect.ymin - vb.ymin) / BLI_rctf_size_y(&vb); + border.xmax = ((float)rect.xmax - vb.xmin) / BLI_rctf_size_x(&vb); + border.ymax = ((float)rect.ymax - vb.ymin) / BLI_rctf_size_y(&vb); /* actually set border */ - CLAMP(scene->r.border.xmin, 0.0f, 1.0f); - CLAMP(scene->r.border.ymin, 0.0f, 1.0f); - CLAMP(scene->r.border.xmax, 0.0f, 1.0f); - CLAMP(scene->r.border.ymax, 0.0f, 1.0f); + CLAMP(border.xmin, 0.0f, 1.0f); + CLAMP(border.ymin, 0.0f, 1.0f); + CLAMP(border.xmax, 0.0f, 1.0f); + CLAMP(border.ymax, 0.0f, 1.0f); + + if (rv3d->persp == RV3D_CAMOB) { + scene->r.border = border; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); + } + else { + v3d->render_border = border; + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } /* drawing a border surrounding the entire camera view switches off border rendering * or the border covers no pixels */ - if ((scene->r.border.xmin <= 0.0f && scene->r.border.xmax >= 1.0f && - scene->r.border.ymin <= 0.0f && scene->r.border.ymax >= 1.0f) || - (scene->r.border.xmin == scene->r.border.xmax || - scene->r.border.ymin == scene->r.border.ymax)) + if ((border.xmin <= 0.0f && border.xmax >= 1.0f && + border.ymin <= 0.0f && border.ymax >= 1.0f) || + (border.xmin == border.xmax || border.ymin == border.ymax)) { - scene->r.mode &= ~R_BORDER; + if (rv3d->persp == RV3D_CAMOB) + scene->r.mode &= ~R_BORDER; + else + v3d->flag2 &= ~V3D_RENDER_BORDER; } else { - scene->r.mode |= R_BORDER; + if (rv3d->persp == RV3D_CAMOB) + scene->r.mode |= R_BORDER; + else + v3d->flag2 |= V3D_RENDER_BORDER; } - - WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); return OPERATOR_FINISHED; @@ -2662,7 +2704,7 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) ot->modal = WM_border_select_modal; ot->cancel = WM_border_select_cancel; - ot->poll = view3d_camera_active_poll; + ot->poll = ED_operator_view3d_active; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -2670,7 +2712,56 @@ void VIEW3D_OT_render_border(wmOperatorType *ot) /* rna */ WM_operator_properties_border(ot); + RNA_def_boolean(ot->srna, "camera_only", 0, "Camera Only", "Set render border for camera view and final render only"); } + +/* ********************* Set render border operator ****************** */ + +static int clear_render_border_exec(bContext *C, wmOperator *UNUSED(op)) +{ + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = ED_view3d_context_rv3d(C); + + Scene *scene = CTX_data_scene(C); + rctf *border = NULL; + + if (rv3d->persp == RV3D_CAMOB) { + scene->r.mode &= ~R_BORDER; + border = &scene->r.border; + + WM_event_add_notifier(C, NC_SCENE | ND_RENDER_OPTIONS, NULL); + } + else { + v3d->flag2 &= ~V3D_RENDER_BORDER; + border = &v3d->render_border; + + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_VIEW3D, NULL); + } + + border->xmin = 0.0f; + border->ymin = 0.0f; + border->xmax = 1.0f; + border->ymax = 1.0f; + + return OPERATOR_FINISHED; + +} + +void VIEW3D_OT_clear_render_border(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Clear Render Border"; + ot->description = "Clear the boundaries of the border render and enables border render"; + ot->idname = "VIEW3D_OT_clear_render_border"; + + /* api callbacks */ + ot->exec = clear_render_border_exec; + ot->poll = ED_operator_view3d_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ********************* Border Zoom operator ****************** */ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) @@ -2729,7 +2820,7 @@ static int view3d_zoom_border_exec(bContext *C, wmOperator *op) /* no depths to use, we cant do anything! */ if (depth_close == FLT_MAX) { - BKE_report(op->reports, RPT_ERROR, "Depth Too Large"); + BKE_report(op->reports, RPT_ERROR, "Depth too large"); return OPERATOR_CANCELLED; } /* convert border to 3d coordinates */ @@ -2901,7 +2992,7 @@ static EnumPropertyItem prop_view_items[] = { {RV3D_VIEW_RIGHT, "RIGHT", 0, "Right", "View From the Right"}, {RV3D_VIEW_TOP, "TOP", 0, "Top", "View From the Top"}, {RV3D_VIEW_BOTTOM, "BOTTOM", 0, "Bottom", "View From the Bottom"}, - {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the active camera"}, + {RV3D_VIEW_CAMERA, "CAMERA", 0, "Camera", "View From the Active Camera"}, {0, NULL, 0, NULL, NULL} }; @@ -3125,7 +3216,7 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot) /* identifiers */ ot->name = "View numpad"; - ot->description = "Set the view"; + ot->description = "Use a preset viewpoint"; ot->idname = "VIEW3D_OT_viewnumpad"; /* api callbacks */ @@ -3135,8 +3226,8 @@ void VIEW3D_OT_viewnumpad(wmOperatorType *ot) /* flags */ ot->flag = 0; - prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "The Type of view"); - RNA_def_property_flag(prop, PROP_SKIP_SAVE); + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_items, 0, "View", "Preset viewpoint to use"); + RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); prop = RNA_def_boolean(ot->srna, "align_active", 0, "Align Active", "Align to the active object's axis"); RNA_def_property_flag(prop, PROP_SKIP_SAVE); } @@ -3213,7 +3304,9 @@ void VIEW3D_OT_view_orbit(wmOperatorType *ot) /* flags */ ot->flag = 0; - RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit"); + + /* properties */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_orbit_items, 0, "Orbit", "Direction of View Orbit"); } static EnumPropertyItem prop_view_pan_items[] = { @@ -3262,7 +3355,9 @@ void VIEW3D_OT_view_pan(wmOperatorType *ot) /* flags */ ot->flag = 0; - RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan"); + + /* Properties */ + ot->prop = RNA_def_enum(ot->srna, "type", prop_view_pan_items, 0, "Pan", "Direction of View Pan"); } static int viewpersportho_exec(bContext *C, wmOperator *UNUSED(op)) @@ -3290,7 +3385,7 @@ void VIEW3D_OT_view_persportho(wmOperatorType *ot) { /* identifiers */ ot->name = "View Persp/Ortho"; - ot->description = "Switch the current view from perspective/orthographic"; + ot->description = "Switch the current view from perspective/orthographic projection"; ot->idname = "VIEW3D_OT_view_persportho"; /* api callbacks */ @@ -3406,7 +3501,8 @@ void VIEW3D_OT_background_image_remove(wmOperatorType *ot) /* flags */ ot->flag = 0; - + + /* properties */ RNA_def_int(ot->srna, "index", 0, 0, INT_MAX, "Index", "Background image index to remove", 0, INT_MAX); } @@ -3534,7 +3630,7 @@ static int view3d_cursor3d_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent * /* flip = */ initgrabz(rv3d, fp[0], fp[1], fp[2]); } - if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(ar, fp, mval_fl, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { short depth_used = FALSE; if (U.uiflag & USER_ZBUF_CURSOR) { /* maybe this should be accessed some other way */ 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_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 5bfabf4fc4a..3017891183e 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -40,6 +40,7 @@ struct ARegionType; struct BoundBox; struct DerivedMesh; struct Object; +struct SmokeDomainSettings; struct ViewContext; struct bAnimVizSettings; struct bContext; @@ -50,8 +51,6 @@ struct wmNDOFMotionData; struct wmOperatorType; struct wmWindowManager; -#define BL_NEAR_CLIP 0.001 - /* drawing flags: */ enum { DRAW_PICKING = (1 << 0), @@ -97,6 +96,7 @@ void VIEW3D_OT_cursor3d(struct wmOperatorType *ot); void VIEW3D_OT_manipulator(struct wmOperatorType *ot); void VIEW3D_OT_enable_manipulator(struct wmOperatorType *ot); void VIEW3D_OT_render_border(struct wmOperatorType *ot); +void VIEW3D_OT_clear_render_border(struct wmOperatorType *ot); void VIEW3D_OT_zoom_border(struct wmOperatorType *ot); void view3d_boxview_copy(ScrArea *sa, ARegion *ar); @@ -212,7 +212,20 @@ ARegion *view3d_has_tools_region(ScrArea *sa); extern const char *view3d_context_dir[]; /* doc access */ /* draw_volume.c */ -void draw_volume(struct ARegion *ar, struct GPUTexture *tex, float min[3], float max[3], int res[3], float dx, struct GPUTexture *tex_shadow); +void draw_smoke_volume(struct SmokeDomainSettings *sds, struct Object *ob, + struct GPUTexture *tex, float min[3], float max[3], + int res[3], float dx, float base_scale, float viewnormal[3], + struct GPUTexture *tex_shadow, struct GPUTexture *tex_flame); + +//#define SMOKE_DEBUG_VELOCITY +//#define SMOKE_DEBUG_HEAT + +#ifdef SMOKE_DEBUG_VELOCITY +void draw_smoke_velocity(struct SmokeDomainSettings *domain, struct Object *ob); +#endif +#ifdef SMOKE_DEBUG_HEAT +void draw_smoke_heat(struct SmokeDomainSettings *domain, struct Object *ob); +#endif /* workaround for trivial but noticeable camera bug caused by imprecision * between view border calculation in 2D/3D space, workaround for bug [#28037]. diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c new file mode 100644 index 00000000000..0472f9f2c10 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -0,0 +1,415 @@ +/* + * ***** 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/view3d_iterators.c + * \ingroup spview3d + */ + +#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/space_view3d/view3d_ops.c b/source/blender/editors/space_view3d/view3d_ops.c index 14c02c2357e..73f1563417c 100644 --- a/source/blender/editors/space_view3d/view3d_ops.c +++ b/source/blender/editors/space_view3d/view3d_ops.c @@ -83,6 +83,7 @@ void view3d_operatortypes(void) WM_operatortype_append(VIEW3D_OT_select_circle); WM_operatortype_append(VIEW3D_OT_smoothview); WM_operatortype_append(VIEW3D_OT_render_border); + WM_operatortype_append(VIEW3D_OT_clear_render_border); WM_operatortype_append(VIEW3D_OT_zoom_border); WM_operatortype_append(VIEW3D_OT_manipulator); WM_operatortype_append(VIEW3D_OT_enable_manipulator); @@ -136,8 +137,10 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_verify_item(keymap, "VIEW3D_OT_move", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_dolly", MIDDLEMOUSE, KM_PRESS, KM_CTRL | KM_SHIFT, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); - WM_keymap_verify_item(keymap, "VIEW3D_OT_view_center_cursor", PADPERIOD, KM_PRESS, KM_CTRL, 0); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", FALSE); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_to_active", PADPERIOD, KM_PRESS, KM_SHIFT, 0); WM_keymap_verify_item(keymap, "VIEW3D_OT_view_lock_clear", PADPERIOD, KM_PRESS, KM_ALT, 0); @@ -169,6 +172,9 @@ void view3d_keymap(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, 0, 0); RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */ + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", HOMEKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "use_all_regions", TRUE); + RNA_boolean_set(kmi->ptr, "center", FALSE); /* only without camera view */ kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_view_all", CKEY, KM_PRESS, KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "center", TRUE); @@ -340,7 +346,13 @@ void view3d_keymap(wmKeyConfig *keyconf) WM_keymap_add_item(keymap, "VIEW3D_OT_clip_border", BKEY, KM_PRESS, KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_zoom_border", BKEY, KM_PRESS, KM_SHIFT, 0); - WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); + + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "camera_only", TRUE); + kmi = WM_keymap_add_item(keymap, "VIEW3D_OT_render_border", BKEY, KM_PRESS, KM_CTRL, 0); + RNA_boolean_set(kmi->ptr, "camera_only", FALSE); + + WM_keymap_add_item(keymap, "VIEW3D_OT_clear_render_border", BKEY, KM_PRESS, KM_CTRL | KM_ALT, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_camera_to_view", PAD0, KM_PRESS, KM_ALT | KM_CTRL, 0); WM_keymap_add_item(keymap, "VIEW3D_OT_object_as_camera", PAD0, KM_PRESS, KM_CTRL, 0); diff --git a/source/blender/editors/space_view3d/view3d_project.c b/source/blender/editors/space_view3d/view3d_project.c new file mode 100644 index 00000000000..5362f0377c3 --- /dev/null +++ b/source/blender/editors/space_view3d/view3d_project.c @@ -0,0 +1,493 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2008 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/space_view3d/view3d_project.c + * \ingroup spview3d + */ + +#include "DNA_object_types.h" +#include "DNA_screen_types.h" +#include "DNA_scene_types.h" +#include "DNA_view3d_types.h" + +#include "BLO_sys_types.h" /* int64_t */ + +#include "BIF_gl.h" /* bglMats */ +#include "BIF_glutil.h" /* bglMats */ + +#include "BLI_math_vector.h" + +#include "ED_view3d.h" /* own include */ + +#define BL_NEAR_CLIP 0.001 + +/* Non Clipping Projection Functions + * ********************************* */ + +/** + * \note use #ED_view3d_ob_project_mat_get to get the projection matrix + */ +void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4]) +{ + float vec4[4]; + + copy_v3_v3(vec4, co); + vec4[3] = 1.0; + /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ + + mul_m4_v4(mat, vec4); + + if (vec4[3] > FLT_EPSILON) { + r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; + r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; + } + else { + zero_v2(r_co); + } +} + +/** + * \note use #ED_view3d_ob_project_mat_get to get projecting mat + */ +void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4]) +{ + float vec4[4]; + + copy_v3_v3(vec4, vec); + vec4[3] = 1.0; + /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ + + mul_m4_v4(mat, vec4); + + if (vec4[3] > FLT_EPSILON) { + r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; + r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; + r_co[2] = vec4[2] / vec4[3]; + } + else { + zero_v3(r_co); + } +} + + +/* Clipping Projection Functions + * ***************************** */ + +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_DEFAULT); + + if (ret != V3D_PROJ_RET_OK) { + base->sx = IS_CLIPPED; + base->sy = 0; + } + + return ret; +} + +/* perspmat is typically... + * - 'rv3d->perspmat', is_local == FALSE + * - 'rv3d->perspmatob', is_local == TRUE + */ +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], 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) { + if (ED_view3d_clipping_test(rv3d, co, is_local)) { + return V3D_PROJ_RET_CLIP_BB; + } + } + } + + copy_v3_v3(vec4, co); + vec4[3] = 1.0; + mul_m4_v4(perspmat, vec4); + + if (vec4[3] > (float)BL_NEAR_CLIP) { + fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]); + if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) { + fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]); + if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) { + r_co[0] = (short)floor(fx); + r_co[1] = (short)floor(fy); + } + else { + return V3D_PROJ_RET_CLIP_WIN; + } + } + else { + return V3D_PROJ_RET_CLIP_WIN; + } + } + else { + return V3D_PROJ_RET_CLIP_NEAR; + } + + return V3D_PROJ_RET_OK; +} + +eV3DProjStatus ED_view3d_project_short_ex(ARegion *ar, float perspmat[4][4], const int is_local, + 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); + if (ret == V3D_PROJ_RET_OK) { + if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && + (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) + { + r_co[0] = (short)floor(tvec[0]); + r_co[1] = (short)floor(tvec[1]); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +eV3DProjStatus ED_view3d_project_int_ex(ARegion *ar, float perspmat[4][4], const int is_local, + 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); + if (ret == V3D_PROJ_RET_OK) { + if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && + (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) + { + r_co[0] = (int)floor(tvec[0]); + r_co[1] = (int)floor(tvec[1]); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +eV3DProjStatus ED_view3d_project_float_ex(ARegion *ar, float perspmat[4][4], const int is_local, + 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); + if (ret == V3D_PROJ_RET_OK) { + if (finite(tvec[0]) && + finite(tvec[1])) + { + copy_v2_v2(r_co, tvec); + } + else { + ret = V3D_PROJ_RET_OVERFLOW; + } + } + return ret; +} + +/* --- short --- */ +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], 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], 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], 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], 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], const eV3DProjTest flag) +{ + RegionView3D *rv3d = ar->regiondata; + return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); +} + + + +/* More Generic Window/Ray/Vector projection functions + * *************************************************** */ + +/* odd function, need to document better */ +int initgrabz(RegionView3D *rv3d, float x, float y, float z) +{ + int flip = FALSE; + if (rv3d == NULL) return flip; + rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3]; + if (rv3d->zfac < 0.0f) + flip = TRUE; + /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that + * (accounting for near zero values) + */ + if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f; + + /* Negative zfac means x, y, z was behind the camera (in perspective). + * This gives flipped directions, so revert back to ok default case. + */ + /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok + * Aligorith, 2009Aug31 */ + //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; + if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac; + + return flip; +} + +/** + * Calculate a 3d viewpoint and direction vector from 2d window coordinates. + * This ray_start is located at the viewpoint, ray_normal is the direction towards mval. + * ray_start is clipped by the view near limit so points in front of it are always in view. + * In orthographic view the resulting ray_normal will match the view vector. + * \param ar The region (used for the window width and height). + * \param v3d The 3d viewport (used for near clipping value). + * \param mval The area relative 2d location (such as event->mval, converted into float[2]). + * \param ray_start The world-space starting point of the segment. + * \param ray_normal The normalized world-space direction of towards mval. + */ +void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]) +{ + float ray_end[3]; + + ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end); + sub_v3_v3v3(ray_normal, ray_end, ray_start); + normalize_v3(ray_normal); +} + +/** + * Calculate a normalized 3d direction vector from the viewpoint towards a global location. + * In orthographic view the resulting vector will match the view vector. + * \param rv3d The region (used for the window width and height). + * \param coord The world-space location. + * \param vec The resulting normalized vector. + */ +void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3]) +{ + if (rv3d->is_persp) { + float p1[4], p2[4]; + + copy_v3_v3(p1, coord); + p1[3] = 1.0f; + copy_v3_v3(p2, p1); + p2[3] = 1.0f; + mul_m4_v4(rv3d->viewmat, p2); + + mul_v3_fl(p2, 2.0f); + + mul_m4_v4(rv3d->viewinv, p2); + + sub_v3_v3v3(vec, p1, p2); + } + else { + copy_v3_v3(vec, rv3d->viewinv[2]); + } + normalize_v3(vec); +} + +/** + * Calculate a 3d location from 2d window coordinates. + * \param ar The region (used for the window width and height). + * \param depth_pt The reference location used to calculate the Z depth. + * \param mval The area relative location (such as event->mval converted to floats). + * \param out The resulting world-space location. + */ +void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + float line_sta[3]; + float line_end[3]; + + if (rv3d->is_persp) { + float mousevec[3]; + copy_v3_v3(line_sta, rv3d->viewinv[3]); + ED_view3d_win_to_vector(ar, mval, mousevec); + add_v3_v3v3(line_end, line_sta, mousevec); + + if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) { + /* highly unlikely to ever happen, mouse vec paralelle with view plane */ + zero_v3(out); + } + } + else { + const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f; + const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f; + line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0]; + line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1]; + line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2]; + + add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]); + closest_to_line_v3(out, depth_pt, line_sta, line_end); + } +} + +/** + * Calculate a 3d difference vector from 2d window offset. + * note that initgrabz() must be called first to determine + * the depth used to calculate the delta. + * \param ar The region (used for the window width and height). + * \param mval The area relative 2d difference (such as event->mval[0] - other_x). + * \param out The resulting world-space delta. + */ +void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + float dx, dy; + + dx = 2.0f * mval[0] * rv3d->zfac / ar->winx; + dy = 2.0f * mval[1] * rv3d->zfac / ar->winy; + + out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy); + out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy); + out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy); +} + +/** + * Calculate a 3d direction vector from 2d window coordinates. + * This direction vector starts and the view in the direction of the 2d window coordinates. + * In orthographic view all window coordinates yield the same vector. + * + * \note doesn't rely on initgrabz + * for perspective view, get the vector direction to + * the mouse cursor as a normalized vector. + * + * \param ar The region (used for the window width and height). + * \param mval The area relative 2d location (such as event->mval converted to floats). + * \param out The resulting normalized world-space direction vector. + */ +void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->is_persp) { + out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f; + out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f; + out[2] = -0.5f; + mul_project_m4_v3(rv3d->persinv, out); + sub_v3_v3(out, rv3d->viewinv[3]); + } + else { + copy_v3_v3(out, rv3d->viewinv[2]); + } + normalize_v3(out); +} + +/** + * Calculate a 3d segment from 2d window coordinates. + * This ray_start is located at the viewpoint, ray_end is a far point. + * ray_start and ray_end are clipped by the view near and far limits + * so points along this line are always in view. + * In orthographic view all resulting segments will be parallel. + * \param ar The region (used for the window width and height). + * \param v3d The 3d viewport (used for near and far clipping range). + * \param mval The area relative 2d location (such as event->mval, converted into float[2]). + * \param ray_start The world-space starting point of the segment. + * \param ray_end The world-space end point of the segment. + */ +void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) +{ + RegionView3D *rv3d = ar->regiondata; + + if (rv3d->is_persp) { + float vec[3]; + ED_view3d_win_to_vector(ar, mval, vec); + + copy_v3_v3(ray_start, rv3d->viewinv[3]); + madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near); + madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far); + } + else { + float vec[4]; + vec[0] = 2.0f * mval[0] / ar->winx - 1; + vec[1] = 2.0f * mval[1] / ar->winy - 1; + vec[2] = 0.0f; + vec[3] = 1.0f; + + mul_m4_v4(rv3d->persinv, vec); + + madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2], 1000.0f); + madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f); + } + + /* clipping */ + if (rv3d->rflag & RV3D_CLIPPING) { + int a; + for (a = 0; a < 4; a++) { + clip_line_plane(ray_start, ray_end, rv3d->clip[a]); + } + } +} + + +/* Utility functions for projection + * ******************************** */ + +void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4]) +{ + float vmat[4][4]; + + mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat); + mult_m4_m4m4(pmat, rv3d->winmat, vmat); +} + +/** + * Uses window coordinates (x,y) and depth component z to find a point in + * modelspace */ +void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z) +{ + double ux, uy, uz; + + gluUnProject(x, y, z, mats->modelview, mats->projection, + (GLint *)mats->viewport, &ux, &uy, &uz); + + out[0] = ux; + out[1] = uy; + out[2] = uz; +} diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 53f2c2e9f5e..c30adf844a8 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -120,7 +120,7 @@ int view3d_get_view_aligned_coordinate(ViewContext *vc, float fp[3], const int m initgrabz(vc->rv3d, fp[0], fp[1], fp[2]); - if (ret == V3D_PROJ_RET_SUCCESS) { + if (ret == V3D_PROJ_RET_OK) { const float mval_f[2] = {(float)(mval_cpy[0] - mval[0]), (float)(mval_cpy[1] - mval[1])}; ED_view3d_win_to_delta(vc->ar, mval_f, dvec); @@ -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; + + BLI_lasso_boundbox(&rect, mcords, moves); - view3d_userdata_lassoselect_init(&data, vc, NULL, mcords, moves, select); + 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) @@ -856,9 +888,10 @@ static void view3d_lasso_select(bContext *C, ViewContext *vc, do_lasso_select_paintface(vc, mcords, moves, extend, select); else if (paint_vertsel_test(ob)) do_lasso_select_paintvert(vc, mcords, moves, extend, select); - else if (ob && ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT)) - ; - else if (ob && ob->mode & OB_MODE_PARTICLE_EDIT) + else if (ob && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT | OB_MODE_TEXTURE_PAINT))) { + /* pass */ + } + else if (ob && (ob->mode & OB_MODE_PARTICLE_EDIT)) PE_lasso_select(C, mcords, moves, extend, select); else { do_lasso_select_objects(vc, mcords, moves, extend, select); @@ -911,7 +944,7 @@ static int view3d_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); view3d_lasso_select(C, &vc, mcords, mcords_tot, extend, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return OPERATOR_FINISHED; } @@ -1387,9 +1420,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 +1446,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; @@ -1506,7 +1545,8 @@ static int mouse_select(bContext *C, const int mval[2], short extend, short dese } } } - else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) { /* then bone is found */ + else if (ED_do_pose_selectbuffer(scene, basact, buffer, hits, extend, deselect, toggle) ) { + /* then bone is found */ /* we make the armature selected: * not-selected active object in posemode won't work well for tools */ @@ -1582,6 +1622,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 */ @@ -1594,7 +1636,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 */ @@ -1603,23 +1649,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; } } @@ -1627,13 +1670,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; @@ -1669,16 +1712,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); } } @@ -1692,42 +1735,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); } } @@ -1753,18 +1796,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); } } @@ -1773,7 +1816,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); } } @@ -1972,12 +2015,10 @@ static int do_object_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, i } if (bone_selected) { - Object *ob = base->object; - - if (ob && (ob->type == OB_ARMATURE)) { - bArmature *arm = ob->data; + if (base->object && (base->object->type == OB_ARMATURE)) { + bArmature *arm = base->object->data; - WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob); + WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, base->object); if (arm && (arm->flag & ARM_HAS_VIZ_DEPS)) { /* mask modifier ('armature' mode), etc. */ @@ -2215,7 +2256,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; @@ -2229,6 +2271,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; @@ -2236,31 +2281,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); } } @@ -2283,7 +2324,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); } } @@ -2292,7 +2333,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); } } @@ -2301,7 +2342,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); } } @@ -2344,16 +2385,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); @@ -2387,17 +2425,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); } } @@ -2408,18 +2444,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 @@ -2428,7 +2462,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; @@ -2438,17 +2472,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; } } @@ -2461,7 +2495,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; @@ -2479,7 +2513,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; @@ -2493,13 +2527,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; @@ -2516,7 +2548,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; @@ -2526,17 +2558,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; } } @@ -2549,7 +2581,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); @@ -2568,7 +2600,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); @@ -2577,13 +2609,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; @@ -2597,7 +2627,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 */ @@ -2632,14 +2662,15 @@ 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_SUCCESS) + V3D_PROJ_TEST_CLIP_BB | V3D_PROJ_TEST_CLIP_WIN) == V3D_PROJ_RET_OK) { if (len_squared_v2v2(mval_fl, screen_co) <= radius_squared) { ED_base_object_select(base, select); diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index f138a95b0ef..de8cbd856e8 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,13 +241,15 @@ 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; v3d->lens = sms.new_lens; } + ED_view3d_camera_lock_sync(v3d, rv3d); + if (rv3d->viewlock & RV3D_BOXVIEW) view3d_boxview_copy(sa, ar); @@ -569,328 +571,27 @@ void ED_view3d_clipping_calc(BoundBox *bb, float planes[4][4], bglMats *mats, co } } -/** - * Calculate a 3d segment from 2d window coordinates. - * This ray_start is located at the viewpoint, ray_end is a far point. - * ray_start and ray_end are clipped by the view near and far limits - * so points along this line are always in view. - * In orthographic view all resulting segments will be parallel. - * \param ar The region (used for the window width and height). - * \param v3d The 3d viewport (used for near and far clipping range). - * \param mval The area relative 2d location (such as event->mval, converted into float[2]). - * \param ray_start The world-space starting point of the segment. - * \param ray_end The world-space end point of the segment. - */ -void ED_view3d_win_to_segment_clip(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_end[3]) -{ - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->is_persp) { - float vec[3]; - ED_view3d_win_to_vector(ar, mval, vec); - - copy_v3_v3(ray_start, rv3d->viewinv[3]); - madd_v3_v3v3fl(ray_start, rv3d->viewinv[3], vec, v3d->near); - madd_v3_v3v3fl(ray_end, rv3d->viewinv[3], vec, v3d->far); - } - else { - float vec[4]; - vec[0] = 2.0f * mval[0] / ar->winx - 1; - vec[1] = 2.0f * mval[1] / ar->winy - 1; - vec[2] = 0.0f; - vec[3] = 1.0f; - - mul_m4_v4(rv3d->persinv, vec); - - madd_v3_v3v3fl(ray_start, vec, rv3d->viewinv[2], 1000.0f); - madd_v3_v3v3fl(ray_end, vec, rv3d->viewinv[2], -1000.0f); - } - - /* clipping */ - if (rv3d->rflag & RV3D_CLIPPING) { - int a; - for (a = 0; a < 4; a++) { - clip_line_plane(ray_start, ray_end, rv3d->clip[a]); - } - } -} - -/** - * Calculate a 3d viewpoint and direction vector from 2d window coordinates. - * This ray_start is located at the viewpoint, ray_normal is the direction towards mval. - * ray_start is clipped by the view near limit so points in front of it are always in view. - * In orthographic view the resulting ray_normal will match the view vector. - * \param ar The region (used for the window width and height). - * \param v3d The 3d viewport (used for near clipping value). - * \param mval The area relative 2d location (such as event->mval, converted into float[2]). - * \param ray_start The world-space starting point of the segment. - * \param ray_normal The normalized world-space direction of towards mval. - */ -void ED_view3d_win_to_ray(ARegion *ar, View3D *v3d, const float mval[2], float ray_start[3], float ray_normal[3]) -{ - float ray_end[3]; - - ED_view3d_win_to_segment_clip(ar, v3d, mval, ray_start, ray_end); - sub_v3_v3v3(ray_normal, ray_end, ray_start); - normalize_v3(ray_normal); -} - -/** - * Calculate a normalized 3d direction vector from the viewpoint towards a global location. - * In orthographic view the resulting vector will match the view vector. - * \param rv3d The region (used for the window width and height). - * \param coord The world-space location. - * \param vec The resulting normalized vector. - */ -void ED_view3d_global_to_vector(RegionView3D *rv3d, const float coord[3], float vec[3]) -{ - if (rv3d->is_persp) { - float p1[4], p2[4]; - - copy_v3_v3(p1, coord); - p1[3] = 1.0f; - copy_v3_v3(p2, p1); - p2[3] = 1.0f; - mul_m4_v4(rv3d->viewmat, p2); - - mul_v3_fl(p2, 2.0f); - - mul_m4_v4(rv3d->viewinv, p2); - - sub_v3_v3v3(vec, p1, p2); - } - else { - copy_v3_v3(vec, rv3d->viewinv[2]); - } - normalize_v3(vec); -} - -int initgrabz(RegionView3D *rv3d, float x, float y, float z) -{ - int flip = FALSE; - if (rv3d == NULL) return flip; - rv3d->zfac = rv3d->persmat[0][3] * x + rv3d->persmat[1][3] * y + rv3d->persmat[2][3] * z + rv3d->persmat[3][3]; - if (rv3d->zfac < 0.0f) - flip = TRUE; - /* if x,y,z is exactly the viewport offset, zfac is 0 and we don't want that - * (accounting for near zero values) - */ - if (rv3d->zfac < 1.e-6f && rv3d->zfac > -1.e-6f) rv3d->zfac = 1.0f; - - /* Negative zfac means x, y, z was behind the camera (in perspective). - * This gives flipped directions, so revert back to ok default case. - */ - /* NOTE: I've changed this to flip zfac to be positive again for now so that GPencil draws ok - * Aligorith, 2009Aug31 */ - //if (rv3d->zfac < 0.0f) rv3d->zfac = 1.0f; - if (rv3d->zfac < 0.0f) rv3d->zfac = -rv3d->zfac; - - return flip; -} - -/** - * Calculate a 3d location from 2d window coordinates. - * \param ar The region (used for the window width and height). - * \param depth_pt The reference location used to calculate the Z depth. - * \param mval The area relative location (such as event->mval converted to floats). - * \param out The resulting world-space location. - */ -void ED_view3d_win_to_3d(ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - - float line_sta[3]; - float line_end[3]; - - if (rv3d->is_persp) { - float mousevec[3]; - copy_v3_v3(line_sta, rv3d->viewinv[3]); - ED_view3d_win_to_vector(ar, mval, mousevec); - add_v3_v3v3(line_end, line_sta, mousevec); - - if (isect_line_plane_v3(out, line_sta, line_end, depth_pt, rv3d->viewinv[2], TRUE) == 0) { - /* highly unlikely to ever happen, mouse vec paralelle with view plane */ - zero_v3(out); - } - } - else { - const float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f; - const float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f; - line_sta[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0]; - line_sta[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1]; - line_sta[2] = (rv3d->persinv[0][2] * dx) + (rv3d->persinv[1][2] * dy) + rv3d->viewinv[3][2]; - - add_v3_v3v3(line_end, line_sta, rv3d->viewinv[2]); - closest_to_line_v3(out, depth_pt, line_sta, line_end); - } -} - -/** - * Calculate a 3d difference vector from 2d window offset. - * note that initgrabz() must be called first to determine - * the depth used to calculate the delta. - * \param ar The region (used for the window width and height). - * \param mval The area relative 2d difference (such as event->mval[0] - other_x). - * \param out The resulting world-space delta. - */ -void ED_view3d_win_to_delta(ARegion *ar, const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - float dx, dy; - - dx = 2.0f * mval[0] * rv3d->zfac / ar->winx; - dy = 2.0f * mval[1] * rv3d->zfac / ar->winy; - - out[0] = (rv3d->persinv[0][0] * dx + rv3d->persinv[1][0] * dy); - out[1] = (rv3d->persinv[0][1] * dx + rv3d->persinv[1][1] * dy); - out[2] = (rv3d->persinv[0][2] * dx + rv3d->persinv[1][2] * dy); -} - -/** - * Calculate a 3d direction vector from 2d window coordinates. - * This direction vector starts and the view in the direction of the 2d window coordinates. - * In orthographic view all window coordinates yield the same vector. - * - * \note doesn't rely on initgrabz - * for perspective view, get the vector direction to - * the mouse cursor as a normalized vector. - * - * \param ar The region (used for the window width and height). - * \param mval The area relative 2d location (such as event->mval converted to floats). - * \param out The resulting normalized world-space direction vector. - */ -void ED_view3d_win_to_vector(ARegion *ar, const float mval[2], float out[3]) -{ - RegionView3D *rv3d = ar->regiondata; - - if (rv3d->is_persp) { - out[0] = 2.0f * (mval[0] / ar->winx) - 1.0f; - out[1] = 2.0f * (mval[1] / ar->winy) - 1.0f; - out[2] = -0.5f; - mul_project_m4_v3(rv3d->persinv, out); - sub_v3_v3(out, rv3d->viewinv[3]); - } - else { - copy_v3_v3(out, rv3d->viewinv[2]); - } - normalize_v3(out); -} - -float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y) -{ - ViewDepths *vd = vc->rv3d->depths; - - x -= vc->ar->winrct.xmin; - y -= vc->ar->winrct.ymin; - - if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) - return vd->depths[y * vd->w + x]; - else - return 1; -} - -void ED_view3d_depth_tag_update(RegionView3D *rv3d) -{ - if (rv3d->depths) - rv3d->depths->damaged = 1; -} - -void ED_view3d_ob_project_mat_get(RegionView3D *rv3d, Object *ob, float pmat[4][4]) -{ - float vmat[4][4]; - - mult_m4_m4m4(vmat, rv3d->viewmat, ob->obmat); - mult_m4_m4m4(pmat, rv3d->winmat, vmat); -} - -/* Uses window coordinates (x,y) and depth component z to find a point in - * modelspace */ -void ED_view3d_unproject(bglMats *mats, float out[3], const float x, const float y, const float z) -{ - double ux, uy, uz; - - gluUnProject(x, y, z, mats->modelview, mats->projection, - (GLint *)mats->viewport, &ux, &uy, &uz); - - out[0] = ux; - out[1] = uy; - out[2] = uz; -} - -/* use #ED_view3d_ob_project_mat_get to get projecting mat */ -void ED_view3d_project_float_v2_m4(const ARegion *ar, const float co[3], float r_co[2], float mat[4][4]) -{ - float vec4[4]; - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ - - mul_m4_v4(mat, vec4); - - if (vec4[3] > FLT_EPSILON) { - r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; - r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; - } - else { - zero_v2(r_co); - } -} - -/* use #ED_view3d_ob_project_mat_get to get projecting mat */ -void ED_view3d_project_float_v3_m4(ARegion *ar, const float vec[3], float r_co[3], float mat[4][4]) -{ - float vec4[4]; - - copy_v3_v3(vec4, vec); - vec4[3] = 1.0; - /* r_co[0] = IS_CLIPPED; */ /* always overwritten */ - - mul_m4_v4(mat, vec4); - - if (vec4[3] > FLT_EPSILON) { - r_co[0] = (float)(ar->winx / 2.0f) + (ar->winx / 2.0f) * vec4[0] / vec4[3]; - r_co[1] = (float)(ar->winy / 2.0f) + (ar->winy / 2.0f) * vec4[1] / vec4[3]; - r_co[2] = vec4[2] / vec4[3]; - } - else { - zero_v3(r_co); - } -} - -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); - - if (ret != V3D_PROJ_RET_SUCCESS) { - base->sx = IS_CLIPPED; - base->sy = 0; - } - - return ret; -} int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) { /* return 1: draw */ - + float mat[4][4]; float vec[4], min, max; int a, flag = -1, fl; - + if (bb == NULL) return 1; if (bb->flag & OB_BB_DISABLED) return 1; - + mult_m4_m4m4(mat, rv3d->persmat, obmat); - + for (a = 0; a < 8; a++) { copy_v3_v3(vec, bb->vec[a]); vec[3] = 1.0; mul_m4_v4(mat, vec); max = vec[3]; min = -vec[3]; - + fl = 0; if (vec[0] < min) fl += 1; if (vec[0] > max) fl += 2; @@ -898,153 +599,31 @@ int ED_view3d_boundbox_clip(RegionView3D *rv3d, float obmat[][4], BoundBox *bb) if (vec[1] > max) fl += 8; if (vec[2] < min) fl += 16; if (vec[2] > max) fl += 32; - + flag &= fl; if (flag == 0) return 1; } - - return 0; -} - -/* perspmat is typically... - * - 'rv3d->perspmat', is_local == FALSE - * - 'rv3d->perspmatob', is_local == TRUE - */ -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) -{ - float fx, fy, vec4[4]; - if (flag & V3D_PROJ_TEST_CLIP_BB) { - RegionView3D *rv3d = ar->regiondata; - if (rv3d->rflag & RV3D_CLIPPING) { - if (ED_view3d_clipping_test(rv3d, co, is_local)) { - return V3D_PROJ_RET_CLIP_BB; - } - } - } - - copy_v3_v3(vec4, co); - vec4[3] = 1.0; - mul_m4_v4(perspmat, vec4); - - if (vec4[3] > (float)BL_NEAR_CLIP) { - fx = ((float)ar->winx / 2.0f) * (1.0f + vec4[0] / vec4[3]); - if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fx > 0 && fx < ar->winx)) { - fy = ((float)ar->winy / 2.0f) * (1.0f + vec4[1] / vec4[3]); - if (((flag & V3D_PROJ_TEST_CLIP_WIN) == 0) || (fy > 0.0f && fy < (float)ar->winy)) { - r_co[0] = (short)floor(fx); - r_co[1] = (short)floor(fy); - } - else { - return V3D_PROJ_RET_CLIP_WIN; - } - } - else { - return V3D_PROJ_RET_CLIP_WIN; - } - } - else { - return V3D_PROJ_RET_CLIP_NEAR; - } - - return V3D_PROJ_RET_SUCCESS; -} - -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) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { - if ((tvec[0] > -32700.0 && tvec[0] < 32700.0f) && - (tvec[1] > -32700.0 && tvec[1] < 32700.0f)) - { - r_co[0] = (short)floor(tvec[0]); - r_co[1] = (short)floor(tvec[1]); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; -} - -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) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { - if ((tvec[0] > -2140000000.0 && tvec[0] < 2140000000.0f) && - (tvec[1] > -2140000000.0 && tvec[1] < 2140000000.0f)) - { - r_co[0] = (int)floor(tvec[0]); - r_co[1] = (int)floor(tvec[1]); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; -} - -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) -{ - float tvec[2]; - eV3DProjStatus ret = ed_view3d_project__internal(ar, perspmat, is_local, co, tvec, flag); - if (ret == V3D_PROJ_RET_SUCCESS) { - if (finite(tvec[0]) && - finite(tvec[1])) - { - copy_v2_v2(r_co, tvec); - } - else { - ret = V3D_PROJ_RET_OVERFLOW; - } - } - return ret; + return 0; } -/* --- short --- */ -eV3DProjStatus ED_view3d_project_short_global(ARegion *ar, const float co[3], short r_co[2], 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) +float ED_view3d_depth_read_cached(ViewContext *vc, int x, int y) { - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_short_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); -} + ViewDepths *vd = vc->rv3d->depths; + + x -= vc->ar->winrct.xmin; + y -= vc->ar->winrct.ymin; -/* --- int --- */ -eV3DProjStatus ED_view3d_project_int_global(ARegion *ar, const float co[3], int r_co[2], 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) -{ - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_int_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); + if (vd && vd->depths && x > 0 && y > 0 && x < vd->w && y < vd->h) + return vd->depths[y * vd->w + x]; + else + return 1; } -/* --- float --- */ -eV3DProjStatus ED_view3d_project_float_global(ARegion *ar, const float co[3], float r_co[2], 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) +void ED_view3d_depth_tag_update(RegionView3D *rv3d) { - RegionView3D *rv3d = ar->regiondata; - return ED_view3d_project_float_ex(ar, rv3d->persmatob, TRUE, co, r_co, flag); + if (rv3d->depths) + rv3d->depths->damaged = 1; } /* copies logic of get_view3d_viewplane(), keep in sync */ @@ -1458,7 +1037,7 @@ static int view3d_localview_init(Main *bmain, Scene *scene, ScrArea *sa, ReportL locallay = free_localbit(bmain); if (locallay == 0) { - BKE_reportf(reports, RPT_ERROR, "No more than 8 localviews"); + BKE_reportf(reports, RPT_ERROR, "No more than 8 local views"); ok = FALSE; } else { @@ -1647,7 +1226,6 @@ static int localview_exec(bContext *C, wmOperator *op) void VIEW3D_OT_localview(wmOperatorType *ot) { - /* identifiers */ ot->name = "Local View"; ot->description = "Toggle display of selected object(s) separately and centered in view"; diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c index d2354a4a7ad..4a61978cc80 100644 --- a/source/blender/editors/transform/transform.c +++ b/source/blender/editors/transform/transform.c @@ -90,15 +90,12 @@ #include "BLI_linklist.h" #include "BLI_smallhash.h" #include "BLI_array.h" -#include "PIL_time.h" #include "UI_interface_icons.h" #include "UI_resources.h" #include "transform.h" -#include <stdio.h> // XXX: duplicated??? - static void drawTransformApply(const struct bContext *C, ARegion *ar, void *arg); static int doEdgeSlide(TransInfo *t, float perc); @@ -230,7 +227,7 @@ void projectIntView(TransInfo *t, const float vec[3], int adr[2]) { if (t->spacetype == SPACE_VIEW3D) { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { adr[0] = (int)2140000000.0f; /* this is what was done in 2.64, perhaps we can be smarter? */ adr[1] = (int)2140000000.0f; } @@ -355,7 +352,7 @@ void projectFloatView(TransInfo *t, const float vec[3], float adr[2]) case SPACE_VIEW3D: { if (t->ar->regiontype == RGN_TYPE_WINDOW) { - if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, vec, adr, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { /* XXX, 2.64 and prior did this, weak! */ adr[0] = t->ar->winx / 2.0f; adr[1] = t->ar->winy / 2.0f; @@ -1273,7 +1270,6 @@ int transformEvent(TransInfo *t, wmEvent *event) t->redraw |= t->handleEvent(t, event); if (handled || t->redraw) { - t->last_update = PIL_check_seconds_timer(); return 0; } else { @@ -1562,49 +1558,31 @@ static void drawTransformView(const struct bContext *C, ARegion *UNUSED(ar), voi } /* just draw a little warning message in the top-right corner of the viewport to warn that autokeying is enabled */ -static void drawAutoKeyWarning(TransInfo *t, ARegion *ar) +static void drawAutoKeyWarning(TransInfo *UNUSED(t), ARegion *ar) { - int show_warning; - - /* red border around the viewport */ - UI_ThemeColor(TH_REDALERT); + const char printable[] = "Auto Keying On"; + float printable_size[2]; + int xco, yco; + + BLF_width_and_height_default(printable, &printable_size[0], &printable_size[1]); - glBegin(GL_LINE_LOOP); - glVertex2f(1, 1); - glVertex2f(1, ar->winy-1); - glVertex2f(ar->winx-1, ar->winy-1); - glVertex2f(ar->winx-1, 1); - glEnd(); + xco = ar->winx - (int)printable_size[0] - 10; + yco = ar->winy - (int)printable_size[1] - 10; - /* Entire warning should "blink" to catch periphery attention without being overly distracting - * much like how a traditional recording sign in the corner of a camcorder works - * - * - Blink frequency here is 0.5 secs (i.e. a compromise between epilepsy-inducing flicker + too slow to notice). - * We multiply by two to speed up the odd/even time-in-seconds = on/off toggle. - * - Always start with warning shown so that animators are more likely to notice when starting to transform + /* warning text (to clarify meaning of overlays) + * - original color was red to match the icon, but that clashes badly with a less nasty border */ - show_warning = (int)(t->last_update * 2.0) & 1; + UI_ThemeColorShade(TH_TEXT_HI, -50); + BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); - if ((show_warning) || (t->state == TRANS_STARTING)) { - const char printable[] = "Auto Keying On"; - int xco, yco; - - xco = ar->winx - BLF_width_default(printable) - 10; - yco = ar->winy - BLF_height_default(printable) - 10; - - /* red warning text */ - UI_ThemeColor(TH_REDALERT); - BLF_draw_default_ascii(xco, ar->winy - 17, 0.0f, printable, sizeof(printable)); - - /* autokey recording icon... */ - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glEnable(GL_BLEND); - - xco -= (ICON_DEFAULT_WIDTH + 2); - UI_icon_draw(xco, yco, ICON_REC); - - glDisable(GL_BLEND); - } + /* autokey recording icon... */ + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glEnable(GL_BLEND); + + xco -= (ICON_DEFAULT_WIDTH + 2); + UI_icon_draw(xco, yco, ICON_REC); + + glDisable(GL_BLEND); } static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, void *arg) @@ -1613,10 +1591,18 @@ static void drawTransformPixel(const struct bContext *UNUSED(C), ARegion *ar, vo Scene *scene = t->scene; Object *ob = OBACT; - /* draw autokeyframing hint in the corner */ - if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { - drawAutoKeyWarning(t, ar); - } + /* draw autokeyframing hint in the corner + * - only draw if enabled (advanced users may be distracted/annoyed), + * for objects that will be autokeyframed (no point ohterwise), + * AND only for the active region (as showing all is too overwhelming) + */ + if ((U.autokey_flag & AUTOKEY_FLAG_NOWARNING) == 0) { + if (ar == t->ar) { + if (ob && autokeyframe_cfra_can_key(scene, &ob->id)) { + drawAutoKeyWarning(t, ar); + } + } + } } void saveTransform(bContext *C, TransInfo *t, wmOperator *op) @@ -4037,12 +4023,15 @@ int Tilt(TransInfo *t, const int UNUSED(mval[2])) outputNumInput(&(t->num), c); - sprintf(str, "Tilt: %s %s", &c[0], t->proptext); + sprintf(str, "Tilt: %s° %s", &c[0], t->proptext); final = DEG2RADF(final); + + /* XXX For some reason, this seems needed for this op, else RNA prop is not updated... :/ */ + t->values[0] = final; } else { - sprintf(str, "Tilt: %.2f %s", RAD2DEGF(final), t->proptext); + sprintf(str, "Tilt: %.2f° %s", RAD2DEGF(final), t->proptext); } for (i = 0; i < t->total; i++, td++) { @@ -4853,7 +4842,7 @@ static void calcNonProportionalEdgeSlide(TransInfo *t, SlideData *sld, const flo sv->edge_len = len_v3v3(dw_p, up_p); mul_v3_m4v3(v_proj, t->obedit->obmat, sv->v->co); - if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, v_proj, v_proj, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { dist = len_squared_v2v2(mval, v_proj); if (dist < min_dist) { min_dist = dist; @@ -4871,10 +4860,9 @@ static int createSlideVerts(TransInfo *t) { BMEditMesh *em = BMEdit_FromObject(t->obedit); BMesh *bm = em->bm; - BMIter iter, iter2; + BMIter iter; BMEdge *e, *e1; BMVert *v, *v2, *first; - BMLoop *l, *l1, *l2; TransDataSlideVert *sv_array; BMBVHTree *btree = BMBVH_NewBVH(em, BMBVH_RESPECT_HIDDEN, NULL, NULL); SmallHash table; @@ -4914,6 +4902,7 @@ static int createSlideVerts(TransInfo *t) /*ensure valid selection*/ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + BMIter iter2; numsel = 0; BM_ITER_ELEM (e, &iter2, v, BM_EDGES_OF_VERT) { if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { @@ -4966,6 +4955,8 @@ static int createSlideVerts(TransInfo *t) j = 0; while (1) { + BMLoop *l, *l1, *l2; + v = NULL; BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_TAG)) @@ -5099,7 +5090,7 @@ static int createSlideVerts(TransInfo *t) if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { BMIter iter2; BMEdge *e2; - float vec1[3], mval[2] = {t->mval[0], t->mval[1]}, d; + float vec1[3], d; /* search cross edges for visible edge to the mouse cursor, * then use the shared vertex to calculate screen vector*/ diff --git a/source/blender/editors/transform/transform.h b/source/blender/editors/transform/transform.h index 40f53423d37..1f9775821d1 100644 --- a/source/blender/editors/transform/transform.h +++ b/source/blender/editors/transform/transform.h @@ -323,8 +323,6 @@ typedef struct TransInfo { float axis[3]; float axis_orig[3]; /* TransCon can change 'axis', store the original value here */ - double last_update; /* Time of last update (in seconds) */ - void *view; struct bContext *context; /* Only valid (non null) during an operator called function. */ struct ScrArea *sa; diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 39a5da94798..2e9d1ee670f 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -3986,13 +3986,13 @@ static void SeqTransInfo(TransInfo *t, Sequence *seq, int *recursive, int *count *flag = (seq->flag | SELECT) & ~(SEQ_LEFTSEL | SEQ_RIGHTSEL); if (t->frame_side == 'R') { - if (right <= cfra) *count = *flag = 0; /* ignore */ - else if (left > cfra) ; /* keep the selection */ + if (right <= cfra) { *count = *flag = 0; } /* ignore */ + else if (left > cfra) { } /* keep the selection */ else *flag |= SEQ_RIGHTSEL; } else { - if (left >= cfra) *count = *flag = 0; /* ignore */ - else if (right < cfra) ; /* keep the selection */ + if (left >= cfra) { *count = *flag = 0; } /* ignore */ + else if (right < cfra) { } /* keep the selection */ else *flag |= SEQ_LEFTSEL; } } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 81a4c082dcc..fc0c174a525 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -605,8 +605,10 @@ static void TRANSFORM_OT_trackball(struct wmOperatorType *ot) static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ - ot->name = "Rotate"; + ot->name = "Rotate"; ot->description = "Rotate selected items"; ot->idname = OP_ROTATION; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; @@ -618,19 +620,22 @@ static void TRANSFORM_OT_rotate(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_screenactive; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + prop = RNA_def_float(ot->srna, "value", 0.0f, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + RNA_def_property_subtype(prop, PROP_ANGLE); Transform_Properties(ot, P_AXIS | P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_GEO_SNAP); } static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ - ot->name = "Tilt"; + ot->name = "Tilt"; /* optionals - * "Tilt selected vertices" - * "Specify an extra axis rotation for selected vertices of 3d curve" */ - ot->description = "Tilt selected control vertices of 3d curve"; + * "Specify an extra axis rotation for selected vertices of 3D curve" */ + ot->description = "Tilt selected control vertices of 3D curve"; ot->idname = OP_TILT; ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING; @@ -641,9 +646,10 @@ static void TRANSFORM_OT_tilt(struct wmOperatorType *ot) ot->cancel = transform_cancel; ot->poll = ED_operator_editcurve_3d; - RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + prop = RNA_def_float(ot->srna, "value", 0.0, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI * 2, M_PI * 2); + RNA_def_property_subtype(prop, PROP_ANGLE); - Transform_Properties(ot, P_CONSTRAINT | P_PROPORTIONAL | P_MIRROR | P_SNAP); + Transform_Properties(ot, P_PROPORTIONAL | P_MIRROR | P_SNAP); } static void TRANSFORM_OT_warp(struct wmOperatorType *ot) diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c index 0e25739c34a..845d5b73f0c 100644 --- a/source/blender/editors/transform/transform_orientations.c +++ b/source/blender/editors/transform/transform_orientations.c @@ -631,7 +631,6 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], /* if there's an edge available, use that for the tangent */ if (em->bm->totedgesel >= 1) { BMEdge *eed = NULL; - BMIter iter; BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { @@ -746,14 +745,14 @@ int getTransformOrientation(const bContext *C, float normal[3], float plane[3], MetaBall *mb = obedit->data; if (mb->lastelem) { - float mat[4][4]; + float qmat[3][3]; /* Rotation of MetaElem is stored in quat */ - quat_to_mat4(mat, mb->lastelem->quat); + quat_to_mat3(qmat, mb->lastelem->quat); - copy_v3_v3(normal, mat[2]); + copy_v3_v3(normal, qmat[2]); - negate_v3_v3(plane, mat[1]); + negate_v3_v3(plane, qmat[1]); result = ORIENTATION_FACE; } diff --git a/source/blender/editors/transform/transform_snap.c b/source/blender/editors/transform/transform_snap.c index 2f2b31de89d..94b8abb8850 100644 --- a/source/blender/editors/transform/transform_snap.c +++ b/source/blender/editors/transform/transform_snap.c @@ -317,7 +317,7 @@ void applyProject(TransInfo *t) copy_v3_v3(iloc, td->ob->obmat[3]); } - if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_float_global(t->ar, iloc, mval, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { if (snapObjectsTransform(t, mval, &dist, loc, no, t->tsnap.modeSelect)) { // if (t->flag & (T_EDIT|T_POSE)) { // mul_m4_v3(imat, loc); @@ -603,7 +603,7 @@ int updateSelectedSnapPoint(TransInfo *t) int dx, dy; int dist; - if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(t->ar, p->co, screen_loc, V3D_PROJ_TEST_NOP) != V3D_PROJ_RET_OK) { continue; } @@ -1236,7 +1236,7 @@ static int snapEdge(ARegion *ar, float v1co[3], short v1no[3], float v2co[3], sh new_depth = len_v3v3(location, ray_start); - if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); } else { @@ -1297,7 +1297,7 @@ static int snapVertex(ARegion *ar, float vco[3], short vno[3], float obmat[][4], new_depth = len_v3v3(location, ray_start); - if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_SUCCESS) { + if (ED_view3d_project_int_global(ar, location, screen_loc, V3D_PROJ_TEST_NOP) == V3D_PROJ_RET_OK) { new_dist = abs(screen_loc[0] - (int)mval[0]) + abs(screen_loc[1] - (int)mval[1]); } else { diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c index d6794912043..7aaae404d15 100644 --- a/source/blender/editors/uvedit/uvedit_draw.c +++ b/source/blender/editors/uvedit/uvedit_draw.c @@ -453,8 +453,6 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) int drawfaces, interpedges; Image *ima = sima->image; - StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); - activetf = EDBM_mtexpoly_active_get(em, &efa_act, FALSE, FALSE); /* will be set to NULL if hidden */ activef = BM_active_face_get(bm, FALSE, FALSE); ts = scene->toolsettings; @@ -823,51 +821,6 @@ static void draw_uvs(SpaceImage *sima, Scene *scene, Object *obedit) bglEnd(); } - /* finally draw stitch preview */ - if (stitch_preview) { - int i, index = 0; - glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); - glEnableClientState(GL_VERTEX_ARRAY); - - glEnable(GL_BLEND); - - UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris); - glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3); - - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys); - for (i = 0; i < stitch_preview->num_polys; i++) { - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - UI_ThemeColor4(TH_STITCH_PREVIEW_FACE); - glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); - glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE); - glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); - - index += stitch_preview->uvs_per_polygon[i]; - } - glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); -#if 0 - UI_ThemeColor4(TH_STITCH_PREVIEW_VERT); - glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3); -#endif - glDisable(GL_BLEND); - - /* draw vert preview */ - glPointSize(pointsize * 2.0f); - UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); - glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); - - UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); - glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); - glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); - - glPopClientAttrib(); - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - } - glPointSize(1.0); } diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h index f0ff79ae25e..3a89d6ce892 100644 --- a/source/blender/editors/uvedit/uvedit_intern.h +++ b/source/blender/editors/uvedit/uvedit_intern.h @@ -75,30 +75,6 @@ void uv_find_nearest_edge(struct Scene *scene, struct Image *ima, struct BMEditM struct UvElement *ED_uv_element_get(struct UvElementMap *map, struct BMFace *efa, struct BMLoop *l); void uvedit_live_unwrap_update(struct SpaceImage *sima, struct Scene *scene, struct Object *obedit); -/* smart stitch */ - -/* object that stores display data for previewing before accepting stitching */ -typedef struct StitchPreviewer { - /* here we'll store the preview triangle indices of the mesh */ - float *preview_polys; - /* uvs per polygon. */ - unsigned int *uvs_per_polygon; - /*number of preview polygons */ - unsigned int num_polys; - /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ - float *preview_stitchable; - float *preview_unstitchable; - /* here we'll store the number of elements to be drawn */ - unsigned int num_stitchable; - unsigned int num_unstitchable; - unsigned int preview_uvs; - /* ...and here we'll store the triangles*/ - float *static_tris; - unsigned int num_static_tris; -} StitchPreviewer; - -StitchPreviewer *uv_get_stitch_previewer(void); - /* operators */ void UV_OT_average_islands_scale(struct wmOperatorType *ot); diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c index 6e655faf35f..acc69309a8c 100644 --- a/source/blender/editors/uvedit/uvedit_ops.c +++ b/source/blender/editors/uvedit/uvedit_ops.c @@ -170,7 +170,6 @@ void ED_object_assign_active_image(Main *bmain, Object *ob, int mat_nr, Image *i void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *ima, Image *previma) { BMEditMesh *em; - BMFace *efa; BMIter iter; MTexPoly *tf; int update = 0; @@ -198,6 +197,8 @@ void ED_uvedit_assign_image(Main *bmain, Scene *scene, Object *obedit, Image *im ED_object_assign_active_image(bmain, obedit, efa->mat_nr + 1, ima); } else { + BMFace *efa; + /* old shading system, assign image to selected faces */ #ifdef USE_SWITCH_ASPECT float prev_aspect[2], fprev_aspect; @@ -771,13 +772,15 @@ static int nearest_uv_between(BMEditMesh *em, BMFace *efa, int UNUSED(nverts), i BM_ITER_ELEM (l, &iter, efa, BM_LOOPS_OF_FACE) { luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); - if (i == id1) + if (i == id1) { uv1 = luv->uv; - else if (i == id) - ; /* uv2 = luv->uv; */ /* UNUSED */ - else if (i == id2) + } + else if (i == id) { + /* uv2 = luv->uv; */ /* UNUSED */ + } + else if (i == id2) { uv3 = luv->uv; - + } i++; } @@ -1310,9 +1313,7 @@ static void weld_align_uv(bContext *C, int tool) Object *obedit; Image *ima; BMEditMesh *em; - BMIter iter, liter; MTexPoly *tf; - MLoopUV *luv; float cent[2], min[2], max[2]; scene = CTX_data_scene(C); @@ -1324,6 +1325,7 @@ static void weld_align_uv(bContext *C, int tool) INIT_MINMAX2(min, max); if (tool == 'a') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1335,7 +1337,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); DO_MINMAX2(luv->uv, min, max); } } @@ -1347,6 +1349,7 @@ static void weld_align_uv(bContext *C, int tool) uvedit_center(scene, ima, obedit, cent, 0); if (tool == 'x' || tool == 'w') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1357,7 +1360,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); luv->uv[0] = cent[0]; } @@ -1366,6 +1369,7 @@ static void weld_align_uv(bContext *C, int tool) } if (tool == 'y' || tool == 'w') { + BMIter iter, liter; BMFace *efa; BMLoop *l; @@ -1376,7 +1380,7 @@ static void weld_align_uv(bContext *C, int tool) BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) { if (uvedit_uv_select_test(em, scene, l)) { - luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); + MLoopUV *luv = CustomData_bmesh_get(&em->bm->ldata, l->head.data, CD_MLOOPUV); luv->uv[1] = cent[1]; } @@ -2131,7 +2135,7 @@ static int select_linked_internal(bContext *C, wmOperator *op, wmEvent *event, i NearestHit hit, *hit_p = NULL; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't select linked when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot select linked when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2238,7 +2242,7 @@ static int select_split_exec(bContext *C, wmOperator *op) short change = FALSE; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't split selection when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot split selection when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2279,6 +2283,7 @@ static int select_split_exec(bContext *C, wmOperator *op) } if (change) { + WM_event_add_notifier(C, NC_SPACE | ND_SPACE_IMAGE, NULL); return OPERATOR_FINISHED; } else { @@ -2316,7 +2321,7 @@ static int unlink_selection_exec(bContext *C, wmOperator *op) MLoopUV *luv; if (ts->uv_flag & UV_SYNC_SELECTION) { - BKE_report(op->reports, RPT_ERROR, "Can't unlink selection when sync selection is enabled"); + BKE_report(op->reports, RPT_ERROR, "Cannot unlink selection when sync selection is enabled"); return OPERATOR_CANCELLED; } @@ -2487,13 +2492,16 @@ static void uv_faces_do_sticky(SpaceImage *sima, Scene *scene, Object *obedit, s break; if (efa_index != vlist_iter->f) { + BMLoop *l_other; efa_vlist = EDBM_face_at_index(em, vlist_iter->f); /* tf_vlist = CustomData_bmesh_get(&em->bm->pdata, efa_vlist->head.data, CD_MTEXPOLY); */ /* UNUSED */ + l_other = BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex); + if (select) - uvedit_uv_select_enable(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex), FALSE); + uvedit_uv_select_enable(em, scene, l_other, FALSE); else - uvedit_uv_select_disable(em, scene, BM_iter_at_index(em->bm, BM_LOOPS_OF_FACE, efa_vlist, vlist_iter->tfindex)); + uvedit_uv_select_disable(em, scene, l_other); } vlist_iter = vlist_iter->next; } @@ -2827,7 +2835,7 @@ static int uv_lasso_select_exec(bContext *C, wmOperator *op) select = !RNA_boolean_get(op->ptr, "deselect"); change = do_lasso_select_mesh_uv(C, mcords, mcords_tot, select); - MEM_freeN(mcords); + MEM_freeN((void *)mcords); return change ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c index 4e0e7944e84..2b225118472 100644 --- a/source/blender/editors/uvedit/uvedit_smart_stitch.c +++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c @@ -46,6 +46,8 @@ #include "BLI_math_vector.h" #include "BLI_string.h" +#include "BIF_gl.h" + #include "BKE_context.h" #include "BKE_customdata.h" #include "BKE_depsgraph.h" @@ -55,6 +57,7 @@ #include "ED_mesh.h" #include "ED_uvedit.h" #include "ED_screen.h" +#include "ED_space_api.h" #include "RNA_access.h" #include "RNA_define.h" @@ -63,11 +66,32 @@ #include "WM_types.h" #include "UI_view2d.h" +#include "UI_resources.h" #include "uvedit_intern.h" /* ********************** smart stitch operator *********************** */ +/* object that stores display data for previewing before accepting stitching */ +typedef struct StitchPreviewer { + /* here we'll store the preview triangle indices of the mesh */ + float *preview_polys; + /* uvs per polygon. */ + unsigned int *uvs_per_polygon; + /*number of preview polygons */ + unsigned int num_polys; + /* preview data. These will be either the previewed vertices or edges depending on stitch mode settings */ + float *preview_stitchable; + float *preview_unstitchable; + /* here we'll store the number of elements to be drawn */ + unsigned int num_stitchable; + unsigned int num_unstitchable; + unsigned int preview_uvs; + /* ...and here we'll store the triangles*/ + float *static_tris; + unsigned int num_static_tris; +} StitchPreviewer; + struct IslandStitchData; @@ -143,6 +167,8 @@ typedef struct StitchState { int static_island; /* store number of primitives per face so that we can allocate the active island buffer later */ unsigned int *tris_per_island; + + void *draw_handle; } StitchState; typedef struct PreviewPosition { @@ -216,7 +242,7 @@ static void stitch_preview_delete(void) /* "getter method" */ -StitchPreviewer *uv_get_stitch_previewer(void) +static StitchPreviewer *uv_get_stitch_previewer(void) { return _stitch_preview; } @@ -981,6 +1007,55 @@ static void stitch_calculate_edge_normal(BMEditMesh *em, UvEdge *edge, float *no normalize_v2(normal); } +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); + StitchPreviewer *stitch_preview = uv_get_stitch_previewer(); + + glPushClientAttrib(GL_CLIENT_VERTEX_ARRAY_BIT); + glEnableClientState(GL_VERTEX_ARRAY); + + glEnable(GL_BLEND); + + UI_ThemeColor4(TH_STITCH_PREVIEW_ACTIVE); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->static_tris); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_static_tris * 3); + + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_polys); + for (i = 0; i < stitch_preview->num_polys; i++) { + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + UI_ThemeColor4(TH_STITCH_PREVIEW_FACE); + glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); + glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + UI_ThemeColor4(TH_STITCH_PREVIEW_EDGE); + glDrawArrays(GL_POLYGON, index, stitch_preview->uvs_per_polygon[i]); + + index += stitch_preview->uvs_per_polygon[i]; + } + glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); +#if 0 + UI_ThemeColor4(TH_STITCH_PREVIEW_VERT); + glDrawArrays(GL_TRIANGLES, 0, stitch_preview->num_tris * 3); +#endif + glDisable(GL_BLEND); + + /* draw vert preview */ + glPointSize(pointsize * 2.0f); + UI_ThemeColor4(TH_STITCH_PREVIEW_STITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_stitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_stitchable); + + UI_ThemeColor4(TH_STITCH_PREVIEW_UNSTITCHABLE); + glVertexPointer(2, GL_FLOAT, 0, stitch_preview->preview_unstitchable); + glDrawArrays(GL_POINTS, 0, stitch_preview->num_unstitchable); + + glPopClientAttrib(); + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + +} + static int stitch_init(bContext *C, wmOperator *op) { /* for fast edge lookup... */ @@ -1016,6 +1091,7 @@ static int stitch_init(bContext *C, wmOperator *op) state->static_island = RNA_int_get(op->ptr, "static_island"); state->midpoints = RNA_boolean_get(op->ptr, "midpoint_snap"); state->clear_seams = RNA_boolean_get(op->ptr, "clear_seams"); + state->draw_handle = ED_region_draw_cb_activate(CTX_wm_region(C)->type, stitch_draw, NULL, REGION_DRAW_POST_VIEW); /* in uv synch selection, all uv's are visible */ if (ts->uv_flag & UV_SYNC_SELECTION) { state->element_map = EDBM_uv_element_map_create(state->em, 0, 1); @@ -1282,6 +1358,8 @@ static void stitch_exit(bContext *C, wmOperator *op, int finished) if (sa) ED_area_headerprint(sa, NULL); + ED_region_draw_cb_exit(CTX_wm_region(C)->type, stitch_state->draw_handle); + DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c index 7c06fbd2a9d..19a1c4339ad 100644 --- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c +++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c @@ -223,7 +223,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, BMLoop *ls[3]; float *co[4]; float *uv[4]; - int i, lsel; + int lsel; if ((BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) || (sel && BM_elem_flag_test(efa, BM_ELEM_SELECT) == 0)) continue; @@ -245,6 +245,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, // tf = CustomData_bmesh_get(&em->bm->pdata, efa->head.data, CD_MTEXPOLY); // UNUSED if (efa->len == 3 || efa->len == 4) { + int i; /* for quads let parametrize split, it can make better decisions * about which split is best for unwrapping than scanfill */ i = 0; @@ -291,6 +292,7 @@ static ParamHandle *construct_param_handle(Scene *scene, BMEditMesh *em, BLI_scanfill_calc_ex(&sf_ctx, TRUE, efa->no); for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) { + int i; ls[0] = sf_tri->v1->tmp.p; ls[1] = sf_tri->v2->tmp.p; ls[2] = sf_tri->v3->tmp.p; @@ -727,12 +729,10 @@ static int pack_islands_exec(bContext *C, wmOperator *op) return OPERATOR_CANCELLED; } - if (RNA_struct_property_is_set(op->ptr, "margin")) { + if (RNA_struct_property_is_set(op->ptr, "margin")) scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); - } - else { + else RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); - } handle = construct_param_handle(scene, em, implicit, 0, 1, 1); param_pack(handle, scene->toolsettings->uvcalc_margin); @@ -759,7 +759,7 @@ void UV_OT_pack_islands(wmOperatorType *ot) ot->poll = ED_operator_uvedit; /* properties */ - RNA_def_float_factor(ot->srna, "margin", 0.0f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); + RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } /* ******************** Average Islands Scale operator **************** */ @@ -1184,7 +1184,8 @@ static int unwrap_exec(bContext *C, wmOperator *op) mat4_to_size(obsize, obedit->obmat); if (!compare_v3v3(obsize, unitsize, 1e-4f)) - BKE_report(op->reports, RPT_INFO, "Object scale is not 1.0. Unwrap will operate on a non-scaled version of the mesh."); + BKE_report(op->reports, RPT_INFO, + "Object scale is not 1.0, unwrap will operate on a non-scaled version of the mesh"); /* remember last method for live unwrap */ if (RNA_struct_property_is_set(op->ptr, "method")) @@ -1192,6 +1193,12 @@ static int unwrap_exec(bContext *C, wmOperator *op) else RNA_enum_set(op->ptr, "method", scene->toolsettings->unwrapper); + /* remember packing marging */ + if (RNA_struct_property_is_set(op->ptr, "margin")) + scene->toolsettings->uvcalc_margin = RNA_float_get(op->ptr, "margin"); + else + RNA_float_set(op->ptr, "margin", scene->toolsettings->uvcalc_margin); + scene->toolsettings->uv_subsurf_level = subsurf_level; if (fill_holes) scene->toolsettings->uvcalc_flag |= UVCALC_FILLHOLES; @@ -1239,8 +1246,9 @@ void UV_OT_unwrap(wmOperatorType *ot) "Map UVs taking image aspect ratio into account"); RNA_def_boolean(ot->srna, "use_subsurf_data", 0, "Use Subsurf Data", "Map UVs taking vertex position after subsurf into account"); - RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "SubSurf Target", + RNA_def_int(ot->srna, "uv_subsurf_level", 1, 1, 6, "Subsurf Target", "Number of times to subdivide before calculating UVs", 1, 6); + RNA_def_float_factor(ot->srna, "margin", 0.001f, 0.0f, 1.0f, "Margin", "Space between islands", 0.0f, 1.0f); } /**************** Project From View operator **************/ diff --git a/source/blender/gpu/GPU_extensions.h b/source/blender/gpu/GPU_extensions.h index 198d002ff0d..f4bb5da0495 100644 --- a/source/blender/gpu/GPU_extensions.h +++ b/source/blender/gpu/GPU_extensions.h @@ -107,7 +107,7 @@ int GPU_type_matches(GPUDeviceType device, GPUOSType os, GPUDriverType driver); GPUTexture *GPU_texture_create_1D(int w, float *pixels, char err_out[256]); GPUTexture *GPU_texture_create_2D(int w, int h, float *pixels, char err_out[256]); -GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels); +GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels); GPUTexture *GPU_texture_create_depth(int w, int h, char err_out[256]); GPUTexture *GPU_texture_create_vsm_shadow_map(int size, char err_out[256]); GPUTexture *GPU_texture_from_blender(struct Image *ima, diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c index 201162262b2..2986ce85c88 100644 --- a/source/blender/gpu/intern/gpu_buffers.c +++ b/source/blender/gpu/intern/gpu_buffers.c @@ -1562,7 +1562,7 @@ GPU_Buffers *GPU_build_mesh_buffers(int (*face_vert_indices)[4], glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, 0); } - if (buffers->index_buf || !buffers->smooth) + if (gpu_vbo_enabled() && (buffers->index_buf || !buffers->smooth)) glGenBuffersARB(1, &buffers->vert_buf); buffers->tot_tri = tottri; @@ -1763,7 +1763,7 @@ static GLuint gpu_get_grid_buffer(int gridsize, GLenum *index_type, unsigned *to /* VBO is disabled; delete the previous buffer (if it exists) and * return an invalid handle */ - if (gpu_vbo_enabled()) { + if (!gpu_vbo_enabled()) { if (buffer) glDeleteBuffersARB(1, &buffer); return 0; diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 956c76aec20..ac05f1e8309 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1019,21 +1019,53 @@ void GPU_free_smoke(SmokeModifierData *smd) if (smd->domain->tex_shadow) GPU_texture_free(smd->domain->tex_shadow); smd->domain->tex_shadow = NULL; + + if (smd->domain->tex_flame) + GPU_texture_free(smd->domain->tex_flame); + smd->domain->tex_flame = NULL; } } void GPU_create_smoke(SmokeModifierData *smd, int highres) { #ifdef WITH_SMOKE - if (smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && !highres) - smd->domain->tex = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smoke_get_density(smd->domain->fluid)); - else if (smd->type & MOD_SMOKE_TYPE_DOMAIN && !smd->domain->tex && highres) - smd->domain->tex = GPU_texture_create_3D(smd->domain->res_wt[0], smd->domain->res_wt[1], smd->domain->res_wt[2], smoke_turbulence_get_density(smd->domain->wt)); + if (smd->type & MOD_SMOKE_TYPE_DOMAIN) { + SmokeDomainSettings *sds = smd->domain; + if (!sds->tex && !highres) { + /* rgba texture for color + density */ + if (smoke_has_colors(sds->fluid)) { + float *data = MEM_callocN(sizeof(float)*sds->total_cells*4, "smokeColorTexture"); + smoke_get_rgba(sds->fluid, data, 0); + sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 4, data); + MEM_freeN(data); + } + /* density only */ + else { + sds->tex = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_density(sds->fluid)); + } + sds->tex_flame = (smoke_has_fuel(sds->fluid)) ? GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, smoke_get_flame(sds->fluid)) : NULL; + } + else if (!sds->tex && highres) { + /* rgba texture for color + density */ + if (smoke_turbulence_has_colors(sds->wt)) { + float *data = MEM_callocN(sizeof(float)*smoke_turbulence_get_cells(sds->wt)*4, "smokeColorTexture"); + smoke_turbulence_get_rgba(sds->wt, data, 0); + sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 4, data); + MEM_freeN(data); + } + /* density only */ + else { + sds->tex = GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_density(sds->wt)); + } + sds->tex_flame = (smoke_turbulence_has_fuel(sds->wt)) ? GPU_texture_create_3D(sds->res_wt[0], sds->res_wt[1], sds->res_wt[2], 1, smoke_turbulence_get_flame(sds->wt)) : NULL; + } - smd->domain->tex_shadow = GPU_texture_create_3D(smd->domain->res[0], smd->domain->res[1], smd->domain->res[2], smd->domain->shadow); + sds->tex_shadow = GPU_texture_create_3D(sds->res[0], sds->res[1], sds->res[2], 1, sds->shadow); + } #else // WITH_SMOKE (void)highres; smd->domain->tex= NULL; + smd->domain->tex_flame= NULL; smd->domain->tex_shadow= NULL; #endif // WITH_SMOKE } diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index c5f427fbcab..798868a5efe 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -442,7 +442,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in } -GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) +GPUTexture *GPU_texture_create_3D(int w, int h, int depth, int channels, float *fpixels) { GPUTexture *tex; GLenum type, format, internalformat; @@ -480,9 +480,15 @@ GPUTexture *GPU_texture_create_3D(int w, int h, int depth, float *fpixels) GPU_print_error("3D glBindTexture"); - type = GL_FLOAT; // GL_UNSIGNED_BYTE - format = GL_RED; - internalformat = GL_INTENSITY; + type = GL_FLOAT; + if (channels == 4) { + format = GL_RGBA; + internalformat = GL_RGBA; + } + else { + format = GL_RED; + internalformat = GL_INTENSITY; + } //if (fpixels) // pixels = GPU_texture_convert_pixels(w*h*depth, fpixels); diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c index e035f1c3f5a..e5f08d38ce8 100644 --- a/source/blender/gpu/intern/gpu_material.c +++ b/source/blender/gpu/intern/gpu_material.c @@ -780,7 +780,9 @@ static void shade_one_light(GPUShadeInput *shi, GPUShadeResult *shr, GPULamp *la } } - if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS); + if (mat->scene->gm.flag & GAME_GLSL_NO_SHADERS) { + /* pass */ + } else if (!(lamp->mode & LA_NO_SPEC) && !(lamp->mode & LA_ONLYSHADOW) && (GPU_link_changed(shi->spec) || ma->spec != 0.0f)) { diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 81c3cab97d4..716ffc2b254 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1992,7 +1992,7 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out vec4 result) result = vec4(L*color.rgb, 1.0); } -void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 result) +void node_bsdf_glossy(vec4 color, float roughness, vec3 N, out vec4 result) { /* ambient light */ vec3 L = vec3(0.2); @@ -2013,12 +2013,12 @@ void node_bsdf_glossy(vec4 color, float roughness, vec3 N, vec3 I, out vec4 resu result = vec4(L*color.rgb, 1.0); } -void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 I, out vec4 result) +void node_bsdf_anisotropic(vec4 color, float roughnessU, float roughnessV, vec3 N, vec3 T, out vec4 result) { node_bsdf_diffuse(color, 0.0, N, result); } -void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, vec3 I, out vec4 result) +void node_bsdf_glass(vec4 color, float roughness, float ior, vec3 N, out vec4 result) { node_bsdf_diffuse(color, 0.0, N, result); } @@ -2195,7 +2195,8 @@ void node_light_path( out float is_glossy_ray, out float is_singular_ray, out float is_reflection_ray, - out float is_transmission_ray) + out float is_transmission_ray, + out float ray_length) { is_camera_ray = 1.0; is_shadow_ray = 0.0; @@ -2204,6 +2205,7 @@ void node_light_path( is_singular_ray = 0.0; is_reflection_ray = 0.0; is_transmission_ray = 0.0; + ray_length = 1.0; } void node_light_falloff(float strength, float tsmooth, out float quadratic, out float linear, out float constant) @@ -2221,6 +2223,10 @@ void node_object_info(out vec3 location, out float object_index, out float mater random = 0.0; } +void node_bump(float strength, float height, vec3 N, out vec3 result) +{ + result = N; +} /* output */ diff --git a/source/blender/ikplugin/BIK_api.h b/source/blender/ikplugin/BIK_api.h index e1d5f50edfb..4fc273bd435 100644 --- a/source/blender/ikplugin/BIK_api.h +++ b/source/blender/ikplugin/BIK_api.h @@ -92,5 +92,4 @@ void BIK_test_constraint(struct Object *ob, struct bConstraint *cons); } #endif -#endif // __BIK_API_H__ - +#endif /* __BIK_API_H__ */ diff --git a/source/blender/ikplugin/CMakeLists.txt b/source/blender/ikplugin/CMakeLists.txt index 903267c5618..0a0e0e664b4 100644 --- a/source/blender/ikplugin/CMakeLists.txt +++ b/source/blender/ikplugin/CMakeLists.txt @@ -56,9 +56,11 @@ endif() if(WITH_IK_ITASC) add_definitions(-DWITH_IK_ITASC) list(APPEND INC - ../../../extern/Eigen3 ../../../intern/itasc ) + list(APPEND INC_SYS + ../../../extern/Eigen3 + ) list(APPEND SRC intern/itasc_plugin.cpp intern/itasc_plugin.h diff --git a/source/blender/ikplugin/intern/ikplugin_api.h b/source/blender/ikplugin/intern/ikplugin_api.h index 77c962269dc..53d9da8e614 100644 --- a/source/blender/ikplugin/intern/ikplugin_api.h +++ b/source/blender/ikplugin/intern/ikplugin_api.h @@ -60,5 +60,4 @@ typedef struct IKPlugin IKPlugin; } #endif -#endif // __IKPLUGIN_API_H__ - +#endif /* __IKPLUGIN_API_H__ */ diff --git a/source/blender/ikplugin/intern/iksolver_plugin.h b/source/blender/ikplugin/intern/iksolver_plugin.h index dd00c5f4add..c2ae4f937e7 100644 --- a/source/blender/ikplugin/intern/iksolver_plugin.h +++ b/source/blender/ikplugin/intern/iksolver_plugin.h @@ -47,5 +47,4 @@ void iksolver_execute_tree(struct Scene *scene, struct Object *ob, struct bPose } #endif -#endif // __IKSOLVER_PLUGIN_H__ - +#endif /* __IKSOLVER_PLUGIN_H__ */ diff --git a/source/blender/ikplugin/intern/itasc_plugin.h b/source/blender/ikplugin/intern/itasc_plugin.h index 0d5fde0bec0..0500125b4c7 100644 --- a/source/blender/ikplugin/intern/itasc_plugin.h +++ b/source/blender/ikplugin/intern/itasc_plugin.h @@ -52,5 +52,4 @@ void itasc_test_constraint(struct Object *ob, struct bConstraint *cons); } #endif -#endif // __ITASC_PLUGIN_H__ - +#endif /* __ITASC_PLUGIN_H__ */ diff --git a/source/blender/imbuf/CMakeLists.txt b/source/blender/imbuf/CMakeLists.txt index bbe70a7d73f..344ae604ed4 100644 --- a/source/blender/imbuf/CMakeLists.txt +++ b/source/blender/imbuf/CMakeLists.txt @@ -25,7 +25,6 @@ set(INC . - ../avi ../blenkernel ../blenlib ../blenloader @@ -143,6 +142,13 @@ if(WITH_IMAGE_REDCODE) add_definitions(-DWITH_REDCODE) endif() +if(WITH_CODEC_AVI) + list(APPEND INC + ../avi + ) + add_definitions(-DWITH_AVI) +endif() + if(WITH_CODEC_QUICKTIME) list(APPEND INC ../quicktime diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index e2604241caf..0653956e113 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -130,7 +130,8 @@ void IMB_colormanagement_colorspace_items_add(struct EnumPropertyItem **items, i void IMB_partial_display_buffer_update(struct ImBuf *ibuf, const float *linear_buffer, const unsigned char *buffer_byte, int stride, int offset_x, int offset_y, const struct ColorManagedViewSettings *view_settings, const struct ColorManagedDisplaySettings *display_settings, - int xmin, int ymin, int xmax, int ymax); + int xmin, int ymin, int xmax, int ymax, + int update_orig_byte_buffer); /* ** Pixel processor functions ** */ struct ColormanageProcessor *IMB_colormanagement_display_processor_new(const struct ColorManagedViewSettings *view_settings, diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h index f03f709f13f..76c247b2195 100644 --- a/source/blender/imbuf/IMB_imbuf_types.h +++ b/source/blender/imbuf/IMB_imbuf_types.h @@ -242,7 +242,7 @@ typedef struct ImBuf { ((unsigned long)(unsigned char)(ch1) << 8) | \ ((unsigned long)(unsigned char)(ch2) << 16) | \ ((unsigned long)(unsigned char)(ch3) << 24)) -#endif //MAKEFOURCC +#endif /* MAKEFOURCC */ /* * FOURCC codes for DX compressed-texture pixel formats @@ -255,7 +255,7 @@ typedef struct ImBuf { #define FOURCC_DXT4 (MAKEFOURCC('D','X','T','4')) #define FOURCC_DXT5 (MAKEFOURCC('D','X','T','5')) -#endif // DDS +#endif /* DDS */ extern const char *imb_ext_image[]; extern const char *imb_ext_image_qt[]; extern const char *imb_ext_movie[]; diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h index d5cc4929aed..ed349e8f7eb 100644 --- a/source/blender/imbuf/intern/IMB_anim.h +++ b/source/blender/imbuf/intern/IMB_anim.h @@ -62,7 +62,9 @@ #include "imbuf.h" -#include "AVI_avi.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif #ifdef WITH_QUICKTIME # if defined(_WIN32) || defined(__APPLE__) diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c index 394f5169046..4aeba9af89d 100644 --- a/source/blender/imbuf/intern/anim_movie.c +++ b/source/blender/imbuf/intern/anim_movie.c @@ -78,7 +78,9 @@ #include "imbuf.h" -#include "AVI_avi.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif #ifdef WITH_QUICKTIME #if defined(_WIN32) || defined(__APPLE__) @@ -185,6 +187,7 @@ static void an_stringenc(char *string, const char *head, const char *tail, unsig BLI_stringenc(string, head, tail, numlen, pic); } +#ifdef WITH_AVI static void free_anim_avi(struct anim *anim) { #if defined(_WIN32) && !defined(FREE_WINDOWS) @@ -219,6 +222,7 @@ static void free_anim_avi(struct anim *anim) anim->duration = 0; } +#endif /* WITH_AVI */ #ifdef WITH_FFMPEG static void free_anim_ffmpeg(struct anim *anim); @@ -235,7 +239,10 @@ void IMB_free_anim(struct anim *anim) } free_anim_movie(anim); + +#ifdef WITH_AVI free_anim_avi(anim); +#endif #ifdef WITH_QUICKTIME free_anim_quicktime(anim); @@ -287,7 +294,7 @@ struct anim *IMB_open_anim(const char *name, int ib_flags, int streamindex, char return(anim); } - +#ifdef WITH_AVI static int startavi(struct anim *anim) { @@ -397,7 +404,9 @@ static int startavi(struct anim *anim) return 0; } +#endif /* WITH_AVI */ +#ifdef WITH_AVI static ImBuf *avi_fetchibuf(struct anim *anim, int position) { ImBuf *ibuf = NULL; @@ -447,6 +456,7 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position) return ibuf; } +#endif /* WITH_AVI */ #ifdef WITH_FFMPEG @@ -1206,7 +1216,11 @@ static ImBuf *anim_getnew(struct anim *anim) if (anim == NULL) return(NULL); free_anim_movie(anim); + +#ifdef WITH_AVI free_anim_avi(anim); +#endif + #ifdef WITH_QUICKTIME free_anim_quicktime(anim); #endif @@ -1233,6 +1247,7 @@ static ImBuf *anim_getnew(struct anim *anim) if (startmovie(anim)) return (NULL); ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); /* fake */ break; +#ifdef WITH_AVI case ANIM_AVI: if (startavi(anim)) { printf("couldnt start avi\n"); @@ -1240,6 +1255,7 @@ static ImBuf *anim_getnew(struct anim *anim) } ibuf = IMB_allocImBuf(anim->x, anim->y, 24, 0); break; +#endif #ifdef WITH_QUICKTIME case ANIM_QTIME: if (startquicktime(anim)) return (0); @@ -1331,11 +1347,13 @@ struct ImBuf *IMB_anim_absolute(struct anim *anim, int position, IMB_convert_rgba_to_abgr(ibuf); } break; +#ifdef WITH_AVI case ANIM_AVI: ibuf = avi_fetchibuf(anim, position); if (ibuf) anim->curposition = position; break; +#endif #ifdef WITH_QUICKTIME case ANIM_QTIME: ibuf = qtime_fetchibuf(anim, position); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 37510c10e9a..ff474d85a8c 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -99,6 +99,7 @@ static pthread_mutex_t processor_lock = BLI_MUTEX_INITIALIZER; typedef struct ColormanageProcessor { OCIO_ConstProcessorRcPtr *processor; CurveMapping *curve_mapping; + int is_data_result; } ColormanageProcessor; /*********************** Color managed cache *************************/ @@ -1207,6 +1208,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle) int predivide = handle->predivide; int is_data = handle->is_data; + int is_data_display = handle->cm_processor->is_data_result; linear_buffer = MEM_callocN(buffer_size * sizeof(float), "color conversion linear buffer"); @@ -1228,7 +1230,7 @@ static void *display_buffer_apply_get_linear_buffer(DisplayBufferThread *handle) *fp = (float)(*cp) / 255.0f; } - if (!is_data) { + if (!is_data && !is_data_display) { /* convert float buffer to scene linear space */ IMB_colormanagement_transform(linear_buffer, width, height, channels, from_colorspace, to_colorspace, predivide); @@ -1822,7 +1824,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet if (global_tot_display) ibuf->display_buffer_flags = MEM_callocN(sizeof(unsigned int) * global_tot_display, "imbuf display_buffer_flags"); } - else if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) { + else if (ibuf->userflags & IB_DISPLAY_BUFFER_INVALID) { /* all display buffers were marked as invalid from other areas, * now propagate this flag to internal color management routines */ @@ -2347,7 +2349,6 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe } else if (byte_buffer) { rgba_uchar_to_float(pixel, byte_buffer + linear_index); - IMB_colormanagement_colorspace_to_scene_linear_v3(pixel, rect_colorspace); } @@ -2382,9 +2383,9 @@ static void partial_buffer_update_rect(ImBuf *ibuf, unsigned char *display_buffe void IMB_partial_display_buffer_update(ImBuf *ibuf, const float *linear_buffer, const unsigned char *byte_buffer, int stride, int offset_x, int offset_y, const ColorManagedViewSettings *view_settings, const ColorManagedDisplaySettings *display_settings, - int xmin, int ymin, int xmax, int ymax) + int xmin, int ymin, int xmax, int ymax, int update_orig_byte_buffer) { - if (ibuf->rect && ibuf->rect_float) { + if ((ibuf->rect && ibuf->rect_float) || update_orig_byte_buffer) { /* update byte buffer created by legacy color management */ unsigned char *rect = (unsigned char *) ibuf->rect; @@ -2449,28 +2450,29 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag const ColorManagedDisplaySettings *display_settings) { ColormanageProcessor *cm_processor; + ColorManagedViewSettings default_view_settings; + const ColorManagedViewSettings *applied_view_settings; + ColorSpace *display_space; cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor"); - { - ColorManagedViewSettings default_view_settings; - const ColorManagedViewSettings *applied_view_settings; + if (view_settings) { + applied_view_settings = view_settings; + } + else { + init_default_view_settings(display_settings, &default_view_settings); + applied_view_settings = &default_view_settings; + } - if (view_settings) { - applied_view_settings = view_settings; - } - else { - init_default_view_settings(display_settings, &default_view_settings); - applied_view_settings = &default_view_settings; - } + display_space = display_transform_get_colorspace(applied_view_settings, display_settings); + cm_processor->is_data_result = display_space->is_data; - cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device, - applied_view_settings->exposure, applied_view_settings->gamma); + cm_processor->processor = create_display_buffer_processor(applied_view_settings->view_transform, display_settings->display_device, + applied_view_settings->exposure, applied_view_settings->gamma); - if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { - cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping); - curvemapping_premultiply(cm_processor->curve_mapping, FALSE); - } + if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) { + cm_processor->curve_mapping = curvemapping_copy(applied_view_settings->curve_mapping); + curvemapping_premultiply(cm_processor->curve_mapping, FALSE); } return cm_processor; @@ -2479,9 +2481,13 @@ ColormanageProcessor *IMB_colormanagement_display_processor_new(const ColorManag ColormanageProcessor *IMB_colormanagement_colorspace_processor_new(const char *from_colorspace, const char *to_colorspace) { ColormanageProcessor *cm_processor; + ColorSpace *color_space; cm_processor = MEM_callocN(sizeof(ColormanageProcessor), "colormanagement processor"); + color_space = colormanage_colorspace_get_named(to_colorspace); + cm_processor->is_data_result = color_space->is_data; + cm_processor->processor = create_colorspace_transform_processor(from_colorspace, to_colorspace); return cm_processor; diff --git a/source/blender/imbuf/intern/dds/BlockDXT.h b/source/blender/imbuf/intern/dds/BlockDXT.h index c6712f4f058..9b90b744b67 100644 --- a/source/blender/imbuf/intern/dds/BlockDXT.h +++ b/source/blender/imbuf/intern/dds/BlockDXT.h @@ -271,4 +271,4 @@ void mem_read(Stream & mem, BlockATI1 & block); void mem_read(Stream & mem, BlockATI2 & block); void mem_read(Stream & mem, BlockCTX1 & block); -#endif // __BLOCKDXT_H__ +#endif /* __BLOCKDXT_H__ */ diff --git a/source/blender/imbuf/intern/dds/Color.h b/source/blender/imbuf/intern/dds/Color.h index 17de0a596c6..6676057d710 100644 --- a/source/blender/imbuf/intern/dds/Color.h +++ b/source/blender/imbuf/intern/dds/Color.h @@ -96,4 +96,4 @@ public: }; }; -#endif // __COLOR_H__ +#endif /* __COLOR_H__ */ diff --git a/source/blender/imbuf/intern/dds/ColorBlock.h b/source/blender/imbuf/intern/dds/ColorBlock.h index 2bf362f2780..f0864f06e6f 100644 --- a/source/blender/imbuf/intern/dds/ColorBlock.h +++ b/source/blender/imbuf/intern/dds/ColorBlock.h @@ -104,4 +104,4 @@ inline Color32 & ColorBlock::color(uint x, uint y) return m_color[y * 4 + x]; } -#endif // __COLORBLOCK_H__ +#endif /* __COLORBLOCK_H__ */ diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index a851533b1f3..ccac1c08b41 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -200,4 +200,4 @@ void mem_read(Stream & mem, DDSCaps & caps); void mem_read(Stream & mem, DDSHeader & header); void mem_read(Stream & mem, DDSHeader10 & header); -#endif // __DIRECTDRAWSURFACE_H__ +#endif /* __DIRECTDRAWSURFACE_H__ */ diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h index 5dcf3011c76..81074fba6b7 100644 --- a/source/blender/imbuf/intern/dds/Image.h +++ b/source/blender/imbuf/intern/dds/Image.h @@ -101,4 +101,4 @@ inline Color32 & Image::pixel(uint x, uint y) return pixel(y * width() + x); } -#endif // __IMAGE_H__ +#endif /* __IMAGE_H__ */ diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h index 308ea810f03..ce36fb00b97 100644 --- a/source/blender/imbuf/intern/dds/PixelFormat.h +++ b/source/blender/imbuf/intern/dds/PixelFormat.h @@ -135,4 +135,4 @@ } // PixelFormat namespace -#endif // _DDS_IMAGE_PIXELFORMAT_H +#endif /* __PIXELFORMAT_H__ */ diff --git a/source/blender/imbuf/intern/dds/Stream.h b/source/blender/imbuf/intern/dds/Stream.h index 9f513ca8aba..7fed4ca89e7 100644 --- a/source/blender/imbuf/intern/dds/Stream.h +++ b/source/blender/imbuf/intern/dds/Stream.h @@ -45,5 +45,4 @@ unsigned int mem_read(Stream & mem, unsigned short & i); unsigned int mem_read(Stream & mem, unsigned char & i); unsigned int mem_read(Stream & mem, unsigned char *i, unsigned int cnt); -#endif // __STREAM_H__ - +#endif /* __STREAM_H__ */ diff --git a/source/blender/imbuf/intern/indexer.c b/source/blender/imbuf/intern/indexer.c index f35a4345366..593e08062fe 100644 --- a/source/blender/imbuf/intern/indexer.c +++ b/source/blender/imbuf/intern/indexer.c @@ -36,18 +36,19 @@ #include "IMB_indexer.h" #include "IMB_anim.h" -#include "AVI_avi.h" #include "imbuf.h" #include "MEM_guardedalloc.h" #include "DNA_userdef_types.h" #include "BKE_global.h" -#ifdef WITH_FFMPEG - -#include "ffmpeg_compat.h" +#ifdef WITH_AVI +# include "AVI_avi.h" +#endif -#endif //WITH_FFMPEG +#ifdef WITH_FFMPEG +# include "ffmpeg_compat.h" +#endif static char magic[] = "BlenMIdx"; @@ -989,6 +990,7 @@ static int index_rebuild_ffmpeg(FFmpegIndexBuilderContext *context, * - internal AVI (fallback) rebuilder * ---------------------------------------------------------------------- */ +#ifdef WITH_AVI typedef struct FallbackIndexBuilderContext { int anim_type; @@ -1149,6 +1151,8 @@ static void index_rebuild_fallback(FallbackIndexBuilderContext *context, } } +#endif /* WITH_AVI */ + /* ---------------------------------------------------------------------- * - public API * ---------------------------------------------------------------------- */ @@ -1164,15 +1168,19 @@ IndexBuildContext *IMB_anim_index_rebuild_context(struct anim *anim, IMB_Timecod context = index_ffmpeg_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality); break; #endif +#ifdef WITH_AVI default: context = index_fallback_create_context(anim, tcs_in_use, proxy_sizes_in_use, quality); break; +#endif } if (context) context->anim_type = anim->curtype; return context; + + (void)tcs_in_use, (void)proxy_sizes_in_use, (void)quality; } void IMB_anim_index_rebuild(struct IndexBuildContext *context, @@ -1184,10 +1192,14 @@ void IMB_anim_index_rebuild(struct IndexBuildContext *context, index_rebuild_ffmpeg((FFmpegIndexBuilderContext *)context, stop, do_update, progress); break; #endif +#ifdef WITH_AVI default: index_rebuild_fallback((FallbackIndexBuilderContext *)context, stop, do_update, progress); break; +#endif } + + (void)stop, (void)do_update, (void)progress; } void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop) @@ -1198,10 +1210,15 @@ void IMB_anim_index_rebuild_finish(IndexBuildContext *context, short stop) index_rebuild_ffmpeg_finish((FFmpegIndexBuilderContext *)context, stop); break; #endif +#ifdef WITH_AVI default: index_rebuild_fallback_finish((FallbackIndexBuilderContext *)context, stop); break; +#endif } + + (void)stop; + (void)proxy_sizes; /* static defined at top of the file */ } diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 833671e3f2f..8dd791c8508 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -211,7 +211,12 @@ int IMB_ispic(const char *filename) static int isavi(const char *name) { +#ifdef WITH_AVI return AVI_is_avi(name); +#else + (void)name; + return FALSE; +#endif } #ifdef WITH_QUICKTIME @@ -223,6 +228,10 @@ static int isqtime(const char *name) #ifdef WITH_FFMPEG +/* BLI_vsnprintf in ffmpeg_log_callback() causes invalid warning */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-format-attribute" + static char ffmpeg_last_error[1024]; static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_list arg) @@ -240,6 +249,8 @@ static void ffmpeg_log_callback(void *ptr, int level, const char *format, va_lis } } +#pragma GCC diagnostic pop + void IMB_ffmpeg_init(void) { av_register_all(); diff --git a/source/blender/makesdna/DNA_action_types.h b/source/blender/makesdna/DNA_action_types.h index 59874e0434b..a730bee4f79 100644 --- a/source/blender/makesdna/DNA_action_types.h +++ b/source/blender/makesdna/DNA_action_types.h @@ -564,6 +564,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/makesdna/DNA_mask_types.h b/source/blender/makesdna/DNA_mask_types.h index bf388d8c018..5b25d1a072c 100644 --- a/source/blender/makesdna/DNA_mask_types.h +++ b/source/blender/makesdna/DNA_mask_types.h @@ -211,4 +211,4 @@ enum { MASK_ANIMF_EXPAND = (1 << 4) }; -#endif // __DNA_MASK_TYPES_H__ +#endif /* __DNA_MASK_TYPES_H__ */ diff --git a/source/blender/makesdna/DNA_material_types.h b/source/blender/makesdna/DNA_material_types.h index f3c527b6531..09451754dee 100644 --- a/source/blender/makesdna/DNA_material_types.h +++ b/source/blender/makesdna/DNA_material_types.h @@ -295,6 +295,7 @@ typedef struct Material { #define MA_CUBIC 1 #define MA_OBCOLOR 2 #define MA_APPROX_OCCLUSION 4 +#define MA_GROUP_LOCAL 8 /* diff_shader */ #define MA_DIFF_LAMBERT 0 diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index 1dd2aa6c59b..67d540db177 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -54,6 +54,7 @@ typedef enum PFieldType { PFIELD_BOID = 10, /* Defines predator / goal for boids */ PFIELD_TURBULENCE = 11, /* Force defined by BLI_gTurbulence */ PFIELD_DRAG = 12, /* Linear & quadratic drag */ + PFIELD_SMOKEFLOW = 13, /* Force based on smoke simulation air flow */ NUM_PFIELD_TYPES } PFieldType; @@ -110,14 +111,17 @@ typedef struct PartDeflect { struct RNG *rng; /* random noise generator for e.g. wind */ float f_noise; /* noise of force */ int seed; /* noise random seed */ + + struct Object *f_source; /* force source object */ } PartDeflect; typedef struct EffectorWeights { struct Group *group; /* only use effectors from this group of objects */ - float weight[13]; /* effector type specific weights */ + float weight[14]; /* effector type specific weights */ float global_gravity; short flag, rt[3]; + int pad; } EffectorWeights; /* EffectorWeights->flag */ @@ -365,6 +369,7 @@ typedef struct SoftBody { #define PFIELD_DO_LOCATION (1<<14) #define PFIELD_DO_ROTATION (1<<15) #define PFIELD_GUIDE_PATH_WEIGHT (1<<16) /* apply curve weights */ +#define PFIELD_SMOKE_DENSITY (1<<17) /* multiply smoke force by density */ /* pd->falloff */ #define PFIELD_FALL_SPHERE 0 diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h index 3a8620fdaba..2fc04c4a5db 100644 --- a/source/blender/makesdna/DNA_object_types.h +++ b/source/blender/makesdna/DNA_object_types.h @@ -378,6 +378,7 @@ typedef struct DupliObject { #define OB_DUPLIPARTS 2048 #define OB_RENDER_DUPLI 4096 #define OB_NO_CONSTRAINTS 8192 /* runtime constraints disable */ +#define OB_NO_PSYS_UPDATE 16384 /* hack to work around particle issue */ /* (short) ipoflag */ /* XXX: many old flags for features removed due to incompatibility diff --git a/source/blender/makesdna/DNA_packedFile_types.h b/source/blender/makesdna/DNA_packedFile_types.h index f01e89d18c9..4ec5866e8c3 100644 --- a/source/blender/makesdna/DNA_packedFile_types.h +++ b/source/blender/makesdna/DNA_packedFile_types.h @@ -45,7 +45,7 @@ enum PF_FileStatus PF_EQUAL = 0, PF_DIFFERS = 1, PF_NOFILE = 2, - + PF_WRITE_ORIGINAL = 3, PF_WRITE_LOCAL = 4, PF_USE_LOCAL = 5, @@ -53,7 +53,7 @@ enum PF_FileStatus PF_KEEP = 7, PF_REMOVE = 8, PF_NOOP = 9, - + PF_ASK = 10 }; diff --git a/source/blender/makesdna/DNA_smoke_types.h b/source/blender/makesdna/DNA_smoke_types.h index cceb7333478..76ba3fcf7f8 100644 --- a/source/blender/makesdna/DNA_smoke_types.h +++ b/source/blender/makesdna/DNA_smoke_types.h @@ -39,6 +39,7 @@ #define MOD_SMOKE_HIGH_SMOOTH (1<<5) /* smoothens high res emission*/ #define MOD_SMOKE_FILE_LOAD (1<<6) /* flag for file load */ +#define MOD_SMOKE_ADAPTIVE_DOMAIN (1<<7) /* noise */ #define MOD_SMOKE_NOISEWAVE (1<<0) @@ -61,6 +62,12 @@ #define SM_COLL_RIGID 1 #define SM_COLL_ANIMATED 2 +/* smoke data fileds (active_fields) */ +#define SM_ACTIVE_HEAT (1<<0) +#define SM_ACTIVE_FIRE (1<<1) +#define SM_ACTIVE_COLORS (1<<2) +#define SM_ACTIVE_COLOR_SET (1<<3) + typedef struct SmokeDomainSettings { struct SmokeModifierData *smd; /* for fast RNA access */ struct FLUID_3D *fluid; @@ -71,17 +78,37 @@ typedef struct SmokeDomainSettings { struct GPUTexture *tex; struct GPUTexture *tex_wt; struct GPUTexture *tex_shadow; + struct GPUTexture *tex_flame; float *shadow; - float p0[3]; /* start point of BB */ - float p1[3]; /* end point of BB */ - float dx; /* edge length of one cell */ - float omega; /* smoke color - from 0 to 1 */ - float temp; /* fluid temperature */ - float tempAmb; /* ambient temperature */ + + /* simulation data */ + float p0[3]; /* start point of BB in local space (includes sub-cell shift for adaptive domain)*/ + float p1[3]; /* end point of BB in local space */ + float dp0[3]; /* difference from object center to grid start point */ + float cell_size[3]; /* size of simulation cell in local space */ + float global_size[3]; /* global size of domain axises */ + float prev_loc[3]; + int shift[3]; /* current domain shift in simulation cells */ + float shift_f[3]; /* exact domain shift */ + float obj_shift_f[3]; /* how much object has shifted since previous smoke frame (used to "lock" domain while drawing) */ + float imat[4][4]; /* domain object imat */ + float obmat[4][4]; /* domain obmat */ + + int base_res[3]; /* initial "non-adapted" resolution */ + int res_min[3]; /* cell min */ + int res_max[3]; /* cell max */ + int res[3]; /* data resolution (res_max-res_min) */ + int total_cells; + float dx; /* 1.0f / res */ + float scale; /* largest domain size */ + + /* user settings */ + int adapt_margin; + int adapt_res; + float adapt_threshold; + float alpha; float beta; - float scale; /* largest domain size */ - int res[3]; /* domain resolution */ int amplify; /* wavelet amplification */ int maxres; /* longest axis on the BB gets this resolution assigned */ int flags; /* show up-res or low res, etc */ @@ -92,7 +119,6 @@ typedef struct SmokeDomainSettings { float strength; int res_wt[3]; float dx_wt; - int v3dnum; int cache_comp; int cache_high_comp; @@ -103,31 +129,67 @@ typedef struct SmokeDomainSettings { int border_collisions; /* How domain border collisions are handled */ float time_scale; float vorticity; - int pad2; + int active_fields; + float active_color[3]; /* monitor color situation of simulation */ + int pad; + + /* flame parameters */ + float burning_rate, flame_smoke, flame_vorticity; + float flame_ignition, flame_max_temp; + float flame_smoke_color[3]; } SmokeDomainSettings; /* inflow / outflow */ /* type */ -#define MOD_SMOKE_FLOW_TYPE_OUTFLOW (1<<1) +#define MOD_SMOKE_FLOW_TYPE_SMOKE 0 +#define MOD_SMOKE_FLOW_TYPE_FIRE 1 +#define MOD_SMOKE_FLOW_TYPE_OUTFLOW 2 +#define MOD_SMOKE_FLOW_TYPE_SMOKEFIRE 3 + +/* flow source */ +#define MOD_SMOKE_FLOW_SOURCE_PARTICLES 0 +#define MOD_SMOKE_FLOW_SOURCE_MESH 1 + +/* flow texture type */ +#define MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO 0 +#define MOD_SMOKE_FLOW_TEXTURE_MAP_UV 1 /* flags */ #define MOD_SMOKE_FLOW_ABSOLUTE (1<<1) /*old style emission*/ #define MOD_SMOKE_FLOW_INITVELOCITY (1<<2) /* passes particles speed to the smoke */ +#define MOD_SMOKE_FLOW_TEXTUREEMIT (1<<3) /* use texture to control emission speed */ typedef struct SmokeFlowSettings { struct SmokeModifierData *smd; /* for fast RNA access */ + struct DerivedMesh *dm; struct ParticleSystem *psys; + struct Tex *noise_texture; + + /* initial velocity */ + float *verts_old; /* previous vertex positions in domain space */ + int numverts; + float vel_multi; // Multiplier for inherited velocity + float vel_normal; + float vel_random; + /* emission */ float density; + float color[3]; + float fuel_amount; float temp; /* delta temperature (temp - ambient temp) */ - float velocity[2]; /* UNUSED, velocity taken from particles */ - float vel_multi; // Multiplier for particle velocity - float vgrp_heat_scale[2]; /* min and max scaling for vgroup_heat */ - short vgroup_flow; /* where inflow/outflow happens - red=1=action */ + float volume_density; /* density emitted within mesh volume */ + float surface_distance; /* maximum emission distance from mesh surface */ + /* texture control */ + float texture_size; + float texture_offset; + int pad; + char uvlayer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */ short vgroup_density; - short vgroup_heat; - short type; /* inflow =0 or outflow = 1 */ + + short type; /* smoke, flames, both, outflow */ + short source; + short texture_type; int flags; /* absolute emission etc*/ } SmokeFlowSettings; @@ -139,20 +201,11 @@ typedef struct SmokeFlowSettings { /* collision objects (filled with smoke) */ typedef struct SmokeCollSettings { struct SmokeModifierData *smd; /* for fast RNA access */ - struct BVHTree *bvhtree; /* bounding volume hierarchy for this cloth object */ - float *points; - float *points_old; - float *vel; // UNUSED - int *tridivs; - float mat[4][4]; - float mat_old[4][4]; - int numpoints; - int numverts; // check if mesh changed - int numtris; - float dx; /* global domain cell length taken from (scale / resolution) */ + struct DerivedMesh *dm; + float *verts_old; + int numverts; short type; // static = 0, rigid = 1, dynamic = 2 short pad; - int pad2; } SmokeCollSettings; #endif diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 4b8fc9c7ed6..2469656ecd7 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -618,7 +618,7 @@ enum FileSortTypeE { #define FILE_MAXFILE 256 #define FILE_MAX 1024 -#define FILE_MAX_LIBEXTRA (FILE_MAX + 32) +#define FILE_MAX_LIBEXTRA (FILE_MAX + MAX_ID_NAME) /* filesel types */ #define FILE_UNIX 8 diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index 9fdd9216549..ce94a229750 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -171,6 +171,9 @@ typedef struct VoxelData { short flag; short extend; short smoked_type; + short data_type; + short pad; + int _pad; struct Object *object; /* for rendering smoke sims */ float int_multiplier; @@ -470,6 +473,7 @@ typedef struct ColorMapping { #define MTEX_BUMP_TEXTURESPACE 2048 /* #define MTEX_BUMP_FLIPPED 4096 */ /* UNUSED */ #define MTEX_BICUBIC_BUMP 8192 +#define MTEX_MAPTO_BOUNDS 16384 /* blendtype */ #define MTEX_BLEND 0 @@ -577,6 +581,11 @@ typedef struct ColorMapping { #define TEX_VD_SMOKEDENSITY 0 #define TEX_VD_SMOKEHEAT 1 #define TEX_VD_SMOKEVEL 2 +#define TEX_VD_SMOKEFLAME 3 + +/* data_type */ +#define TEX_VD_INTENSITY 0 +#define TEX_VD_RGBA_PREMUL 1 /******************** Ocean *****************************/ /* output */ diff --git a/source/blender/makesdna/DNA_tracking_types.h b/source/blender/makesdna/DNA_tracking_types.h index 1ab64ed1cc1..c6cefce2994 100644 --- a/source/blender/makesdna/DNA_tracking_types.h +++ b/source/blender/makesdna/DNA_tracking_types.h @@ -162,7 +162,10 @@ typedef struct MovieTrackingSettings { short speed; /* speed of tracking */ /* ** reconstruction settings ** */ - int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ + int keyframe1 DNA_DEPRECATED, + keyframe2 DNA_DEPRECATED; /* two keyframes for reconstrution initialization + * were moved to per-tracking object settings + */ /* which camera intrinsics to refine. uses on the REFINE_* flags */ short refine_camera_intrinsics, pad2; @@ -220,6 +223,8 @@ typedef struct MovieTrackingObject { ListBase tracks; /* list of tracks use to tracking this object */ MovieTrackingReconstruction reconstruction; /* reconstruction data for this object */ + + int keyframe1, keyframe2; /* two keyframes for reconstrution initialization */ } MovieTrackingObject; typedef struct MovieTrackingStats { diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 96f0c0e7a9a..2c51a956e18 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -49,11 +49,14 @@ struct ColorBand; #define MAX_STYLE_NAME 64 /* default uifont_id offered by Blender */ -#define UIFONT_DEFAULT 0 -/*#define UIFONT_BITMAP 1*/ /*UNUSED*/ -/* free slots */ -#define UIFONT_CUSTOM1 2 -#define UIFONT_CUSTOM2 3 +typedef enum eUIFont_ID { + UIFONT_DEFAULT = 0, +/* UIFONT_BITMAP = 1 */ /* UNUSED */ + + /* free slots */ + UIFONT_CUSTOM1 = 2, + UIFONT_CUSTOM2 = 3 +} eUIFont_ID; /* default fonts to load/initalize */ /* first font is the default (index 0), others optional */ @@ -64,7 +67,6 @@ typedef struct uiFont { short uifont_id; /* own id */ short r_to_l; /* fonts that read from left to right */ short pad; - } uiFont; /* this state defines appearance of text */ @@ -79,13 +81,14 @@ typedef struct uiFontStyle { short align; /* text align hint */ float shadowalpha; /* total alpha */ float shadowcolor; /* 1 value, typically white or black anyway */ - } uiFontStyle; /* uiFontStyle->align */ -#define UI_STYLE_TEXT_LEFT 0 -#define UI_STYLE_TEXT_CENTER 1 -#define UI_STYLE_TEXT_RIGHT 2 +typedef enum eFontStyle_Align { + UI_STYLE_TEXT_LEFT = 0, + UI_STYLE_TEXT_CENTER = 1, + UI_STYLE_TEXT_RIGHT = 2 +} eFontStyle_Align; /* this is fed to the layout engine and widget code */ @@ -145,7 +148,6 @@ typedef struct uiPanelColors { } uiPanelColors; typedef struct ThemeUI { - /* Interface Elements (buttons, menus, icons) */ uiWidgetColors wcol_regular, wcol_tool, wcol_text; uiWidgetColors wcol_radio, wcol_option, wcol_toggle; @@ -209,8 +211,8 @@ typedef struct ThemeSpace { char vertex[4], vertex_select[4]; char edge[4], edge_select[4]; char edge_seam[4], edge_sharp[4], edge_facesel[4], edge_crease[4]; - char face[4], face_select[4]; // solid faces - char face_dot[4]; // selected color + char face[4], face_select[4]; /* solid faces */ + char face_dot[4]; /* selected color */ char extra_edge_len[4], extra_face_angle[4], extra_face_area[4], pad3[4]; char normal[4]; char vertex_normal[4]; @@ -225,7 +227,7 @@ typedef struct ThemeSpace { char handle_free[4], handle_auto[4], handle_vect[4], handle_align[4], handle_auto_clamped[4]; char handle_sel_free[4], handle_sel_auto[4], handle_sel_vect[4], handle_sel_align[4], handle_sel_auto_clamped[4]; - char ds_channel[4], ds_subchannel[4]; // dopesheet + char ds_channel[4], ds_subchannel[4]; /* dopesheet */ char console_output[4], console_input[4], console_info[4], console_error[4]; char console_cursor[4]; @@ -233,10 +235,10 @@ typedef struct ThemeSpace { char vertex_size, outline_width, facedot_size; char noodle_curving; - char syntaxl[4], syntaxn[4], syntaxb[4]; // syntax for textwindow and nodes + char syntaxl[4], syntaxn[4], syntaxb[4]; /* syntax for textwindow and nodes */ char syntaxv[4], syntaxc[4]; - char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; // for sequence editor + char movie[4], movieclip[4], mask[4], image[4], scene[4], audio[4]; /* for sequence editor */ char effect[4], hpad0[4], transition[4], meta[4]; char editmesh_active[4]; @@ -288,8 +290,10 @@ typedef struct ThemeWireColor { } ThemeWireColor; /* flags for ThemeWireColor */ -#define TH_WIRECOLOR_CONSTCOLS (1<<0) -#define TH_WIRECOLOR_TEXTCOLS (1<<1) +typedef enum eWireColor_Flags { + TH_WIRECOLOR_CONSTCOLS = (1 << 0), + TH_WIRECOLOR_TEXTCOLS = (1 << 1), +} eWireColor_Flags; /* A theme */ typedef struct bTheme { @@ -322,7 +326,6 @@ typedef struct bTheme { /*ThemeWireColor tobj[20];*/ int active_theme_area, pad; - } bTheme; /* for the moment only the name. may want to store options with this later */ @@ -346,8 +349,8 @@ typedef struct UserDef { char pythondir[768]; char sounddir[768]; char i18ndir[768]; - char image_editor[1024]; /* 1024 = FILE_MAX */ - char anim_player[1024]; /* 1024 = FILE_MAX */ + char image_editor[1024]; /* 1024 = FILE_MAX */ + char anim_player[1024]; /* 1024 = FILE_MAX */ int anim_player_preset; short v2d_min_gridsize; /* minimum spacing between gridlines in View2D grids */ @@ -394,7 +397,7 @@ typedef struct UserDef { int memcachelimit; int prefetchframes; short frameserverport; - short pad_rot_angle; /*control the rotation step of the view when PAD2, PAD4, PAD6&PAD8 is use*/ + short pad_rot_angle; /* control the rotation step of the view when PAD2, PAD4, PAD6&PAD8 is use */ short obcenter_dia; short rvisize; /* rotating view icon size */ short rvibright; /* rotating view icon brightness */ @@ -423,7 +426,7 @@ typedef struct UserDef { short autokey_mode; /* autokeying mode */ short autokey_flag; /* flags for autokeying */ - short text_render, pad9; /*options for text rendering*/ + short text_render, pad9; /* options for text rendering */ struct ColorBand coba_weight; /* from texture.h */ @@ -446,217 +449,258 @@ extern UserDef U; /* from blenkernel blender.c */ /* ***************** USERDEF ****************** */ /* userpref/section */ -#define USER_SECTION_INTERFACE 0 -#define USER_SECTION_EDIT 1 -#define USER_SECTION_FILE 2 -#define USER_SECTION_SYSTEM 3 -#define USER_SECTION_THEME 4 -#define USER_SECTION_INPUT 5 -#define USER_SECTION_ADDONS 6 +typedef enum eUserPref_Section { + USER_SECTION_INTERFACE = 0, + USER_SECTION_EDIT = 1, + USER_SECTION_FILE = 2, + USER_SECTION_SYSTEM = 3, + USER_SECTION_THEME = 4, + USER_SECTION_INPUT = 5, + USER_SECTION_ADDONS = 6, +} eUserPref_Section; /* flag */ -#define USER_AUTOSAVE (1 << 0) -/*#define USER_AUTOGRABGRID (1 << 1) deprecated */ -/*#define USER_AUTOROTGRID (1 << 2) deprecated */ -/*#define USER_AUTOSIZEGRID (1 << 3) deprecated */ -#define USER_SCENEGLOBAL (1 << 4) -#define USER_TRACKBALL (1 << 5) -/*#define USER_DUPLILINK (1 << 6) deprecated */ -/*#define USER_FSCOLLUM (1 << 7) deprecated */ -#define USER_MAT_ON_OB (1 << 8) -/*#define USER_NO_CAPSLOCK (1 << 9)*/ /* not used anywhere */ -/*#define USER_VIEWMOVE (1 << 10)*/ /* not used anywhere */ -#define USER_TOOLTIPS (1 << 11) -#define USER_TWOBUTTONMOUSE (1 << 12) -#define USER_NONUMPAD (1 << 13) -#define USER_LMOUSESELECT (1 << 14) -#define USER_FILECOMPRESS (1 << 15) -#define USER_SAVE_PREVIEWS (1 << 16) -#define USER_CUSTOM_RANGE (1 << 17) -#define USER_ADD_EDITMODE (1 << 18) -#define USER_ADD_VIEWALIGNED (1 << 19) -#define USER_RELPATHS (1 << 20) -#define USER_RELEASECONFIRM (1 << 21) -#define USER_SCRIPT_AUTOEXEC_DISABLE (1 << 22) -#define USER_FILENOUI (1 << 23) -#define USER_NONEGFRAMES (1 << 24) -#define USER_TXT_TABSTOSPACES_DISABLE (1 << 25) -#define USER_TOOLTIPS_PYTHON (1 << 26) - +typedef enum eUserPref_Flag { + USER_AUTOSAVE = (1 << 0), +/* USER_AUTOGRABGRID = (1 << 1), deprecated */ +/* USER_AUTOROTGRID = (1 << 2), deprecated */ +/* USER_AUTOSIZEGRID = (1 << 3), deprecated */ + USER_SCENEGLOBAL = (1 << 4), + USER_TRACKBALL = (1 << 5), +/* USER_DUPLILINK = (1 << 6), deprecated */ +/* USER_FSCOLLUM = (1 << 7), deprecated */ + USER_MAT_ON_OB = (1 << 8), +/* USER_NO_CAPSLOCK = (1 << 9), */ /* not used anywhere */ +/* USER_VIEWMOVE = (1 << 10), */ /* not used anywhere */ + USER_TOOLTIPS = (1 << 11), + USER_TWOBUTTONMOUSE = (1 << 12), + USER_NONUMPAD = (1 << 13), + USER_LMOUSESELECT = (1 << 14), + USER_FILECOMPRESS = (1 << 15), + USER_SAVE_PREVIEWS = (1 << 16), + USER_CUSTOM_RANGE = (1 << 17), + USER_ADD_EDITMODE = (1 << 18), + USER_ADD_VIEWALIGNED = (1 << 19), + USER_RELPATHS = (1 << 20), + USER_RELEASECONFIRM = (1 << 21), + USER_SCRIPT_AUTOEXEC_DISABLE = (1 << 22), + USER_FILENOUI = (1 << 23), + USER_NONEGFRAMES = (1 << 24), + USER_TXT_TABSTOSPACES_DISABLE = (1 << 25), + USER_TOOLTIPS_PYTHON = (1 << 26), +} eUserPref_Flag; + /* helper macro for checking frame clamping */ #define FRAMENUMBER_MIN_CLAMP(cfra) { \ if ((U.flag & USER_NONEGFRAMES) && (cfra < 0)) \ cfra = 0; \ } (void)0 -/* viewzom */ -#define USER_ZOOM_CONT 0 -#define USER_ZOOM_SCALE 1 -#define USER_ZOOM_DOLLY 2 +/* viewzoom */ +typedef enum eViewZoom_Style { + USER_ZOOM_CONT = 0, + USER_ZOOM_SCALE = 1, + USER_ZOOM_DOLLY = 2 +} eViewZoom_Style; /* uiflag */ -// old flag for #define USER_KEYINSERTACT (1 << 0) -// old flag for #define USER_KEYINSERTOBJ (1 << 1) -#define USER_WHEELZOOMDIR (1 << 2) -#define USER_FILTERFILEEXTS (1 << 3) -#define USER_DRAWVIEWINFO (1 << 4) -#define USER_PLAINMENUS (1 << 5) // old EVTTOCONSOLE print ghost events, here for tuhopuu compat. --phase - // old flag for hide pulldown was here -/*#define USER_FLIPFULLSCREEN (1 << 7)*/ /* deprecated */ -#define USER_ALLWINCODECS (1 << 8) -#define USER_MENUOPENAUTO (1 << 9) -#define USER_ZBUF_CURSOR (1 << 10) -#define USER_AUTOPERSP (1 << 11) -#define USER_LOCKAROUND (1 << 12) -#define USER_GLOBALUNDO (1 << 13) -#define USER_ORBIT_SELECTION (1 << 14) -#define USER_ZBUF_ORBIT (1 << 15) -#define USER_HIDE_DOT (1 << 16) -#define USER_SHOW_ROTVIEWICON (1 << 17) -#define USER_SHOW_VIEWPORTNAME (1 << 18) -#define USER_CAM_LOCK_NO_PARENT (1 << 19) -#define USER_ZOOM_TO_MOUSEPOS (1 << 20) -#define USER_SHOW_FPS (1 << 21) -#define USER_MMB_PASTE (1 << 22) -#define USER_MENUFIXEDORDER (1 << 23) -#define USER_CONTINUOUS_MOUSE (1 << 24) -#define USER_ZOOM_INVERT (1 << 25) -#define USER_ZOOM_HORIZ (1 << 26) /* for CONTINUE and DOLLY zoom */ -#define USER_SPLASH_DISABLE (1 << 27) -#define USER_HIDE_RECENT (1 << 28) -#define USER_SHOW_THUMBNAILS (1 << 29) -#define USER_QUIT_PROMPT (1 << 30) +typedef enum eUserpref_UI_Flag { + /* flags 0 and 1 were old flags (for autokeying) that aren't used anymore */ + USER_WHEELZOOMDIR = (1 << 2), + USER_FILTERFILEEXTS = (1 << 3), + USER_DRAWVIEWINFO = (1 << 4), + USER_PLAINMENUS = (1 << 5), + /* flags 6 and 7 were old flags that are no-longer used */ + USER_ALLWINCODECS = (1 << 8), + USER_MENUOPENAUTO = (1 << 9), + USER_ZBUF_CURSOR = (1 << 10), + USER_AUTOPERSP = (1 << 11), + USER_LOCKAROUND = (1 << 12), + USER_GLOBALUNDO = (1 << 13), + USER_ORBIT_SELECTION = (1 << 14), + USER_ZBUF_ORBIT = (1 << 15), + USER_HIDE_DOT = (1 << 16), + USER_SHOW_ROTVIEWICON = (1 << 17), + USER_SHOW_VIEWPORTNAME = (1 << 18), + USER_CAM_LOCK_NO_PARENT = (1 << 19), + USER_ZOOM_TO_MOUSEPOS = (1 << 20), + USER_SHOW_FPS = (1 << 21), + USER_MMB_PASTE = (1 << 22), + USER_MENUFIXEDORDER = (1 << 23), + USER_CONTINUOUS_MOUSE = (1 << 24), + USER_ZOOM_INVERT = (1 << 25), + USER_ZOOM_HORIZ = (1 << 26), /* for CONTINUE and DOLLY zoom */ + USER_SPLASH_DISABLE = (1 << 27), + USER_HIDE_RECENT = (1 << 28), + USER_SHOW_THUMBNAILS = (1 << 29), + USER_QUIT_PROMPT = (1 << 30) +} eUserpref_UI_Flag; /* Auto-Keying mode */ +typedef enum eAutokey_Mode { /* AUTOKEY_ON is a bitflag */ -#define AUTOKEY_ON 1 + AUTOKEY_ON = 1, + /* AUTOKEY_ON + 2**n... (i.e. AUTOKEY_MODE_NORMAL = AUTOKEY_ON + 2) to preserve setting, even when autokey turned off */ -#define AUTOKEY_MODE_NORMAL 3 -#define AUTOKEY_MODE_EDITKEYS 5 + AUTOKEY_MODE_NORMAL = 3, + AUTOKEY_MODE_EDITKEYS = 5 +} eAutokey_Mode; /* Auto-Keying flag * U.autokey_flag (not strictly used when autokeying only - is also used when keyframing these days) * note: AUTOKEY_FLAG_* is used with a macro, search for lines like IS_AUTOKEY_FLAG(INSERTAVAIL) */ -#define AUTOKEY_FLAG_INSERTAVAIL (1<<0) -#define AUTOKEY_FLAG_INSERTNEEDED (1<<1) -#define AUTOKEY_FLAG_AUTOMATKEY (1<<2) -#define AUTOKEY_FLAG_XYZ2RGB (1<<3) - -/* toolsettings->autokey_flag */ -#define AUTOKEY_FLAG_ONLYKEYINGSET (1<<6) -#define ANIMRECORD_FLAG_WITHNLA (1<<10) +typedef enum eAutokey_Flag { + AUTOKEY_FLAG_INSERTAVAIL = (1 << 0), + AUTOKEY_FLAG_INSERTNEEDED = (1 << 1), + AUTOKEY_FLAG_AUTOMATKEY = (1 << 2), + AUTOKEY_FLAG_XYZ2RGB = (1 << 3), + + /* toolsettings->autokey_flag */ + AUTOKEY_FLAG_ONLYKEYINGSET = (1 << 6), + AUTOKEY_FLAG_NOWARNING = (1 << 7), + ANIMRECORD_FLAG_WITHNLA = (1 << 10), +} eAutokey_Flag; /* transopts */ -#define USER_TR_TOOLTIPS (1 << 0) -#define USER_TR_IFACE (1 << 1) -/*#define USER_TR_MENUS (1 << 2) deprecated*/ -/*#define USER_TR_FILESELECT (1 << 3) deprecated*/ -/*#define USER_TR_TEXTEDIT (1 << 4) deprecated*/ -#define USER_DOTRANSLATE (1 << 5) -#define USER_USETEXTUREFONT (1 << 6) -/*#define CONVERT_TO_UTF8 (1 << 7) deprecated*/ +typedef enum eUserpref_Translation_Flags { + USER_TR_TOOLTIPS = (1 << 0), + USER_TR_IFACE = (1 << 1), +/* USER_TR_MENUS = (1 << 2) deprecated */ +/* USER_TR_FILESELECT = (1 << 3) deprecated */ +/* USER_TR_TEXTEDIT = (1 << 4) deprecated */ + USER_DOTRANSLATE = (1 << 5), + USER_USETEXTUREFONT = (1 << 6), +/* CONVERT_TO_UTF8 = (1 << 7) deprecated */ +} eUserpref_Translation_Flags; /* dupflag */ -#define USER_DUP_MESH (1 << 0) -#define USER_DUP_CURVE (1 << 1) -#define USER_DUP_SURF (1 << 2) -#define USER_DUP_FONT (1 << 3) -#define USER_DUP_MBALL (1 << 4) -#define USER_DUP_LAMP (1 << 5) -#define USER_DUP_IPO (1 << 6) -#define USER_DUP_MAT (1 << 7) -#define USER_DUP_TEX (1 << 8) -#define USER_DUP_ARM (1 << 9) -#define USER_DUP_ACT (1 << 10) -#define USER_DUP_PSYS (1 << 11) +typedef enum eDupli_ID_Flags { + USER_DUP_MESH = (1 << 0), + USER_DUP_CURVE = (1 << 1), + USER_DUP_SURF = (1 << 2), + USER_DUP_FONT = (1 << 3), + USER_DUP_MBALL = (1 << 4), + USER_DUP_LAMP = (1 << 5), + USER_DUP_IPO = (1 << 6), + USER_DUP_MAT = (1 << 7), + USER_DUP_TEX = (1 << 8), + USER_DUP_ARM = (1 << 9), + USER_DUP_ACT = (1 << 10), + USER_DUP_PSYS = (1 << 11) +} eDupli_ID_Flags; /* gameflags */ -// #define USER_DEPRECATED_FLAG 1 -// #define USER_DISABLE_SOUND 2 deprecated, don't use without checking for -// backwards compatibilty in do_versions! -#define USER_DISABLE_MIPMAP 4 -#define USER_DISABLE_VBO 8 -#define USER_DISABLE_AA 16 +typedef enum eOpenGL_RenderingOptions { + /* USER_DEPRECATED_FLAG = (1 << 0), */ + /* USER_DISABLE_SOUND = (1 << 1), */ /* deprecated, don't use without checking for */ + /* backwards compatibilty in do_versions! */ + USER_DISABLE_MIPMAP = (1 << 2), + USER_DISABLE_VBO = (1 << 3), + USER_DISABLE_AA = (1 << 4), +} eOpenGL_RenderingOptions; /* wm draw method */ -#define USER_DRAW_TRIPLE 0 -#define USER_DRAW_OVERLAP 1 -#define USER_DRAW_FULL 2 -#define USER_DRAW_AUTOMATIC 3 -#define USER_DRAW_OVERLAP_FLIP 4 - -/* text draw options*/ -#define USER_TEXT_DISABLE_AA (1 << 0) +typedef enum eWM_DrawMethod { + USER_DRAW_TRIPLE = 0, + USER_DRAW_OVERLAP = 1, + USER_DRAW_FULL = 2, + USER_DRAW_AUTOMATIC = 3, + USER_DRAW_OVERLAP_FLIP = 4, +} eWM_DrawMethod; + +/* text draw options */ +typedef enum eText_Draw_Options { + USER_TEXT_DISABLE_AA = (1 << 0), +} eText_Draw_Options; /* tw_flag (transform widget) */ /* gp_settings (Grease Pencil Settings) */ -#define GP_PAINT_DOSMOOTH (1<<0) -#define GP_PAINT_DOSIMPLIFY (1<<1) +typedef enum eGP_UserdefSettings { + GP_PAINT_DOSMOOTH = (1 << 0), + GP_PAINT_DOSIMPLIFY = (1 << 1), +} eGP_UserdefSettings; /* color picker types */ -#define USER_CP_CIRCLE 0 -#define USER_CP_SQUARE_SV 1 -#define USER_CP_SQUARE_HS 2 -#define USER_CP_SQUARE_HV 3 +typedef enum eColorPicker_Types { + USER_CP_CIRCLE = 0, + USER_CP_SQUARE_SV = 1, + USER_CP_SQUARE_HS = 2, + USER_CP_SQUARE_HV = 3, +} eColorPicker_Types; /* timecode display styles */ +typedef enum eTimecodeStyles { /* as little info as is necessary to show relevant info * with '+' to denote the frames * i.e. HH:MM:SS+FF, MM:SS+FF, SS+FF, or MM:SS */ -#define USER_TIMECODE_MINIMAL 0 + USER_TIMECODE_MINIMAL = 0, + /* reduced SMPTE - (HH:)MM:SS:FF */ -#define USER_TIMECODE_SMPTE_MSF 1 + USER_TIMECODE_SMPTE_MSF = 1, + /* full SMPTE - HH:MM:SS:FF */ -#define USER_TIMECODE_SMPTE_FULL 2 + USER_TIMECODE_SMPTE_FULL = 2, + /* milliseconds for sub-frames - HH:MM:SS.sss */ -#define USER_TIMECODE_MILLISECONDS 3 + USER_TIMECODE_MILLISECONDS = 3, + /* seconds only */ -#define USER_TIMECODE_SECONDS_ONLY 4 + USER_TIMECODE_SECONDS_ONLY = 4, +} eTimecodeStyles; /* theme drawtypes */ -#define TH_MINIMAL 0 -#define TH_ROUNDSHADED 1 -#define TH_ROUNDED 2 -#define TH_OLDSKOOL 3 -#define TH_SHADED 4 +/* XXX: These are probably only for the old UI engine? */ +typedef enum eTheme_DrawTypes { + TH_MINIMAL = 0, + TH_ROUNDSHADED = 1, + TH_ROUNDED = 2, + TH_OLDSKOOL = 3, + TH_SHADED = 4 +} eTheme_DrawTypes; /* ndof_flag (3D mouse options) */ -#define NDOF_SHOW_GUIDE (1 << 0) -#define NDOF_FLY_HELICOPTER (1 << 1) -#define NDOF_LOCK_HORIZON (1 << 2) -/* the following might not need to be saved between sessions, - * but they do need to live somewhere accessible... */ -#define NDOF_SHOULD_PAN (1 << 3) -#define NDOF_SHOULD_ZOOM (1 << 4) -#define NDOF_SHOULD_ROTATE (1 << 5) -/* orbit navigation modes - * only two options, so it's sort of a hybrid bool/enum - * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */ - -// #define NDOF_ORBIT_MODE (1 << 6) -// #define NDOF_OM_TARGETCAMERA 0 -// #define NDOF_OM_OBJECT NDOF_ORBIT_MODE - -/* actually... users probably don't care about what the mode - * is called, just that it feels right */ -/* zoom is up/down if this flag is set (otherwise forward/backward) */ -#define NDOF_ZOOM_UPDOWN (1 << 7) -#define NDOF_ZOOM_INVERT (1 << 8) -#define NDOF_ROTATE_INVERT_AXIS (1 << 9) -#define NDOF_TILT_INVERT_AXIS (1 << 10) -#define NDOF_ROLL_INVERT_AXIS (1 << 11) -#define NDOF_PANX_INVERT_AXIS (1 << 12) -#define NDOF_PANY_INVERT_AXIS (1 << 13) -#define NDOF_PANZ_INVERT_AXIS (1 << 14) -#define NDOF_TURNTABLE (1 << 15) +typedef enum eNdof_Flag { + NDOF_SHOW_GUIDE = (1 << 0), + NDOF_FLY_HELICOPTER = (1 << 1), + NDOF_LOCK_HORIZON = (1 << 2), + + /* the following might not need to be saved between sessions, + * but they do need to live somewhere accessible... */ + NDOF_SHOULD_PAN = (1 << 3), + NDOF_SHOULD_ZOOM = (1 << 4), + NDOF_SHOULD_ROTATE = (1 << 5), + + /* orbit navigation modes + * only two options, so it's sort of a hybrid bool/enum + * if ((U.ndof_flag & NDOF_ORBIT_MODE) == NDOF_OM_OBJECT)... */ + + // NDOF_ORBIT_MODE = (1 << 6), + // #define NDOF_OM_TARGETCAMERA 0 + // #define NDOF_OM_OBJECT NDOF_ORBIT_MODE + + /* actually... users probably don't care about what the mode + * is called, just that it feels right */ + /* zoom is up/down if this flag is set (otherwise forward/backward) */ + NDOF_ZOOM_UPDOWN = (1 << 7), + NDOF_ZOOM_INVERT = (1 << 8), + NDOF_ROTATE_INVERT_AXIS = (1 << 9), + NDOF_TILT_INVERT_AXIS = (1 << 10), + NDOF_ROLL_INVERT_AXIS = (1 << 11), + NDOF_PANX_INVERT_AXIS = (1 << 12), + NDOF_PANY_INVERT_AXIS = (1 << 13), + NDOF_PANZ_INVERT_AXIS = (1 << 14), + NDOF_TURNTABLE = (1 << 15), +} eNdof_Flag; /* compute_device_type */ -#define USER_COMPUTE_DEVICE_NONE 0 -#define USER_COMPUTE_DEVICE_OPENCL 1 -#define USER_COMPUTE_DEVICE_CUDA 2 +typedef enum eCompute_Device_Type { + USER_COMPUTE_DEVICE_NONE = 0, + USER_COMPUTE_DEVICE_OPENCL = 1, + USER_COMPUTE_DEVICE_CUDA = 2, +} eCompute_Device_Type; #ifdef __cplusplus } diff --git a/source/blender/makesdna/DNA_view3d_types.h b/source/blender/makesdna/DNA_view3d_types.h index 9da10381af0..c83b0bc366f 100644 --- a/source/blender/makesdna/DNA_view3d_types.h +++ b/source/blender/makesdna/DNA_view3d_types.h @@ -169,6 +169,7 @@ typedef struct View3D { short view DNA_DEPRECATED; struct Object *camera, *ob_centre; + rctf render_border; struct ListBase bgpicbase; struct BGpic *bgpic DNA_DEPRECATED; /* deprecated, use bgpicbase, only kept for do_versions(...) */ @@ -267,6 +268,7 @@ typedef struct View3D { #define V3D_SHOW_CAMERAPATH 256 #define V3D_SHOW_BUNDLENAME 512 #define V3D_BACKFACE_CULLING 1024 +#define V3D_RENDER_BORDER 2048 /* View3D->around */ #define V3D_CENTER 0 diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index 780ca0b5878..2294abc0735 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -334,7 +334,7 @@ typedef struct wmOperator { #define OPERATOR_FLAGS_ALL ((1<<5)-1) /* sanity checks for debug mode only */ -#define OPERATOR_RETVAL_CHECK(ret) BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret) +#define OPERATOR_RETVAL_CHECK(ret) (void)ret, BLI_assert(ret != 0 && (ret & OPERATOR_FLAGS_ALL) == ret) /* wmOperator flag */ #define OP_GRAB_POINTER 1 diff --git a/source/blender/makesdna/intern/makesdna.c b/source/blender/makesdna/intern/makesdna.c index 2041ee01d6e..24457f557b0 100644 --- a/source/blender/makesdna/intern/makesdna.c +++ b/source/blender/makesdna/intern/makesdna.c @@ -487,11 +487,15 @@ static int preprocess_include(char *maindata, int len) } /* do not copy when: */ - if (comment) ; - else if (cp[0] == ' ' && cp[1] == ' ') ; - else if (cp[-1] == '*' && cp[0] == ' ') ; /* pointers with a space */ - - /* skip special keywords */ + if (comment) { + /* pass */ + } + else if (cp[0] == ' ' && cp[1] == ' ') { + /* pass */ + } + else if (cp[-1] == '*' && cp[0] == ' ') { + /* pointers with a space */ + } /* skip special keywords */ else if (strncmp("DNA_DEPRECATED", cp, 14) == 0) { /* single values are skipped already, so decrement 1 less */ a -= 13; @@ -1030,7 +1034,9 @@ static int make_structDNA(char *baseDirectory, FILE *file) if (debugSDNA > -1) printf("Writing file ... "); - if (nr_names == 0 || nr_structs == 0) ; + if (nr_names == 0 || nr_structs == 0) { + /* pass */ + } else { strcpy(str, "SDNA"); dna_write(file, str, 4); @@ -1090,7 +1096,9 @@ static int make_structDNA(char *baseDirectory, FILE *file) int a; fp = fopen("padding.c", "w"); - if (fp == NULL) ; + if (fp == NULL) { + /* pass */ + } else { /* add all include files defined in the global array */ diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index f6142f37248..89be5761fac 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -1102,8 +1102,8 @@ static char *rna_def_property_lookup_int_func(FILE *f, StructRNA *srna, Property return NULL; /* only supported in case of standard next functions */ - if (strcmp(nextfunc, "rna_iterator_array_next") == 0) ; - else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) ; + if (strcmp(nextfunc, "rna_iterator_array_next") == 0) {} + else if (strcmp(nextfunc, "rna_iterator_listbase_next") == 0) {} else return NULL; } @@ -1372,9 +1372,12 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp) CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)prop; const char *nextfunc = (const char *)cprop->next; - if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) ; - else if (dp->dnalengthname || dp->dnalengthfixed) + if (dp->dnatype && strcmp(dp->dnatype, "ListBase") == 0) { + /* pass */ + } + else if (dp->dnalengthname || dp->dnalengthfixed) { cprop->length = (void *)rna_def_property_length_func(f, srna, prop, dp, (const char *)cprop->length); + } /* test if we can allow raw array access, if it is using our standard * array get/next function, we can be sure it is an actual array */ diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index c88944b4584..610895002aa 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -996,7 +996,7 @@ void RNA_property_float_range(PointerRNA *ptr, PropertyRNA *prop, float *hardmin IDProperty *item; item = IDP_GetPropertyTypeFromGroup(idp_ui, "min", IDP_DOUBLE); - *hardmin = item ? (float)IDP_Double(item) : FLT_MIN; + *hardmin = item ? (float)IDP_Double(item) : -FLT_MAX; item = IDP_GetPropertyTypeFromGroup(idp_ui, "max", IDP_DOUBLE); *hardmax = item ? (float)IDP_Double(item) : FLT_MAX; @@ -3169,7 +3169,7 @@ static int rna_raw_access(ReportList *reports, PointerRNA *ptr, PropertyRNA *pro itemtype = RNA_property_type(iprop); } else { - BKE_reportf(reports, RPT_ERROR, "Property named %s not found", propname); + BKE_reportf(reports, RPT_ERROR, "Property named '%s' not found", propname); err = 1; break; } @@ -3606,7 +3606,7 @@ static char *rna_path_token(const char **path, char *fixedbuf, int fixedlen, int /* copy string, taking into account escaped ] */ if (bracket) { for (p = *path, i = 0, j = 0; i < len; i++, p++) { - if (*p == '\\' && *(p + 1) == quote) ; + if (*p == '\\' && *(p + 1) == quote) {} else buf[j++] = *p; } diff --git a/source/blender/makesrna/intern/rna_action.c b/source/blender/makesrna/intern/rna_action.c index b3ef977a5c0..54e213c1ac6 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/makesrna/intern/rna_animation_api.c b/source/blender/makesrna/intern/rna_animation_api.c index 39128b48cd8..b93fd9daa36 100644 --- a/source/blender/makesrna/intern/rna_animation_api.c +++ b/source/blender/makesrna/intern/rna_animation_api.c @@ -60,7 +60,7 @@ static void rna_KeyingSet_context_refresh(KeyingSet *ks, bContext *C, ReportList break; case MODIFYKEY_MISSING_TYPEINFO: - BKE_report(reports, RPT_ERROR, "Incomplete built-in Keying Set. Appears to be missing type info"); + BKE_report(reports, RPT_ERROR, "Incomplete built-in Keying Set, appears to be missing type info"); break; } } diff --git a/source/blender/makesrna/intern/rna_armature.c b/source/blender/makesrna/intern/rna_armature.c index ceadaa036f1..fa43bf39319 100644 --- a/source/blender/makesrna/intern/rna_armature.c +++ b/source/blender/makesrna/intern/rna_armature.c @@ -103,7 +103,7 @@ static void rna_Armature_act_edit_bone_set(PointerRNA *ptr, PointerRNA value) static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, const char *name) { if (arm->edbo == NULL) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in editmode, cant add an editbone", arm->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in edit mode, cannot add an editbone", arm->id.name + 2); return NULL; } return ED_armature_edit_bone_add(arm, name); @@ -112,12 +112,12 @@ static EditBone *rna_Armature_edit_bone_new(bArmature *arm, ReportList *reports, static void rna_Armature_edit_bone_remove(bArmature *arm, ReportList *reports, EditBone *ebone) { if (arm->edbo == NULL) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in editmode, cant remove an editbone", arm->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' not in edit mode, cannot remove an editbone", arm->id.name + 2); return; } if (BLI_findindex(arm->edbo, ebone) == -1) { - BKE_reportf(reports, RPT_ERROR, "Armature '%s' doesn't contain bone '%s'", arm->id.name + 2, ebone->name); + BKE_reportf(reports, RPT_ERROR, "Armature '%s' does not contain bone '%s'", arm->id.name + 2, ebone->name); return; } diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c index 4d33dc2f1e9..4de034b6407 100644 --- a/source/blender/makesrna/intern/rna_color.c +++ b/source/blender/makesrna/intern/rna_color.c @@ -505,13 +505,17 @@ static void rna_ColorManagedColorspaceSettings_reload_update(Main *UNUSED(bmain) Image *ima = (Image *) id; BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD); + WM_main_add_notifier(NC_IMAGE | ND_DISPLAY, &ima->id); + WM_main_add_notifier(NC_IMAGE | NA_EDITED, &ima->id); } else if (GS(id->name) == ID_MC) { MovieClip *clip = (MovieClip *) id; BKE_movieclip_reload(clip); + WM_main_add_notifier(NC_MOVIECLIP | ND_DISPLAY, &clip->id); + WM_main_add_notifier(NC_MOVIECLIP | NA_EDITED, &clip->id); } } diff --git a/source/blender/makesrna/intern/rna_curve.c b/source/blender/makesrna/intern/rna_curve.c index c47cb8ef2af..ad05eff9568 100644 --- a/source/blender/makesrna/intern/rna_curve.c +++ b/source/blender/makesrna/intern/rna_curve.c @@ -62,9 +62,9 @@ EnumPropertyItem keyframe_handle_type_items[] = { }; EnumPropertyItem beztriple_interpolation_mode_items[] = { - {BEZT_IPO_CONST, "CONSTANT", 0, "Constant", ""}, - {BEZT_IPO_LIN, "LINEAR", 0, "Linear", ""}, - {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", ""}, + {BEZT_IPO_CONST, "CONSTANT", 0, "Constant", "No interpolation. Value of A gets held until B is encountered"}, + {BEZT_IPO_LIN, "LINEAR", 0, "Linear", "Straight-line interpolation between A and B (i.e. no ease in/out)"}, + {BEZT_IPO_BEZ, "BEZIER", 0, "Bezier", "Smooth interpolation between A and B, with some control over curve shape"}, {0, NULL, 0, NULL, NULL} }; @@ -511,7 +511,7 @@ static void rna_Nurb_update_knot_v(Main *bmain, Scene *scene, PointerRNA *ptr) static void rna_Curve_spline_points_add(ID *id, Nurb *nu, ReportList *reports, int number) { if (nu->type == CU_BEZIER) { - BKE_report(reports, RPT_ERROR, "Bezier spline can't have points added"); + BKE_report(reports, RPT_ERROR, "Bezier spline cannot have points added"); } else if (number == 0) { /* do nothing */ @@ -581,7 +581,7 @@ static void rna_Curve_spline_remove(Curve *cu, ReportList *reports, Nurb *nu) found = BLI_remlink_safe(nurbs, nu); if (!found) { - BKE_reportf(reports, RPT_ERROR, "Curve \"%s\" does not contain spline given", cu->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Curve '%s' does not contain spline given", cu->id.name + 2); return; } @@ -721,7 +721,7 @@ static void rna_def_bpoint(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Curve_update_data"); /* Number values */ - prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "alfa"); /*RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/ RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); @@ -808,13 +808,14 @@ static void rna_def_beztriple(BlenderRNA *brna) RNA_def_property_update(prop, 0, "rna_Curve_update_points"); /* Number values */ - prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "tilt", PROP_FLOAT, PROP_ANGLE); RNA_def_property_float_sdna(prop, NULL, "alfa"); /*RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);*/ RNA_def_property_ui_text(prop, "Tilt", "Tilt in 3D View"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); - prop = RNA_def_property(srna, "weight", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "weight_softbody", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight"); RNA_def_property_range(prop, 0.01f, 100.0f); RNA_def_property_ui_text(prop, "Weight", "Softbody goal weight"); RNA_def_property_update(prop, 0, "rna_Curve_update_data"); @@ -1163,7 +1164,7 @@ static void rna_def_curve_spline_points(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_Curve_spline_points_add"); RNA_def_function_ui_description(func, "Add a number of points to this spline"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); - RNA_def_int(func, "count", 1, 1, INT_MAX, "Number", "Number of points to add to the spline", 1, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); #if 0 func= RNA_def_function(srna, "remove", "rna_Curve_spline_remove"); @@ -1190,7 +1191,7 @@ static void rna_def_curve_spline_bezpoints(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_Curve_spline_bezpoints_add"); RNA_def_function_ui_description(func, "Add a number of points to this spline"); RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_USE_REPORTS); - RNA_def_int(func, "count", 1, INT_MIN, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); #if 0 func = RNA_def_function(srna, "remove", "rna_Curve_spline_remove"); diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c index 45092d09ce1..d4e0ba68d9d 100644 --- a/source/blender/makesrna/intern/rna_define.c +++ b/source/blender/makesrna/intern/rna_define.c @@ -46,6 +46,17 @@ #include "rna_internal.h" + +#ifdef DEBUG +# define ASSERT_SOFT_HARD_LIMITS \ + if (softmin < hardmin || softmax > hardmax) { \ + fprintf(stderr, "Error with soft/hard limits: %s.%s\n", CONTAINER_RNA_ID(cont), identifier); \ + BLI_assert(!"invalid soft/hard limits"); \ + } (void)0 +#else +# define ASSERT_SOFT_HARD_LIMITS (void)0 +#endif + /* Global used during defining */ BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1}; @@ -2248,12 +2259,15 @@ PropertyRNA *RNA_def_boolean_vector(StructOrFunctionRNA *cont_, const char *iden return prop; } -PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, int hardmin, - int hardmax, const char *ui_name, const char *ui_description, int softmin, int softmax) +PropertyRNA *RNA_def_int(StructOrFunctionRNA *cont_, const char *identifier, int default_value, + int hardmin, int hardmax, const char *ui_name, const char *ui_description, + int softmin, int softmax) { ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE); RNA_def_property_int_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2270,6 +2284,8 @@ PropertyRNA *RNA_def_int_vector(StructOrFunctionRNA *cont_, const char *identifi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_XYZ); /* XXX */ if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_int_array_default(prop, default_value); @@ -2287,6 +2303,8 @@ PropertyRNA *RNA_def_int_array(StructOrFunctionRNA *cont_, const char *identifie ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_INT, PROP_NONE); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_int_array_default(prop, default_value); @@ -2426,6 +2444,8 @@ PropertyRNA *RNA_def_float(StructOrFunctionRNA *cont_, const char *identifier, f ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2442,6 +2462,8 @@ PropertyRNA *RNA_def_float_vector(StructOrFunctionRNA *cont_, const char *identi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_XYZ); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2472,6 +2494,8 @@ PropertyRNA *RNA_def_float_color(StructOrFunctionRNA *cont_, const char *identif ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_COLOR); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2489,10 +2513,9 @@ PropertyRNA *RNA_def_float_matrix(StructOrFunctionRNA *cont_, const char *identi { ContainerRNA *cont = cont_; PropertyRNA *prop; - int length[2]; + const int length[2] = {rows, columns}; - length[0] = rows; - length[1] = columns; + ASSERT_SOFT_HARD_LIMITS; prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_MATRIX); RNA_def_property_multi_array(prop, 2, length); @@ -2510,7 +2533,9 @@ PropertyRNA *RNA_def_float_rotation(StructOrFunctionRNA *cont_, const char *iden { ContainerRNA *cont = cont_; PropertyRNA *prop; - + + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, (len != 0) ? PROP_EULER : PROP_ANGLE); if (len != 0) { RNA_def_property_array(prop, len); @@ -2534,6 +2559,8 @@ PropertyRNA *RNA_def_float_array(StructOrFunctionRNA *cont_, const char *identif ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_NONE); if (len != 0) RNA_def_property_array(prop, len); if (default_value) RNA_def_property_float_array_default(prop, default_value); @@ -2551,6 +2578,8 @@ PropertyRNA *RNA_def_float_percentage(StructOrFunctionRNA *cont_, const char *id ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_PERCENTAGE); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); @@ -2567,6 +2596,8 @@ PropertyRNA *RNA_def_float_factor(StructOrFunctionRNA *cont_, const char *identi ContainerRNA *cont = cont_; PropertyRNA *prop; + ASSERT_SOFT_HARD_LIMITS; + prop = RNA_def_property(cont, identifier, PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_default(prop, default_value); if (hardmin != hardmax) RNA_def_property_range(prop, hardmin, hardmax); diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 24b14fdb884..d899b5833bb 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -1497,7 +1497,7 @@ static void rna_def_fcurve_keyframe_points(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "add", "rna_FKeyframe_points_add"); RNA_def_function_ui_description(func, "Add a keyframe point to a F-Curve"); - RNA_def_int(func, "count", 1, 1, INT_MAX, "Number", "Number of points to add to the spline", 1, INT_MAX); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the spline", 0, INT_MAX); func = RNA_def_function(srna, "remove", "rna_FKeyframe_points_remove"); RNA_def_function_ui_description(func, "Remove keyframe from an F-Curve"); diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index bf7f4984ea1..b0fcfb9b540 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -111,6 +111,112 @@ static void rna_GPencilLayer_info_set(PointerRNA *ptr, const char *value) BLI_uniquename(&gpd->layers, gpl, "GP_Layer", '.', offsetof(bGPDlayer, info), sizeof(gpl->info)); } +static void rna_GPencil_stroke_point_add(bGPDstroke *stroke, int count) +{ + if (count > 0) { + if (stroke->points == NULL) + stroke->points = MEM_callocN(sizeof(bGPDspoint) * count, "gp_stroke_points"); + else + stroke->points = MEM_reallocN(stroke->points, sizeof(bGPDspoint) * (stroke->totpoints + count)); + + stroke->totpoints += count; + } +} + +static void rna_GPencil_stroke_point_pop(bGPDstroke *stroke, ReportList *reports, int index) +{ + bGPDspoint *pt_tmp = stroke->points; + + /* python style negative indexing */ + if (index < 0) { + index += stroke->totpoints; + } + + if (stroke->totpoints <= index || index < 0) { + BKE_report(reports, RPT_ERROR, "GPencilStrokePoints.pop: index out of range"); + return; + } + + stroke->totpoints--; + + stroke->points = MEM_callocN(sizeof(bGPDspoint) * stroke->totpoints, "gp_stroke_points"); + + if (index > 0) + memcpy(stroke->points, pt_tmp, sizeof(bGPDspoint) * index); + + if (index < stroke->totpoints) + memcpy(&stroke->points[index], &pt_tmp[index + 1], sizeof(bGPDspoint) * (stroke->totpoints - index)); + + /* free temp buffer */ + MEM_freeN(pt_tmp); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDstroke *rna_GPencil_stroke_new(bGPDframe *frame) +{ + bGPDstroke *stroke = MEM_callocN(sizeof(bGPDstroke), "gp_stroke"); + + BLI_addtail(&frame->strokes, stroke); + + return stroke; +} + +static void rna_GPencil_stroke_remove(bGPDframe *frame, ReportList *reports, bGPDstroke *stroke) +{ + if (BLI_findindex(&frame->strokes, stroke) == -1) { + BKE_reportf(reports, RPT_ERROR, "Stroke not found in grease pencil frame"); + return; + } + + BLI_freelinkN(&frame->strokes, stroke); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDframe *rna_GPencil_frame_new(bGPDlayer *layer, ReportList *reports, int frame_number) +{ + bGPDframe *frame; + + if (BKE_gpencil_layer_find_frame(layer, frame_number)) { + BKE_reportf(reports, RPT_ERROR, "Frame already exists on this frame number"); + return NULL; + } + + frame = gpencil_frame_addnew(layer, frame_number); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); + + return frame; +} + +static void rna_GPencil_frame_remove(bGPDlayer *layer, ReportList *reports, bGPDframe *frame) +{ + if (BLI_findindex(&layer->frames, frame) == -1) { + BKE_reportf(reports, RPT_ERROR, "Frame not found in grease pencil layer"); + return; + } + + gpencil_layer_delframe(layer, frame); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); +} + +static bGPDframe *rna_GPencil_frame_copy(bGPDlayer *layer, bGPDframe *src) +{ + bGPDframe *frame = gpencil_frame_duplicate(src); + + while (BKE_gpencil_layer_find_frame(layer, frame->framenum)) { + frame->framenum++; + } + + BLI_addtail(&layer->frames, frame); + + WM_main_add_notifier(NC_GPENCIL | NA_EDITED, NULL); + + return frame; +} + static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int setactive) { bGPDlayer *gl = gpencil_layer_addnew(gpd, name, setactive); @@ -122,14 +228,7 @@ static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int seta static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, bGPDlayer *layer) { - bGPDlayer *gl; - - for (gl = gpd->layers.first; gl; gl = gl->next) { - if (gl == layer) - break; - } - - if (gl == NULL) { + if (BLI_findindex(&gpd->layers, layer) == -1) { BKE_reportf(reports, RPT_ERROR, "Layer not found in grease pencil data"); return; } @@ -139,6 +238,27 @@ static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, bGPDlaye WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); } +static void rna_GPencil_frame_clear(bGPDframe *frame) +{ + free_gpencil_strokes(frame); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + +static void rna_GPencil_layer_clear(bGPDlayer *layer) +{ + free_gpencil_frames(layer); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + +static void rna_GPencil_clear(bGPdata *gpd) +{ + free_gpencil_layers(&gpd->layers); + + WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL); +} + #else static void rna_def_gpencil_stroke_point(BlenderRNA *brna) @@ -154,19 +274,49 @@ static void rna_def_gpencil_stroke_point(BlenderRNA *brna) RNA_def_property_float_sdna(prop, NULL, "x"); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Coordinates", ""); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); prop = RNA_def_property(srna, "pressure", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "pressure"); RNA_def_property_range(prop, 0.0f, 1.0f); RNA_def_property_ui_text(prop, "Pressure", "Pressure of tablet at point when drawing it"); - RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); +} + +static void rna_def_gpencil_stroke_points_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + /* PropertyRNA *parm; */ + + RNA_def_property_srna(cprop, "GPencilStrokePoints"); + srna = RNA_def_struct(brna, "GPencilStrokePoints", NULL); + RNA_def_struct_sdna(srna, "bGPDstroke"); + RNA_def_struct_ui_text(srna, "Grease Pencil Stroke Points", "Collection of grease pencil stroke points"); + + func = RNA_def_function(srna, "add", "rna_GPencil_stroke_point_add"); + RNA_def_function_ui_description(func, "Add a new grease pencil stroke point"); + RNA_def_int(func, "count", 1, 0, INT_MAX, "Number", "Number of points to add to the stroke", 0, INT_MAX); + + func = RNA_def_function(srna, "pop", "rna_GPencil_stroke_point_pop"); + RNA_def_function_ui_description(func, "Remove a grease pencil stroke point"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_int(func, "index", -1, INT_MIN, INT_MAX, "Index", "point index", INT_MIN, INT_MAX); } static void rna_def_gpencil_stroke(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + static EnumPropertyItem stroke_draw_mode_items[] = { + {0, "SCREEN", 0, "Screen", "Stroke is in screen-space"}, + {GP_STROKE_3DSPACE, "3DSPACE", 0, "3D Space", "Stroke is in 3D-space"}, + {GP_STROKE_2DSPACE, "2DSPACE", 0, "2D Space", "Stroke is in 2D-space"}, + {GP_STROKE_2DIMAGE, "2DIMAGE", 0, "2D Image", "Stroke is in 2D-space (but with special 'image' scaling)"}, + {0, NULL, 0, NULL, NULL} + }; srna = RNA_def_struct(brna, "GPencilStroke", NULL); RNA_def_struct_sdna(srna, "bGPDstroke"); @@ -177,15 +327,45 @@ static void rna_def_gpencil_stroke(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "points", "totpoints"); RNA_def_property_struct_type(prop, "GPencilStrokePoint"); RNA_def_property_ui_text(prop, "Stroke Points", "Stroke data points"); - - /* Flags - Readonly type-info really... */ - /* TODO... */ + rna_def_gpencil_stroke_points_api(brna, prop); + + prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, stroke_draw_mode_items); + RNA_def_property_ui_text(prop, "Draw Mode", ""); + RNA_def_property_update(prop, 0, "rna_GPencil_update"); +} + +static void rna_def_gpencil_strokes_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "GPencilStrokes"); + srna = RNA_def_struct(brna, "GPencilStrokes", NULL); + RNA_def_struct_sdna(srna, "bGPDframe"); + RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil frames"); + + func = RNA_def_function(srna, "new", "rna_GPencil_stroke_new"); + RNA_def_function_ui_description(func, "Add a new grease pencil frame"); + parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "", "The newly created stroke"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_GPencil_stroke_remove"); + RNA_def_function_ui_description(func, "Remove a grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "stroke", "GPencilStroke", "Stroke", "The stroke to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); } static void rna_def_gpencil_frame(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + FunctionRNA *func; srna = RNA_def_struct(brna, "GPencilFrame", NULL); RNA_def_struct_sdna(srna, "bGPDframe"); @@ -196,7 +376,8 @@ static void rna_def_gpencil_frame(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "strokes", NULL); RNA_def_property_struct_type(prop, "GPencilStroke"); RNA_def_property_ui_text(prop, "Strokes", "Freehand curves defining the sketch on this frame"); - + rna_def_gpencil_strokes_api(brna, prop); + /* Frame Number */ prop = RNA_def_property(srna, "frame_number", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "framenum"); @@ -211,12 +392,51 @@ static void rna_def_gpencil_frame(BlenderRNA *brna) prop = RNA_def_property(srna, "select", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_FRAME_SELECT); RNA_def_property_ui_text(prop, "Select", "Frame is selected for editing in the DopeSheet"); + + func = RNA_def_function(srna, "clear", "rna_GPencil_frame_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil frame data"); +} + +static void rna_def_gpencil_frames_api(BlenderRNA *brna, PropertyRNA *cprop) +{ + StructRNA *srna; + + FunctionRNA *func; + PropertyRNA *parm; + + RNA_def_property_srna(cprop, "GPencilFrames"); + srna = RNA_def_struct(brna, "GPencilFrames", NULL); + RNA_def_struct_sdna(srna, "bGPDlayer"); + RNA_def_struct_ui_text(srna, "Grease Pencil Frames", "Collection of grease pencil frames"); + + func = RNA_def_function(srna, "new", "rna_GPencil_frame_new"); + RNA_def_function_ui_description(func, "Add a new grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_int(func, "frame_number", 1, MINFRAME, MAXFRAME, "Frame Number", "The frame on which this sketch appears", MINFRAME, MAXFRAME); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_pointer(func, "frame", "GPencilFrame", "", "The newly created frame"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_GPencil_frame_remove"); + RNA_def_function_ui_description(func, "Remove a grease pencil frame"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + parm = RNA_def_pointer(func, "frame", "GPencilFrame", "Frame", "The frame to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + + func = RNA_def_function(srna, "copy", "rna_GPencil_frame_copy"); + RNA_def_function_ui_description(func, "Copy a grease pencil frame"); + parm = RNA_def_pointer(func, "source", "GPencilFrame", "Source", "The source frame"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + parm = RNA_def_pointer(func, "copy", "GPencilFrame", "", "The newly copied frame"); + RNA_def_function_return(func, parm); } static void rna_def_gpencil_layer(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; + + FunctionRNA *func; srna = RNA_def_struct(brna, "GPencilLayer", NULL); RNA_def_struct_sdna(srna, "bGPDlayer"); @@ -234,7 +454,8 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "frames", NULL); RNA_def_property_struct_type(prop, "GPencilFrame"); RNA_def_property_ui_text(prop, "Frames", "Sketches for this layer on different frames"); - + rna_def_gpencil_frames_api(brna, prop); + /* Active Frame */ prop = RNA_def_property(srna, "active_frame", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "actframe"); @@ -317,9 +538,12 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", GP_LAYER_NO_XRAY); RNA_def_property_ui_text(prop, "X Ray", "Make the layer draw in front of objects"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); + + func = RNA_def_function(srna, "clear", "rna_GPencil_layer_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil layer data"); } -static void rna_def_gpencil_layers(BlenderRNA *brna, PropertyRNA *cprop) +static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop) { StructRNA *srna; PropertyRNA *prop; @@ -357,7 +581,8 @@ static void rna_def_gpencil_data(BlenderRNA *brna) { StructRNA *srna; PropertyRNA *prop; - + FunctionRNA *func; + static EnumPropertyItem draw_mode_items[] = { {GP_DATA_VIEWALIGN, "CURSOR", 0, "Cursor", "Draw stroke at the 3D cursor"}, {0, "VIEW", 0, "View", "Stick stroke to the view "}, /* weird, GP_DATA_VIEWALIGN is inverted */ @@ -376,7 +601,7 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_collection_sdna(prop, NULL, "layers", NULL); RNA_def_property_struct_type(prop, "GPencilLayer"); RNA_def_property_ui_text(prop, "Layers", ""); - rna_def_gpencil_layers(brna, prop); + rna_def_gpencil_layers_api(brna, prop); /* Flags */ prop = RNA_def_property(srna, "draw_mode", PROP_ENUM, PROP_NONE); @@ -390,6 +615,8 @@ static void rna_def_gpencil_data(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Only Endpoints", "Only use the first and last parts of the stroke for snapping"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, NULL); + func = RNA_def_function(srna, "clear", "rna_GPencil_clear"); + RNA_def_function_ui_description(func, "Remove all the grease pencil data"); } /* --- */ diff --git a/source/blender/makesrna/intern/rna_group.c b/source/blender/makesrna/intern/rna_group.c index 586b71aa2da..4baf46fd0b5 100644 --- a/source/blender/makesrna/intern/rna_group.c +++ b/source/blender/makesrna/intern/rna_group.c @@ -54,7 +54,7 @@ static PointerRNA rna_Group_objects_get(CollectionPropertyIterator *iter) static void rna_Group_objects_link(Group *group, bContext *C, ReportList *reports, Object *object) { if (!add_to_group(group, object, CTX_data_scene(C), NULL)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" already in group \"%s\"", object->id.name + 2, group->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' already in group '%s'", object->id.name + 2, group->id.name + 2); return; } @@ -64,7 +64,7 @@ static void rna_Group_objects_link(Group *group, bContext *C, ReportList *report static void rna_Group_objects_unlink(Group *group, bContext *C, ReportList *reports, Object *object) { if (!rem_from_group(group, object, CTX_data_scene(C), NULL)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" not in group \"%s\"", object->id.name + 2, group->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' not in group '%s'", object->id.name + 2, group->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_image_api.c b/source/blender/makesrna/intern/rna_image_api.c index 7766dff4273..d8ae579cd6b 100644 --- a/source/blender/makesrna/intern/rna_image_api.c +++ b/source/blender/makesrna/intern/rna_image_api.c @@ -184,7 +184,10 @@ static void rna_Image_update(Image *image, ReportList *reports) return; } - IMB_rect_from_float(ibuf); + if (ibuf->rect) + IMB_rect_from_float(ibuf); + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; } static void rna_Image_scale(Image *image, ReportList *reports, int width, int height) @@ -297,9 +300,9 @@ void RNA_api_image(StructRNA *srna) func = RNA_def_function(srna, "scale", "rna_Image_scale"); RNA_def_function_ui_description(func, "Scale the image in pixels"); RNA_def_function_flag(func, FUNC_USE_REPORTS); - parm = RNA_def_int(func, "width", 0, 1, 10000, "", "Width", 1, 10000); + parm = RNA_def_int(func, "width", 1, 1, 10000, "", "Width", 1, 10000); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "height", 0, 1, 10000, "", "Height", 1, 10000); + parm = RNA_def_int(func, "height", 1, 1, 10000, "", "Height", 1, 10000); RNA_def_property_flag(parm, PROP_REQUIRED); func = RNA_def_function(srna, "gl_touch", "rna_Image_gl_touch"); diff --git a/source/blender/makesrna/intern/rna_lattice.c b/source/blender/makesrna/intern/rna_lattice.c index d4082cf3d9f..e4a29d9c674 100644 --- a/source/blender/makesrna/intern/rna_lattice.c +++ b/source/blender/makesrna/intern/rna_lattice.c @@ -240,6 +240,12 @@ static void rna_def_latticepoint(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Deformed Location", ""); RNA_def_property_update(prop, 0, "rna_Lattice_update_data"); + prop = RNA_def_property(srna, "weight_softbody", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight"); + RNA_def_property_range(prop, 0.01f, 100.0f); + RNA_def_property_ui_text(prop, "Weight", "Softbody goal weight"); + RNA_def_property_update(prop, 0, "rna_Lattice_update_data"); + prop = RNA_def_property(srna, "groups", PROP_COLLECTION, PROP_NONE); RNA_def_property_collection_funcs(prop, "rna_LatticePoint_groups_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", @@ -320,7 +326,7 @@ static void rna_def_lattice(BlenderRNA *brna) RNA_def_property_collection_funcs(prop, "rna_Lattice_points_begin", "rna_iterator_array_next", "rna_iterator_array_end", "rna_iterator_array_get", NULL, NULL, NULL, NULL); RNA_def_property_ui_text(prop, "Points", "Points of the lattice"); - + /* pointers */ rna_def_animdata_common(srna); } diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 3485f6b2528..b77af6988ec 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -71,6 +71,7 @@ #include "BKE_speaker.h" #include "BKE_movieclip.h" #include "BKE_mask.h" +#include "BKE_gpencil.h" #include "BKE_linestyle.h" #include "DNA_armature_types.h" @@ -93,9 +94,12 @@ #include "DNA_node_types.h" #include "DNA_movieclip_types.h" #include "DNA_mask_types.h" +#include "DNA_gpencil_types.h" #include "ED_screen.h" +#include "BLF_translation.h" + static Camera *rna_Main_cameras_new(Main *UNUSED(bmain), const char *name) { ID *id = BKE_camera_add(name); @@ -107,7 +111,7 @@ static void rna_Main_cameras_remove(Main *bmain, ReportList *reports, struct Cam if (ID_REAL_USERS(camera) <= 0) BKE_libblock_free(&bmain->camera, camera); else - BKE_reportf(reports, RPT_ERROR, "Camera \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Camera '%s' must have zero users to be removed, found %d", camera->id.name + 2, ID_REAL_USERS(camera)); /* XXX python now has invalid pointer? */ @@ -127,7 +131,7 @@ static void rna_Main_scenes_remove(Main *bmain, bContext *C, ReportList *reports else if (scene->id.next) newscene = scene->id.next; else { - BKE_reportf(reports, RPT_ERROR, "Scene \"%s\" is the last, cant ve removed", scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Scene '%s' is the last, cannot be removed", scene->id.name + 2); return; } @@ -174,7 +178,7 @@ static Object *rna_Main_objects_new(Main *UNUSED(bmain), ReportList *reports, co if (RNA_enum_id_from_value(id_type_items, GS(data->name), &idname) == 0) idname = "UNKNOWN"; - BKE_reportf(reports, RPT_ERROR, "ID type '%s' is not valid for a object", idname); + BKE_reportf(reports, RPT_ERROR, "ID type '%s' is not valid for an object", idname); return NULL; } } @@ -198,7 +202,7 @@ static void rna_Main_objects_remove(Main *bmain, ReportList *reports, struct Obj BKE_libblock_free(&bmain->object, object); } else { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Object '%s' must have zero users to be removed, found %d", object->id.name + 2, ID_REAL_USERS(object)); } } @@ -214,7 +218,7 @@ static void rna_Main_materials_remove(Main *bmain, ReportList *reports, struct M if (ID_REAL_USERS(material) <= 0) BKE_libblock_free(&bmain->mat, material); else - BKE_reportf(reports, RPT_ERROR, "Material \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Material '%s' must have zero users to be removed, found %d", material->id.name + 2, ID_REAL_USERS(material)); /* XXX python now has invalid pointer? */ @@ -232,7 +236,7 @@ static void rna_Main_nodetree_remove(Main *bmain, ReportList *reports, struct bN if (ID_REAL_USERS(tree) <= 0) BKE_libblock_free(&bmain->nodetree, tree); else - BKE_reportf(reports, RPT_ERROR, "Node Tree \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Node tree '%s' must have zero users to be removed, found %d", tree->id.name + 2, ID_REAL_USERS(tree)); /* XXX python now has invalid pointer? */ @@ -249,7 +253,7 @@ void rna_Main_meshes_remove(Main *bmain, ReportList *reports, Mesh *mesh) if (ID_REAL_USERS(mesh) <= 0) BKE_libblock_free(&bmain->mesh, mesh); else - BKE_reportf(reports, RPT_ERROR, "Mesh \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Mesh '%s' must have zero users to be removed, found %d", mesh->id.name + 2, ID_REAL_USERS(mesh)); /* XXX python now has invalid pointer? */ @@ -267,7 +271,7 @@ static void rna_Main_lamps_remove(Main *bmain, ReportList *reports, Lamp *lamp) if (ID_REAL_USERS(lamp) <= 0) BKE_libblock_free(&bmain->lamp, lamp); else - BKE_reportf(reports, RPT_ERROR, "Lamp \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Lamp '%s' must have zero users to be removed, found %d", lamp->id.name + 2, ID_REAL_USERS(lamp)); /* XXX python now has invalid pointer? */ @@ -288,8 +292,8 @@ static Image *rna_Main_images_load(Main *UNUSED(bmain), ReportList *reports, con ima = BKE_image_load(filepath); if (!ima) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unsupported image format"); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unsupported image format")); return ima; } @@ -298,7 +302,7 @@ static void rna_Main_images_remove(Main *bmain, ReportList *reports, Image *imag if (ID_REAL_USERS(image) <= 0) BKE_libblock_free(&bmain->image, image); else - BKE_reportf(reports, RPT_ERROR, "Image \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Image '%s' must have zero users to be removed, found %d", image->id.name + 2, ID_REAL_USERS(image)); /* XXX python now has invalid pointer? */ @@ -315,7 +319,7 @@ static void rna_Main_lattices_remove(Main *bmain, ReportList *reports, struct La if (ID_REAL_USERS(lt) <= 0) BKE_libblock_free(&bmain->latt, lt); else - BKE_reportf(reports, RPT_ERROR, "Lattice \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Lattice '%s' must have zero users to be removed, found %d", lt->id.name + 2, ID_REAL_USERS(lt)); } @@ -330,7 +334,7 @@ static void rna_Main_curves_remove(Main *bmain, ReportList *reports, struct Curv if (ID_REAL_USERS(cu) <= 0) BKE_libblock_free(&bmain->curve, cu); else - BKE_reportf(reports, RPT_ERROR, "Curve \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Curve '%s' must have zero users to be removed, found %d", cu->id.name + 2, ID_REAL_USERS(cu)); } @@ -345,7 +349,7 @@ static void rna_Main_metaballs_remove(Main *bmain, ReportList *reports, struct M if (ID_REAL_USERS(mb) <= 0) BKE_libblock_free(&bmain->mball, mb); else - BKE_reportf(reports, RPT_ERROR, "Metaball \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Metaball '%s' must have zero users to be removed, found %d", mb->id.name + 2, ID_REAL_USERS(mb)); } @@ -357,8 +361,8 @@ static VFont *rna_Main_fonts_load(Main *bmain, ReportList *reports, const char * font = BKE_vfont_load(bmain, filepath); if (!font) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unsupported font format"); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unsupported font format")); return font; @@ -368,7 +372,7 @@ static void rna_Main_fonts_remove(Main *bmain, ReportList *reports, VFont *vfont if (ID_REAL_USERS(vfont) <= 0) BKE_libblock_free(&bmain->vfont, vfont); else - BKE_reportf(reports, RPT_ERROR, "Font \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Font '%s' must have zero users to be removed, found %d", vfont->id.name + 2, ID_REAL_USERS(vfont)); /* XXX python now has invalid pointer? */ @@ -386,7 +390,7 @@ static void rna_Main_textures_remove(Main *bmain, ReportList *reports, struct Te if (ID_REAL_USERS(tex) <= 0) BKE_libblock_free(&bmain->tex, tex); else - BKE_reportf(reports, RPT_ERROR, "Texture \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Texture '%s' must have zero users to be removed, found %d", tex->id.name + 2, ID_REAL_USERS(tex)); } @@ -401,7 +405,7 @@ static void rna_Main_brushes_remove(Main *bmain, ReportList *reports, struct Bru if (ID_REAL_USERS(brush) <= 0) BKE_libblock_free(&bmain->brush, brush); else - BKE_reportf(reports, RPT_ERROR, "Brush \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Brush '%s' must have zero users to be removed, found %d", brush->id.name + 2, ID_REAL_USERS(brush)); } @@ -416,7 +420,7 @@ static void rna_Main_worlds_remove(Main *bmain, ReportList *reports, struct Worl if (ID_REAL_USERS(world) <= 0) BKE_libblock_free(&bmain->world, world); else - BKE_reportf(reports, RPT_ERROR, "World \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "World '%s' must have zero users to be removed, found %d", world->id.name + 2, ID_REAL_USERS(world)); } @@ -442,7 +446,7 @@ static void rna_Main_speakers_remove(Main *bmain, ReportList *reports, Speaker * if (ID_REAL_USERS(speaker) <= 0) BKE_libblock_free(&bmain->speaker, speaker); else - BKE_reportf(reports, RPT_ERROR, "Speaker \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Speaker '%s' must have zero users to be removed, found %d", speaker->id.name + 2, ID_REAL_USERS(speaker)); /* XXX python now has invalid pointer? */ @@ -467,8 +471,8 @@ static Text *rna_Main_texts_load(Main *bmain, ReportList *reports, const char *f txt = BKE_text_load(filepath, bmain->name); if (!txt) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s", filepath, - errno ? strerror(errno) : "Unable to load text"); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to load text")); return txt; } @@ -484,7 +488,7 @@ static void rna_Main_armatures_remove(Main *bmain, ReportList *reports, bArmatur if (ID_REAL_USERS(arm) <= 0) BKE_libblock_free(&bmain->armature, arm); else - BKE_reportf(reports, RPT_ERROR, "Armature \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Armature '%s' must have zero users to be removed, found %d", arm->id.name + 2, ID_REAL_USERS(arm)); /* XXX python now has invalid pointer? */ @@ -502,7 +506,7 @@ static void rna_Main_actions_remove(Main *bmain, ReportList *reports, bAction *a if (ID_REAL_USERS(act) <= 0) BKE_libblock_free(&bmain->action, act); else - BKE_reportf(reports, RPT_ERROR, "Action \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Action '%s' must have zero users to be removed, found %d", act->id.name + 2, ID_REAL_USERS(act)); /* XXX python now has invalid pointer? */ @@ -519,7 +523,7 @@ static void rna_Main_particles_remove(Main *bmain, ReportList *reports, Particle if (ID_REAL_USERS(part) <= 0) BKE_libblock_free(&bmain->particle, part); else - BKE_reportf(reports, RPT_ERROR, "Particle Settings \"%s\" must have zero users to be removed, found %d", + BKE_reportf(reports, RPT_ERROR, "Particle settings '%s' must have zero users to be removed, found %d", part->id.name + 2, ID_REAL_USERS(part)); /* XXX python now has invalid pointer? */ @@ -533,8 +537,8 @@ static MovieClip *rna_Main_movieclip_load(Main *UNUSED(bmain), ReportList *repor clip = BKE_movieclip_file_add(filepath); if (!clip) - BKE_reportf(reports, RPT_ERROR, "Can't read: \"%s\", %s.", filepath, - errno ? strerror(errno) : "Unable to load movie clip"); + BKE_reportf(reports, RPT_ERROR, "Cannot read '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to load movie clip")); return clip; } @@ -562,6 +566,19 @@ static void rna_Main_masks_remove(Main *bmain, Mask *mask) /* XXX python now has invalid pointer? */ } +static void rna_Main_grease_pencil_remove(Main *bmain, ReportList *reports, bGPdata *gpd) +{ + if (ID_REAL_USERS(gpd) <= 0) { + BKE_gpencil_free(gpd); + BKE_libblock_free(&bmain->gpencil, gpd); + } + else + BKE_reportf(reports, RPT_ERROR, "Grease Pencil '%s' must have zero users to be removed, found %d", + gpd->id.name + 2, ID_REAL_USERS(gpd)); + + /* XXX python now has invalid pointer? */ +} + FreestyleLineStyle *rna_Main_linestyles_new(Main *bmain, const char* name) { FreestyleLineStyle *linestyle = FRS_new_linestyle(name, bmain); @@ -994,9 +1011,9 @@ void RNA_def_main_images(BlenderRNA *brna, PropertyRNA *cprop) RNA_def_function_ui_description(func, "Add a new image to the main database"); parm = RNA_def_string(func, "name", "Image", 0, "", "New name for the datablock"); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "width", 1024, 1, INT_MAX, "", "Width of the image", 0, INT_MAX); + parm = RNA_def_int(func, "width", 1024, 1, INT_MAX, "", "Width of the image", 1, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); - parm = RNA_def_int(func, "height", 1024, 1, INT_MAX, "", "Height of the image", 0, INT_MAX); + parm = RNA_def_int(func, "height", 1024, 1, INT_MAX, "", "Height of the image", 1, INT_MAX); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_boolean(func, "alpha", 0, "Alpha", "Use alpha channel"); RNA_def_boolean(func, "float_buffer", 0, "Float Buffer", "Create an image with floating point color"); @@ -1528,6 +1545,20 @@ void RNA_def_main_gpencil(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_boolean(func, "value", 0, "Value", ""); RNA_def_property_flag(parm, PROP_REQUIRED); + func = RNA_def_function(srna, "new", "gpencil_data_addnew"); + RNA_def_function_flag(func, FUNC_NO_SELF); + parm = RNA_def_string(func, "name", "GreasePencil", 0, "", "New name for the datablock"); + RNA_def_property_flag(parm, PROP_REQUIRED); + /* return type */ + parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "New grease pencil datablock"); + RNA_def_function_return(func, parm); + + func = RNA_def_function(srna, "remove", "rna_Main_grease_pencil_remove"); + RNA_def_function_flag(func, FUNC_USE_REPORTS); + RNA_def_function_ui_description(func, "Remove a grease pencil instance from the current blendfile"); + parm = RNA_def_pointer(func, "grease_pencil", "GreasePencil", "", "Grease Pencil to remove"); + RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); + prop = RNA_def_property(srna, "is_updated", PROP_BOOLEAN, PROP_NONE); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_boolean_funcs(prop, "rna_Main_gpencil_is_updated_get", NULL); diff --git a/source/blender/makesrna/intern/rna_material.c b/source/blender/makesrna/intern/rna_material.c index 96529de074b..a2fbada3cc1 100644 --- a/source/blender/makesrna/intern/rna_material.c +++ b/source/blender/makesrna/intern/rna_material.c @@ -319,7 +319,7 @@ MTex *rna_mtex_texture_slots_add(ID *self_id, struct bContext *C, ReportList *re { MTex *mtex = add_mtex_id(self_id, -1); if (mtex == NULL) { - BKE_reportf(reports, RPT_ERROR, "maximum number of textures added %d", MAX_MTEX); + BKE_reportf(reports, RPT_ERROR, "Maximum number of textures added %d", MAX_MTEX); return NULL; } @@ -334,7 +334,7 @@ MTex *rna_mtex_texture_slots_create(ID *self_id, struct bContext *C, ReportList MTex *mtex; if (index < 0 || index >= MAX_MTEX) { - BKE_reportf(reports, RPT_ERROR, "index %d is invalid", index); + BKE_reportf(reports, RPT_ERROR, "Index %d is invalid", index); return NULL; } @@ -354,12 +354,12 @@ void rna_mtex_texture_slots_clear(ID *self_id, struct bContext *C, ReportList *r give_active_mtex(self_id, &mtex_ar, &act); if (mtex_ar == NULL) { - BKE_report(reports, RPT_ERROR, "mtex not found for this type"); + BKE_report(reports, RPT_ERROR, "Mtex not found for this type"); return; } if (index < 0 || index >= MAX_MTEX) { - BKE_reportf(reports, RPT_ERROR, "index %d is invalid", index); + BKE_reportf(reports, RPT_ERROR, "Index %d is invalid", index); return; } @@ -468,6 +468,12 @@ static void rna_def_material_mtex(BlenderRNA *brna) "from their parent"); RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_map_to_bounds", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_MAPTO_BOUNDS); + RNA_def_property_ui_text(prop, "Map to Bounds", + "Map coordinates in object bounds"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_from_original", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "texflag", MTEX_OB_DUPLI_ORIG); RNA_def_property_ui_text(prop, "From Original", @@ -1817,7 +1823,12 @@ void RNA_def_material(BlenderRNA *brna) "Material uses the light group exclusively - these lamps are excluded " "from other scene lighting"); RNA_def_property_update(prop, 0, "rna_Material_update"); - + + prop= RNA_def_property(srna, "use_light_group_local", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "shade_flag", MA_GROUP_LOCAL); + RNA_def_property_ui_text(prop, "Light Group Local", "When linked in, Material uses local light group with the same name"); + RNA_def_property_update(prop, 0, "rna_Material_update"); + prop = RNA_def_property(srna, "use_raytrace", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "mode", MA_TRACEBLE); RNA_def_property_ui_text(prop, "Traceable", diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index df73fcd96dd..5ddf2073f19 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1275,12 +1275,12 @@ static PointerRNA rna_Mesh_tessface_vertex_color_new(struct Mesh *me, struct bCo int index; if (me->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessface colors's in editmode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface colors in edit mode"); return PointerRNA_NULL; } if (me->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessface colors's when MPoly's exist"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface colors when MPoly's exist"); return PointerRNA_NULL; } @@ -1368,12 +1368,12 @@ static PointerRNA rna_Mesh_tessface_uv_texture_new(struct Mesh *me, struct bCont int index; if (me->edit_btmesh) { - BKE_report(reports, RPT_ERROR, "Can't add tessface uv's in editmode"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface uv's in edit mode"); return PointerRNA_NULL; } if (me->mpoly) { - BKE_report(reports, RPT_ERROR, "Can't add tessface uv's when MPoly's exist"); + BKE_report(reports, RPT_ERROR, "Cannot add tessface uv's when MPoly's exist"); return PointerRNA_NULL; } diff --git a/source/blender/makesrna/intern/rna_meta.c b/source/blender/makesrna/intern/rna_meta.c index c8b52b45604..fe2c29632f2 100644 --- a/source/blender/makesrna/intern/rna_meta.c +++ b/source/blender/makesrna/intern/rna_meta.c @@ -133,7 +133,7 @@ static void rna_MetaBall_elements_remove(MetaBall *mb, ReportList *reports, Meta found = BLI_remlink_safe(&mb->elems, ml); if (!found) { - BKE_reportf(reports, RPT_ERROR, "Metaball \"%s\" does not contain spline given", mb->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Metaball '%s' does not contain spline given", mb->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 1b26c0447ff..8a8bb2a2384 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -257,9 +257,6 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr) { SmokeModifierData *smd = (SmokeModifierData *)ptr->data; Object *ob = (Object *)ptr->id.data; - ParticleSystemModifierData *psmd = NULL; - ParticleSystem *psys = NULL; - ParticleSettings *part = NULL; /* nothing changed */ if ((smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) @@ -273,28 +270,6 @@ static void rna_Smoke_set_type(Main *bmain, Scene *scene, PointerRNA *ptr) ob->dt = OB_WIRE; break; case MOD_SMOKE_TYPE_FLOW: - for (psys = ob->particlesystem.first; psys; psys = psys->next) - if (psys->part->type == PART_EMITTER) - break; - if (ob->type == OB_MESH && !psys) { - /* add particle system */ - psmd = (ParticleSystemModifierData *)object_add_particle_system(scene, ob, NULL); - if (psmd) { - psys = psmd->psys; - part = psys->part; - part->lifetime = 1.0f; - part->sta = 1.0f; - part->end = 250.0f; - part->ren_as = PART_DRAW_NOT; - part->flag |= PART_UNBORN; - part->draw_as = PART_DRAW_DOT; - BLI_strncpy(psys->name, "SmokeParticles", sizeof(psys->name)); - psys->recalc |= (PSYS_RECALC_RESET | PSYS_RECALC_PHYS); - DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA); - } - } - if (smd->flow) - smd->flow->psys = psys; case MOD_SMOKE_TYPE_COLL: case 0: default: diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c index 4ff1365427e..8378cb92e20 100644 --- a/source/blender/makesrna/intern/rna_nla.c +++ b/source/blender/makesrna/intern/rna_nla.c @@ -302,7 +302,7 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo NlaStrip *strip = add_nlastrip(action); if (strip == NULL) { - BKE_reportf(reports, RPT_ERROR, "Unable to create new strip"); + BKE_report(reports, RPT_ERROR, "Unable to create new strip"); return NULL; } @@ -310,8 +310,8 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo strip->start = start; if (BKE_nlastrips_add_strip(&track->strips, strip) == 0) { - BKE_reportf(reports, RPT_ERROR, - "Unable to add strip. Track doesn't have any space to accommodate this new strip"); + BKE_report(reports, RPT_ERROR, + "Unable to add strip (the track does not have any space to accommodate this new strip)"); free_nlastrip(NULL, strip); return NULL; } @@ -348,7 +348,7 @@ static NlaStrip *rna_NlaStrip_new(NlaTrack *track, bContext *C, ReportList *repo static void rna_NlaStrip_remove(NlaTrack *track, bContext *C, ReportList *reports, NlaStrip *strip) { if (BLI_findindex(&track->strips, strip) == -1) { - BKE_reportf(reports, RPT_ERROR, "NLA's Strip '%s' not found in track '%s'", strip->name, track->name); + BKE_reportf(reports, RPT_ERROR, "NLA strip '%s' not found in track '%s'", strip->name, track->name); return; } else { diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index d650c8dbf69..0d7d20d04ae 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -689,7 +689,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r bNodeTemplate ntemp; if (type == NODE_GROUP && group == NULL) { - BKE_reportf(reports, RPT_ERROR, "node type \'GROUP\' missing group argument"); + BKE_report(reports, RPT_ERROR, "Node type 'GROUP' missing group argument"); return NULL; } @@ -700,7 +700,7 @@ static bNode *rna_NodeTree_node_new(bNodeTree *ntree, bContext *C, ReportList *r node = nodeAddNode(ntree, &ntemp); if (node == NULL) { - BKE_reportf(reports, RPT_ERROR, "Unable to create node"); + BKE_report(reports, RPT_ERROR, "Unable to create node"); } else { ntreeUpdateTree(ntree); /* update group node socket links*/ @@ -756,7 +756,7 @@ static bNode *rna_NodeTree_node_texture_new(bNodeTree *ntree, bContext *C, Repor static void rna_NodeTree_node_remove(bNodeTree *ntree, ReportList *reports, bNode *node) { if (BLI_findindex(&ntree->nodes, node) == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in nodetree", node->name); + BKE_reportf(reports, RPT_ERROR, "Unable to locate node '%s' in node tree", node->name); } else { if (node->id) @@ -800,7 +800,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, nodeFindNode(ntree, tosock, &tonode, NULL, &to_in_out); if (&from_in_out == &to_in_out) { - BKE_reportf(reports, RPT_ERROR, "Same input/output direction of sockets"); + BKE_report(reports, RPT_ERROR, "Same input/output direction of sockets"); return NULL; } @@ -827,7 +827,7 @@ static bNodeLink *rna_NodeTree_link_new(bNodeTree *ntree, ReportList *reports, static void rna_NodeTree_link_remove(bNodeTree *ntree, ReportList *reports, bNodeLink *link) { if (BLI_findindex(&ntree->links, link) == -1) { - BKE_reportf(reports, RPT_ERROR, "Unable to locate link in nodetree"); + BKE_report(reports, RPT_ERROR, "Unable to locate link in node tree"); } else { nodeRemLink(ntree, link); @@ -882,9 +882,9 @@ static bNodeSocket *rna_NodeTree_input_expose(bNodeTree *ntree, ReportList *repo int index, in_out; if (!nodeFindNode(ntree, sock, &node, &index, &in_out)) - BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in nodetree"); + BKE_report(reports, RPT_ERROR, "Unable to locate socket in node tree"); else if (in_out != SOCK_IN) - BKE_reportf(reports, RPT_ERROR, "Socket is not an input"); + BKE_report(reports, RPT_ERROR, "Socket is not an input"); else { /* XXX should check if tree is a group here! no good way to do this currently. */ gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_IN); @@ -906,9 +906,9 @@ static bNodeSocket *rna_NodeTree_output_expose(bNodeTree *ntree, ReportList *rep int index, in_out; if (!nodeFindNode(ntree, sock, &node, &index, &in_out)) - BKE_reportf(reports, RPT_ERROR, "Unable to locate socket in nodetree"); + BKE_report(reports, RPT_ERROR, "Unable to locate socket in node tree"); else if (in_out != SOCK_OUT) - BKE_reportf(reports, RPT_ERROR, "Socket is not an output"); + BKE_report(reports, RPT_ERROR, "Socket is not an output"); else { /* XXX should check if tree is a group here! no good way to do this currently. */ gsock = node_group_add_socket(ntree, sock->name, sock->type, SOCK_OUT); @@ -1462,7 +1462,8 @@ static void def_sh_tex_sky(StructRNA *srna) RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "turbidity", PROP_FLOAT, PROP_NONE); - RNA_def_property_ui_text(prop, "Turbidity", ""); + RNA_def_property_range(prop, 1.0f, 30.0f); + RNA_def_property_ui_text(prop, "Turbidity", "Atmospheric turbidity"); RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } diff --git a/source/blender/makesrna/intern/rna_nodetree_types.h b/source/blender/makesrna/intern/rna_nodetree_types.h index db1e1e16adf..6d97e959112 100644 --- a/source/blender/makesrna/intern/rna_nodetree_types.h +++ b/source/blender/makesrna/intern/rna_nodetree_types.h @@ -67,6 +67,7 @@ DefNode( ShaderNode, SH_NODE_ADD_SHADER, 0, "AD DefNode( ShaderNode, SH_NODE_ATTRIBUTE, def_sh_attribute, "ATTRIBUTE", Attribute, "Attribute", "" ) DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BACKGROUND", Background, "Background", "" ) DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" ) +DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, 0, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy Bsdf", "" ) DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glossy, "BSDF_GLASS", BsdfGlass, "Glass Bsdf", "" ) @@ -81,6 +82,7 @@ DefNode( ShaderNode, SH_NODE_LIGHT_PATH, 0, "LI DefNode( ShaderNode, SH_NODE_LIGHT_FALLOFF, 0, "LIGHT_FALLOFF", LightFalloff, "Light Falloff", "" ) DefNode( ShaderNode, SH_NODE_OBJECT_INFO, 0, "OBJECT_INFO", ObjectInfo, "Object Info", "" ) DefNode( ShaderNode, SH_NODE_PARTICLE_INFO, 0, "PARTICLE_INFO", ParticleInfo, "Particle Info", "" ) +DefNode( ShaderNode, SH_NODE_BUMP, 0, "BUMP", BumpNode, "Bump", "" ) DefNode( ShaderNode, SH_NODE_TEX_IMAGE, def_sh_tex_image, "TEX_IMAGE", TexImage, "Image Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_ENVIRONMENT, def_sh_tex_environment, "TEX_ENVIRONMENT", TexEnvironment, "Environment Texture","" ) DefNode( ShaderNode, SH_NODE_TEX_SKY, def_sh_tex_sky, "TEX_SKY", TexSky, "Sky Texture", "" ) @@ -91,7 +93,7 @@ DefNode( ShaderNode, SH_NODE_TEX_WAVE, def_sh_tex_wave, "TE DefNode( ShaderNode, SH_NODE_TEX_MUSGRAVE, def_sh_tex_musgrave, "TEX_MUSGRAVE", TexMusgrave, "Musgrave Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_VORONOI, def_sh_tex_voronoi, "TEX_VORONOI", TexVoronoi, "Voronoi Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_CHECKER, def_sh_tex_checker, "TEX_CHECKER", TexChecker, "Checker Texture", "" ) -DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) +DefNode( ShaderNode, SH_NODE_TEX_BRICK, def_sh_tex_brick, "TEX_BRICK", TexBrick, "Brick Texture", "" ) DefNode( ShaderNode, SH_NODE_TEX_COORD, def_sh_tex_coord, "TEX_COORD", TexCoord, "Texture Coordinate","" ) DefNode( CompositorNode, CMP_NODE_VIEWER, def_cmp_viewer, "VIEWER", Viewer, "Viewer", "" ) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 879a77527cd..3204dc8e6bc 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -158,7 +158,7 @@ Mesh *rna_Object_to_mesh(Object *ob, ReportList *reports, Scene *sce, int apply_ /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked */ if (tmpobj->type != OB_MESH) { BKE_libblock_free_us(&(G.main->object), tmpobj); - BKE_report(reports, RPT_ERROR, "cant convert curve to mesh. Does the curve have any segments?"); + BKE_report(reports, RPT_ERROR, "Cannot convert curve to mesh (does the curve have any segments?)"); return NULL; } @@ -351,7 +351,7 @@ void rna_Object_create_duplilist(Object *ob, ReportList *reports, Scene *sce, in /* free duplilist if a user forgets to */ if (ob->duplilist) { - BKE_reportf(reports, RPT_WARNING, "Object.dupli_list has not been freed"); + BKE_report(reports, RPT_WARNING, "Object.dupli_list has not been freed"); free_object_duplilist(ob->duplilist); ob->duplilist = NULL; @@ -387,7 +387,7 @@ static PointerRNA rna_Object_shape_key_add(Object *ob, bContext *C, ReportList * return keyptr; } else { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\"does not support shapes", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' does not support shapes", ob->id.name + 2); return PointerRNA_NULL; } } @@ -402,14 +402,14 @@ static void rna_Mesh_assign_verts_to_group(Object *ob, bDeformGroup *group, int float weight, int assignmode) { if (ob->type != OB_MESH) { - BKE_report(reports, RPT_ERROR, "Object should be of MESH type"); + BKE_report(reports, RPT_ERROR, "Object should be of mesh type"); return; } Mesh *me = (Mesh *)ob->data; int group_index = BLI_findlink(&ob->defbase, group); if (group_index == -1) { - BKE_report(reports, RPT_ERROR, "No deform groups assigned to mesh"); + BKE_report(reports, RPT_ERROR, "No vertex groups assigned to mesh"); return; } @@ -441,7 +441,7 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start BVHTreeFromMesh treeData = {NULL}; if (ob->derivedFinal == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" has no mesh data to be used for ray casting", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' has no mesh data to be used for ray casting", ob->id.name + 2); return; } @@ -449,7 +449,7 @@ static void rna_Object_ray_cast(Object *ob, ReportList *reports, float ray_start bvhtree_from_mesh_faces(&treeData, ob->derivedFinal, 0.0f, 4, 6); if (treeData.tree == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" could not create internal data for ray casting", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' could not create internal data for ray casting", ob->id.name + 2); return; } else { @@ -483,7 +483,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl BVHTreeFromMesh treeData = {NULL}; if (ob->derivedFinal == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" has no mesh data to be used for finding nearest point", + BKE_reportf(reports, RPT_ERROR, "Object '%s' has no mesh data to be used for finding nearest point", ob->id.name + 2); return; } @@ -492,7 +492,7 @@ static void rna_Object_closest_point_on_mesh(Object *ob, ReportList *reports, fl bvhtree_from_mesh_faces(&treeData, ob->derivedFinal, 0.0f, 4, 6); if (treeData.tree == NULL) { - BKE_reportf(reports, RPT_ERROR, "object \"%s\" could not create internal data for finding nearest point", + BKE_reportf(reports, RPT_ERROR, "Object '%s' could not create internal data for finding nearest point", ob->id.name + 2); return; } diff --git a/source/blender/makesrna/intern/rna_object_force.c b/source/blender/makesrna/intern/rna_object_force.c index 1c896133408..940d59ec9b3 100644 --- a/source/blender/makesrna/intern/rna_object_force.c +++ b/source/blender/makesrna/intern/rna_object_force.c @@ -1056,6 +1056,13 @@ static void rna_def_effector_weight(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); RNA_def_property_ui_text(prop, "Drag", "Drag effector weight"); RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); + + prop = RNA_def_property(srna, "smokeflow", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "weight[13]"); + RNA_def_property_range(prop, -200.0f, 200.0f); + RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3); + RNA_def_property_ui_text(prop, "Smoke Flow", "Smoke Flow effector weight"); + RNA_def_property_update(prop, 0, "rna_EffectorWeight_update"); } static void rna_def_field(BlenderRNA *brna) @@ -1082,6 +1089,7 @@ static void rna_def_field(BlenderRNA *brna) {PFIELD_BOID, "BOID", ICON_FORCE_BOID, "Boid", ""}, {PFIELD_TURBULENCE, "TURBULENCE", ICON_FORCE_TURBULENCE, "Turbulence", "Create turbulence with a noise field"}, {PFIELD_DRAG, "DRAG", ICON_FORCE_DRAG, "Drag", "Create a force that dampens motion"}, + {PFIELD_SMOKEFLOW, "SMOKE_FLOW", ICON_FORCE_SMOKEFLOW, "Smoke Flow", "Create a force based on smoke simulation air flow"}, {0, NULL, 0, NULL, NULL} }; @@ -1307,7 +1315,7 @@ static void rna_def_field(BlenderRNA *brna) prop = RNA_def_property(srna, "use_2d_force", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_TEX_2D); - RNA_def_property_ui_text(prop, "2D", "Apply force only in 2d"); + RNA_def_property_ui_text(prop, "2D", "Apply force only in 2D"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); prop = RNA_def_property(srna, "use_root_coords", PROP_BOOLEAN, PROP_NONE); @@ -1334,6 +1342,11 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_MULTIPLE_SPRINGS); RNA_def_property_ui_text(prop, "Multiple Springs", "Every point is effected by multiple springs"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop = RNA_def_property(srna, "use_smoke_density", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag", PFIELD_SMOKE_DENSITY); + RNA_def_property_ui_text(prop, "Apply Density", "Adjust force strength based on smoke density"); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /* Pointer */ @@ -1342,6 +1355,12 @@ static void rna_def_field(BlenderRNA *brna) RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "Texture", "Texture to use as force"); RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); + + prop = RNA_def_property(srna, "source_object", PROP_POINTER, PROP_NONE); + RNA_def_property_pointer_sdna(prop, NULL, "f_source"); + RNA_def_property_ui_text(prop, "Domain Object", "Select domain object of the smoke simulation"); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_update(prop, 0, "rna_FieldSettings_update"); /********** Curve Guide Field Settings **********/ diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c index d2e4e8edbfb..736753894d1 100644 --- a/source/blender/makesrna/intern/rna_render.c +++ b/source/blender/makesrna/intern/rna_render.c @@ -160,7 +160,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo return NULL; if (strlen(identifier) >= sizeof(dummyet.idname)) { - BKE_reportf(reports, RPT_ERROR, "registering render engine class: '%s' is too long, maximum length is %d", + BKE_reportf(reports, RPT_ERROR, "Registering render engine class: '%s' is too long, maximum length is %d", identifier, (int)sizeof(dummyet.idname)); return NULL; } @@ -329,7 +329,6 @@ static void rna_def_render_engine(BlenderRNA *brna) prop = RNA_def_pointer(func, "result", "RenderResult", "Result", ""); RNA_def_property_flag(prop, PROP_REQUIRED); prop = RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't merge back results"); - RNA_def_property_flag(prop, PROP_REQUIRED); func = RNA_def_function(srna, "test_break", "RE_engine_test_break"); prop = RNA_def_boolean(func, "do_break", 0, "Break", ""); diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c index 62ba3a7e663..24f17034ea1 100644 --- a/source/blender/makesrna/intern/rna_scene.c +++ b/source/blender/makesrna/intern/rna_scene.c @@ -360,7 +360,7 @@ static Base *rna_Scene_object_link(Scene *scene, bContext *C, ReportList *report Base *base; if (BKE_scene_base_find(scene, ob)) { - BKE_reportf(reports, RPT_ERROR, "Object \"%s\" is already in scene \"%s\"", ob->id.name + 2, scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' is already in scene '%s'", ob->id.name + 2, scene->id.name + 2); return NULL; } @@ -392,7 +392,7 @@ static void rna_Scene_object_unlink(Scene *scene, ReportList *reports, Object *o return; } if (base == scene->basact && ob->mode != OB_MODE_OBJECT) { - BKE_reportf(reports, RPT_ERROR, "Object '%s' must be in 'Object Mode' to unlink", ob->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Object '%s' must be in object mode to unlink", ob->id.name + 2); return; } if (scene->basact == base) { @@ -1329,7 +1329,7 @@ static TimeMarker *rna_TimeLine_add(Scene *scene, const char name[]) static void rna_TimeLine_remove(Scene *scene, ReportList *reports, TimeMarker *marker) { if (!BLI_remlink_safe(&scene->markers, marker)) { - BKE_reportf(reports, RPT_ERROR, "TimelineMarker '%s' not found in scene '%s'", marker->name, scene->id.name + 2); + BKE_reportf(reports, RPT_ERROR, "Timeline marker '%s' not found in scene '%s'", marker->name, scene->id.name + 2); return; } @@ -1360,7 +1360,7 @@ static KeyingSet *rna_Scene_keying_set_new(Scene *sce, ReportList *reports, cons return ks; } else { - BKE_report(reports, RPT_ERROR, "Keying Set could not be added"); + BKE_report(reports, RPT_ERROR, "Keying set could not be added"); return NULL; } } @@ -4042,14 +4042,14 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "mode", R_MBLUR); RNA_def_property_ui_text(prop, "Motion Blur", "Use multi-sampled 3D scene motion blur"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); prop = RNA_def_property(srna, "motion_blur_samples", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "mblur_samples"); RNA_def_property_range(prop, 1, 32); RNA_def_property_ui_text(prop, "Motion Samples", "Number of scene samples to take with motion blur"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); prop = RNA_def_property(srna, "motion_blur_shutter", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "blurfac"); @@ -4057,7 +4057,7 @@ static void rna_def_scene_render_data(BlenderRNA *brna) RNA_def_property_ui_range(prop, 0.01, 2.0f, 1, 0); RNA_def_property_ui_text(prop, "Shutter", "Time taken in frames between shutter open and close"); RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL); + RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, "rna_Scene_glsl_update"); /* border */ prop = RNA_def_property(srna, "use_border", PROP_BOOLEAN, PROP_NONE); diff --git a/source/blender/makesrna/intern/rna_sequencer_api.c b/source/blender/makesrna/intern/rna_sequencer_api.c index f63ef6c8d76..067589ca543 100644 --- a/source/blender/makesrna/intern/rna_sequencer_api.c +++ b/source/blender/makesrna/intern/rna_sequencer_api.c @@ -234,9 +234,10 @@ static Sequence *rna_Sequences_new_sound(ID *id, Editing *ed, Main *bmain, Repor } #else /* WITH_AUDASPACE */ static Sequence *rna_Sequences_new_sound(ID *UNUSED(id), Editing *UNUSED(ed), Main *UNUSED(bmain), ReportList *reports, - const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), int UNUSED(start_frame)) + const char *UNUSED(name), const char *UNUSED(file), int UNUSED(channel), + int UNUSED(start_frame)) { - BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support."); + BKE_report(reports, RPT_ERROR, "Blender compiled without Audaspace support"); return NULL; } #endif /* WITH_AUDASPACE */ @@ -249,39 +250,37 @@ static Sequence *rna_Sequences_new_effect(ID *id, Editing *ed, ReportList *repor Scene *scene = (Scene *)id; Sequence *seq; struct SeqEffectHandle sh; + int num_inputs = BKE_sequence_effect_get_num_inputs(type); - switch (BKE_sequence_effect_get_num_inputs(type)) { + switch (num_inputs) { case 0: if (end_frame <= start_frame) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: End frame not set"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: end frame not set"); return NULL; } break; case 1: if (seq1 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 1 input sequence"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 1 input sequence"); return NULL; } break; case 2: if (seq1 == NULL || seq2 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 2 input sequences"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 2 input sequences"); return NULL; } break; case 3: if (seq1 == NULL || seq2 == NULL || seq3 == NULL) { - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: Effect takes 3 input sequences"); + BKE_report(reports, RPT_ERROR, "Sequences.new_effect: effect takes 3 input sequences"); return NULL; } break; default: - BKE_report(reports, RPT_ERROR, - "Sequences.new_effect: BKE_sequence_effect_get_num_inputs() > 3 (should never happen)"); + BKE_reportf(reports, RPT_ERROR, + "Sequences.new_effect: effect expects more than 3 inputs (%d, should never happen!)", + num_inputs); return NULL; } @@ -456,7 +455,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_clip", "rna_Sequences_new_clip"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "clip", "MovieClip", "", "Movie clip to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -472,8 +471,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_mask", "rna_Sequences_new_mask"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); - RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_function_ui_description(func, "Add a new mask sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "mask", "Mask", "", "Mask to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -490,7 +489,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_scene", "rna_Sequences_new_scene"); RNA_def_function_flag(func, FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new scene sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_pointer(func, "scene", "Scene", "", "Scene to add"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL); @@ -507,7 +506,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_image", "rna_Sequences_new_image"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new image sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to image"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -524,7 +523,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_movie", "rna_Sequences_new_movie"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new movie sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -540,8 +539,8 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_sound", "rna_Sequences_new_sound"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID | FUNC_USE_MAIN); - RNA_def_function_ui_description(func, "Add a new movie clip sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + RNA_def_function_ui_description(func, "Add a new sound sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_string(func, "filepath", "File", 0, "", "Filepath to movie"); RNA_def_property_flag(parm, PROP_REQUIRED); @@ -558,7 +557,7 @@ void RNA_api_sequences(BlenderRNA *brna, PropertyRNA *cprop) func = RNA_def_function(srna, "new_effect", "rna_Sequences_new_effect"); RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_SELF_ID); RNA_def_function_ui_description(func, "Add a new effect sequence"); - parm = RNA_def_string(func, "name", "Name", 0, "", "New name for the sequence"); + parm = RNA_def_string(func, "name", "Name", 0, "", "Name for the new sequence"); RNA_def_property_flag(parm, PROP_REQUIRED); parm = RNA_def_enum(func, "type", seq_effect_items, 0, "Type", "type for the new sequence"); diff --git a/source/blender/makesrna/intern/rna_smoke.c b/source/blender/makesrna/intern/rna_smoke.c index e8818248609..faad2407516 100644 --- a/source/blender/makesrna/intern/rna_smoke.c +++ b/source/blender/makesrna/intern/rna_smoke.c @@ -65,14 +65,20 @@ static void rna_Smoke_dependency_update(Main *bmain, Scene *scene, PointerRNA *p DAG_scene_sort(bmain, scene); } +static void rna_Smoke_resetCache(Main *bmain, Scene *scene, PointerRNA *ptr) +{ + SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data; + if (settings->smd && settings->smd->domain) + settings->point_cache[0]->flag |= PTCACHE_OUTDATED; + DAG_id_tag_update(ptr->id.data, OB_RECALC_DATA); +} + static void rna_Smoke_reset(Main *bmain, Scene *scene, PointerRNA *ptr) { SmokeDomainSettings *settings = (SmokeDomainSettings *)ptr->data; smokeModifier_reset(settings->smd); - - if (settings->smd && settings->smd->domain) - settings->point_cache[0]->flag |= PTCACHE_OUTDATED; + rna_Smoke_resetCache(bmain, scene, ptr); rna_Smoke_update(bmain, scene, ptr); } @@ -142,6 +148,30 @@ static void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values) memcpy(values, density, size * sizeof(float)); } +static void rna_SmokeFlow_density_vgroup_get(PointerRNA *ptr, char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_vgroup_name_index_get(ptr, value, flow->vgroup_density); +} + +static int rna_SmokeFlow_density_vgroup_length(PointerRNA *ptr) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + return rna_object_vgroup_name_index_length(ptr, flow->vgroup_density); +} + +static void rna_SmokeFlow_density_vgroup_set(PointerRNA *ptr, const char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_vgroup_name_index_set(ptr, value, &flow->vgroup_density); +} + +static void rna_SmokeFlow_uvlayer_set(PointerRNA *ptr, const char *value) +{ + SmokeFlowSettings *flow = (SmokeFlowSettings *)ptr->data; + rna_object_uvlayer_name_set(ptr, value, flow->uvlayer_name, sizeof(flow->uvlayer_name)); +} + #else static void rna_def_smoke_domain_settings(BlenderRNA *brna) @@ -217,7 +247,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5); RNA_def_property_ui_text(prop, "Density", "How much density affects smoke motion (higher value results in faster rising smoke)"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "beta", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "beta"); @@ -225,7 +255,7 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_ui_range(prop, -5.0, 5.0, 0.02, 5); RNA_def_property_ui_text(prop, "Heat", "How much heat affects smoke motion (higher value results in faster rising smoke)"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "collision_group", PROP_POINTER, PROP_NONE); RNA_def_property_pointer_sdna(prop, NULL, "coll_group"); @@ -253,24 +283,24 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_range(prop, 0.0, 10.0); RNA_def_property_ui_range(prop, 0.0, 10.0, 1, 2); RNA_def_property_ui_text(prop, "Strength", "Strength of noise"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "dissolve_speed", PROP_INT, PROP_NONE); RNA_def_property_int_sdna(prop, NULL, "diss_speed"); RNA_def_property_range(prop, 1.0, 10000.0); RNA_def_property_ui_range(prop, 1.0, 10000.0, 1, 0); RNA_def_property_ui_text(prop, "Dissolve Speed", "Dissolve Speed"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "use_dissolve_smoke", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE); RNA_def_property_ui_text(prop, "Dissolve Smoke", "Enable smoke to disappear over time"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "use_dissolve_smoke_log", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_DISSOLVE_LOG); RNA_def_property_ui_text(prop, "Logarithmic dissolve", "Using 1/x "); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "point_cache", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_NEVER_NULL); @@ -297,21 +327,21 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "smooth_emitter", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_HIGH_SMOOTH); RNA_def_property_ui_text(prop, "Smooth Emitter", "Smooth emitted smoke to avoid blockiness"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "time_scale", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "time_scale"); RNA_def_property_range(prop, 0.2, 1.5); RNA_def_property_ui_range(prop, 0.2, 1.5, 0.02, 5); RNA_def_property_ui_text(prop, "Time Scale", "Adjust simulation speed"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "vorticity", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vorticity"); RNA_def_property_range(prop, 0.01, 4.0); RNA_def_property_ui_range(prop, 0.01, 4.0, 0.02, 5); RNA_def_property_ui_text(prop, "Vorticity", "Amount of turbulence/rotation in fluid"); - RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE); RNA_def_property_array(prop, 32); @@ -321,25 +351,80 @@ static void rna_def_smoke_domain_settings(BlenderRNA *brna) RNA_def_property_float_funcs(prop, "rna_SmokeModifier_density_get", NULL, NULL); RNA_def_property_ui_text(prop, "Density", "Smoke density"); - prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "dx"); + prop = RNA_def_property(srna, "cell_size", PROP_FLOAT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "dx", "Cell Size"); + RNA_def_property_ui_text(prop, "cell_size", "Cell Size"); - prop = RNA_def_property(srna, "start_point", PROP_FLOAT, PROP_XYZ); + prop = RNA_def_property(srna, "start_point", PROP_FLOAT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_float_sdna(prop, NULL, "p0"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "p0", "Start point"); - prop = RNA_def_property(srna, "scale", PROP_FLOAT, PROP_NONE); - RNA_def_property_float_sdna(prop, NULL, "scale"); - RNA_def_property_clear_flag(prop, PROP_EDITABLE); - RNA_def_property_ui_text(prop, "scale", "Domain scale factor"); - - prop = RNA_def_property(srna, "domain_resolution", PROP_INT, PROP_XYZ); + prop = RNA_def_property(srna, "domain_resolution", PROP_INT, PROP_XYZ); /* can change each frame when using adaptive domain */ RNA_def_property_int_sdna(prop, NULL, "res"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_ui_text(prop, "res", "Smoke Grid Resolution"); + + prop = RNA_def_property(srna, "burning_rate", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 4.0); + RNA_def_property_ui_range(prop, 0.01, 2.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Speed", "Speed of the burning reaction. Use larger values for smaller flame"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_smoke", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 8.0); + RNA_def_property_ui_range(prop, 0.0, 4.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Smoke", "Amount of smoke created by burning fuel"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_vorticity", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Vorticity", "Additional vorticity for the flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_ignition", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.5, 5.0); + RNA_def_property_ui_range(prop, 0.5, 2.5, 1.0, 5); + RNA_def_property_ui_text(prop, "Ignition", "Minimum temperature of flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_max_temp", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 1.0, 10.0); + RNA_def_property_ui_range(prop, 1.0, 5.0, 1.0, 5); + RNA_def_property_ui_text(prop, "Maximum", "Maximum temperature of flames"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "flame_smoke_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Smoke Color", "Color of smoke emitted from burning fuel"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "use_adaptive_domain", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_ADAPTIVE_DOMAIN); + RNA_def_property_ui_text(prop, "Adaptive Domain", "Adapt simulation resolution and size to fluid"); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "additional_res", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "adapt_res"); + RNA_def_property_range(prop, 0, 512); + RNA_def_property_ui_range(prop, 0, 512, 2, 0); + RNA_def_property_ui_text(prop, "Additional", "Maximum number of additional cells"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "adapt_margin", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "adapt_margin"); + RNA_def_property_range(prop, 2, 24); + RNA_def_property_ui_range(prop, 2, 24, 2, 0); + RNA_def_property_ui_text(prop, "Margin", "Margin added around fluid to minimize boundary interference"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); + + prop = RNA_def_property(srna, "adapt_threshold", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 0.5); + RNA_def_property_ui_range(prop, 0.01, 0.5, 1.0, 5); + RNA_def_property_ui_text(prop, "Threshold", "Maximum amount of fluid cell can contain before it's considered empty"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_resetCache"); } static void rna_def_smoke_flow_settings(BlenderRNA *brna) @@ -347,6 +432,26 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) StructRNA *srna; PropertyRNA *prop; + static EnumPropertyItem smoke_flow_types[] = { + {MOD_SMOKE_FLOW_TYPE_OUTFLOW, "OUTFLOW", 0, "Outflow", "Delete smoke from simulation"}, + {MOD_SMOKE_FLOW_TYPE_SMOKE, "SMOKE", 0, "Smoke", "Add smoke"}, + {MOD_SMOKE_FLOW_TYPE_SMOKEFIRE, "BOTH", 0, "Fire + Smoke", "Add fire and smoke"}, + {MOD_SMOKE_FLOW_TYPE_FIRE, "FIRE", 0, "Fire", "Add fire"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem smoke_flow_sources[] = { + {MOD_SMOKE_FLOW_SOURCE_PARTICLES, "PARTICLES", ICON_PARTICLES, "Particle System", "Emit smoke from particles"}, + {MOD_SMOKE_FLOW_SOURCE_MESH, "MESH", ICON_META_CUBE, "Mesh", "Emit smoke from mesh surface or volume"}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem smoke_flow_texture_types[] = { + {MOD_SMOKE_FLOW_TEXTURE_MAP_AUTO, "AUTO", 0, "Generated", "Generated coordinates centered to flow object"}, + {MOD_SMOKE_FLOW_TEXTURE_MAP_UV, "UV", 0, "UV", "Use UV layer for texture coordinates"}, + {0, NULL, 0, NULL, NULL} + }; + srna = RNA_def_struct(brna, "SmokeFlowSettings", NULL); RNA_def_struct_ui_text(srna, "Flow Settings", "Smoke flow settings"); RNA_def_struct_sdna(srna, "SmokeFlowSettings"); @@ -354,11 +459,23 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "density", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "density"); - RNA_def_property_range(prop, 0.001, 1); - RNA_def_property_ui_range(prop, 0.001, 1.0, 1.0, 4); + RNA_def_property_range(prop, 0.0, 1); + RNA_def_property_ui_range(prop, 0.0, 1.0, 1.0, 4); RNA_def_property_ui_text(prop, "Density", ""); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + prop = RNA_def_property(srna, "smoke_color", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_float_sdna(prop, NULL, "color"); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Smoke Color", "Color of smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "fuel_amount", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 10); + RNA_def_property_ui_range(prop, 0.0, 5.0, 1.0, 4); + RNA_def_property_ui_text(prop, "Flame Rate", ""); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + prop = RNA_def_property(srna, "temperature", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "temp"); RNA_def_property_range(prop, -10, 10); @@ -373,9 +490,16 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Particle Systems", "Particle systems emitted from the object"); RNA_def_property_update(prop, 0, "rna_Smoke_reset_dependancy"); - prop = RNA_def_property(srna, "use_outflow", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "type", MOD_SMOKE_FLOW_TYPE_OUTFLOW); - RNA_def_property_ui_text(prop, "Outflow", "Delete smoke from simulation"); + prop = RNA_def_property(srna, "smoke_flow_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "type"); + RNA_def_property_enum_items(prop, smoke_flow_types); + RNA_def_property_ui_text(prop, "Flow Type", "Change how flow affects the simulation"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "smoke_flow_source", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "source"); + RNA_def_property_enum_items(prop, smoke_flow_sources); + RNA_def_property_ui_text(prop, "Source", "Change how smoke is emitted"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); prop = RNA_def_property(srna, "use_absolute", PROP_BOOLEAN, PROP_NONE); @@ -385,14 +509,82 @@ static void rna_def_smoke_flow_settings(BlenderRNA *brna) prop = RNA_def_property(srna, "initial_velocity", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_INITVELOCITY); - RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke inherits its velocity from the emitter particle"); + RNA_def_property_ui_text(prop, "Initial Velocity", "Smoke has some initial velocity when it is emitted"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); prop = RNA_def_property(srna, "velocity_factor", PROP_FLOAT, PROP_NONE); RNA_def_property_float_sdna(prop, NULL, "vel_multi"); RNA_def_property_range(prop, -2.0, 2.0); RNA_def_property_ui_range(prop, -2.0, 2.0, 0.05, 5); - RNA_def_property_ui_text(prop, "Multiplier", "Multiplier to adjust velocity passed to smoke"); + RNA_def_property_ui_text(prop, "Source", "Multiplier of source velocity passed to smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "velocity_normal", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vel_normal"); + RNA_def_property_range(prop, -2.0, 2.0); + RNA_def_property_ui_range(prop, -2.0, 2.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Normal", "Amount of normal directional velocity"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "velocity_random", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "vel_random"); + RNA_def_property_range(prop, 0.0, 2.0); + RNA_def_property_ui_range(prop, 0.0, 2.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Random", "Amount of random velocity"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "volume_density", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 1.0); + RNA_def_property_ui_range(prop, 0.0, 1.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Volume", "Factor for smoke emitted from inside the mesh volume"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "surface_distance", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.5, 10.0); + RNA_def_property_ui_range(prop, 0.5, 5.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Surface", "Maximum distance from mesh surface to emit smoke"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "density_vertex_group", PROP_STRING, PROP_NONE); + RNA_def_property_string_funcs(prop, "rna_SmokeFlow_density_vgroup_get", + "rna_SmokeFlow_density_vgroup_length", + "rna_SmokeFlow_density_vgroup_set"); + RNA_def_property_ui_text(prop, "Vertex Group", + "Name of Vertex Group which determines surface emission rate"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "use_texture", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flags", MOD_SMOKE_FLOW_TEXTUREEMIT); + RNA_def_property_ui_text(prop, "Use Texture", "Use a texture to control emission strength"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_map_type", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_sdna(prop, NULL, "texture_type"); + RNA_def_property_enum_items(prop, smoke_flow_texture_types); + RNA_def_property_ui_text(prop, "Mapping", "Texture mapping type"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "uv_layer", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "uvlayer_name"); + RNA_def_property_ui_text(prop, "UV Map", "UV map name"); + RNA_def_property_string_funcs(prop, NULL, NULL, "rna_SmokeFlow_uvlayer_set"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "noise_texture", PROP_POINTER, PROP_NONE); + RNA_def_property_flag(prop, PROP_EDITABLE); + RNA_def_property_ui_text(prop, "Texture", "Texture that controls emission strength"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_size", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.01, 10.0); + RNA_def_property_ui_range(prop, 0.1, 5.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Size", "Size of texture mapping"); + RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); + + prop = RNA_def_property(srna, "texture_offset", PROP_FLOAT, PROP_NONE); + RNA_def_property_range(prop, 0.0, 200.0); + RNA_def_property_ui_range(prop, 0.0, 100.0, 0.05, 5); + RNA_def_property_ui_text(prop, "Offset", "Z-offset of texture mapping"); RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER, "rna_Smoke_reset"); } diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index ff5f4988cc1..51fb9d413da 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -336,6 +336,15 @@ static void rna_View3D_CursorLocation_set(PointerRNA *ptr, const float *values) copy_v3_v3(cursor, values); } +static float rna_View3D_GridScaleUnit_get(PointerRNA *ptr) +{ + View3D *v3d = (View3D *)(ptr->data); + bScreen *sc = (bScreen *)ptr->id.data; + Scene *scene = (Scene *)sc->scene; + + return ED_view3d_grid_scale(scene, v3d, NULL); +} + static void rna_SpaceView3D_layer_set(PointerRNA *ptr, const int *values) { View3D *v3d = (View3D *)(ptr->data); @@ -1324,7 +1333,7 @@ static void rna_def_background_image(BlenderRNA *brna) srna = RNA_def_struct(brna, "BackgroundImage", NULL); RNA_def_struct_sdna(srna, "BGpic"); - RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3d View background"); + RNA_def_struct_ui_text(srna, "Background Image", "Image and settings for display in the 3D View background"); prop = RNA_def_property(srna, "source", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "source"); @@ -1494,7 +1503,39 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Camera", "Active camera used in this view (when unlocked from the scene's active camera)"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - + + /* render border */ + prop = RNA_def_property(srna, "use_render_border", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_RENDER_BORDER); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_ui_text(prop, "Render Border", + "use a user-defined border region within the frame size for rendered viewport"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_min_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.xmin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum X", "Minimum X value to for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_min_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.ymin"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Minimum Y", "Minimum Y value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_max_x", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.xmax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum X", "Maximum X value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + + prop = RNA_def_property(srna, "render_border_max_y", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "render_border.ymax"); + RNA_def_property_range(prop, 0.0f, 1.0f); + RNA_def_property_ui_text(prop, "Border Maximum Y", "Maximum Y value for the render border"); + RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); + prop = RNA_def_property(srna, "lock_object", PROP_POINTER, PROP_NONE); RNA_def_property_flag(prop, PROP_EDITABLE); RNA_def_property_pointer_sdna(prop, NULL, "ob_centre"); @@ -1571,7 +1612,12 @@ static void rna_def_space_view3d(BlenderRNA *brna) RNA_def_property_range(prop, 1, 1024); RNA_def_property_int_default(prop, 10); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL); - + + prop = RNA_def_property(srna, "grid_scale_unit", PROP_FLOAT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); + RNA_def_property_float_funcs(prop, "rna_View3D_GridScaleUnit_get", NULL, NULL); + RNA_def_property_ui_text(prop, "Grid Scale Unit", "Grid cell size scaled by scene unit system settings"); + prop = RNA_def_property(srna, "show_floor", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_FLOOR); RNA_def_property_ui_text(prop, "Display Grid Floor", "Show the ground plane grid in perspective view"); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index 45e3d15b9be..e77c5d13a6b 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -71,7 +71,7 @@ EnumPropertyItem texture_type_items[] = { {TEX_POINTDENSITY, "POINT_DENSITY", ICON_TEXTURE, "Point Density", ""}, {TEX_STUCCI, "STUCCI", ICON_TEXTURE, "Stucci", "Procedural - create a fractal noise texture"}, {TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - create cell-like patterns based on Worley noise"}, - {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3d texture based on volumetric data"}, + {TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3D texture based on volumetric data"}, {TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - wave generated bands or rings, with optional noise"}, {TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", "Use a texture generated by an Ocean modifier"}, {0, NULL, 0, NULL, NULL} @@ -1800,7 +1800,8 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna) }; static EnumPropertyItem smoked_type_items[] = { - {TEX_VD_SMOKEDENSITY, "SMOKEDENSITY", 0, "Density", "Use smoke density as texture data"}, + {TEX_VD_SMOKEDENSITY, "SMOKEDENSITY", 0, "Smoke", "Use smoke density and color as texture data"}, + {TEX_VD_SMOKEFLAME, "SMOKEFLAME", 0, "Flame", "Use flame temperature as texture data"}, {TEX_VD_SMOKEHEAT, "SMOKEHEAT", 0, "Heat", "Use smoke heat as texture data. Values from -2.0 to 2.0 are used"}, {TEX_VD_SMOKEVEL, "SMOKEVEL", 0, "Velocity", "Use smoke velocity as texture data"}, {0, NULL, 0, NULL, NULL} diff --git a/source/blender/makesrna/intern/rna_texture_api.c b/source/blender/makesrna/intern/rna_texture_api.c index a2880510958..5be9d3a0dec 100644 --- a/source/blender/makesrna/intern/rna_texture_api.c +++ b/source/blender/makesrna/intern/rna_texture_api.c @@ -120,10 +120,10 @@ void RNA_api_environment_map(StructRNA *srna) RNA_def_pointer(func, "scene", "Scene", "", "Overrides the scene from which image parameters are taken"); - RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 0.0f, "File layout", + RNA_def_float_array(func, "layout", 12, default_layout, 0.0f, 1000.0f, "File layout", "Flat array describing the X,Y position of each cube face in the " "output image, where 1 is the size of a face - order is [+Z -Z +Y -X -Y +X] " - "(use -1 to skip a face)", 0.0f, 0.0f); + "(use -1 to skip a face)", 0.0f, 1000.0f); } #endif diff --git a/source/blender/makesrna/intern/rna_tracking.c b/source/blender/makesrna/intern/rna_tracking.c index 0c62a280935..4b744b160fc 100644 --- a/source/blender/makesrna/intern/rna_tracking.c +++ b/source/blender/makesrna/intern/rna_tracking.c @@ -567,18 +567,6 @@ static void rna_def_trackingSettings(BlenderRNA *brna) "Limit speed of tracking to make visual feedback easier " "(this does not affect the tracking quality)"); - /* keyframe_a */ - prop = RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "keyframe1"); - RNA_def_property_ui_text(prop, "Keyframe A", "First keyframe used for reconstruction initialization"); - - /* keyframe_b */ - prop = RNA_def_property(srna, "keyframe_b", PROP_INT, PROP_NONE); - RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); - RNA_def_property_int_sdna(prop, NULL, "keyframe2"); - RNA_def_property_ui_text(prop, "Keyframe B", "Second keyframe used for reconstruction initialization"); - /* intrinsics refinement during bundle adjustment */ prop = RNA_def_property(srna, "refine_intrinsics", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "refine_camera_intrinsics"); @@ -1393,6 +1381,18 @@ static void rna_def_trackingObject(BlenderRNA *brna) RNA_def_property_float_default(prop, 1.0f); RNA_def_property_ui_text(prop, "Scale", "Scale of object solution in camera space"); RNA_def_property_update(prop, NC_MOVIECLIP | NA_EDITED, "rna_trackingObject_flushUpdate"); + + /* keyframe_a */ + prop = RNA_def_property(srna, "keyframe_a", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "keyframe1"); + RNA_def_property_ui_text(prop, "Keyframe A", "First keyframe used for reconstruction initialization"); + + /* keyframe_b */ + prop = RNA_def_property(srna, "keyframe_b", PROP_INT, PROP_NONE); + RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); + RNA_def_property_int_sdna(prop, NULL, "keyframe2"); + RNA_def_property_ui_text(prop, "Keyframe B", "Second keyframe used for reconstruction initialization"); } static void rna_def_trackingObjects(BlenderRNA *brna, PropertyRNA *cprop) diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c index 70d94bfc7ed..7bfa7ccc3c2 100644 --- a/source/blender/makesrna/intern/rna_ui.c +++ b/source/blender/makesrna/intern/rna_ui.c @@ -85,7 +85,7 @@ static ARegionType *region_type_find(ReportList *reports, int space_type, int re /* region type not found? abort */ if (art == NULL) { - BKE_report(reports, RPT_ERROR, "Region not found in spacetype"); + BKE_report(reports, RPT_ERROR, "Region not found in space type"); return NULL; } diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c index 006e1ad3903..2e1c62cce53 100644 --- a/source/blender/makesrna/intern/rna_ui_api.c +++ b/source/blender/makesrna/intern/rna_ui_api.c @@ -439,7 +439,8 @@ void RNA_api_ui_layout(StructRNA *srna) RNA_def_boolean(func, "compact", 0, "", "Use more compact layout"); func = RNA_def_function(srna, "template_list", "uiTemplateList"); - RNA_def_function_ui_description(func, "Item. A list widget to display data. e.g. vertexgroups"); + RNA_def_function_ui_description(func, "Item. A list widget to display data, e.g. vertexgroups " + "(WARNING: only one per panel allowed!)."); RNA_def_function_flag(func, FUNC_USE_CONTEXT); parm = RNA_def_pointer(func, "data", "AnyType", "", "Data from which to take property"); RNA_def_property_flag(parm, PROP_REQUIRED | PROP_RNAPTR); diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 3eadc4468ba..307e2ff4f82 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -2520,7 +2520,7 @@ static void rna_def_userdef_view(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Sub Level Menu Open Delay", "Time delay in 1/10 seconds before automatically opening sub level menus"); - prop = RNA_def_property(srna, "quit_dialog", PROP_BOOLEAN, PROP_NONE); + prop = RNA_def_property(srna, "use_quit_dialog", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "uiflag", USER_QUIT_PROMPT); RNA_def_property_ui_text(prop, "Prompt Quit", "Asks for confirmation when quitting through the window close button"); @@ -2755,6 +2755,11 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_boolean_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_INSERTAVAIL); RNA_def_property_ui_text(prop, "Auto Keyframe Insert Available", "Automatic keyframe insertion in available F-Curves"); + + prop = RNA_def_property(srna, "use_auto_keying_warning", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_negative_sdna(prop, NULL, "autokey_flag", AUTOKEY_FLAG_NOWARNING); + RNA_def_property_ui_text(prop, "Show Auto Keying Warning", + "Show warning indicators when transforming Object and Bones if Auto Keying is enabled"); /* keyframing settings */ prop = RNA_def_property(srna, "use_keyframe_insert_needed", PROP_BOOLEAN, PROP_NONE); @@ -2788,7 +2793,7 @@ static void rna_def_userdef_edit(BlenderRNA *brna) RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", USER_NONEGFRAMES); RNA_def_property_ui_text(prop, "Allow Negative Frames", "Current frame number can be manually set to a negative value"); - + /* fcurve opacity */ prop = RNA_def_property(srna, "fcurve_unselected_alpha", PROP_FLOAT, PROP_FACTOR); RNA_def_property_float_sdna(prop, NULL, "fcu_inactive_alpha"); @@ -2992,7 +2997,7 @@ static void rna_def_userdef_system(BlenderRNA *brna) /* locale according to http://www.roseindia.net/tutorials/I18N/locales-list.shtml */ /* if you edit here, please also edit the source/blender/blenfont/intern/blf_lang.c 's locales */ /* Note: As this list is in alphabetical order, and not defined order, - * here is the highest define currently in use: 33 (Hebrew). */ + * here is the highest define currently in use: 35 (Esperanto). */ static EnumPropertyItem language_items[] = { { 0, "", 0, N_("Nearly Done"), ""}, { 0, "DEFAULT", 0, "Default (Default)", ""}, @@ -3010,25 +3015,27 @@ static void rna_def_userdef_system(BlenderRNA *brna) {14, "TRADITIONAL_CHINESE", 0, "Traditional Chinese (繁體中文)", "zh_TW"}, {18, "UKRAINIAN", 0, "Ukrainian (Український)", "uk_UA"}, { 0, "", 0, N_("In Progress"), ""}, - {22, "BULGARIAN", 0, "Bulgarian (Български)", "bg_BG"}, - {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"}, +/* {22, "BULGARIAN", 0, "Bulgarian (Български)", "bg_BG"},*/ /* XXX Not active nor enough translated. */ +/* {10, "CATALAN", 0, "Catalan (Català)", "ca_AD"},*/ /* XXX Not active nor enough translated. */ {16, "CROATIAN", 0, "Croatian (Hrvatski)", "hr_HR"}, {11, "CZECH", 0, "Czech (Český)", "cs_CZ"}, { 3, "DUTCH", 0, "Dutch (Nederlandse taal)", "nl_NL"}, - { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"}, + {35, "ESPERANTO", 0, "Esperanto (Esperanto)", "eo"}, + {34, "ESTONIAN", 0, "Estonian (Eestlane)", "et_EE"}, +/* { 6, "FINNISH", 0, "Finnish (Suomi)", "fi_FI"},*/ /* XXX Not active nor enough translated. */ { 5, "GERMAN", 0, "German (Deutsch)", "de_DE"}, - {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"}, +/* {23, "GREEK", 0, "Greek (Ελληνικά)", "el_GR"},*/ /* XXX Not active nor enough translated. */ /* using the utf8 flipped form of Hebrew (עִבְרִית)) */ {33, "HEBREW", 0, "Hebrew (תירִבְעִ)", "he_IL"}, {31, "HUNGARIAN", 0, "Hungarian (Magyar)", "hu_HU"}, {27, "INDONESIAN", 0, "Indonesian (Bahasa indonesia)", "id_ID"}, {29, "KYRGYZ", 0, "Kyrgyz (Кыргыз тили)", "ky_KG"}, -/* {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, */ /* XXX No po's yet. */ - {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"}, +/* {24, "KOREAN", 0, "Korean (한국 언어)", "ko_KR"}, */ /* XXX Not active nor enough translated. */ +/* {25, "NEPALI", 0, "Nepali (नेपाली)", "ne_NP"},*/ /* XXX Not active nor enough translated. */ /* using the utf8 flipped form of Persian (فارسی) */ {26, "PERSIAN", 0, "Persian (ﯽﺳﺭﺎﻓ)", "fa_IR"}, - {19, "POLISH", 0, "Polish (Polski)", "pl_PL"}, -/* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX No po's yet. */ +/* {19, "POLISH", 0, "Polish (Polski)", "pl_PL"},*/ /* XXX Not active nor enough translated. */ +/* {20, "ROMANIAN", 0, "Romanian (Român)", "ro_RO"}, */ /* XXX Not active nor enough translated. */ {17, "SERBIAN", 0, "Serbian (Српски)", "sr_RS"}, {28, "SERBIAN_LATIN", 0, "Serbian Latin (Srpski latinica)", "sr_RS@latin"}, { 7, "SWEDISH", 0, "Swedish (Svenska)", "sv_SE"}, diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index d8753f4ff43..30bdc717f50 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -1062,7 +1062,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * } else { BKE_reportf(reports, RPT_ERROR, - "registering operator class: '%s', invalid bl_idname '%s', at position %d", + "Registering operator class: '%s', invalid bl_idname '%s', at position %d", identifier, _operator_idname, i); return NULL; } @@ -1071,7 +1071,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * } if (i > ((int)sizeof(dummyop.idname)) - 3) { - BKE_reportf(reports, RPT_ERROR, "registering operator class: '%s', invalid bl_idname '%s', " + BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', " "is too long, maximum length is %d", identifier, _operator_idname, (int)sizeof(dummyop.idname) - 3); return NULL; @@ -1079,7 +1079,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void * if (dot != 1) { BKE_reportf(reports, RPT_ERROR, - "registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", + "Registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character", identifier, _operator_idname); return NULL; } diff --git a/source/blender/modifiers/MOD_modifiertypes.h b/source/blender/modifiers/MOD_modifiertypes.h index bf411c3b2fc..51e574e276d 100644 --- a/source/blender/modifiers/MOD_modifiertypes.h +++ b/source/blender/modifiers/MOD_modifiertypes.h @@ -79,4 +79,4 @@ extern ModifierTypeInfo modifierType_Skin; /* MOD_util.c */ void modifier_type_init(ModifierTypeInfo *types[]); -#endif //__MOD_MODIFIERTYPES_H__ +#endif /* __MOD_MODIFIERTYPES_H__ */ diff --git a/source/blender/modifiers/intern/MOD_boolean_util.h b/source/blender/modifiers/intern/MOD_boolean_util.h index b996dc6d6ba..209db60f0c9 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.h +++ b/source/blender/modifiers/intern/MOD_boolean_util.h @@ -51,4 +51,4 @@ int NewBooleanMesh(struct Scene *scene, struct Base *base, struct Base *base_sel struct DerivedMesh *NewBooleanDerivedMesh(struct DerivedMesh *dm, struct Object *ob, struct DerivedMesh *dm_select, struct Object *ob_select, int int_op_type); -#endif // MOD_BOOLEAN_UTILS +#endif /* MOD_BOOLEAN_UTILS */ diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index cb6681bfa68..171d601ea6d 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -47,6 +47,10 @@ #include "BKE_particle.h" #include "BKE_cdderivedmesh.h" +#include "BKE_tessmesh.h" + +/* testing only! - Campbell */ +// #define USE_DECIMATE_BMESH #ifdef WITH_MOD_DECIMATE #include "LOD_decimation.h" @@ -70,6 +74,33 @@ static void copyData(ModifierData *md, ModifierData *target) } #ifdef WITH_MOD_DECIMATE +#ifdef USE_DECIMATE_BMESH + +#include "bmesh.h" + +static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), + DerivedMesh *derivedData, + ModifierApplyFlag UNUSED(flag)) +{ + DecimateModifierData *dmd = (DecimateModifierData *) md; + DerivedMesh *dm = derivedData, *result = NULL; + BMEditMesh *em; + BMesh *bm; + + em = DM_to_editbmesh(dm, NULL, FALSE); + bm = em->bm; + + BM_mesh_decimate(bm, dmd->percent); + + BLI_assert(em->looptris == NULL); + result = CDDM_from_BMEditMesh(em, NULL, TRUE, FALSE); + BMEdit_Free(em); + MEM_freeN(em); + + return result; +} + +#else static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), DerivedMesh *derivedData, ModifierApplyFlag UNUSED(flag)) @@ -192,6 +223,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *UNUSED(ob), return dm; } } +#endif // USE_DECIMATE_BMESH #else // WITH_MOD_DECIMATE static DerivedMesh *applyModifier(ModifierData *UNUSED(md), Object *UNUSED(ob), DerivedMesh *derivedData, diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index e64e80efde3..20b02c63605 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -81,6 +81,44 @@ static int dependsOnTime(ModifierData *UNUSED(md)) { return 0; } + +static int isDisabled(ModifierData *md, int useRenderParams) +{ + ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; + ParticleSystem *psys; + ModifierData *ob_md; + + if (!pimd->ob) + return TRUE; + + psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1); + if (psys == NULL) + return TRUE; + + /* If the psys modifier is disabled we cannot use its data. + * First look up the psys modifier from the object, then check if it is enabled. + */ + for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) { + if (ob_md->type == eModifierType_ParticleSystem) { + ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md; + if (psmd->psys == psys) { + int required_mode; + + if (useRenderParams) required_mode = eModifierMode_Render; + else required_mode = eModifierMode_Realtime; + + if (!modifier_isEnabled(md->scene, ob_md, required_mode)) + return TRUE; + + break; + } + } + } + + return FALSE; +} + + static void updateDepgraph(ModifierData *md, DagForest *forest, struct Scene *UNUSED(scene), Object *UNUSED(ob), @@ -384,7 +422,7 @@ ModifierTypeInfo modifierType_ParticleInstance = { /* initData */ initData, /* requiredDataMask */ NULL, /* freeData */ NULL, - /* isDisabled */ NULL, + /* isDisabled */ isDisabled, /* updateDepgraph */ updateDepgraph, /* dependsOnTime */ dependsOnTime, /* dependsOnNormals */ NULL, diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 254c02b7672..cd2ef5957cd 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -44,6 +44,7 @@ #include "BKE_material.h" #include "BKE_modifier.h" #include "BKE_particle.h" +#include "BKE_scene.h" #include "MOD_util.h" @@ -130,6 +131,7 @@ static void deformVerts(ModifierData *md, Object *ob, ParticleSystemModifierData *psmd = (ParticleSystemModifierData *) md; ParticleSystem *psys = NULL; int needsFree = 0; + /* float cfra = BKE_scene_frame_get(md->scene); */ /* UNUSED */ if (ob->particlesystem.first) psys = psmd->psys; @@ -188,9 +190,11 @@ static void deformVerts(ModifierData *md, Object *ob, psmd->totdmface = psmd->dm->getNumTessFaces(psmd->dm); } - psmd->flag &= ~eParticleSystemFlag_psys_updated; - particle_system_update(md->scene, ob, psys); - psmd->flag |= eParticleSystemFlag_psys_updated; + if (!(ob->transflag & OB_NO_PSYS_UPDATE)) { + psmd->flag &= ~eParticleSystemFlag_psys_updated; + particle_system_update(md->scene, ob, psys); + psmd->flag |= eParticleSystemFlag_psys_updated; + } } /* disabled particles in editmode for now, until support for proper derivedmesh diff --git a/source/blender/modifiers/intern/MOD_smoke.c b/source/blender/modifiers/intern/MOD_smoke.c index b9b3b89e06d..4b2ce47b8d9 100644 --- a/source/blender/modifiers/intern/MOD_smoke.c +++ b/source/blender/modifiers/intern/MOD_smoke.c @@ -81,19 +81,31 @@ static void freeData(ModifierData *md) smokeModifier_free(smd); } -static void deformVerts(ModifierData *md, Object *ob, - DerivedMesh *derivedData, - float (*vertexCos)[3], - int UNUSED(numVerts), - ModifierApplyFlag UNUSED(flag)) +static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md) { - SmokeModifierData *smd = (SmokeModifierData *) md; - DerivedMesh *dm = get_cddm(ob, NULL, derivedData, vertexCos); + SmokeModifierData *smd = (SmokeModifierData *)md; + CustomDataMask dataMask = 0; + + if (smd && (smd->type & MOD_SMOKE_TYPE_FLOW) && smd->flow) { + if (smd->flow->source == MOD_SMOKE_FLOW_SOURCE_MESH) { + /* vertex groups */ + if (smd->flow->vgroup_density) + dataMask |= CD_MASK_MDEFORMVERT; + /* uv layer */ + if (smd->flow->texture_type == MOD_SMOKE_FLOW_TEXTURE_MAP_UV) + dataMask |= CD_MASK_MTFACE; + } + } + return dataMask; +} - smokeModifier_do(smd, md->scene, ob, dm); +static DerivedMesh *applyModifier(ModifierData *md, Object *ob, + DerivedMesh *dm, + ModifierApplyFlag UNUSED(flag)) +{ + SmokeModifierData *smd = (SmokeModifierData *) md; - if (dm != derivedData) - dm->release(dm); + return smokeModifier_do(smd, md->scene, ob, dm); } static int dependsOnTime(ModifierData *UNUSED(md)) @@ -102,11 +114,11 @@ static int dependsOnTime(ModifierData *UNUSED(md)) } static void updateDepgraph(ModifierData *md, DagForest *forest, - struct Scene *scene, - Object *UNUSED(ob), + struct Scene *scene, struct Object *ob, DagNode *obNode) { SmokeModifierData *smd = (SmokeModifierData *) md; + Base *base; if (smd && (smd->type & MOD_SMOKE_TYPE_DOMAIN) && smd->domain) { if (smd->domain->fluid_group || smd->domain->coll_group) { @@ -139,8 +151,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } else { - Base *base = scene->base.first; - + base = scene->base.first; for (; base; base = base->next) { SmokeModifierData *smd2 = (SmokeModifierData *)modifiers_findByType(base->object, eModifierType_Smoke); @@ -150,6 +161,14 @@ static void updateDepgraph(ModifierData *md, DagForest *forest, } } } + /* add relation to all "smoke flow" force fields */ + base = scene->base.first; + for (; base; base = base->next) { + if (base->object->pd && base->object->pd->forcefield == PFIELD_SMOKEFLOW && base->object->pd->f_source == ob) { + DagNode *node2 = dag_get_node(forest, base->object); + dag_add_relation(forest, obNode, node2, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Field Source Object"); + } + } } } @@ -167,26 +186,30 @@ static void foreachIDLink(ModifierData *md, Object *ob, walk(userData, ob, (ID **)&smd->domain->effector_weights->group); } } + + if (smd->type == MOD_SMOKE_TYPE_FLOW && smd->flow) { + walk(userData, ob, (ID **)&smd->flow->noise_texture); + } } ModifierTypeInfo modifierType_Smoke = { /* name */ "Smoke", /* structName */ "SmokeModifierData", /* structSize */ sizeof(SmokeModifierData), - /* type */ eModifierTypeType_OnlyDeform, + /* type */ eModifierTypeType_Constructive, /* flags */ eModifierTypeFlag_AcceptsMesh | eModifierTypeFlag_UsesPointCache | eModifierTypeFlag_Single, /* copyData */ copyData, - /* deformVerts */ deformVerts, + /* deformVerts */ NULL, /* deformMatrices */ NULL, /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, - /* applyModifier */ NULL, + /* applyModifier */ applyModifier, /* applyModifierEM */ NULL, /* initData */ initData, - /* requiredDataMask */ NULL, + /* requiredDataMask */ requiredDataMask, /* freeData */ freeData, /* isDisabled */ NULL, /* updateDepgraph */ updateDepgraph, diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 1df7d535c35..cc77d73a736 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -223,7 +223,6 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, const int numEdges = dm->getNumEdges(dm); const int numFaces = dm->getNumPolys(dm); int numLoops = 0, newLoops = 0, newFaces = 0, newEdges = 0; - int j; /* only use material offsets if we have 2 or more materials */ const short mat_nr_max = ob->totcol > 1 ? ob->totcol - 1 : 0; @@ -292,9 +291,11 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, } for (i = 0, mp = orig_mpoly; i < numFaces; i++, mp++) { - MLoop *ml = orig_mloop + mp->loopstart; unsigned int ml_v1; unsigned int ml_v2; + int j; + + ml = orig_mloop + mp->loopstart; for (j = 0, ml_v1 = ml->v, ml_v2 = ml[mp->totloop - 1].v; j < mp->totloop; @@ -376,6 +377,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, for (i = 0; i < dm->numPolyData; i++, mp++) { MLoop *ml2; int e; + int j; ml2 = mloop + mp->loopstart + dm->numLoopData; for (j = 0; j < mp->totloop; j++) { @@ -591,6 +593,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, int *origindex_edge; int *orig_ed; + int j; /* add faces & edges */ origindex_edge = result->getEdgeDataArray(result, CD_ORIGINDEX); @@ -715,13 +718,13 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, for (i = 0; i < newEdges; i++, ed++) { float nor_cpy[3]; short *nor_short; - int j; + int k; /* note, only the first vertex (lower half of the index) is calculated */ normalize_v3_v3(nor_cpy, edge_vert_nos[ed->v1]); - for (j = 0; j < 2; j++) { /* loop over both verts of the edge */ - nor_short = mvert[*(&ed->v1 + j)].no; + for (k = 0; k < 2; k++) { /* loop over both verts of the edge */ + nor_short = mvert[*(&ed->v1 + k)].no; normal_short_to_float_v3(nor, nor_short); add_v3_v3(nor, nor_cpy); normalize_v3(nor); diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index 440d2c157fe..b713f56a4c2 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -186,7 +186,7 @@ static void waveModifier_do(WaveModifierData *md, const float falloff = wmd->falloff; float falloff_fac = 1.0f; /* when falloff == 0.0f this stays at 1.0f */ - if (wmd->flag & MOD_WAVE_NORM && ob->type == OB_MESH) + if ((wmd->flag & MOD_WAVE_NORM) && (ob->type == OB_MESH)) mvert = dm->getVertArray(dm); if (wmd->objectcenter) { diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 08e0e7b0f93..3fd9bfecedf 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -25,6 +25,10 @@ set(INC . + composite + intern + shader + texture ../blenfont ../blenkernel ../blenlib @@ -39,10 +43,6 @@ set(INC set(INC_SYS ${GLEW_INCLUDE_PATH} - intern - composite - shader - texture ) set(SRC @@ -146,13 +146,14 @@ set(SRC shader/nodes/node_shader_vectMath.c shader/nodes/node_shader_attribute.c shader/nodes/node_shader_background.c - # shader/nodes/node_shader_bsdf_anisotropic.c # XXX, why not included? + shader/nodes/node_shader_bsdf_anisotropic.c shader/nodes/node_shader_bsdf_diffuse.c shader/nodes/node_shader_bsdf_glossy.c shader/nodes/node_shader_bsdf_glass.c shader/nodes/node_shader_bsdf_translucent.c shader/nodes/node_shader_bsdf_transparent.c shader/nodes/node_shader_bsdf_velvet.c + shader/nodes/node_shader_bump.c shader/nodes/node_shader_emission.c shader/nodes/node_shader_fresnel.c shader/nodes/node_shader_layer_weight.c diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h index 49428c06e5f..7585ed0d61c 100644 --- a/source/blender/nodes/NOD_shader.h +++ b/source/blender/nodes/NOD_shader.h @@ -88,6 +88,7 @@ void register_node_type_sh_bsdf_glass(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_translucent(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_transparent(struct bNodeTreeType *ttype); void register_node_type_sh_bsdf_velvet(struct bNodeTreeType *ttype); +void register_node_type_sh_bsdf_anisotropic(struct bNodeTreeType *ttype); void register_node_type_sh_emission(struct bNodeTreeType *ttype); void register_node_type_sh_holdout(struct bNodeTreeType *ttype); void register_node_type_sh_volume_transparent(struct bNodeTreeType *ttype); @@ -109,6 +110,7 @@ void register_node_type_sh_tex_wave(struct bNodeTreeType *ttype); void register_node_type_sh_tex_musgrave(struct bNodeTreeType *ttype); void register_node_type_sh_tex_noise(struct bNodeTreeType *ttype); void register_node_type_sh_tex_checker(struct bNodeTreeType *ttype); +void register_node_type_sh_bump(struct bNodeTreeType *ttype); #endif diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c index 9157728b546..4a7643f5771 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c @@ -33,6 +33,8 @@ static bNodeSocketTemplate sh_node_bsdf_anisotropic_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness U"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness V"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -43,7 +45,10 @@ static bNodeSocketTemplate sh_node_bsdf_anisotropic_out[]= { static int node_shader_gpu_bsdf_anisotropic(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_anisotropic", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[3].link) + in[3].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_anisotropic", in, out); } /* node type definition */ @@ -51,7 +56,7 @@ void register_node_type_sh_bsdf_anisotropic(bNodeTreeType *ttype) { static bNodeType ntype; - node_type_base(ttype, &ntype, SH_NODE_BSDF_ANISOTROPIC, "Glossy Anisotropic BSDF", NODE_CLASS_SHADER, 0); + node_type_base(ttype, &ntype, SH_NODE_BSDF_ANISOTROPIC, "Anisotropic BSDF", NODE_CLASS_SHADER, 0); node_type_compatibility(&ntype, NODE_NEW_SHADING); node_type_socket_templates(&ntype, sh_node_bsdf_anisotropic_in, sh_node_bsdf_anisotropic_out); node_type_size(&ntype, 150, 60, 200); diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c index d2e2db3e78a..63ce637fd72 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_diffuse.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_diffuse_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -42,7 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_diffuse_out[]= { static int node_shader_gpu_bsdf_diffuse(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_diffuse", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_diffuse", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c index 8ff0ad57742..7b8b80ae8e2 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glass.c @@ -33,6 +33,7 @@ static bNodeSocketTemplate sh_node_bsdf_glass_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 1.0f, 1000.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -43,7 +44,10 @@ static bNodeSocketTemplate sh_node_bsdf_glass_out[]= { static int node_shader_gpu_bsdf_glass(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_glass", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[3].link) + in[3].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_glass", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c index d28b3454f02..9f42e23ebb6 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_glossy.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_glossy_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Roughness"), 0.2f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -42,8 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_glossy_out[]= { static int node_shader_gpu_bsdf_glossy(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - /* todo: is incoming vector normalized? */ - return GPU_stack_link(mat, "node_bsdf_glossy", in, out, GPU_builtin(GPU_VIEW_NORMAL), GPU_builtin(GPU_VIEW_POSITION)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_glossy", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c index a3ba3ac7ff3..b3290411aee 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_translucent.c @@ -31,6 +31,7 @@ static bNodeSocketTemplate sh_node_bsdf_translucent_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -41,7 +42,10 @@ static bNodeSocketTemplate sh_node_bsdf_translucent_out[]= { static int node_shader_gpu_bsdf_translucent(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_translucent", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[1].link) + in[1].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_translucent", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c index 04a1c1b32df..97bc37a84c9 100644 --- a/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c +++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_velvet.c @@ -32,6 +32,7 @@ static bNodeSocketTemplate sh_node_bsdf_velvet_in[]= { { SOCK_RGBA, 1, N_("Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f}, { SOCK_FLOAT, 1, N_("Sigma"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f}, + { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE}, { -1, 0, "" } }; @@ -42,7 +43,10 @@ static bNodeSocketTemplate sh_node_bsdf_velvet_out[]= { static int node_shader_gpu_bsdf_velvet(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) { - return GPU_stack_link(mat, "node_bsdf_velvet", in, out, GPU_builtin(GPU_VIEW_NORMAL)); + if(!in[2].link) + in[2].link = GPU_builtin(GPU_VIEW_NORMAL); + + return GPU_stack_link(mat, "node_bsdf_velvet", in, out); } /* node type definition */ diff --git a/source/blender/nodes/shader/nodes/node_shader_bump.c b/source/blender/nodes/shader/nodes/node_shader_bump.c new file mode 100644 index 00000000000..315565e619b --- /dev/null +++ b/source/blender/nodes/shader/nodes/node_shader_bump.c @@ -0,0 +1,68 @@ +/* + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2005 Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): none yet. + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/nodes/shader/nodes/node_shader_bump.c + * \ingroup shdnodes + */ + + + +#include "node_shader_util.h" + + +/* **************** BUMP ******************** */ +static bNodeSocketTemplate sh_node_bump_in[]= { + { SOCK_FLOAT, 1, "Strength", 0.1f, 0.0f, 0.0f, 0.0f, -1000.0f, 1000.0f}, + { SOCK_FLOAT, 1, "Height", 1.0f, 1.0f, 1.0f, 1.0f, -1000.0f, 1000.0f, PROP_NONE, SOCK_HIDE_VALUE}, + { -1, 0, "" } +}; + +static bNodeSocketTemplate sh_node_bump_out[]= { + { SOCK_VECTOR, 0, "Normal"}, + { -1, 0, "" } +}; + +static int gpu_shader_bump(GPUMaterial *mat, bNode *UNUSED(node), GPUNodeStack *in, GPUNodeStack *out) +{ + return GPU_stack_link(mat, "node_bump", in, out, GPU_builtin(GPU_VIEW_NORMAL)); +} + +/* node type definition */ +void register_node_type_sh_bump(bNodeTreeType *ttype) +{ + static bNodeType ntype; + + node_type_base(ttype, &ntype, SH_NODE_BUMP, "Bump", NODE_CLASS_OP_VECTOR, NODE_OPTIONS); + node_type_compatibility(&ntype, NODE_NEW_SHADING); + node_type_socket_templates(&ntype, sh_node_bump_in, sh_node_bump_out); + node_type_size(&ntype, 150, 60, 200); + node_type_storage(&ntype, "BumpNode", node_free_standard_storage, node_copy_standard_storage); + node_type_exec(&ntype, NULL); + node_type_gpu(&ntype, gpu_shader_bump); + + nodeRegisterType(ttype, &ntype); +} diff --git a/source/blender/nodes/texture/node_texture_tree.c b/source/blender/nodes/texture/node_texture_tree.c index 9656d93f1b0..1bfd88d3af7 100644 --- a/source/blender/nodes/texture/node_texture_tree.c +++ b/source/blender/nodes/texture/node_texture_tree.c @@ -4,7 +4,7 @@ * 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. + * 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 @@ -240,19 +240,19 @@ void ntreeTexEndExecTree(bNodeTreeExec *exec, int use_tree_data) } int ntreeTexExecTree( - bNodeTree *nodes, - TexResult *texres, - float *co, - float *dxt, float *dyt, - int osatex, - short thread, - Tex *UNUSED(tex), - short which_output, - int cfra, - int preview, - ShadeInput *shi, - MTex *mtex -) { + bNodeTree *nodes, + TexResult *texres, + float co[3], + float dxt[3], float dyt[3], + int osatex, + const short thread, + Tex *UNUSED(tex), + short which_output, + int cfra, + int preview, + ShadeInput *shi, + MTex *mtex) +{ TexCallData data; float *nor = texres->nor; int retval = TEX_INT; diff --git a/source/blender/nodes/texture/node_texture_util.c b/source/blender/nodes/texture/node_texture_util.c index 5e58b74ac3a..06473d800d0 100644 --- a/source/blender/nodes/texture/node_texture_util.c +++ b/source/blender/nodes/texture/node_texture_util.c @@ -4,7 +4,7 @@ * 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. + * 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 @@ -29,7 +29,7 @@ * \ingroup nodes */ - + /* * HOW TEXTURE NODES WORK * @@ -112,13 +112,13 @@ void params_from_cdata(TexParams *out, TexCallData *in) out->mtex = in->mtex; } -void tex_do_preview(bNode *node, float *co, float *col) +void tex_do_preview(bNode *node, const float coord[2], const float col[4]) { - bNodePreview *preview= node->preview; + bNodePreview *preview = node->preview; if (preview) { - int xs= ((co[0] + 1.0f)*0.5f)*preview->xsize; - int ys= ((co[1] + 1.0f)*0.5f)*preview->ysize; + int xs = ((coord[0] + 1.0f) * 0.5f) * preview->xsize; + int ys = ((coord[1] + 1.0f) * 0.5f) * preview->ysize; nodeAddToPreview(node, col, xs, ys, 0); /* 0 = no color management */ } @@ -132,19 +132,19 @@ void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexC dg = out->data = MEM_mallocN(sizeof(TexDelegate), "tex delegate"); else dg = out->data; - - dg->cdata= cdata; + + dg->cdata = cdata; dg->fn = texfn; dg->node = node; - memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack*)); + memcpy(dg->in, in, MAX_SOCKET * sizeof(bNodeStack *)); dg->type = out->sockettype; } void ntreeTexCheckCyclics(struct bNodeTree *ntree) { bNode *node; - for (node= ntree->nodes.first; node; node= node->next) { - + for (node = ntree->nodes.first; node; node = node->next) { + if (node->type == TEX_NODE_TEXTURE && node->id) { /* custom2 stops the node from rendering */ if (node->custom1) { diff --git a/source/blender/nodes/texture/node_texture_util.h b/source/blender/nodes/texture/node_texture_util.h index e938e6fc419..16dbc2f7bfb 100644 --- a/source/blender/nodes/texture/node_texture_util.h +++ b/source/blender/nodes/texture/node_texture_util.h @@ -79,8 +79,10 @@ typedef struct TexCallData { TexResult *target; + /* all float[3] */ float *co; float *dxt, *dyt; + int osatex; char do_preview; short thread; @@ -94,7 +96,7 @@ typedef struct TexCallData { typedef struct TexParams { float *co; float *dxt, *dyt; - float *previewco; + const float *previewco; int cfra; int osatex; @@ -119,7 +121,7 @@ void tex_input_vec(float *out, bNodeStack *in, TexParams *params, short thread); float tex_input_value(bNodeStack *in, TexParams *params, short thread); void tex_output(bNode *node, bNodeStack **in, bNodeStack *out, TexFn texfn, TexCallData *data); -void tex_do_preview(bNode *node, float *coord, float *col); +void tex_do_preview(bNode *node, const float coord[2], const float col[4]); void params_from_cdata(TexParams *out, TexCallData *in); diff --git a/source/blender/nodes/texture/nodes/node_texture_bricks.c b/source/blender/nodes/texture/nodes/node_texture_bricks.c index f6259962529..c575547b3ce 100644 --- a/source/blender/nodes/texture/nodes/node_texture_bricks.c +++ b/source/blender/nodes/texture/nodes/node_texture_bricks.c @@ -66,7 +66,7 @@ static float noise(int n) /* fast integer noise */ static void colorfn(float *out, TexParams *p, bNode *node, bNodeStack **in, short thread) { - float *co = p->co; + const float *co = p->co; float x = co[0]; float y = co[1]; diff --git a/source/blender/nodes/texture/nodes/node_texture_output.c b/source/blender/nodes/texture/nodes/node_texture_output.c index ce22bc00a55..fdd3b97ad59 100644 --- a/source/blender/nodes/texture/nodes/node_texture_output.c +++ b/source/blender/nodes/texture/nodes/node_texture_output.c @@ -65,7 +65,7 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **UNUSED(o tex_input_rgba(&target->tr, in[0], ¶ms, cdata->thread); target->tin = (target->tr + target->tg + target->tb) / 3.0f; - target->talpha = 1; + target->talpha = TRUE; if (target->nor) { if (in[1] && in[1]->hasinput) diff --git a/source/blender/nodes/texture/nodes/node_texture_proc.c b/source/blender/nodes/texture/nodes/node_texture_proc.c index 102f6e1c428..1f724292661 100644 --- a/source/blender/nodes/texture/nodes/node_texture_proc.c +++ b/source/blender/nodes/texture/nodes/node_texture_proc.c @@ -57,7 +57,7 @@ static bNodeSocketTemplate outputs_color_only[]= { { SOCK_RGBA, 1, "Color 2", 1.0f, 1.0f, 1.0f, 1.0f } /* Calls multitex and copies the result to the outputs. Called by xxx_exec, which handles inputs. */ -static void do_proc(float *result, TexParams *p, float *col1, float *col2, char is_normal, Tex *tex, short thread) +static void do_proc(float *result, TexParams *p, const float col1[4], const float col2[4], char is_normal, Tex *tex, const short thread) { TexResult texres; int textype; @@ -69,7 +69,7 @@ static void do_proc(float *result, TexParams *p, float *col1, float *col2, char texres.nor = NULL; textype = multitex_nodes(tex, p->co, p->dxt, p->dyt, p->osatex, - &texres, thread, 0, p->shi, p->mtex); + &texres, thread, 0, p->shi, p->mtex); if (is_normal) return; @@ -83,7 +83,7 @@ static void do_proc(float *result, TexParams *p, float *col1, float *col2, char } } -typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, short thread); +typedef void (*MapFn) (Tex *tex, bNodeStack **in, TexParams *p, const short thread); static void texfn( float *result, diff --git a/source/blender/nodes/texture/nodes/node_texture_rotate.c b/source/blender/nodes/texture/nodes/node_texture_rotate.c index a7832c8c180..2f997d36e71 100644 --- a/source/blender/nodes/texture/nodes/node_texture_rotate.c +++ b/source/blender/nodes/texture/nodes/node_texture_rotate.c @@ -47,7 +47,7 @@ static bNodeSocketTemplate outputs[]= { { -1, 0, "" } }; -static void rotate(float new_co[3], float a, float ax[3], float co[3]) +static void rotate(float new_co[3], float a, float ax[3], const float co[3]) { float para[3]; float perp[3]; diff --git a/source/blender/nodes/texture/nodes/node_texture_valToNor.c b/source/blender/nodes/texture/nodes/node_texture_valToNor.c index 2d107b87578..73dcc72eb40 100644 --- a/source/blender/nodes/texture/nodes/node_texture_valToNor.c +++ b/source/blender/nodes/texture/nodes/node_texture_valToNor.c @@ -47,7 +47,7 @@ static bNodeSocketTemplate outputs[]= { static void normalfn(float *out, TexParams *p, bNode *UNUSED(node), bNodeStack **in, short thread) { float new_co[3]; - float *co = p->co; + const float *co = p->co; float nabla = tex_input_value(in[1], p, thread); float val; diff --git a/source/blender/python/bmesh/bmesh_py_types.c b/source/blender/python/bmesh/bmesh_py_types.c index fd5fa63647b..2cae10101d1 100644 --- a/source/blender/python/bmesh/bmesh_py_types.c +++ b/source/blender/python/bmesh/bmesh_py_types.c @@ -645,7 +645,7 @@ static PyGetSetDef bpy_bmface_getseters[] = { static PyGetSetDef bpy_bmloop_getseters[] = { /* generic */ - // flags are available but not used for loops. + /* flags are available but not used for loops. */ // {(char *)"select", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_select_doc, (void *)BM_ELEM_SELECT}, // {(char *)"hide", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_hide_doc, (void *)BM_ELEM_HIDDEN}, {(char *)"tag", (getter)bpy_bm_elem_hflag_get, (setter)bpy_bm_elem_hflag_set, (char *)bpy_bm_elem_tag_doc, (void *)BM_ELEM_TAG}, diff --git a/source/blender/python/bmesh/bmesh_py_types_select.c b/source/blender/python/bmesh/bmesh_py_types_select.c index 85095596a4e..2ff731559d1 100644 --- a/source/blender/python/bmesh/bmesh_py_types_select.c +++ b/source/blender/python/bmesh/bmesh_py_types_select.c @@ -387,7 +387,7 @@ void BPy_BM_init_types_select(void) BPy_BMEditSelSeq_Type.tp_name = "BMEditSelSeq"; BPy_BMEditSelIter_Type.tp_name = "BMEditSelIter"; - BPy_BMEditSelSeq_Type.tp_doc = NULL; // todo + BPy_BMEditSelSeq_Type.tp_doc = NULL; /* todo */ BPy_BMEditSelIter_Type.tp_doc = NULL; BPy_BMEditSelSeq_Type.tp_repr = (reprfunc)NULL; diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c index 06b6192a091..d4ec8137399 100644 --- a/source/blender/python/generic/idprop_py_api.c +++ b/source/blender/python/generic/idprop_py_api.c @@ -300,40 +300,34 @@ static PyObject *BPy_IDGroup_Map_GetItem(BPy_IDProperty *self, PyObject *item) } /* returns NULL on success, error string on failure */ -static int idp_sequence_type(PyObject *seq) +static int idp_sequence_type(PyObject *seq_fast) { PyObject *item; int type = IDP_INT; - Py_ssize_t i, len = PySequence_Size(seq); + Py_ssize_t i, len = PySequence_Fast_GET_SIZE(seq_fast); for (i = 0; i < len; i++) { - item = PySequence_GetItem(seq, i); + item = PySequence_Fast_GET_ITEM(seq_fast, i); if (PyFloat_Check(item)) { if (type == IDP_IDPARRAY) { /* mixed dict/int */ - Py_DECREF(item); return -1; } type = IDP_DOUBLE; } else if (PyLong_Check(item)) { if (type == IDP_IDPARRAY) { /* mixed dict/int */ - Py_DECREF(item); return -1; } } else if (PyMapping_Check(item)) { if (i != 0 && (type != IDP_IDPARRAY)) { /* mixed dict/int */ - Py_DECREF(item); return -1; } type = IDP_IDPARRAY; } else { - Py_XDECREF(item); return -1; } - - Py_DECREF(item); } return type; @@ -386,48 +380,61 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty //prop->subtype = IDP_STRING_SUB_BYTE; } else if (PySequence_Check(ob)) { + PyObject *ob_seq_fast = PySequence_Fast(ob, "py -> idprop"); PyObject *item; int i; - if ((val.array.type = idp_sequence_type(ob)) == -1) + if (ob_seq_fast == NULL) { + PyErr_Print(); + PyErr_Clear(); + return "error converting the sequence"; + } + + if ((val.array.type = idp_sequence_type(ob_seq_fast)) == -1) { + Py_DECREF(ob_seq_fast); return "only floats, ints and dicts are allowed in ID property arrays"; + } /* validate sequence and derive type. * we assume IDP_INT unless we hit a float * number; then we assume it's */ - val.array.len = PySequence_Size(ob); + val.array.len = PySequence_Fast_GET_SIZE(ob_seq_fast); switch (val.array.type) { case IDP_DOUBLE: prop = IDP_New(IDP_ARRAY, &val, name); for (i = 0; i < val.array.len; i++) { - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); ((double *)IDP_Array(prop))[i] = (float)PyFloat_AsDouble(item); - Py_DECREF(item); } break; case IDP_INT: prop = IDP_New(IDP_ARRAY, &val, name); for (i = 0; i < val.array.len; i++) { - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); ((int *)IDP_Array(prop))[i] = (int)PyLong_AsSsize_t(item); - Py_DECREF(item); } break; case IDP_IDPARRAY: prop = IDP_NewIDPArray(name); for (i = 0; i < val.array.len; i++) { const char *error; - item = PySequence_GetItem(ob, i); + item = PySequence_Fast_GET_ITEM(ob_seq_fast, i); error = BPy_IDProperty_Map_ValidateAndCreate(NULL, prop, item); - Py_DECREF(item); - if (error) + if (error) { + Py_DECREF(ob_seq_fast); return error; + } } break; + default: + Py_DECREF(ob_seq_fast); + return "internal error with idp array.type"; } + + Py_DECREF(ob_seq_fast); } else if (PyMapping_Check(ob)) { PyObject *keys, *vals, *key, *pval; @@ -471,7 +478,7 @@ const char *BPy_IDProperty_Map_ValidateAndCreate(PyObject *name_obj, IDProperty if (group->type == IDP_IDPARRAY) { IDP_AppendArray(group, prop); - // IDP_FreeProperty(item); // IDP_AppendArray does a shallow copy (memcpy), only free memory + // IDP_FreeProperty(item); /* IDP_AppendArray does a shallow copy (memcpy), only free memory */ MEM_freeN(prop); } else { diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h index 481cfb17c7a..935a5f9030b 100644 --- a/source/blender/python/generic/py_capi_utils.h +++ b/source/blender/python/generic/py_capi_utils.h @@ -69,4 +69,4 @@ int PyC_FlagSet_ValueFromID(PyC_FlagSet *item, const char *identifier, int int PyC_FlagSet_ToBitfield(PyC_FlagSet *items, PyObject *value, int *r_value, const char *error_prefix); PyObject *PyC_FlagSet_FromBitfield(PyC_FlagSet *items, int flag); -#endif // __PY_CAPI_UTILS_H__ +#endif /* __PY_CAPI_UTILS_H__ */ diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt index 15aa5164c86..bd660b94321 100644 --- a/source/blender/python/intern/CMakeLists.txt +++ b/source/blender/python/intern/CMakeLists.txt @@ -30,13 +30,13 @@ set(INC ../../blenlib ../../blenloader ../../editors/include + ../../gpu ../../makesdna ../../makesrna ../../windowmanager - ../../gpu + ../../../../intern/cycles/blender ../../freestyle/intern/python ../../../../intern/guardedalloc - ../../../../intern/cycles/blender ) set(INC_SYS diff --git a/source/blender/python/intern/bpy_app.h b/source/blender/python/intern/bpy_app.h index 5bf36f04ba0..226bf44a493 100644 --- a/source/blender/python/intern/bpy_app.h +++ b/source/blender/python/intern/bpy_app.h @@ -29,4 +29,4 @@ PyObject *BPY_app_struct(void); -#endif // __BPY_APP_H__ +#endif /* __BPY_APP_H__ */ diff --git a/source/blender/python/intern/bpy_app_ffmpeg.h b/source/blender/python/intern/bpy_app_ffmpeg.h index cadbb021d31..26d6e13f8f4 100644 --- a/source/blender/python/intern/bpy_app_ffmpeg.h +++ b/source/blender/python/intern/bpy_app_ffmpeg.h @@ -29,4 +29,4 @@ PyObject *BPY_app_ffmpeg_struct(void); -#endif // __BPY_APP_FFMPEG_H__ +#endif /* __BPY_APP_FFMPEG_H__ */ diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c index 4d7f2080bbc..90a0444ceae 100644 --- a/source/blender/python/intern/bpy_app_handlers.c +++ b/source/blender/python/intern/bpy_app_handlers.c @@ -284,7 +284,7 @@ void bpy_app_generic_callback(struct Main *UNUSED(main), struct ID *id, void *ar if (PyList_GET_SIZE(cb_list) > 0) { PyGILState_STATE gilstate = PyGILState_Ensure(); - PyObject *args = PyTuple_New(1); // save python creating each call + PyObject *args = PyTuple_New(1); /* save python creating each call */ PyObject *func; PyObject *ret; Py_ssize_t pos; diff --git a/source/blender/python/intern/bpy_app_handlers.h b/source/blender/python/intern/bpy_app_handlers.h index 1f1eaf04a8b..40ca43909ed 100644 --- a/source/blender/python/intern/bpy_app_handlers.h +++ b/source/blender/python/intern/bpy_app_handlers.h @@ -29,4 +29,4 @@ PyObject *BPY_app_handlers_struct(void); -#endif // __BPY_APP_HANDLERS_H__ +#endif /* __BPY_APP_HANDLERS_H__ */ diff --git a/source/blender/python/intern/bpy_driver.c b/source/blender/python/intern/bpy_driver.c index de23b3bf109..9a79616c23b 100644 --- a/source/blender/python/intern/bpy_driver.c +++ b/source/blender/python/intern/bpy_driver.c @@ -280,7 +280,7 @@ float BPY_driver_exec(ChannelDriver *driver, const float evaltime) } -#if 0 // slow, with this can avoid all Py_CompileString above. +#if 0 /* slow, with this can avoid all Py_CompileString above. */ /* execute expression to get a value */ retval = PyRun_String(expr, Py_eval_input, bpy_pydriver_Dict, driver_vars); #else diff --git a/source/blender/python/intern/bpy_driver.h b/source/blender/python/intern/bpy_driver.h index 6d1696d6cdc..1fccec7e1b2 100644 --- a/source/blender/python/intern/bpy_driver.h +++ b/source/blender/python/intern/bpy_driver.h @@ -36,4 +36,4 @@ extern PyObject *bpy_pydriver_Dict; float BPY_driver_exec(struct ChannelDriver *driver, const float evaltime); void BPY_driver_reset(void); -#endif // __BPY_DRIVER_H__ +#endif /* __BPY_DRIVER_H__ */ diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c index b628f42e759..f6ab100ca1a 100644 --- a/source/blender/python/intern/bpy_interface.c +++ b/source/blender/python/intern/bpy_interface.c @@ -69,7 +69,7 @@ #include "BPY_extern.h" -#include "../generic/bpy_internal_import.h" // our own imports +#include "../generic/bpy_internal_import.h" /* our own imports */ #include "../generic/py_capi_utils.h" /* inittab initialization functions */ @@ -180,10 +180,10 @@ void BPY_text_free_code(Text *text) void BPY_modules_update(bContext *C) { -#if 0 // slow, this runs all the time poll, draw etc 100's of time a sec. +#if 0 /* slow, this runs all the time poll, draw etc 100's of time a sec. */ PyObject *mod = PyImport_ImportModuleLevel("bpy", NULL, NULL, NULL, 0); PyModule_AddObject(mod, "data", BPY_rna_module()); - PyModule_AddObject(mod, "types", BPY_rna_types()); // atm this does not need updating + PyModule_AddObject(mod, "types", BPY_rna_types()); /* atm this does not need updating */ #endif /* refreshes the main struct */ @@ -268,7 +268,7 @@ void BPY_python_start(int argc, const char **argv) Py_Initialize(); - // PySys_SetArgv(argc, argv); // broken in py3, not a huge deal + // PySys_SetArgv(argc, argv); /* broken in py3, not a huge deal */ /* sigh, why do python guys not have a (char **) version anymore? */ { int i; diff --git a/source/blender/python/intern/bpy_traceback.h b/source/blender/python/intern/bpy_traceback.h index 575f9824379..9ac49c370e4 100644 --- a/source/blender/python/intern/bpy_traceback.h +++ b/source/blender/python/intern/bpy_traceback.h @@ -28,4 +28,4 @@ void python_script_error_jump(const char *filepath, int *lineno, int *offset); -#endif // __BPY_TRACEBACK_H__ +#endif /* __BPY_TRACEBACK_H__ */ diff --git a/source/blender/python/intern/bpy_util.c b/source/blender/python/intern/bpy_util.c index 53d0e10a01e..30b6806a796 100644 --- a/source/blender/python/intern/bpy_util.c +++ b/source/blender/python/intern/bpy_util.c @@ -35,6 +35,8 @@ #include "BKE_report.h" #include "BKE_context.h" +#include "BLF_translation.h" + #include "../generic/py_capi_utils.h" static bContext *__py_context = NULL; @@ -79,7 +81,7 @@ short BPy_reports_to_error(ReportList *reports, PyObject *exception, const short short BPy_errors_to_report(ReportList *reports) { PyObject *pystring; - PyObject *pystring_format = NULL; // workaround, see below + PyObject *pystring_format = NULL; /* workaround, see below */ char *cstring; const char *filename; @@ -98,7 +100,7 @@ short BPy_errors_to_report(ReportList *reports) pystring = PyC_ExceptionBuffer(); if (pystring == NULL) { - BKE_report(reports, RPT_ERROR, "unknown py-exception, couldn't convert"); + BKE_report(reports, RPT_ERROR, "Unknown py-exception, couldn't convert"); return 0; } @@ -108,17 +110,18 @@ short BPy_errors_to_report(ReportList *reports) cstring = _PyUnicode_AsString(pystring); -#if 0 // ARG!. workaround for a bug in blenders use of vsnprintf +#if 0 /* ARG!. workaround for a bug in blenders use of vsnprintf */ BKE_reportf(reports, RPT_ERROR, "%s\nlocation:%s:%d\n", cstring, filename, lineno); #else - pystring_format = PyUnicode_FromFormat("%s\nlocation:%s:%d\n", cstring, filename, lineno); + pystring_format = PyUnicode_FromFormat(TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); cstring = _PyUnicode_AsString(pystring_format); BKE_report(reports, RPT_ERROR, cstring); #endif - - fprintf(stderr, "%s\nlocation:%s:%d\n", cstring, filename, lineno); // not exactly needed. just for testing - + + /* not exactly needed. just for testing */ + fprintf(stderr, TIP_("%s\nlocation:%s:%d\n"), cstring, filename, lineno); + Py_DECREF(pystring); - Py_DECREF(pystring_format); // workaround + Py_DECREF(pystring_format); /* workaround */ return 1; } diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c index 8b5e39fbd27..c14b4a0686b 100644 --- a/source/blender/python/mathutils/mathutils_Color.c +++ b/source/blender/python/mathutils/mathutils_Color.c @@ -858,7 +858,7 @@ PyTypeObject color_Type = { * (i.e. it was allocated elsewhere by MEM_mallocN()) * pass Py_NEW - if vector is not a WRAPPER and managed by PYTHON * (i.e. it must be created here with PyMEM_malloc())*/ -PyObject *Color_CreatePyObject(float *col, int type, PyTypeObject *base_type) +PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type) { ColorObject *self; diff --git a/source/blender/python/mathutils/mathutils_Color.h b/source/blender/python/mathutils/mathutils_Color.h index eff09c25a99..d753b60d195 100644 --- a/source/blender/python/mathutils/mathutils_Color.h +++ b/source/blender/python/mathutils/mathutils_Color.h @@ -47,7 +47,7 @@ typedef struct { * blender (stored in blend_data). This is an either/or struct not both*/ //prototypes -PyObject *Color_CreatePyObject(float *col, int type, PyTypeObject *base_type); +PyObject *Color_CreatePyObject(float col[3], int type, PyTypeObject *base_type); PyObject *Color_CreatePyObject_cb(PyObject *cb_user, unsigned char cb_type, unsigned char cb_subtype); diff --git a/source/blender/python/mathutils/mathutils_noise.c b/source/blender/python/mathutils/mathutils_noise.c index da32e36dc02..4977663038d 100644 --- a/source/blender/python/mathutils/mathutils_noise.c +++ b/source/blender/python/mathutils/mathutils_noise.c @@ -43,6 +43,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_noise.h" #include "BLI_utildefines.h" #include "MEM_guardedalloc.h" diff --git a/source/blender/python/mathutils/mathutils_noise.h b/source/blender/python/mathutils/mathutils_noise.h index f4bec88e59a..2ed3e32f4f1 100644 --- a/source/blender/python/mathutils/mathutils_noise.h +++ b/source/blender/python/mathutils/mathutils_noise.h @@ -33,4 +33,4 @@ PyMODINIT_FUNC PyInit_mathutils_noise(void); PyMODINIT_FUNC PyInit_mathutils_noise_types(void); PyMODINIT_FUNC PyInit_mathutils_noise_metrics(void); -#endif // __MATHUTILS_NOISE_H__ +#endif /* __MATHUTILS_NOISE_H__ */ diff --git a/source/blender/python/rna_dump.py b/source/blender/python/rna_dump.py index 489f011e693..15cc60d997e 100644 --- a/source/blender/python/rna_dump.py +++ b/source/blender/python/rna_dump.py @@ -95,7 +95,7 @@ def seek(r, txt, recurs): if GEN_PATH: newtxt = txt + '.' + item - if item == 'rna_type' and VERBOSE_TYPE == False: # just avoid because it spits out loads of data + if item == 'rna_type' and VERBOSE_TYPE is False: # just avoid because it spits out loads of data continue value = getattr(r, item, None) @@ -114,7 +114,7 @@ def seek(r, txt, recurs): except: length = 0 - if VERBOSE == False and length >= 4: + if VERBOSE is False and length >= 4: for i in (0, length - 1): if i > 0: if PRINT_DATA: diff --git a/source/blender/quicktime/apple/quicktime_export.c b/source/blender/quicktime/apple/quicktime_export.c index 659fd997c1f..1d5838e9905 100644 --- a/source/blender/quicktime/apple/quicktime_export.c +++ b/source/blender/quicktime/apple/quicktime_export.c @@ -218,7 +218,7 @@ static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports) /* retreive codecdata from quicktime in a atomcontainer */ myErr = SCGetSettingsAsAtomContainer(qtdata->theComponent, &myContainer); if (myErr != noErr) { - BKE_reportf(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: SCGetSettingsAsAtomContainer failed"); goto bail; } @@ -238,7 +238,7 @@ static OSErr QT_SaveCodecSettingsToScene(RenderData *rd, ReportList *reports) GetCodecInfo(&ci, qtdata->gSpatialSettings.codecType, 0); } else { - BKE_reportf(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: QT_SaveCodecSettingsToScene failed"); } QTUnlockContainer(myContainer); @@ -268,7 +268,7 @@ static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports) if (qcd->cdParms && qcd->cdSize) { myErr = SCSetSettingsFromAtomContainer((GraphicsExportComponent)qtdata->theComponent, (QTAtomContainer)myHandle); if (myErr != noErr) { - BKE_reportf(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: SCSetSettingsFromAtomContainer failed"); goto bail; } @@ -295,7 +295,7 @@ static OSErr QT_GetCodecSettingsFromScene(RenderData *rd, ReportList *reports) } else { - BKE_reportf(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed\n"); + BKE_report(reports, RPT_ERROR, "Quicktime: QT_GetCodecSettingsFromScene failed"); } bail: if (myHandle != NULL) @@ -414,7 +414,7 @@ static void QT_StartAddVideoSamplesToMedia(const Rect *trackFrame, int rectx, in gTemporalSettings = qtdata->gTemporalSettings; if (qtdata->gSpatialSettings.codecType == kH264CodecType) { if (gTemporalSettings.temporalQuality != codecMinQuality) { - BKE_reportf(reports, RPT_WARNING, "Only minimum quality compression supported for QuickTime H.264.\n"); + BKE_report(reports, RPT_WARNING, "Only minimum quality compression supported for Quicktime H.264"); gTemporalSettings.temporalQuality = codecMinQuality; } } @@ -564,7 +564,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R /* hack: create an empty file to make FSPathMakeRef() happy */ myFile = open(theFullPath, O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRUSR | S_IWUSR); if (myFile < 0) { - BKE_reportf(reports, RPT_ERROR, "error while creating movie file!\n"); + BKE_report(reports, RPT_ERROR, "Error while creating movie file!"); /* do something? */ } close(myFile); @@ -599,7 +599,7 @@ int start_qt(struct Scene *scene, struct RenderData *rd, int rectx, int recty, R #endif } else { - //printf("Created QuickTime movie: %s\n", name); + /* printf("Created QuickTime movie: %s\n", name); */ QT_CreateMyVideoTrack(rectx, recty, reports); } @@ -636,7 +636,7 @@ void end_qt(void) DisposeMovie(qtexport->theMovie); - //printf("Finished QuickTime movie.\n"); + /* printf("Finished QuickTime movie.\n"); */ } #ifdef __APPLE__ diff --git a/source/blender/quicktime/quicktime_export.h b/source/blender/quicktime/quicktime_export.h index ed896357c90..cef4cb8c2a6 100644 --- a/source/blender/quicktime/quicktime_export.h +++ b/source/blender/quicktime/quicktime_export.h @@ -164,6 +164,6 @@ enum { }; #endif -#endif //(_WIN32) || (__APPLE__) +#endif /* (_WIN32) || (__APPLE__) */ -#endif // __QUICKTIME_IMP_H__ +#endif /* __QUICKTIME_IMP_H__ */ diff --git a/source/blender/quicktime/quicktime_import.h b/source/blender/quicktime/quicktime_import.h index 19bdbb4814c..fb068fc2533 100644 --- a/source/blender/quicktime/quicktime_import.h +++ b/source/blender/quicktime/quicktime_import.h @@ -51,8 +51,8 @@ #import <Carbon/Carbon.h> #include <QuickTime/Movies.h> #endif -#endif //__MOVIES__ -#endif //USE_QTKIT +#endif /* __MOVIES__ */ +#endif /* USE_QTKIT */ #ifdef _WIN32 #ifndef __FIXMATH__ @@ -76,4 +76,4 @@ ImBuf *qtime_fetchibuf (struct anim *anim, int position); int imb_is_a_quicktime (char *name); ImBuf *imb_quicktime_decode(unsigned char *mem, int size, int flags); -#endif // __QUICKTIME_IMPORT_H__ +#endif /* __QUICKTIME_IMPORT_H__ */ diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h index 57fb80f11c0..10045a8f7e1 100644 --- a/source/blender/render/extern/include/RE_shader_ext.h +++ b/source/blender/render/extern/include/RE_shader_ext.h @@ -191,12 +191,12 @@ struct MTex; struct ImBuf; /* this one uses nodes */ -int multitex_ext(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); +int multitex_ext(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres); /* nodes disabled */ -int multitex_ext_safe(struct Tex *tex, float *texvec, struct TexResult *texres); +int multitex_ext_safe(struct Tex *tex, float texvec[3], struct TexResult *texres); /* only for internal node usage */ -int multitex_nodes(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres, - short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex); +int multitex_nodes(struct Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres, + const short thread, short which_output, struct ShadeInput *shi, struct MTex *mtex); /* shaded view and bake */ struct Render; diff --git a/source/blender/render/intern/include/envmap.h b/source/blender/render/intern/include/envmap.h index 24138884cd2..d0f346f7402 100644 --- a/source/blender/render/intern/include/envmap.h +++ b/source/blender/render/intern/include/envmap.h @@ -46,7 +46,7 @@ struct Render; struct TexResult; void make_envmaps(struct Render *re); -int envmaptex(struct Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, struct TexResult *texres); +int envmaptex(struct Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, struct TexResult *texres); #endif /* __ENVMAP_H__ */ diff --git a/source/blender/render/intern/include/pointdensity.h b/source/blender/render/intern/include/pointdensity.h index cc8fabda49c..e0c293e2473 100644 --- a/source/blender/render/intern/include/pointdensity.h +++ b/source/blender/render/intern/include/pointdensity.h @@ -43,7 +43,7 @@ struct TexResult; void cache_pointdensity(struct Render *re, struct Tex *tex); void make_pointdensities(struct Render *re); void free_pointdensities(struct Render *re); -int pointdensitytex(struct Tex *tex, float *texvec, struct TexResult *texres); +int pointdensitytex(struct Tex *tex, const float texvec[3], struct TexResult *texres); #endif /* __POINTDENSITY_H__ */ diff --git a/source/blender/render/intern/include/rayobject.h b/source/blender/render/intern/include/rayobject.h index 7752baadff4..07fc7d7a6ed 100644 --- a/source/blender/render/intern/include/rayobject.h +++ b/source/blender/render/intern/include/rayobject.h @@ -104,7 +104,7 @@ RayObject *RE_vlakprimitive_from_vlak(VlakPrimitive *face, struct ObjectInstance void RE_rayobject_merge_bb(RayObject *ob, float *min, float *max); /* initializes an hint for optimizing raycast where it is know that a ray will pass by the given BB often the origin point */ -void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float *min, float *max); +void RE_rayobject_hint_bb(RayObject *r, struct RayHint *hint, float min[3], float max[3]); /* initializes an hint for optimizing raycast where it is know that a ray will be contained inside the given cone*/ /* void RE_rayobject_hint_cone(RayObject *r, struct RayHint *hint, float *); */ diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h index 60f3ced5652..dab89e1d1c0 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/include/rendercore.h b/source/blender/render/intern/include/rendercore.h index 0fbbf52e613..30712250440 100644 --- a/source/blender/render/intern/include/rendercore.h +++ b/source/blender/render/intern/include/rendercore.h @@ -62,7 +62,7 @@ typedef struct PixStrMain { /* ------------------------------------------------------------------------- */ -void calc_view_vector(float *view, float x, float y); +void calc_view_vector(float view[3], float x, float y); float mistfactor(float zcor, const float co[3]); /* dist and height, return alpha */ void renderspothalo(struct ShadeInput *shi, float col[4], float alpha); @@ -95,5 +95,4 @@ extern void init_ao_sphere(struct World *wrld); extern void init_render_qmcsampler(Render *re); extern void free_render_qmcsampler(Render *re); -#endif /* RENDER_EXT_H */ - +#endif /* __RENDERCORE_H__ */ diff --git a/source/blender/render/intern/include/renderdatabase.h b/source/blender/render/intern/include/renderdatabase.h index d116dfe7b17..5213f14d773 100644 --- a/source/blender/render/intern/include/renderdatabase.h +++ b/source/blender/render/intern/include/renderdatabase.h @@ -88,7 +88,7 @@ void free_renderdata_vertnodes(struct VertTableNode *vertnodes); void free_renderdata_vlaknodes(struct VlakTableNode *vlaknodes); void project_renderdata(struct Render *re, void (*projectfunc)(const float *, float mat[][4], float *), int do_pano, float xoffs, int do_buckets); -int clip_render_object(float boundbox[][3], float *bounds, float mat[][4]); +int clip_render_object(float boundbox[][3], float bounds[4], float mat[][4]); /* functions are not exported... so wrong names */ diff --git a/source/blender/render/intern/include/shading.h b/source/blender/render/intern/include/shading.h index a8519d8a7fb..4f6e005d742 100644 --- a/source/blender/render/intern/include/shading.h +++ b/source/blender/render/intern/include/shading.h @@ -60,7 +60,7 @@ void shade_material_loop(struct ShadeInput *shi, struct ShadeResult *shr); void shade_input_set_triangle_i(struct ShadeInput *shi, struct ObjectInstanceRen *obi, struct VlakRen *vlr, short i1, short i2, short i3); void shade_input_set_triangle(struct ShadeInput *shi, volatile int obi, volatile int facenr, int normal_flip); void shade_input_copy_triangle(struct ShadeInput *shi, struct ShadeInput *from); -void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float *dxyview, float *co, float *dxco, float *dyco); +void shade_input_calc_viewco(struct ShadeInput *shi, float x, float y, float z, float view[3], float dxyview[2], float co[3], float dxco[3], float dyco[3]); void shade_input_set_viewco(struct ShadeInput *shi, float x, float y, float sx, float sy, float z); void shade_input_set_uv(struct ShadeInput *shi); void shade_input_set_normals(struct ShadeInput *shi); diff --git a/source/blender/render/intern/include/sunsky.h b/source/blender/render/intern/include/sunsky.h index 74e42109be5..04aff810bbb 100644 --- a/source/blender/render/intern/include/sunsky.h +++ b/source/blender/render/intern/include/sunsky.h @@ -69,7 +69,7 @@ typedef struct SunSky { float atm_BetaRM[3]; } SunSky; -void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness, +void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness, float spread, float sun_brightness, float sun_size, float back_scatter, float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace); diff --git a/source/blender/render/intern/include/texture_ocean.h b/source/blender/render/intern/include/texture_ocean.h index 7d4110aadf3..121142aa0b0 100644 --- a/source/blender/render/intern/include/texture_ocean.h +++ b/source/blender/render/intern/include/texture_ocean.h @@ -23,4 +23,9 @@ * ***** END GPL LICENSE BLOCK ***** */ -int ocean_texture(struct Tex *tex, float *texvec, struct TexResult *texres); +#ifndef __TEXTURE_OCEAN_H__ +#define __TEXTURE_OCEAN_H__ + +int ocean_texture(struct Tex *tex, const float texvec[2], struct TexResult *texres); + +#endif /* __TEXTURE_OCEAN_H__ */ diff --git a/source/blender/render/intern/include/volume_precache.h b/source/blender/render/intern/include/volume_precache.h index 8e402bc5418..9aa280d8276 100644 --- a/source/blender/render/intern/include/volume_precache.h +++ b/source/blender/render/intern/include/volume_precache.h @@ -30,8 +30,8 @@ */ -void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax); -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co); +void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3]); +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3]); void volume_precache(Render *re); void free_volume_precache(Render *re); diff --git a/source/blender/render/intern/raytrace/rayobject.cpp b/source/blender/render/intern/raytrace/rayobject.cpp index 6f14c6153f9..c3babf99d51 100644 --- a/source/blender/render/intern/raytrace/rayobject.cpp +++ b/source/blender/render/intern/raytrace/rayobject.cpp @@ -467,7 +467,7 @@ float RE_rayobject_cost(RayObject *r) /* Bounding Boxes */ -void RE_rayobject_merge_bb(RayObject *r, float *min, float *max) +void RE_rayobject_merge_bb(RayObject *r, float min[3], float max[3]) { if (RE_rayobject_isRayFace(r)) { RayFace *face = (RayFace *) RE_rayobject_align(r); diff --git a/source/blender/render/intern/raytrace/rayobject_internal.h b/source/blender/render/intern/raytrace/rayobject_internal.h index 3f768e5adcb..07672f7bfb2 100644 --- a/source/blender/render/intern/raytrace/rayobject_internal.h +++ b/source/blender/render/intern/raytrace/rayobject_internal.h @@ -124,9 +124,9 @@ typedef int (*RE_rayobject_raycast_callback)(RayObject *, struct Isect *); typedef void (*RE_rayobject_add_callback)(RayObject *raytree, RayObject *rayobject); typedef void (*RE_rayobject_done_callback)(RayObject *); typedef void (*RE_rayobject_free_callback)(RayObject *); -typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float *min, float *max); +typedef void (*RE_rayobject_merge_bb_callback)(RayObject *, float min[3], float max[3]); typedef float (*RE_rayobject_cost_callback)(RayObject *); -typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, struct RayHint *, float *, float *); +typedef void (*RE_rayobject_hint_bb_callback)(RayObject *, struct RayHint *, float min[3], float max[3]); typedef struct RayObjectAPI { RE_rayobject_raycast_callback raycast; @@ -154,5 +154,4 @@ int RE_rayobject_intersect(RayObject *r, struct Isect *i); } #endif -#endif - +#endif /* __RAYOBJECT_INTERNAL_H__ */ diff --git a/source/blender/render/intern/raytrace/rayobject_octree.cpp b/source/blender/render/intern/raytrace/rayobject_octree.cpp index 5ae716ac942..77e9dc9d8fd 100644 --- a/source/blender/render/intern/raytrace/rayobject_octree.cpp +++ b/source/blender/render/intern/raytrace/rayobject_octree.cpp @@ -382,8 +382,12 @@ static void d2dda(Octree *oc, short b1, short b2, short c1, short c2, char *ocfa while (TRUE) { - if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) ; - else ocface[oc->ocres * x + y] = 1; + if (x < 0 || y < 0 || x >= oc->ocres || y >= oc->ocres) { + /* pass*/ + } + else { + ocface[oc->ocres * x + y] = 1; + } labdao = labda; if (labdax == labday) { diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp index 3926e8b8e51..678aa8e5634 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp @@ -193,7 +193,7 @@ static void rtbuild_calc_bb(RTBuilder *b) } } -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max) +void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]) { rtbuild_calc_bb(b); DO_MIN(b->bb, min); @@ -457,26 +457,26 @@ static void split_leafs(RTBuilder *b, int *nth, int partitions, int split_axis) /* * Bounding Box utils */ -float bb_volume(float *min, float *max) +float bb_volume(const float min[3], const float max[3]) { return (max[0] - min[0]) * (max[1] - min[1]) * (max[2] - min[2]); } -float bb_area(float *min, float *max) +float bb_area(const float min[3], const float max[3]) { float sub[3], a; sub[0] = max[0] - min[0]; sub[1] = max[1] - min[1]; sub[2] = max[2] - min[2]; - a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2; + a = (sub[0] * sub[1] + sub[0] * sub[2] + sub[1] * sub[2]) * 2.0f; /* used to have an assert() here on negative results * however, in this case its likely some overflow or ffast math error. * so just return 0.0f instead. */ return a < 0.0f ? 0.0f : a; } -int bb_largest_axis(float *min, float *max) +int bb_largest_axis(const float min[3], const float max[3]) { float sub[3]; @@ -497,7 +497,9 @@ int bb_largest_axis(float *min, float *max) } } -int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max) +/* only returns 0 if merging inner and outerbox would create a box larger than outer box */ +int bb_fits_inside(const float outer_min[3], const float outer_max[3], + const float inner_min[3], const float inner_max[3]) { int i; for (i = 0; i < 3; i++) diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h index 22e3d009c07..9e296da144b 100644 --- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h +++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h @@ -86,7 +86,7 @@ RTBuilder *rtbuild_create(int size); void rtbuild_free(RTBuilder *b); void rtbuild_add(RTBuilder *b, RayObject *o); void rtbuild_done(RTBuilder *b, RayObjectControl *c); -void rtbuild_merge_bb(RTBuilder *b, float *min, float *max); +void rtbuild_merge_bb(RTBuilder *b, float min[3], float max[3]); int rtbuild_size(RTBuilder *b); RayObject *rtbuild_get_primitive(RTBuilder *b, int offset); @@ -109,13 +109,14 @@ int rtbuild_median_split_largest_axis(RTBuilder *b, int nchilds); /* bb utils */ -float bb_area(float *min, float *max); -float bb_volume(float *min, float *max); -int bb_largest_axis(float *min, float *max); -int bb_fits_inside(float *outer_min, float *outer_max, float *inner_min, float *inner_max); /* only returns 0 if merging inner and outerbox would create a box larger than outer box */ +float bb_area(const float min[3], const float max[3]); +float bb_volume(const float min[3], const float max[3]); +int bb_largest_axis(const float min[3], const float max[3]); +int bb_fits_inside(const float outer_min[3], const float outer_max[3], + const float inner_min[3], const float inner_max[3]); #ifdef __cplusplus } #endif -#endif +#endif /* __RAYOBJECT_RTBUILD_H__ */ diff --git a/source/blender/render/intern/raytrace/svbvh.h b/source/blender/render/intern/raytrace/svbvh.h index a58094e5021..4fdf3ac23e8 100644 --- a/source/blender/render/intern/raytrace/svbvh.h +++ b/source/blender/render/intern/raytrace/svbvh.h @@ -29,12 +29,11 @@ * \ingroup render */ - -#ifdef __SSE__ - #ifndef __SVBVH_H__ #define __SVBVH_H__ +#ifdef __SSE__ + #include "bvh.h" #include "BLI_memarena.h" #include "BKE_global.h" @@ -231,7 +230,7 @@ struct Reorganize_SVBVH { return node; } - void copy_bb(float *bb, const float *old_bb) + void copy_bb(float bb[6], const float old_bb[6]) { std::copy(old_bb, old_bb + 6, bb); } @@ -282,7 +281,7 @@ struct Reorganize_SVBVH { useless_bb += alloc_childs - nchilds; while (alloc_childs > nchilds) { - const static float def_bb[6] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MIN, FLT_MIN, FLT_MIN }; + const static float def_bb[6] = {FLT_MAX, FLT_MAX, FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX}; alloc_childs--; node->child[alloc_childs] = NULL; copy_bb(node->child_bb + alloc_childs * 6, def_bb); @@ -311,7 +310,6 @@ struct Reorganize_SVBVH { } }; -#endif - -#endif //__SSE__ +#endif /* __SSE__ */ +#endif /* __SVBVH_H__ */ diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c index e3db4b7c266..e399951bd15 100644 --- a/source/blender/render/intern/source/convertblender.c +++ b/source/blender/render/intern/source/convertblender.c @@ -4149,8 +4149,12 @@ static void set_fullsample_trace_flag(Render *re, ObjectRen *obr) vlr->flag |= R_FULL_OSA; } else if (trace) { - if (mode & MA_SHLESS); - else if (vlr->mat->material_type == MA_TYPE_VOLUME); + if (mode & MA_SHLESS) { + /* pass */ + } + else if (vlr->mat->material_type == MA_TYPE_VOLUME) { + /* pass */ + } else if ((mode & MA_RAYMIRROR) || ((mode & MA_TRANSP) && (mode & MA_RAYTRANSP))) { /* for blurry reflect/refract, better to take more samples * inside the raytrace than as OSA samples */ @@ -4768,10 +4772,12 @@ void RE_Database_Free(Render *re) static int allow_render_object(Render *re, Object *ob, int nolamps, int onlyselected, Object *actob) { /* override not showing object when duplis are used with particles */ - if (ob->transflag & OB_DUPLIPARTS) - ; /* let particle system(s) handle showing vs. not showing */ - else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) + if (ob->transflag & OB_DUPLIPARTS) { + /* pass */ /* let particle system(s) handle showing vs. not showing */ + } + else if ((ob->transflag & OB_DUPLI) && !(ob->transflag & OB_DUPLIFRAMES)) { return 0; + } /* don't add non-basic meta objects, ends up having renderobjects with no geometry */ if (ob->type == OB_MBALL && ob!=BKE_mball_basis_find(re->scene, ob)) diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c index 03eb21dfa23..910307f370b 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 */ @@ -642,31 +643,31 @@ static int envcube_isect(EnvMap *env, const float vec[3], float answ[2]) /* ------------------------------------------------------------------------- */ -static void set_dxtdyt(float *dxts, float *dyts, float *dxt, float *dyt, int face) +static void set_dxtdyt(float r_dxt[3], float r_dyt[3], const float dxt[3], const float dyt[3], int face) { if (face == 2 || face == 4) { - dxts[0] = dxt[0]; - dyts[0] = dyt[0]; - dxts[1] = dxt[2]; - dyts[1] = dyt[2]; + r_dxt[0] = dxt[0]; + r_dyt[0] = dyt[0]; + r_dxt[1] = dxt[2]; + r_dyt[1] = dyt[2]; } else if (face == 3 || face == 5) { - dxts[0] = dxt[1]; - dxts[1] = dxt[2]; - dyts[0] = dyt[1]; - dyts[1] = dyt[2]; + r_dxt[0] = dxt[1]; + r_dxt[1] = dxt[2]; + r_dyt[0] = dyt[1]; + r_dyt[1] = dyt[2]; } else { - dxts[0] = dxt[0]; - dyts[0] = dyt[0]; - dxts[1] = dxt[1]; - dyts[1] = dyt[1]; + r_dxt[0] = dxt[0]; + r_dyt[0] = dyt[0]; + r_dxt[1] = dxt[1]; + r_dyt[1] = dyt[1]; } } /* ------------------------------------------------------------------------- */ -int envmaptex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) +int envmaptex(Tex *tex, const float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres) { extern Render R; /* only in this call */ /* texvec should be the already reflected normal */ diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 6c86f2a2999..154292a3065 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -150,8 +150,13 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul fx-= xs; fy-= ys; - if ( (tex->flag & TEX_CHECKER_ODD)==0) { - if ((xs+ys) & 1);else return retval; + if ( (tex->flag & TEX_CHECKER_ODD) == 0) { + if ((xs + ys) & 1) { + /* pass */ + } + else { + return retval; + } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { if ((xs+ys) & 1) return retval; @@ -474,7 +479,9 @@ static void boxsampleclip(struct ImBuf *ibuf, rctf *rf, TexResult *texres) muly= 1.0; - if (starty==endy); + if (starty==endy) { + /* pass */ + } else { if (y==starty) muly= 1.0f-(rf->ymin - y); if (y==endy) muly= (rf->ymax - y); @@ -1453,8 +1460,12 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const image_mipmap_test(tex, ibuf); if (tex->imaflag & TEX_USEALPHA) { - if (tex->imaflag & TEX_CALCALPHA); - else texres->talpha= 1; + if (tex->imaflag & TEX_CALCALPHA) { + /* pass */ + } + else { + texres->talpha = TRUE; + } } texr.talpha= texres->talpha; @@ -1550,11 +1561,17 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const if (boundary==0) { if ( (tex->flag & TEX_CHECKER_ODD)==0) { - if ((xs+ys) & 1); - else return retval; + if ((xs + ys) & 1) { + /* pass */ + } + else { + return retval; + } } if ( (tex->flag & TEX_CHECKER_EVEN)==0) { - if ((xs+ys) & 1) return retval; + if ((xs + ys) & 1) { + return retval; + } } fx-= xs; fy-= ys; diff --git a/source/blender/render/intern/source/initrender.c b/source/blender/render/intern/source/initrender.c index 88c64b44b64..2b564a09024 100644 --- a/source/blender/render/intern/source/initrender.c +++ b/source/blender/render/intern/source/initrender.c @@ -558,20 +558,19 @@ void initparts(Render *re, int do_crop) xparts = re->r.xparts; yparts = re->r.yparts; - /* mininum part size, but for exr tile saving it was checked already */ - if (!(re->r.scemode & (R_EXR_TILE_FILE | R_FULL_SAMPLE))) { - if (re->r.mode & R_PANORAMA) { - if (ceil(re->rectx / (float)xparts) < 8) - xparts = 1 + re->rectx / 8; - } - else + /* minimum part size */ + if (re->r.mode & R_PANORAMA) { + if (ceil(re->rectx / (float)xparts) < 8) + xparts = 1 + re->rectx / 8; + } + else { if (ceil(re->rectx / (float)xparts) < 64) xparts = 1 + re->rectx / 64; - - if (ceil(re->recty / (float)yparts) < 64) - yparts = 1 + re->recty / 64; } + if (ceil(re->recty / (float)yparts) < 64) + yparts = 1 + re->recty / 64; + /* part size */ partx = ceil(re->rectx / (float)xparts); party = ceil(re->recty / (float)yparts); diff --git a/source/blender/render/intern/source/occlusion.c b/source/blender/render/intern/source/occlusion.c index af774c5be73..895c5d6c8fb 100644 --- a/source/blender/render/intern/source/occlusion.c +++ b/source/blender/render/intern/source/occlusion.c @@ -625,9 +625,12 @@ static void occ_build_sh_normalize(OccNode *node) sh_mul(node->sh, 1.0f / node->area); for (b = 0; b < TOTCHILD; b++) { - if (node->childflag & (1 << b)) ; - else if (node->child[b].node) + if (node->childflag & (1 << b)) { + /* pass */ + } + else if (node->child[b].node) { occ_build_sh_normalize(node->child[b].node); + } } } diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 981f705e07c..648c27e0d2f 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -508,7 +508,9 @@ void RE_InitState(Render *re, Render *source, RenderData *rd, SceneRenderLayer * BLI_rw_mutex_lock(&re->resultmutex, THREAD_LOCK_WRITE); if (re->r.scemode & R_PREVIEWBUTS) { - if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) ; + if (re->result && re->result->rectx == re->rectx && re->result->recty == re->recty) { + /* pass */ + } else { render_result_free(re->result); re->result = NULL; @@ -657,8 +659,12 @@ static void *do_part_thread(void *pa_v) } else if (render_display_draw_enabled(&R)) { /* on break, don't merge in result for preview renders, looks nicer */ - if (R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)) ; - else render_result_merge(R.result, pa->result); + if (R.test_break(R.tbh) && (R.r.scemode & R_PREVIEWBUTS)) { + /* pass */ + } + else { + render_result_merge(R.result, pa->result); + } } } @@ -1592,6 +1598,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 */ @@ -1974,7 +1981,7 @@ int RE_is_rendering_allowed(Scene *scene, Object *camera_override, ReportList *r if (scene->r.scemode & R_DOCOMP) { if (scene->use_nodes) { if (!scene->nodetree) { - BKE_report(reports, RPT_ERROR, "No Nodetree in Scene"); + BKE_report(reports, RPT_ERROR, "No node tree in Scene"); return 0; } @@ -2089,6 +2096,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; @@ -2201,6 +2209,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie /* note; the way it gets 32 bits rects is weak... */ if (ibuf->rect == NULL) { ibuf->rect = MEM_mapallocN(sizeof(int) * rres.rectx * rres.recty, "temp 32 bits rect"); + ibuf->mall |= IB_rect; RE_ResultGet32(re, ibuf->rect); do_free = TRUE; } @@ -2214,6 +2223,7 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie if (do_free) { MEM_freeN(ibuf->rect); ibuf->rect = NULL; + ibuf->mall &= ~IB_rect; } /* imbuf knows which rects are not part of ibuf */ @@ -2434,6 +2444,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); @@ -2478,6 +2489,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/pointdensity.c b/source/blender/render/intern/source/pointdensity.c index 49c2bf1d053..f8462dcd888 100644 --- a/source/blender/render/intern/source/pointdensity.c +++ b/source/blender/render/intern/source/pointdensity.c @@ -36,6 +36,7 @@ #include "BLI_math.h" #include "BLI_blenlib.h" +#include "BLI_noise.h" #include "BLI_kdopbvh.h" #include "BLI_utildefines.h" @@ -405,7 +406,7 @@ static void init_pointdensityrangedata(PointDensity *pd, PointDensityRangeData * } -int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) +int pointdensitytex(Tex *tex, const float texvec[3], TexResult *texres) { int retval = TEX_INT; PointDensity *pd = tex->pd; @@ -481,7 +482,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) case TEX_PD_COLOR_PARTAGE: if (pd->coba) { if (do_colorband(pd->coba, age, col)) { - texres->talpha= 1; + texres->talpha = TRUE; copy_v3_v3(&texres->tr, col); texres->tin *= col[3]; texres->ta = texres->tin; @@ -494,7 +495,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) if (pd->coba) { if (do_colorband(pd->coba, speed, col)) { - texres->talpha= 1; + texres->talpha = TRUE; copy_v3_v3(&texres->tr, col); texres->tin *= col[3]; texres->ta = texres->tin; @@ -503,7 +504,7 @@ int pointdensitytex(Tex *tex, float *texvec, TexResult *texres) break; } case TEX_PD_COLOR_PARTVEL: - texres->talpha= 1; + texres->talpha = TRUE; mul_v3_fl(vec, pd->speed_scale); copy_v3_v3(&texres->tr, vec); texres->ta = texres->tin; diff --git a/source/blender/render/intern/source/rayshade.c b/source/blender/render/intern/source/rayshade.c index aa35d73f3b5..260a80d70e9 100644 --- a/source/blender/render/intern/source/rayshade.c +++ b/source/blender/render/intern/source/rayshade.c @@ -2532,7 +2532,7 @@ void ray_shadow(ShadeInput *shi, LampRen *lar, float shadfac[4]) #if 0 /* only when face points away from lamp, in direction of lamp, trace ray and find first exit point */ -static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float *co) +static void ray_translucent(ShadeInput *shi, LampRen *lar, float *distfac, float co[3]) { Isect isec; float lampco[3]; diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c index 982f7e7d824..167e91272e2 100644 --- a/source/blender/render/intern/source/render_texture.c +++ b/source/blender/render/intern/source/render_texture.c @@ -35,6 +35,7 @@ #include "BLI_blenlib.h" #include "BLI_math.h" +#include "BLI_noise.h" #include "BLI_rand.h" #include "BLI_utildefines.h" @@ -184,7 +185,7 @@ static void tex_normal_derivate(Tex *tex, TexResult *texres) -static int blend(Tex *tex, float *texvec, TexResult *texres) +static int blend(Tex *tex, const float texvec[3], TexResult *texres) { float x, y, t; @@ -236,7 +237,7 @@ static int blend(Tex *tex, float *texvec, TexResult *texres) /* newnoise: all noisebased types now have different noisebases to choose from */ -static int clouds(Tex *tex, float *texvec, TexResult *texres) +static int clouds(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -331,7 +332,7 @@ static float wood_int(Tex *tex, float x, float y, float z) return wi; } -static int wood(Tex *tex, float *texvec, TexResult *texres) +static int wood(Tex *tex, const float texvec[3], TexResult *texres) { int rv=TEX_INT; @@ -382,7 +383,7 @@ static float marble_int(Tex *tex, float x, float y, float z) return mi; } -static int marble(Tex *tex, float *texvec, TexResult *texres) +static int marble(Tex *tex, const float texvec[3], TexResult *texres) { int rv=TEX_INT; @@ -406,7 +407,7 @@ static int marble(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ -static int magic(Tex *tex, float *texvec, TexResult *texres) +static int magic(Tex *tex, const float texvec[3], TexResult *texres) { float x, y, z, turb=1.0; int n; @@ -482,7 +483,7 @@ static int magic(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: stucci also modified to use different noisebasis */ -static int stucci(Tex *tex, float *texvec, TexResult *texres) +static int stucci(Tex *tex, const float texvec[3], TexResult *texres) { float nor[3], b2, ofs; int retval= TEX_INT; @@ -524,7 +525,7 @@ static int stucci(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: musgrave terrain noise types */ -static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_mFractalOrfBmTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float (*mgravefunc)(float, float, float, float, float, float, int); @@ -554,7 +555,7 @@ static float mg_mFractalOrfBmTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_ridgedOrHybridMFTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float (*mgravefunc)(float, float, float, float, float, float, float, float, int); @@ -585,7 +586,7 @@ static float mg_ridgedOrHybridMFTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_HTerrainTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -610,7 +611,7 @@ static float mg_HTerrainTex(Tex *tex, float *texvec, TexResult *texres) } -static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres) +static float mg_distNoiseTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; @@ -639,7 +640,7 @@ static float mg_distNoiseTex(Tex *tex, float *texvec, TexResult *texres) /* ------------------------------------------------------------------------- */ /* newnoise: Voronoi texture type, probably the slowest, especially with minkovsky, bumpmapping, could be done another way */ -static float voronoiTex(Tex *tex, float *texvec, TexResult *texres) +static float voronoiTex(Tex *tex, const float texvec[3], TexResult *texres) { int rv = TEX_INT; float da[4], pa[12]; /* distance and point coordinate arrays of 4 nearest neighbors */ @@ -868,7 +869,7 @@ static int cubemap_ob(Object *ob, const float n[3], float x, float y, float z, f /* ------------------------------------------------------------------------- */ -static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], float *dxt, float *dyt) +static void do_2d_mapping(MTex *mtex, float texvec[3], VlakRen *vlr, const float n[3], float dxt[3], float dyt[3]) { Tex *tex; Object *ob= NULL; @@ -884,15 +885,15 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], if (R.osa==0) { if (wrap==MTEX_FLAT) { - fx = (t[0] + 1.0f) / 2.0f; - fy = (t[1] + 1.0f) / 2.0f; + fx = (texvec[0] + 1.0f) / 2.0f; + fy = (texvec[1] + 1.0f) / 2.0f; } - else if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]); - else if (wrap==MTEX_SPHERE) map_to_sphere(&fx, &fy, t[0], t[1], t[2]); + else if (wrap == MTEX_TUBE) map_to_tube( &fx, &fy, texvec[0], texvec[1], texvec[2]); + else if (wrap == MTEX_SPHERE) map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]); else { - if (texco==TEXCO_OBJECT) cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); - else if (texco==TEXCO_GLOB) cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); - else cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); + if (texco == TEXCO_OBJECT) cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else if (texco == TEXCO_GLOB) cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy); } /* repeat */ @@ -932,14 +933,14 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], fy= tex->cropymin+ fy*fac1; } - t[0]= fx; - t[1]= fy; + texvec[0]= fx; + texvec[1]= fy; } else { if (wrap==MTEX_FLAT) { - fx= (t[0] + 1.0f) / 2.0f; - fy= (t[1] + 1.0f) / 2.0f; + fx= (texvec[0] + 1.0f) / 2.0f; + fy= (texvec[1] + 1.0f) / 2.0f; dxt[0]/= 2.0f; dxt[1]/= 2.0f; dxt[2]/= 2.0f; @@ -950,29 +951,36 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], else if (ELEM(wrap, MTEX_TUBE, MTEX_SPHERE)) { /* exception: the seam behind (y<0.0) */ ok= 1; - if (t[1]<=0.0f) { - fx= t[0]+dxt[0]; - fy= t[0]+dyt[0]; - if (fx>=0.0f && fy>=0.0f && t[0]>=0.0f); - else if (fx<=0.0f && fy<=0.0f && t[0]<=0.0f); - else ok= 0; + if (texvec[1]<=0.0f) { + fx= texvec[0]+dxt[0]; + fy= texvec[0]+dyt[0]; + if (fx>=0.0f && fy>=0.0f && texvec[0]>=0.0f) { + /* pass */ + } + else if (fx<=0.0f && fy<=0.0f && texvec[0]<=0.0f) { + /* pass */ + } + else { + ok = 0; + } } + if (ok) { if (wrap==MTEX_TUBE) { - map_to_tube(area, area+1, t[0], t[1], t[2]); - map_to_tube(area + 2, area + 3, t[0] + dxt[0], t[1] + dxt[1], t[2] + dxt[2]); - map_to_tube(area + 4, area + 5, t[0] + dyt[0], t[1] + dyt[1], t[2] + dyt[2]); + map_to_tube(area, area+1, texvec[0], texvec[1], texvec[2]); + map_to_tube(area + 2, area + 3, texvec[0] + dxt[0], texvec[1] + dxt[1], texvec[2] + dxt[2]); + map_to_tube(area + 4, area + 5, texvec[0] + dyt[0], texvec[1] + dyt[1], texvec[2] + dyt[2]); } else { - map_to_sphere(area, area+1, t[0], t[1], t[2]); - map_to_sphere(area + 2, area + 3, t[0] + dxt[0], t[1] + dxt[1], t[2] + dxt[2]); - map_to_sphere(area + 4, area + 5, t[0] + dyt[0], t[1] + dyt[1], t[2] + dyt[2]); + map_to_sphere(area, area+1, texvec[0], texvec[1], texvec[2]); + map_to_sphere(area + 2, area + 3, texvec[0] + dxt[0], texvec[1] + dxt[1], texvec[2] + dxt[2]); + map_to_sphere(area + 4, area + 5, texvec[0] + dyt[0], texvec[1] + dyt[1], texvec[2] + dyt[2]); } areaflag= 1; } else { - if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, t[0], t[1], t[2]); - else map_to_sphere(&fx, &fy, t[0], t[1], t[2]); + if (wrap==MTEX_TUBE) map_to_tube( &fx, &fy, texvec[0], texvec[1], texvec[2]); + else map_to_sphere(&fx, &fy, texvec[0], texvec[1], texvec[2]); dxt[0]/= 2.0f; dxt[1]/= 2.0f; dyt[0]/= 2.0f; @@ -981,9 +989,9 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], } else { - if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, t[0], t[1], t[2], &fx, &fy); - else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, t[0], t[1], t[2], &fx, &fy); - else proj = cubemap(mtex, vlr, n, t[0], t[1], t[2], &fx, &fy); + if (texco==TEXCO_OBJECT) proj = cubemap_ob(ob, n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else if (texco==TEXCO_GLOB) proj = cubemap_glob(n, texvec[0], texvec[1], texvec[2], &fx, &fy); + else proj = cubemap(mtex, vlr, n, texvec[0], texvec[1], texvec[2], &fx, &fy); if (proj==1) { SWAP(float, dxt[1], dxt[2]); @@ -1083,117 +1091,117 @@ static void do_2d_mapping(MTex *mtex, float *t, VlakRen *vlr, const float n[3], dyt[1]*= fac1; } - t[0]= fx; - t[1]= fy; + texvec[0]= fx; + texvec[1]= fy; } } /* ************************************** */ -static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output) +static int multitex(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, const short thread, short which_output) { float tmpvec[3]; - int retval=0; /* return value, int:0, col:1, nor:2, everything:3 */ + int retval = 0; /* return value, int:0, col:1, nor:2, everything:3 */ - texres->talpha= 0; /* is set when image texture returns alpha (considered premul) */ + texres->talpha = FALSE; /* is set when image texture returns alpha (considered premul) */ if (tex->use_nodes && tex->nodetree) { retval = ntreeTexExecTree(tex->nodetree, texres, texvec, dxt, dyt, osatex, thread, - tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL); + tex, which_output, R.r.cfra, (R.r.scemode & R_TEXNODE_PREVIEW) != 0, NULL, NULL); } - else - switch (tex->type) { - - case 0: - texres->tin= 0.0f; - return 0; - case TEX_CLOUDS: - retval= clouds(tex, texvec, texres); - break; - case TEX_WOOD: - retval= wood(tex, texvec, texres); - break; - case TEX_MARBLE: - retval= marble(tex, texvec, texres); - break; - case TEX_MAGIC: - retval= magic(tex, texvec, texres); - break; - case TEX_BLEND: - retval= blend(tex, texvec, texres); - break; - case TEX_STUCCI: - retval= stucci(tex, texvec, texres); - break; - case TEX_NOISE: - retval= texnoise(tex, texres); - break; - case TEX_IMAGE: - if (osatex) retval= imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres); - else retval= imagewrap(tex, tex->ima, NULL, texvec, texres); - BKE_image_tag_time(tex->ima); /* tag image as having being used */ - break; - case TEX_ENVMAP: - retval= envmaptex(tex, texvec, dxt, dyt, osatex, texres); - break; - case TEX_MUSGRAVE: - /* newnoise: musgrave types */ - - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - switch (tex->stype) { - case TEX_MFRACTAL: - case TEX_FBM: - retval= mg_mFractalOrfBmTex(tex, tmpvec, texres); - break; - case TEX_RIDGEDMF: - case TEX_HYBRIDMF: - retval= mg_ridgedOrHybridMFTex(tex, tmpvec, texres); - break; - case TEX_HTERRAIN: - retval= mg_HTerrainTex(tex, tmpvec, texres); - break; + else { + switch (tex->type) { + case 0: + texres->tin= 0.0f; + return 0; + case TEX_CLOUDS: + retval = clouds(tex, texvec, texres); + break; + case TEX_WOOD: + retval = wood(tex, texvec, texres); + break; + case TEX_MARBLE: + retval = marble(tex, texvec, texres); + break; + case TEX_MAGIC: + retval = magic(tex, texvec, texres); + break; + case TEX_BLEND: + retval = blend(tex, texvec, texres); + break; + case TEX_STUCCI: + retval = stucci(tex, texvec, texres); + break; + case TEX_NOISE: + retval = texnoise(tex, texres); + break; + case TEX_IMAGE: + if (osatex) retval = imagewraposa(tex, tex->ima, NULL, texvec, dxt, dyt, texres); + else retval = imagewrap(tex, tex->ima, NULL, texvec, texres); + BKE_image_tag_time(tex->ima); /* tag image as having being used */ + break; + case TEX_ENVMAP: + retval = envmaptex(tex, texvec, dxt, dyt, osatex, texres); + break; + case TEX_MUSGRAVE: + /* newnoise: musgrave types */ + + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + switch (tex->stype) { + case TEX_MFRACTAL: + case TEX_FBM: + retval = mg_mFractalOrfBmTex(tex, tmpvec, texres); + break; + case TEX_RIDGEDMF: + case TEX_HYBRIDMF: + retval = mg_ridgedOrHybridMFTex(tex, tmpvec, texres); + break; + case TEX_HTERRAIN: + retval = mg_HTerrainTex(tex, tmpvec, texres); + break; + } + break; + /* newnoise: voronoi type */ + case TEX_VORONOI: + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + retval = voronoiTex(tex, tmpvec, texres); + break; + case TEX_DISTNOISE: + /* ton: added this, for Blender convention reason. + * artificer: added the use of tmpvec to avoid scaling texvec + */ + copy_v3_v3(tmpvec, texvec); + mul_v3_fl(tmpvec, 1.0f / tex->noisesize); + + retval = mg_distNoiseTex(tex, tmpvec, texres); + break; + case TEX_POINTDENSITY: + retval = pointdensitytex(tex, texvec, texres); + break; + case TEX_VOXELDATA: + retval = voxeldatatex(tex, texvec, texres); + break; + case TEX_OCEAN: + retval = ocean_texture(tex, texvec, texres); + break; } - break; - /* newnoise: voronoi type */ - case TEX_VORONOI: - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - retval= voronoiTex(tex, tmpvec, texres); - break; - case TEX_DISTNOISE: - /* ton: added this, for Blender convention reason. - * artificer: added the use of tmpvec to avoid scaling texvec - */ - copy_v3_v3(tmpvec, texvec); - mul_v3_fl(tmpvec, 1.0f/tex->noisesize); - - retval= mg_distNoiseTex(tex, tmpvec, texres); - break; - case TEX_POINTDENSITY: - retval= pointdensitytex(tex, texvec, texres); - break; - case TEX_VOXELDATA: - retval= voxeldatatex(tex, texvec, texres); - break; - case TEX_OCEAN: - retval= ocean_texture(tex, texvec, texres); - break; } if (tex->flag & TEX_COLORBAND) { float col[4]; if (do_colorband(tex->coba, texres->tin, col)) { - texres->talpha= 1; + texres->talpha = TRUE; texres->tr= col[0]; texres->tg= col[1]; texres->tb= col[2]; @@ -1205,7 +1213,8 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, } /* this is called from the shader and texture nodes */ -int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres, short thread, short which_output, ShadeInput *shi, MTex *mtex) +int multitex_nodes(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres, + const short thread, short which_output, ShadeInput *shi, MTex *mtex) { if (tex==NULL) { memset(texres, 0, sizeof(TexResult)); @@ -1221,13 +1230,13 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, if (mtex) { /* we have mtex, use it for 2d mapping images only */ do_2d_mapping(mtex, texvec, shi->vlr, shi->facenor, dxt, dyt); - rgbnor= multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); + rgbnor = multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); if (mtex->mapto & (MAP_COL+MAP_COLSPEC+MAP_COLMIR)) { 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); } } @@ -1257,12 +1266,13 @@ int multitex_nodes(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, return rgbnor; } - else + else { return multitex(tex, texvec, dxt, dyt, osatex, texres, thread, which_output); + } } /* this is called for surface shading */ -static int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, float *dyt, TexResult *texres) +static int multitex_mtex(ShadeInput *shi, MTex *mtex, float texvec[3], float dxt[3], float dyt[3], TexResult *texres) { Tex *tex = mtex->tex; @@ -1279,13 +1289,13 @@ static int multitex_mtex(ShadeInput *shi, MTex *mtex, float *texvec, float *dxt, /* Warning, if the texres's values are not declared zero, check the return value to be sure * the color values are set before using the r/g/b values, otherwise you may use uninitialized values - Campbell */ -int multitex_ext(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex, TexResult *texres) +int multitex_ext(Tex *tex, float texvec[3], float dxt[3], float dyt[3], int osatex, TexResult *texres) { return multitex_nodes(tex, texvec, dxt, dyt, osatex, texres, 0, 0, NULL, NULL); } /* extern-tex doesn't support nodes (ntreeBeginExec() can't be called when rendering is going on) */ -int multitex_ext_safe(Tex *tex, float *texvec, TexResult *texres) +int multitex_ext_safe(Tex *tex, float texvec[3], TexResult *texres) { int use_nodes= tex->use_nodes, retval; @@ -1510,7 +1520,8 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen return in; } -static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, float* dx, float* dy, float* texvec, float* dxt, float* dyt) +static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, + const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3]) { /* new: first swap coords, then map, then trans/scale */ if (tex->type == TEX_IMAGE) { @@ -1542,10 +1553,10 @@ static void texco_mapping(ShadeInput* shi, Tex* tex, MTex* mtex, float* co, floa texvec[0] = mtex->size[0]*(texvec[0] - 0.5f) + mtex->ofs[0] + 0.5f; texvec[1] = mtex->size[1]*(texvec[1] - 0.5f) + mtex->ofs[1] + 0.5f; if (shi->osatex) { - dxt[0] = mtex->size[0]*dxt[0]; - dxt[1] = mtex->size[1]*dxt[1]; - dyt[0] = mtex->size[0]*dyt[0]; - dyt[1] = mtex->size[1]*dyt[1]; + dxt[0] = mtex->size[0] * dxt[0]; + dxt[1] = mtex->size[1] * dxt[1]; + dyt[0] = mtex->size[0] * dyt[0]; + dyt[1] = mtex->size[1] * dyt[1]; } /* problem: repeat-mirror is not a 'repeat' but 'extend' in imagetexture.c */ @@ -1675,7 +1686,8 @@ static void compatible_bump_uv_derivs(CompatibleBump *compat_bump, ShadeInput *s } } -static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt) +static int compatible_bump_compute(CompatibleBump *compat_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, + float Tnor, const float co[3], const float dx[3], const float dy[3], float texvec[3], float dxt[3], float dyt[3]) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ float tco[3], texv[3], cd, ud, vd, du, dv, idu, idv; @@ -1831,7 +1843,9 @@ static void ntap_bump_init(NTapBump *ntap_bump) memset(ntap_bump, 0, sizeof(*ntap_bump)); } -static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, float Tnor, float *co, float *dx, float *dy, float *texvec, float *dxt, float *dyt) +static int ntap_bump_compute(NTapBump *ntap_bump, ShadeInput *shi, MTex *mtex, Tex *tex, TexResult *texres, + float Tnor, const float co[3], const float dx[3], const float dy[3], + float texvec[3], float dxt[3], float dyt[3]) { TexResult ttexr = {0, 0, 0, 0, 0, texres->talpha, NULL}; /* temp TexResult */ @@ -2257,11 +2271,11 @@ void do_material_tex(ShadeInput *shi, Render *re) if (texres.nor && !((tex->type==TEX_IMAGE) && (tex->imaflag & TEX_NORMALMAP))) { if (use_compat_bump) { rgbnor = compatible_bump_compute(&compat_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); + &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); } else if (use_ntap_bump) { rgbnor = ntap_bump_compute(&ntap_bump, shi, mtex, tex, - &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); + &texres, Tnor*stencilTin, co, dx, dy, texvec, dxt, dyt); } else { texco_mapping(shi, tex, mtex, co, dx, dy, texvec, dxt, dyt); @@ -2377,7 +2391,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); } @@ -2445,7 +2459,9 @@ void do_material_tex(ShadeInput *shi, Render *re) copy_v3_v3(nor, texres.nor); - if (mtex->normapspace == MTEX_NSPACE_CAMERA); + if (mtex->normapspace == MTEX_NSPACE_CAMERA) { + /* pass */ + } else if (mtex->normapspace == MTEX_NSPACE_WORLD) { mul_mat3_m4_v3(re->viewmat, nor); } @@ -2651,6 +2667,13 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ mul_m4_v3(shi->obi->duplitexmat, co); } mul_m4_v3(ob->imat_ren, co); + + if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) { + /* use bb vec[0] as min and bb vec[6] as max */ + co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f; + co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f; + co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f; + } } } /* not really orco, but 'local' */ @@ -2663,6 +2686,13 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ Object *ob= shi->obi->ob; copy_v3_v3(co, xyz); mul_m4_v3(ob->imat_ren, co); + + if (mtex->texflag & MTEX_MAPTO_BOUNDS && ob->bb) { + /* use bb vec[0] as min and bb vec[6] as max */ + co[0] = (co[0] - ob->bb->vec[0][0]) / (ob->bb->vec[6][0]-ob->bb->vec[0][0]) * 2.0f - 1.0f; + co[1] = (co[1] - ob->bb->vec[0][1]) / (ob->bb->vec[6][1]-ob->bb->vec[0][1]) * 2.0f - 1.0f; + co[2] = (co[2] - ob->bb->vec[0][2]) / (ob->bb->vec[6][2]-ob->bb->vec[0][2]) * 2.0f - 1.0f; + } } } else if (mtex->texco==TEXCO_GLOB) { @@ -2729,6 +2759,12 @@ void do_volume_tex(ShadeInput *shi, const float *xyz, int mapto_flag, float col_ if ((rgbnor & TEX_RGB) == 0) { copy_v3_v3(tcol, &mtex->r); } + else if (mtex->mapto & MAP_DENSITY) { + copy_v3_v3(tcol, &texres.tr); + if (texres.talpha) { + texres.tin = stencilTin; + } + } else { copy_v3_v3(tcol, &texres.tr); if (texres.talpha) { @@ -2887,7 +2923,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); } @@ -2922,10 +2958,14 @@ void do_halo_tex(HaloRen *har, float xn, float yn, float col_r[4]) } if (mtex->mapto & MAP_ALPHA) { if (rgb) { - if (texres.talpha) texres.tin= texres.ta; - else texres.tin = rgb_to_bw(&texres.tr); + if (texres.talpha) { + texres.tin = texres.ta; + } + else { + texres.tin = rgb_to_bw(&texres.tr); + } } - + col_r[3]*= texres.tin; } } @@ -3102,7 +3142,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); } @@ -3316,7 +3356,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); } diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c index 0d894073cee..0bfbed8e58c 100644 --- a/source/blender/render/intern/source/rendercore.c +++ b/source/blender/render/intern/source/rendercore.c @@ -59,6 +59,7 @@ #include "BKE_main.h" #include "BKE_node.h" #include "BKE_texture.h" +#include "BKE_scene.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -93,7 +94,7 @@ extern struct Render R; /* x and y are current pixels in rect to be rendered */ /* do not normalize! */ -void calc_view_vector(float *view, float x, float y) +void calc_view_vector(float view[3], float x, float y) { view[2]= -ABS(R.clipsta); @@ -271,16 +272,26 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl) har= R.sortedhalos[a]; /* layer test, clip halo with y */ - if ((har->lay & lay)==0); - else if (testrect.ymin > har->maxy); - else if (testrect.ymax < har->miny); + if ((har->lay & lay) == 0) { + /* pass */ + } + else if (testrect.ymin > har->maxy) { + /* pass */ + } + else if (testrect.ymax < har->miny) { + /* pass */ + } else { minx= floor(har->xs-har->rad); maxx= ceil(har->xs+har->rad); - if (testrect.xmin > maxx); - else if (testrect.xmax < minx); + if (testrect.xmin > maxx) { + /* pass */ + } + else if (testrect.xmax < minx) { + /* pass */ + } else { minx= MAX2(minx, testrect.xmin); @@ -980,7 +991,9 @@ static void convert_to_key_alpha(RenderPart *pa, RenderLayer *rl) float *rectf= rlpp[sample]->rectf; for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) { - if (rectf[3] >= 1.0f); + if (rectf[3] >= 1.0f) { + /* pass */ + } else if (rectf[3] > 0.0f) { rectf[0] /= rectf[3]; rectf[1] /= rectf[3]; @@ -1833,16 +1846,23 @@ static void renderhalo_post(RenderResult *rr, float *rectf, HaloRen *har) /* pos har->miny= miny= haloys - har->rad/R.ycor; har->maxy= maxy= haloys + har->rad/R.ycor; - if (maxy<0); - else if (rr->recty<miny); + if (maxy < 0) { + /* pass */ + } + else if (rr->recty < miny) { + /* pass */ + } else { - minx= floor(haloxs-har->rad); - maxx= ceil(haloxs+har->rad); + minx = floor(haloxs - har->rad); + maxx = ceil(haloxs + har->rad); - if (maxx<0); - else if (rr->rectx<minx); + if (maxx < 0) { + /* pass */ + } + else if (rr->rectx < minx) { + /* pass */ + } else { - if (minx<0) minx= 0; if (maxx>=rr->rectx) maxx= rr->rectx-1; if (miny<0) miny= 0; @@ -2099,7 +2119,9 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua copy_v3_v3(nor, shi->vn); - if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA); + if (R.r.bake_normal_space == R_BAKE_SPACE_CAMERA) { + /* pass */ + } else if (R.r.bake_normal_space == R_BAKE_SPACE_TANGENT) { float mat[3][3], imat[3][3]; @@ -2202,7 +2224,8 @@ static void bake_shade(void *handle, Object *ob, ShadeInput *shi, int UNUSED(qua float rgb[3]; copy_v3_v3(rgb, shr.combined); - IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); + if (R.scene_color_manage) + IMB_colormanagement_scene_linear_to_colorspace_v3(rgb, bs->rect_colorspace); rgb_float_to_uchar(col, rgb); } else { @@ -2492,7 +2515,9 @@ static int get_next_bake_face(BakeShade *bs) /* clear image */ if (R.r.bake_flag & R_BAKE_CLEAR) IMB_rectfill(ibuf, (ibuf->planes == R_IMF_PLANES_RGBA) ? vec_alpha : vec_solid); - + + ibuf->userflags |= IB_DISPLAY_BUFFER_INVALID; + /* might be read by UI to set active image for display */ R.bakebuf= ima; } @@ -2630,6 +2655,8 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up Image *ima; int a, vdone = FALSE, use_mask = FALSE, result = BAKE_RESULT_OK; + re->scene_color_manage = BKE_scene_check_color_management_enabled(re->scene); + /* initialize render global */ R= *re; R.bakebuf= NULL; @@ -2712,7 +2739,6 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up RE_bake_ibuf_filter(ibuf, (char *)ibuf->userdata, re->r.bake_filter); ibuf->userflags |= IB_BITMAPDIRTY; - if (ibuf->rect_float) IMB_rect_from_float(ibuf); } } diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c index 6395a04b534..1721741d64d 100644 --- a/source/blender/render/intern/source/renderdatabase.c +++ b/source/blender/render/intern/source/renderdatabase.c @@ -976,10 +976,13 @@ HaloRen *RE_inithalo(Render *re, ObjectRen *obr, Material *ma, if (ma->mtex[0]) { - if ( (ma->mode & MA_HALOTEX) ) har->tex= 1; - else if (har->mat->septex & (1<<0)); /* only 1 level textures */ + if (ma->mode & MA_HALOTEX) { + har->tex = 1; + } + else if (har->mat->septex & (1 << 0)) { + /* only 1 level textures */ + } else { - mtex= ma->mtex[0]; copy_v3_v3(texvec, vec); @@ -1353,40 +1356,42 @@ void RE_makeRenderInstances(Render *re) re->instancetable= newlist; } -int clip_render_object(float boundbox[][3], float *bounds, float winmat[][4]) +int clip_render_object(float boundbox[][3], float bounds[4], float winmat[][4]) { float mat[4][4], vec[4]; - int a, fl, flag= -1; + int a, fl, flag = -1; copy_m4_m4(mat, winmat); - for (a=0; a<8; a++) { + for (a=0; a < 8; a++) { vec[0]= (a & 1)? boundbox[0][0]: boundbox[1][0]; vec[1]= (a & 2)? boundbox[0][1]: boundbox[1][1]; vec[2]= (a & 4)? boundbox[0][2]: boundbox[1][2]; vec[3]= 1.0; mul_m4_v4(mat, vec); - fl= 0; + fl = 0; if (bounds) { - if (vec[0] < bounds[0]*vec[3]) fl |= 1; - else if (vec[0] > bounds[1]*vec[3]) fl |= 2; + if (vec[0] < bounds[0] * vec[3]) fl |= 1; + else if (vec[0] > bounds[1] * vec[3]) fl |= 2; - if (vec[1] > bounds[3]*vec[3]) fl |= 4; - else if (vec[1]< bounds[2]*vec[3]) fl |= 8; + if (vec[1] > bounds[3] * vec[3]) fl |= 4; + else if (vec[1] < bounds[2] * vec[3]) fl |= 8; } else { - if (vec[0] < -vec[3]) fl |= 1; - else if (vec[0] > vec[3]) fl |= 2; + if (vec[0] < -vec[3]) fl |= 1; + else if (vec[0] > vec[3]) fl |= 2; - if (vec[1] > vec[3]) fl |= 4; + if (vec[1] > vec[3]) fl |= 4; else if (vec[1] < -vec[3]) fl |= 8; } - if (vec[2] < -vec[3]) fl |= 16; - else if (vec[2] > vec[3]) fl |= 32; + if (vec[2] < -vec[3]) fl |= 16; + else if (vec[2] > vec[3]) fl |= 32; flag &= fl; - if (flag==0) return 0; + if (flag == 0) { + return 0; + } } return flag; diff --git a/source/blender/render/intern/source/shadeinput.c b/source/blender/render/intern/source/shadeinput.c index ff543b8ce06..36e9f4cb785 100644 --- a/source/blender/render/intern/source/shadeinput.c +++ b/source/blender/render/intern/source/shadeinput.c @@ -87,12 +87,6 @@ extern struct Render R; * */ -#define VECADDISFAC(v1,v3,fac) { \ - *(v1 + 0) += *(v3 + 0) * (fac); \ - *(v1 + 1) += *(v3 + 1) * (fac); \ - *(v1 + 2) += *(v3 + 2) * (fac); \ -} (void)0 - /* initialize material variables in shadeinput, * doing inverse gamma correction where applicable */ void shade_input_init_material(ShadeInput *shi) @@ -121,13 +115,13 @@ void shade_material_loop(ShadeInput *shi, ShadeResult *shr) shi->depth--; /* a couple of passes */ - VECADDISFAC(shr->combined, shr_t.combined, fac); + madd_v3_v3fl(shr->combined, shr_t.combined, fac); if (shi->passflag & SCE_PASS_SPEC) - VECADDISFAC(shr->spec, shr_t.spec, fac); + madd_v3_v3fl(shr->spec, shr_t.spec, fac); if (shi->passflag & SCE_PASS_DIFFUSE) - VECADDISFAC(shr->diff, shr_t.diff, fac); + madd_v3_v3fl(shr->diff, shr_t.diff, fac); if (shi->passflag & SCE_PASS_SHADOW) - VECADDISFAC(shr->shad, shr_t.shad, fac); + madd_v3_v3fl(shr->shad, shr_t.shad, fac); negate_v3(shi->vn); negate_v3(shi->facenor); diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c index 6742244ea61..100cbd416e0 100644 --- a/source/blender/render/intern/source/shadeoutput.c +++ b/source/blender/render/intern/source/shadeoutput.c @@ -123,30 +123,45 @@ float mistfactor(float zcor, float const co[3]) { float fac, hi; - fac= zcor - R.wrld.miststa; /* zcor is calculated per pixel */ + fac = zcor - R.wrld.miststa; /* zcor is calculated per pixel */ /* fac= -co[2]-R.wrld.miststa; */ - if (fac>0.0f) { - if (fac< R.wrld.mistdist) { + if (fac > 0.0f) { + if (fac < R.wrld.mistdist) { - fac= (fac/(R.wrld.mistdist)); + fac = (fac / R.wrld.mistdist); - if (R.wrld.mistype==0) fac*= fac; - else if (R.wrld.mistype==1); - else fac= sqrt(fac); + if (R.wrld.mistype == 0) { + fac *= fac; + } + else if (R.wrld.mistype == 1) { + /* pass */ + } + else { + fac = sqrt(fac); + } + } + else { + fac = 1.0f; } - else fac= 1.0f; } - else fac= 0.0f; + else { + fac = 0.0f; + } /* height switched off mist */ if (R.wrld.misthi!=0.0f && fac!=0.0f) { /* at height misthi the mist is completely gone */ - hi= R.viewinv[0][2]*co[0]+R.viewinv[1][2]*co[1]+R.viewinv[2][2]*co[2]+R.viewinv[3][2]; + hi = R.viewinv[0][2] * co[0] + + R.viewinv[1][2] * co[1] + + R.viewinv[2][2] * co[2] + + R.viewinv[3][2]; - if (hi>R.wrld.misthi) fac= 0.0f; + if (hi > R.wrld.misthi) { + fac = 0.0f; + } else if (hi>0.0f) { hi= (R.wrld.misthi-hi)/R.wrld.misthi; fac*= hi*hi; @@ -453,9 +468,10 @@ static float area_lamp_energy(float (*area)[3], const float co[3], const float v /* cross product */ #define CROSS(dest, a, b) \ - { dest[0]= a[1] * b[2] - a[2] * b[1]; \ - dest[1]= a[2] * b[0] - a[0] * b[2]; \ - dest[2]= a[0] * b[1] - a[1] * b[0]; \ + { \ + dest[0]= a[1] * b[2] - a[2] * b[1]; \ + dest[1]= a[2] * b[0] - a[0] * b[2]; \ + dest[2]= a[0] * b[1] - a[1] * b[0]; \ } (void)0 CROSS(cross[0], vec[0], vec[1]); @@ -1351,7 +1367,9 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int /* this complex construction screams for a nicer implementation! (ton) */ if (R.r.mode & R_SHADOW) { if (ma->mode & MA_SHADOW) { - if (lar->type==LA_HEMI || lar->type==LA_AREA); + if (lar->type == LA_HEMI || lar->type == LA_AREA) { + /* pass */ + } else if ((ma->mode & MA_RAYBIAS) && (lar->mode & LA_SHAD_RAY) && (vlr->flag & R_SMOOTH)) { float thresh= shi->obr->ob->smoothresh; if (inp>thresh) @@ -1466,8 +1484,10 @@ static void shade_one_light(LampRen *lar, ShadeInput *shi, ShadeResult *shr, int if (shadfac[3]>0.0f && shi->spec!=0.0f && !(lar->mode & LA_NO_SPEC) && !(lar->mode & LA_ONLYSHADOW)) { - if (!(passflag & (SCE_PASS_COMBINED|SCE_PASS_SPEC))); - else if (lar->type==LA_HEMI) { + if (!(passflag & (SCE_PASS_COMBINED | SCE_PASS_SPEC))) { + /* pass */ + } + else if (lar->type == LA_HEMI) { float t; /* hemi uses no spec shaders (yet) */ diff --git a/source/blender/render/intern/source/sss.c b/source/blender/render/intern/source/sss.c index 69e738e840d..77d68e6c85a 100644 --- a/source/blender/render/intern/source/sss.c +++ b/source/blender/render/intern/source/sss.c @@ -238,7 +238,9 @@ static void approximate_Rd_rgb(ScatterSettings **ss, float rr, float *rd) float indexf, t, idxf; int index; - if (rr > (RD_TABLE_RANGE_2*RD_TABLE_RANGE_2)); + if (rr > (RD_TABLE_RANGE_2 * RD_TABLE_RANGE_2)) { + /* pass */ + } else if (rr > RD_TABLE_RANGE) { rr= sqrt(rr); indexf= rr*(RD_TABLE_SIZE/RD_TABLE_RANGE_2); @@ -379,7 +381,7 @@ static void add_radiance(ScatterTree *tree, float *frontrad, float *backrad, flo } } -static void traverse_octree(ScatterTree *tree, ScatterNode *node, float *co, int self, ScatterResult *result) +static void traverse_octree(ScatterTree *tree, ScatterNode *node, const float co[3], int self, ScatterResult *result) { float sub[3], dist; int i, index = 0; @@ -430,7 +432,7 @@ static void traverse_octree(ScatterTree *tree, ScatterNode *node, float *co, int } } -static void compute_radiance(ScatterTree *tree, float *co, float *rad) +static void compute_radiance(ScatterTree *tree, const float co[3], float *rad) { ScatterResult result; float rdsum[3], backrad[3], backrdsum[3]; diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c index 94e94b98d26..1288b0305b1 100644 --- a/source/blender/render/intern/source/sunsky.c +++ b/source/blender/render/intern/source/sunsky.c @@ -146,7 +146,7 @@ static float PerezFunction(struct SunSky *sunsky, const float *lam, float theta, * sun_size, controls sun's size * back_scatter, controls back scatter light * */ -void InitSunSky(struct SunSky *sunsky, float turb, float *toSun, float horizon_brightness, +void InitSunSky(struct SunSky *sunsky, float turb, const float toSun[3], float horizon_brightness, float spread, float sun_brightness, float sun_size, float back_scatter, float skyblendfac, short skyblendtype, float sky_exposure, float sky_colorspace) { diff --git a/source/blender/render/intern/source/texture_ocean.c b/source/blender/render/intern/source/texture_ocean.c index b2bc635cba7..a7547479093 100644 --- a/source/blender/render/intern/source/texture_ocean.c +++ b/source/blender/render/intern/source/texture_ocean.c @@ -55,7 +55,7 @@ extern struct Render R; /* ***** actual texture sampling ***** */ -int ocean_texture(Tex *tex, float *texvec, TexResult *texres) +int ocean_texture(Tex *tex, const float texvec[2], TexResult *texres) { OceanTex *ot = tex->ot; ModifierData *md; diff --git a/source/blender/render/intern/source/volume_precache.c b/source/blender/render/intern/source/volume_precache.c index 8a92695a15e..fb7ea38ef68 100644 --- a/source/blender/render/intern/source/volume_precache.c +++ b/source/blender/render/intern/source/volume_precache.c @@ -92,7 +92,7 @@ static int intersect_outside_volume(RayObject *tree, Isect *isect, float *offset } /* Uses ray tracing to check if a point is inside or outside an ObjectInstanceRen */ -static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), float *co) +static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), const float co[3]) { Isect isect= {{0}}; float dir[3] = {0.0f, 0.0f, 1.0f}; @@ -118,7 +118,7 @@ static int point_inside_obi(RayObject *tree, ObjectInstanceRen *UNUSED(obi), flo } /* find the bounding box of an objectinstance in global space */ -void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float *bbmin, float *bbmax) +void global_bounds_obi(Render *re, ObjectInstanceRen *obi, float bbmin[3], float bbmax[3]) { ObjectRen *obr = obi->obr; VolumePrecache *vp = obi->volume_precache; @@ -826,7 +826,7 @@ void free_volume_precache(Render *re) BLI_freelistN(&re->volumes); } -int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, float *co) +int point_inside_volume_objectinstance(Render *re, ObjectInstanceRen *obi, const float co[3]) { RayObject *tree; int inside=0; diff --git a/source/blender/render/intern/source/voxeldata.c b/source/blender/render/intern/source/voxeldata.c index d73171648fb..7eccacb816d 100644 --- a/source/blender/render/intern/source/voxeldata.c +++ b/source/blender/render/intern/source/voxeldata.c @@ -227,69 +227,102 @@ static void init_frame_smoke(VoxelData *vd, float cfra) /* draw code for smoke */ if ((md = (ModifierData *)modifiers_findByType(ob, eModifierType_Smoke))) { SmokeModifierData *smd = (SmokeModifierData *)md; - + SmokeDomainSettings *sds = smd->domain; - if (smd->domain && smd->domain->fluid) { - if (cfra < smd->domain->point_cache[0]->startframe) + if (sds && sds->fluid) { + if (cfra < sds->point_cache[0]->startframe) ; /* don't show smoke before simulation starts, this could be made an option in the future */ else if (vd->smoked_type == TEX_VD_SMOKEHEAT) { size_t totRes; size_t i; float *heat; - copy_v3_v3_int(vd->resol, smd->domain->res); - totRes = vd_resol_size(vd); + if (!smoke_has_heat(sds->fluid)) return; - /* scaling heat values from -2.0-2.0 to 0.0-1.0 */ + copy_v3_v3_int(vd->resol, sds->res); + totRes = vd_resol_size(vd); vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); + /* get heat data */ + heat = smoke_get_heat(sds->fluid); - - heat = smoke_get_heat(smd->domain->fluid); - + /* scale heat values from -2.0-2.0 to 0.0-1.0 */ for (i = 0; i < totRes; i++) { vd->dataset[i] = (heat[i] + 2.0f) / 4.0f; } - - /* vd->dataset = smoke_get_heat(smd->domain->fluid); */ } else if (vd->smoked_type == TEX_VD_SMOKEVEL) { size_t totRes; size_t i; float *xvel, *yvel, *zvel; - copy_v3_v3_int(vd->resol, smd->domain->res); + copy_v3_v3_int(vd->resol, sds->res); totRes = vd_resol_size(vd); - - /* scaling heat values from -2.0-2.0 to 0.0-1.0 */ vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); + /* get velocity data */ + xvel = smoke_get_velocity_x(sds->fluid); + yvel = smoke_get_velocity_y(sds->fluid); + zvel = smoke_get_velocity_z(sds->fluid); - xvel = smoke_get_velocity_x(smd->domain->fluid); - yvel = smoke_get_velocity_y(smd->domain->fluid); - zvel = smoke_get_velocity_z(smd->domain->fluid); - + /* map velocities between 0 and 0.3f */ for (i = 0; i < totRes; i++) { vd->dataset[i] = sqrt(xvel[i] * xvel[i] + yvel[i] * yvel[i] + zvel[i] * zvel[i]) * 3.0f; } } - else { + else if (vd->smoked_type == TEX_VD_SMOKEFLAME) { size_t totRes; - float *density; + float *flame; - if (smd->domain->flags & MOD_SMOKE_HIGHRES) { - smoke_turbulence_get_res(smd->domain->wt, vd->resol); - density = smoke_turbulence_get_density(smd->domain->wt); + if (sds->flags & MOD_SMOKE_HIGHRES) { + if (!smoke_turbulence_has_fuel(sds->wt)) return; + smoke_turbulence_get_res(sds->wt, vd->resol); + flame = smoke_turbulence_get_flame(sds->wt); } else { - copy_v3_v3_int(vd->resol, smd->domain->res); - density = smoke_get_density(smd->domain->fluid); + if (!smoke_has_fuel(sds->fluid)) return; + copy_v3_v3_int(vd->resol, sds->res); + flame = smoke_get_flame(sds->fluid); + } + + /* always store copy, as smoke internal data can change */ + totRes= vd_resol_size(vd); + vd->dataset = MEM_mapallocN(sizeof(float)*(totRes), "smoke data"); + memcpy(vd->dataset, flame, sizeof(float)*totRes); + } + else { + size_t totCells; + int depth = 4; + vd->data_type = TEX_VD_RGBA_PREMUL; + + /* data resolution */ + if (sds->flags & MOD_SMOKE_HIGHRES) { + smoke_turbulence_get_res(sds->wt, vd->resol); + } + else { + copy_v3_v3_int(vd->resol, sds->res); } /* TODO: is_vd_res_ok(rvd) doesnt check this resolution */ - totRes = vd_resol_size(vd); + totCells = vd_resol_size(vd) * depth; /* always store copy, as smoke internal data can change */ - vd->dataset = MEM_mapallocN(sizeof(float) * (totRes), "smoke data"); - memcpy(vd->dataset, density, sizeof(float) * totRes); + vd->dataset = MEM_mapallocN(sizeof(float) * totCells, "smoke data"); + + if (sds->flags & MOD_SMOKE_HIGHRES) { + if (smoke_turbulence_has_colors(sds->wt)) { + smoke_turbulence_get_rgba(sds->wt, vd->dataset, 1); + } + else { + smoke_turbulence_get_rgba_from_density(sds->wt, sds->active_color, vd->dataset, 1); + } + } + else { + if (smoke_has_colors(sds->fluid)) { + smoke_get_rgba(sds->fluid, vd->dataset, 1); + } + else { + smoke_get_rgba_from_density(sds->fluid, sds->active_color, vd->dataset, 1); + } + } } /* end of fluid condition */ } } @@ -320,6 +353,8 @@ void cache_voxeldata(Tex *tex, int scene_frame) MEM_freeN(vd->dataset); vd->dataset = NULL; } + /* reset data_type */ + vd->data_type = TEX_VD_INTENSITY; if (vd->flag & TEX_VD_STILL) curframe = vd->still_frame; @@ -379,9 +414,11 @@ void make_voxeldata(struct Render *re) int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texres) { - int retval = TEX_INT; VoxelData *vd = tex->vd; - float co[3], offset[3] = {0.5, 0.5, 0.5}; + float co[3], offset[3] = {0.5, 0.5, 0.5}, a; + int retval = (vd->data_type == TEX_VD_RGBA_PREMUL) ? TEX_RGB : TEX_INT; + int depth = (vd->data_type == TEX_VD_RGBA_PREMUL) ? 4 : 1; + int ch; if (vd->dataset == NULL) { texres->tin = 0.0f; @@ -420,29 +457,61 @@ int voxeldatatex(struct Tex *tex, const float texvec[3], struct TexResult *texre break; } } - - switch (vd->interp_type) { - case TEX_VD_NEARESTNEIGHBOR: - texres->tin = BLI_voxel_sample_nearest(vd->dataset, vd->resol, co); - break; - case TEX_VD_LINEAR: - texres->tin = BLI_voxel_sample_trilinear(vd->dataset, vd->resol, co); - break; - case TEX_VD_QUADRATIC: - texres->tin = BLI_voxel_sample_triquadratic(vd->dataset, vd->resol, co); - break; - case TEX_VD_TRICUBIC_CATROM: - case TEX_VD_TRICUBIC_BSPLINE: - texres->tin = BLI_voxel_sample_tricubic(vd->dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); - break; + + for (ch = 0; ch < depth; ch++) { + float *dataset = vd->dataset + ch*vd->resol[0]*vd->resol[1]*vd->resol[2]; + float *result = &texres->tin; + + if (vd->data_type == TEX_VD_RGBA_PREMUL) { + switch (ch) { + case 0: + result = &texres->tr; + break; + case 1: + result = &texres->tg; + break; + case 2: + result = &texres->tb; + break; + } + } + + switch (vd->interp_type) { + case TEX_VD_NEARESTNEIGHBOR: + *result = BLI_voxel_sample_nearest(dataset, vd->resol, co); + break; + case TEX_VD_LINEAR: + *result = BLI_voxel_sample_trilinear(dataset, vd->resol, co); + break; + case TEX_VD_QUADRATIC: + *result = BLI_voxel_sample_triquadratic(dataset, vd->resol, co); + break; + case TEX_VD_TRICUBIC_CATROM: + case TEX_VD_TRICUBIC_BSPLINE: + *result = BLI_voxel_sample_tricubic(dataset, vd->resol, co, (vd->interp_type == TEX_VD_TRICUBIC_BSPLINE)); + break; + } } - + + a = texres->tin; texres->tin *= vd->int_multiplier; BRICONT; - texres->tr = texres->tin; - texres->tg = texres->tin; - texres->tb = texres->tin; + if (vd->data_type == TEX_VD_RGBA_PREMUL) { + /* unmultiply */ + if (a>0.001f) { + texres->tr /= a; + texres->tg /= a; + texres->tb /= a; + } + texres->talpha = 1; + } + else { + texres->tr = texres->tin; + texres->tg = texres->tin; + texres->tb = texres->tin; + } + texres->ta = texres->tin; BRICONTRGB; diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c index bf6962d0087..ba62baae897 100644 --- a/source/blender/render/intern/source/zbuf.c +++ b/source/blender/render/intern/source/zbuf.c @@ -2038,7 +2038,9 @@ static void zmask_rect(int *rectz, int *rectp, int xs, int ys, int neg) MEM_freeN(temprectp); - if (neg); /* z values for negative are already correct */ + if (neg) { + /* z values for negative are already correct */ + } else { /* clear not filled z values */ for (len= xs*ys -1; len>=0; len--) { diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index dae0e9193c2..ffeb7aff6fa 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -29,6 +29,7 @@ set(INC ../blenkernel ../blenlib ../blenloader + ../compositor ../editors/include ../editors/io ../gpu @@ -37,7 +38,6 @@ set(INC ../makesdna ../makesrna ../nodes - ../compositor ../render/extern/include ../../gameengine/BlenderRoutines ../../../intern/elbeem/extern diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 82bd37eb6cc..99d1c14059a 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -540,7 +540,11 @@ typedef struct wmOperatorType { /* verify if the operator can be executed in the current context, note * that the operator might still fail to execute even if this return true */ - int (*poll)(struct bContext *); + int (*poll)(struct bContext *) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; /* optional panel for redo and repeat, autogenerated if not set */ void (*ui)(struct bContext *, struct wmOperator *); @@ -564,7 +568,11 @@ typedef struct wmOperatorType { /* only used for operators defined with python * use to store pointers to python functions */ void *pyop_data; - int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot); + int (*pyop_poll)(struct bContext *, struct wmOperatorType *ot) +#ifdef __GNUC__ + __attribute__((warn_unused_result)) +#endif + ; /* RNA integration */ ExtensionRNA ext; diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 2f238cd22e7..73950bdfa19 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -255,8 +255,12 @@ void wm_event_do_notifiers(bContext *C) for (win = wm->windows.first; win; win = win->next) { /* filter out notifiers */ - if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) ; - else if (note->category == NC_SCENE && note->reference && note->reference != win->screen->scene) ; + if (note->category == NC_SCREEN && note->reference && note->reference != win->screen) { + /* pass */ + } + else if (note->category == NC_SCENE && note->reference && note->reference != win->screen->scene) { + /* pass */ + } else { ScrArea *sa; ARegion *ar; @@ -883,8 +887,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, wm_operator_reports(C, op, retval, (reports != NULL)); } - if (retval & OPERATOR_HANDLED) - ; /* do nothing, wm_operator_exec() has been called somewhere */ + if (retval & OPERATOR_HANDLED) { + /* do nothing, wm_operator_exec() has been called somewhere */ + } else if (retval & OPERATOR_FINISHED) { if (!is_nested_call) { /* not called by py script */ WM_operator_last_properties_store(op); @@ -2919,7 +2924,7 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U event.keymodifier = 0; /* if test_break set, it catches this. XXX Keep global for now? */ - if (event.type == ESCKEY) + if (event.type == ESCKEY && event.val == KM_PRESS) G.is_break = TRUE; wm_event_add(win, &event); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index aab20e5849b..433c447bfd4 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -192,9 +192,12 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* cases 1 and 2 */ if (oldwmlist->first == NULL) { - if (G.main->wm.first) ; /* nothing todo */ - else + if (G.main->wm.first) { + /* nothing todo */ + } + else { wm_add_default(C); + } } else { /* cases 3 and 4 */ @@ -450,9 +453,8 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) if (sce->r.engine[0] && BLI_findstring(&R_engines, sce->r.engine, offsetof(RenderEngineType, idname)) == NULL) { - BKE_reportf(reports, RPT_WARNING, - "Engine not available: '%s' for scene: %s, " - "an addon may need to be installed or enabled", + BKE_reportf(reports, RPT_ERROR, "Engine '%s' not available for scene '%s' " + "(an addon may need to be installed or enabled)", sce->r.engine, sce->id.name + 2); } } @@ -465,17 +467,17 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) else if (retval == BKE_READ_EXOTIC_OK_OTHER) BKE_write_undo(C, "Import file"); else if (retval == BKE_READ_EXOTIC_FAIL_OPEN) { - BKE_reportf(reports, RPT_ERROR, IFACE_("Can't read file: \"%s\", %s."), filepath, - errno ? strerror(errno) : IFACE_("Unable to open the file")); + BKE_reportf(reports, RPT_ERROR, "Cannot read file '%s': %s", filepath, + errno ? strerror(errno) : TIP_("unable to open the file")); } else if (retval == BKE_READ_EXOTIC_FAIL_FORMAT) { - BKE_reportf(reports, RPT_ERROR, IFACE_("File format is not supported in file: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "File format is not supported in file '%s'", filepath); } else if (retval == BKE_READ_EXOTIC_FAIL_PATH) { - BKE_reportf(reports, RPT_ERROR, IFACE_("File path invalid: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "File path '%s' invalid", filepath); } else { - BKE_reportf(reports, RPT_ERROR, IFACE_("Unknown error loading: \"%s\"."), filepath); + BKE_reportf(reports, RPT_ERROR, "Unknown error loading '%s'", filepath); BLI_assert(!"invalid 'retval'"); } @@ -791,7 +793,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re /* send the OnSave event */ for (li = G.main->library.first; li; li = li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { - BKE_reportf(reports, RPT_ERROR, "Can't overwrite used library '%.240s'", filepath); + BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath); return -1; } } diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 9bb3b2a0e69..658a13a8918 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -302,7 +302,7 @@ int WM_init_game(bContext *C) else { ReportTimerInfo *rti; - BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found. Game auto start is not possible."); + BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found, game auto start is not possible"); /* After adding the report to the global list, reset the report timer. */ WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index e4d6b3dd465..8c9d4861a9e 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -79,6 +79,7 @@ #include "BIF_glutil.h" /* for paint cursor */ #include "BLF_api.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" @@ -1161,7 +1162,7 @@ int WM_operator_props_popup(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) if ((op->type->flag & OPTYPE_REGISTER) == 0) { BKE_reportf(op->reports, RPT_ERROR, - "Operator '%s' does not have register enabled, incorrect invoke function.", op->type->idname); + "Operator '%s' does not have register enabled, incorrect invoke function", op->type->idname); return OPERATOR_CANCELLED; } @@ -1192,11 +1193,12 @@ int WM_operator_redo_popup(bContext *C, wmOperator *op) { /* CTX_wm_reports(C) because operator is on stack, not active in event system */ if ((op->type->flag & OPTYPE_REGISTER) == 0) { - BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s' does not have register enabled, incorrect invoke function.", op->type->idname); + BKE_reportf(CTX_wm_reports(C), RPT_ERROR, + "Operator redo '%s' does not have register enabled, incorrect invoke function", op->type->idname); return OPERATOR_CANCELLED; } if (op->type->poll && op->type->poll(C) == 0) { - BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s': wrong context.", op->type->idname); + BKE_reportf(CTX_wm_reports(C), RPT_ERROR, "Operator redo '%s': wrong context", op->type->idname); return OPERATOR_CANCELLED; } @@ -1232,7 +1234,7 @@ static void WM_OT_debug_menu(wmOperatorType *ot) ot->exec = wm_debug_menu_exec; ot->poll = WM_operator_winactive; - RNA_def_int(ot->srna, "debug_value", 0, -10000, 10000, "Debug Value", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "debug_value", 0, SHRT_MIN, SHRT_MAX, "Debug Value", "", -10000, 10000); } @@ -1838,6 +1840,7 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) /* mark all library linked objects to be updated */ recalc_all_library_objects(bmain); + IMB_colormanagement_check_file_config(bmain); /* append, rather than linking */ if ((flag & FILE_LINK) == 0) { @@ -3127,7 +3130,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, /* check flags */ if ((flags & RC_PROP_REQUIRE_BOOL) && (flags & RC_PROP_REQUIRE_FLOAT)) { - BKE_reportf(op->reports, RPT_ERROR, "Property can't be both boolean and float"); + BKE_report(op->reports, RPT_ERROR, "Property cannot be both boolean and float"); return 0; } @@ -3150,7 +3153,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, if (flags & RC_PROP_ALLOW_MISSING) return 1; else { - BKE_reportf(op->reports, RPT_ERROR, "Couldn't resolve path %s", name); + BKE_reportf(op->reports, RPT_ERROR, "Could not resolve path '%s'", name); return 0; } } @@ -3163,8 +3166,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, ((flags & RC_PROP_REQUIRE_FLOAT) && prop_type != PROP_FLOAT)) { MEM_freeN(str); - BKE_reportf(op->reports, RPT_ERROR, - "Property from path %s is not a float", name); + BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' is not a float", name); return 0; } } @@ -3172,8 +3174,7 @@ static int radial_control_get_path(PointerRNA *ctx_ptr, wmOperator *op, /* check property's array length */ if (*r_prop && (len = RNA_property_array_length(r_ptr, *r_prop)) != req_length) { MEM_freeN(str); - BKE_reportf(op->reports, RPT_ERROR, - "Property from path %s has length %d instead of %d", + BKE_reportf(op->reports, RPT_ERROR, "Property from path '%s' has length %d instead of %d", name, len, req_length); return 0; } @@ -3241,8 +3242,7 @@ static int radial_control_get_properties(bContext *C, wmOperator *op) else if (rc->image_id_ptr.data) { /* extra check, pointer must be to an ID */ if (!RNA_struct_is_ID(rc->image_id_ptr.type)) { - BKE_report(op->reports, RPT_ERROR, - "Pointer from path image_id is not an ID"); + BKE_report(op->reports, RPT_ERROR, "Pointer from path image_id is not an ID"); return 0; } } diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c index 35cc1545c40..cf5bce568d5 100644 --- a/source/blender/windowmanager/intern/wm_playanim.c +++ b/source/blender/windowmanager/intern/wm_playanim.c @@ -89,6 +89,8 @@ typedef struct PlayState { short stopped; short go; + int fstep; + /* current picture */ struct PlayAnimPict *picture; @@ -213,7 +215,6 @@ typedef struct PlayAnimPict { static struct ListBase picsbase = {NULL, NULL}; static int fromdisk = FALSE; -static int fstep = 1; static float zoomx = 1.0, zoomy = 1.0; static double ptottime = 0.0, swaptime = 0.04; @@ -229,7 +230,7 @@ static int pupdate_time(void) return (ptottime < 0); } -static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid) +static void playanim_toscreen(PlayAnimPict *picture, struct ImBuf *ibuf, int fontid, int fstep) { if (ibuf == NULL) { @@ -287,7 +288,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) int pic; ibuf = IMB_anim_absolute(anim, 0, IMB_TC_NONE, IMB_PROXY_NONE); if (ibuf) { - playanim_toscreen(NULL, ibuf, fontid); + playanim_toscreen(NULL, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } @@ -390,7 +391,7 @@ static void build_pict_list(char *first, int totframes, int fstep, int fontid) ibuf = IMB_loadiffname(picture->name, picture->IB_flags, NULL); } if (ibuf) { - playanim_toscreen(picture, ibuf, fontid); + playanim_toscreen(picture, ibuf, fontid, fstep); IMB_freeImBuf(ibuf); } pupdate_time(); @@ -446,34 +447,34 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) ps->pingpong = !ps->pingpong; break; case GHOST_kKeyNumpad1: - if (val) swaptime = fstep / 60.0; + if (val) swaptime = ps->fstep / 60.0; break; case GHOST_kKeyNumpad2: - if (val) swaptime = fstep / 50.0; + if (val) swaptime = ps->fstep / 50.0; break; case GHOST_kKeyNumpad3: - if (val) swaptime = fstep / 30.0; + if (val) swaptime = ps->fstep / 30.0; break; case GHOST_kKeyNumpad4: if (g_WS.qual & WS_QUAL_SHIFT) - swaptime = fstep / 24.0; + swaptime = ps->fstep / 24.0; else - swaptime = fstep / 25.0; + swaptime = ps->fstep / 25.0; break; case GHOST_kKeyNumpad5: - if (val) swaptime = fstep / 20.0; + if (val) swaptime = ps->fstep / 20.0; break; case GHOST_kKeyNumpad6: - if (val) swaptime = fstep / 15.0; + if (val) swaptime = ps->fstep / 15.0; break; case GHOST_kKeyNumpad7: - if (val) swaptime = fstep / 12.0; + if (val) swaptime = ps->fstep / 12.0; break; case GHOST_kKeyNumpad8: - if (val) swaptime = fstep / 10.0; + if (val) swaptime = ps->fstep / 10.0; break; case GHOST_kKeyNumpad9: - if (val) swaptime = fstep / 6.0; + if (val) swaptime = ps->fstep / 6.0; break; case GHOST_kKeyLeftArrow: if (val) { @@ -531,10 +532,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) if (val) { if (g_WS.qual & WS_QUAL_SHIFT) { if (ps->curframe_ibuf) - printf(" Name: %s | Speed: %.2f frames/s\n", ps->curframe_ibuf->name, fstep / swaptime); + printf(" Name: %s | Speed: %.2f frames/s\n", ps->curframe_ibuf->name, ps->fstep / swaptime); } else { - swaptime = fstep / 5.0; + swaptime = ps->fstep / 5.0; } } break; @@ -675,7 +676,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void) glPixelZoom(zoomx, zoomy); glEnable(GL_DITHER); ptottime = 0.0; - playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid); + playanim_toscreen(ps->picture, ps->curframe_ibuf, ps->fontid, ps->fstep); break; } @@ -747,6 +748,8 @@ void WM_main_playanim(int argc, const char **argv) ps.picture = NULL; /* resetmap = FALSE */ + ps.fstep = 1; + ps.fontid = -1; while (argc > 1) { @@ -794,8 +797,8 @@ void WM_main_playanim(int argc, const char **argv) argv++; break; case 'j': - fstep = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]))); - swaptime *= fstep; + ps.fstep = MIN2(MAXFRAME, MAX2(1, atoi(argv[2]))); + swaptime *= ps.fstep; argc--; argv++; break; @@ -894,11 +897,11 @@ void WM_main_playanim(int argc, const char **argv) efra = MAXFRAME; } - build_pict_list(filepath, (efra - sfra) + 1, fstep, ps.fontid); + build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); for (i = 2; i < argc; i++) { BLI_strncpy(filepath, argv[i], sizeof(filepath)); - build_pict_list(filepath, (efra - sfra) + 1, fstep, ps.fontid); + build_pict_list(filepath, (efra - sfra) + 1, ps.fstep, ps.fontid); } IMB_freeImBuf(ibuf); @@ -970,7 +973,7 @@ void WM_main_playanim(int argc, const char **argv) while (pupdate_time()) PIL_sleep_ms(1); ptottime -= swaptime; - playanim_toscreen(ps.picture, ibuf, ps.fontid); + playanim_toscreen(ps.picture, ibuf, ps.fontid, ps.fstep); } /* else deleten */ else { printf("error: can't play this image type\n"); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index d0bed4e5965..44827302d7d 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -300,11 +300,9 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) void wm_window_title(wmWindowManager *wm, wmWindow *win) { - /* handle the 'temp' window, only set title when not set before */ if (win->screen && win->screen->temp) { - char *title = GHOST_GetTitle(win->ghostwin); - if (title == NULL || title[0] == 0) - GHOST_SetTitle(win->ghostwin, "Blender"); + /* nothing to do for 'temp' windows, + * because WM_window_open_temp always sets window title */ } else { |