diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-04-01 17:47:19 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2013-04-01 17:47:19 +0400 |
commit | 5524ed9ba2d60331abed47c9df0bc2fcf330b36b (patch) | |
tree | e8380010f140f022b77236af171d97083a294006 | |
parent | 1360bb6fb0bf0c5c14235c47bf1399accbcecc6f (diff) | |
parent | 689f3aa174ff795044a4dab719edf60b7b1f5bd3 (diff) |
Merged changes in the trunk up to revision 55700.
Conflicts resolved:
source/blender/editors/mesh/mesh_intern.h
236 files changed, 5163 insertions, 3525 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 382e0108978..f33bb73e607 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1070,28 +1070,28 @@ elseif(WIN32) set(OPENCOLLADA ${LIBDIR}/opencollada) set(OPENCOLLADA_INCLUDE_DIRS - ${LIBDIR}/opencollada/include/COLLADAStreamWriter/include - ${LIBDIR}/opencollada/include/COLLADABaseUtils/include - ${LIBDIR}/opencollada/include/COLLADAFramework/include - ${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include - ${LIBDIR}/opencollada/include/GeneratedSaxParser/include + ${OPENCOLLADA}/include/opencollada/COLLADAStreamWriter + ${OPENCOLLADA}/include/opencollada/COLLADABaseUtils + ${OPENCOLLADA}/include/opencollada/COLLADAFramework + ${OPENCOLLADA}/include/opencollada/COLLADASaxFrameworkLoader + ${OPENCOLLADA}/include/opencollada/GeneratedSaxParser ) set_lib_path(OPENCOLLADA_LIBPATH "opencollada") set(OPENCOLLADA_LIBRARIES - ${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADASaxFrameworkLoader.lib - ${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADAFramework.lib - ${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADABaseUtils.lib - ${OPENCOLLADA_LIBPATH}/lib/OpenCOLLADAStreamWriter.lib - ${OPENCOLLADA_LIBPATH}/lib/MathMLSolver.lib - ${OPENCOLLADA_LIBPATH}/lib/GeneratedSaxParser.lib - ${OPENCOLLADA_LIBPATH}/lib/xml2.lib - ${OPENCOLLADA_LIBPATH}/lib/buffer.lib - ${OPENCOLLADA_LIBPATH}/lib/ftoa.lib - ${OPENCOLLADA_LIBPATH}/lib/UTF.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADASaxFrameworkLoader.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADAFramework.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADABaseUtils.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/OpenCOLLADAStreamWriter.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/MathMLSolver.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/GeneratedSaxParser.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/xml.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/buffer.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/ftoa.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/UTF.lib ) set(PCRE_LIBRARIES - ${OPENCOLLADA_LIBPATH}/lib/pcre.lib + ${OPENCOLLADA_LIBPATH}/lib/opencollada/pcre.lib ) unset(OPENCOLLADA_LIBPATH) @@ -1292,13 +1292,13 @@ elseif(WIN32) if(WITH_OPENCOLLADA) set(OPENCOLLADA ${LIBDIR}/opencollada) set(OPENCOLLADA_INCLUDE_DIRS - ${LIBDIR}/opencollada/include/COLLADAStreamWriter/include - ${LIBDIR}/opencollada/include/COLLADABaseUtils/include - ${LIBDIR}/opencollada/include/COLLADAFramework/include - ${LIBDIR}/opencollada/include/COLLADASaxFrameworkLoader/include - ${LIBDIR}/opencollada/include/GeneratedSaxParser/include + ${OPENCOLLADA}/include/COLLADAStreamWriter + ${OPENCOLLADA}/include/COLLADABaseUtils + ${OPENCOLLADA}/include/COLLADAFramework + ${OPENCOLLADA}/include/COLLADASaxFrameworkLoader + ${OPENCOLLADA}/include/GeneratedSaxParser ) - set(OPENCOLLADA_LIBPATH ${OPENCOLLADA}/lib ${OPENCOLLADA}/lib) + set(OPENCOLLADA_LIBPATH ${OPENCOLLADA}/lib/opencollada) if(WITH_MINGW64) set(OPENCOLLADA_LIBRARIES OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver pcre buffer ftoa xml) else() diff --git a/GNUmakefile b/GNUmakefile index c1b67c86ed2..c7db7ab947a 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -272,7 +272,9 @@ project_eclipse: check_cppcheck: $(CMAKE_CONFIG) cd $(BUILD_DIR) ; \ - python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py + python3 $(BLENDER_DIR)/build_files/cmake/cmake_static_check_cppcheck.py 2> \ + $(BLENDER_DIR)/check_cppcheck.txt + @echo "written: check_cppcheck.txt" check_clang_array: $(CMAKE_CONFIG) diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 81a12dbf910..85b27365d6e 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -1066,8 +1066,8 @@ compile_OpenCOLLADA() { # XXX For now, always update from latest repo... git pull origin master - # XXX We have to stick to this revision, the next one introduced a change to ExtraHandler' parseElement signature :/ - git checkout c89cf095c40aa2a518b1104c448825eacc92d174 + # Stick to same rev as windows' libs... + git checkout e886e196673222f2f4bc32b936dc96419fff815f git reset --hard # Always refresh the whole build! diff --git a/build_files/buildbot/slave_compile.py b/build_files/buildbot/slave_compile.py index caa4acc4ecd..a8fc05829fb 100644 --- a/build_files/buildbot/slave_compile.py +++ b/build_files/buildbot/slave_compile.py @@ -156,9 +156,9 @@ else: if builder.find('win') != -1: dlls = ('msvcm90.dll', 'msvcp90.dll', 'msvcr90.dll', 'vcomp90.dll', 'Microsoft.VC90.CRT.manifest', 'Microsoft.VC90.OpenMP.manifest') if builder.find('win64') == -1: - dlls_path = 'C:\\b\\redist\\x86' + dlls_path = 'C:\\b\\redist\\x86' else: - dlls_path = 'C:\\b\\redist\\amd64' + dlls_path = 'C:\\b\\redist\\amd64' for dll in dlls: shutil.copyfile(os.path.join(dlls_path, dll), os.path.join(install_dir, dll)) diff --git a/build_files/cmake/cmake_static_check_cppcheck.py b/build_files/cmake/cmake_static_check_cppcheck.py index 2f7ffa5c240..25e39376dd2 100644 --- a/build_files/cmake/cmake_static_check_cppcheck.py +++ b/build_files/cmake/cmake_static_check_cppcheck.py @@ -41,9 +41,9 @@ CHECKER_ARGS = [ # not sure why this is needed, but it is. "-I" + os.path.join(project_source_info.SOURCE_DIR, "extern", "glew", "include"), "--suppress=*:%s/extern/glew/include/GL/glew.h:241" % project_source_info.SOURCE_DIR, - # "--max-configs=1", # speeds up execution + "--max-configs=1", # speeds up execution # "--check-config", # when includes are missing - # "--enable=all", # if you want sixty hundred pedantic suggestions + "--enable=all", # if you want sixty hundred pedantic suggestions ] if USE_QUIET: diff --git a/build_files/scons/config/win32-mingw-config.py b/build_files/scons/config/win32-mingw-config.py index 691a4842625..507768c4207 100644 --- a/build_files/scons/config/win32-mingw-config.py +++ b/build_files/scons/config/win32-mingw-config.py @@ -141,9 +141,9 @@ BF_COLLADA_INC = '${BF_COLLADA}' BF_COLLADA_LIB = 'bf_collada' BF_OPENCOLLADA = LIBDIR + '/opencollada' -BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include' +BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada' BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver expat pcre buffer ftoa' -BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib' +BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada' #Cycles WITH_BF_CYCLES = True diff --git a/build_files/scons/config/win32-vc-config.py b/build_files/scons/config/win32-vc-config.py index 5aa1e7650cc..76d2bb7c525 100644 --- a/build_files/scons/config/win32-vc-config.py +++ b/build_files/scons/config/win32-vc-config.py @@ -139,9 +139,9 @@ BF_COLLADA_INC = '${BF_COLLADA}' BF_COLLADA_LIB = 'bf_collada' BF_OPENCOLLADA = LIBDIR + '/opencollada' -BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include' -BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF' -BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib' +BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada' +BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml pcre buffer ftoa UTF' +BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada' WITH_BF_3DMOUSE = True diff --git a/build_files/scons/config/win64-mingw-config.py b/build_files/scons/config/win64-mingw-config.py index 203d63bb1a1..b817f24da11 100644 --- a/build_files/scons/config/win64-mingw-config.py +++ b/build_files/scons/config/win64-mingw-config.py @@ -138,9 +138,9 @@ BF_COLLADA_INC = '${BF_COLLADA}' BF_COLLADA_LIB = 'bf_collada' BF_OPENCOLLADA = LIBDIR + '/opencollada' -BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include' +BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada' BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser UTF MathMLSolver pcre buffer ftoa xml' -BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib' +BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada' #Cycles WITH_BF_CYCLES = True diff --git a/build_files/scons/config/win64-vc-config.py b/build_files/scons/config/win64-vc-config.py index c2f57dab0a7..18e64bba7d7 100644 --- a/build_files/scons/config/win64-vc-config.py +++ b/build_files/scons/config/win64-vc-config.py @@ -135,9 +135,9 @@ BF_COLLADA_INC = '${BF_COLLADA}' BF_COLLADA_LIB = 'bf_collada' BF_OPENCOLLADA = LIBDIR + '/opencollada' -BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include' -BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml2 pcre buffer ftoa UTF' -BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib' +BF_OPENCOLLADA_INC = '${BF_OPENCOLLADA}/include/opencollada' +BF_OPENCOLLADA_LIB = 'OpenCOLLADAStreamWriter OpenCOLLADASaxFrameworkLoader OpenCOLLADAFramework OpenCOLLADABaseUtils GeneratedSaxParser MathMLSolver xml pcre buffer ftoa UTF' +BF_OPENCOLLADA_LIBPATH = '${BF_OPENCOLLADA}/lib/opencollada' WITH_BF_3DMOUSE = True diff --git a/extern/recastnavigation/recast-capi.cpp b/extern/recastnavigation/recast-capi.cpp index 1cf8ed5546e..1c11d87f639 100644 --- a/extern/recastnavigation/recast-capi.cpp +++ b/extern/recastnavigation/recast-capi.cpp @@ -309,7 +309,7 @@ static inline void swapfunc(char* a, char* b, int n, int swaptype) #define vecswap(a, b, n) if ((n) > 0) swapfunc(a, b, n, swaptype) #define CMP(t, x, y) (cmp((t), (x), (y))) -static inline char * med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk) +static inline char *med3(char *a, char *b, char *c, cmp_t *cmp, void *thunk) { return CMP(thunk, a, b) < 0 ? (CMP(thunk, b, c) < 0 ? b : (CMP(thunk, a, c) < 0 ? c : a )) diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp index 47bfe4e69b9..c359c5ec3e2 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp @@ -41,53 +41,65 @@ extern "C" { #include "ffmpeg_compat.h" } -int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer) +int AUD_FFMPEGReader::decode(AVPacket& packet, AUD_Buffer& buffer) { - // save packet parameters - uint8_t *audio_pkg_data = packet->data; - int audio_pkg_size = packet->size; + AVFrame* frame = NULL; + int got_frame; + int read_length; + uint8_t* orig_data = packet.data; + int orig_size = packet.size; int buf_size = buffer.getSize(); int buf_pos = 0; - int read_length, data_size; - - AVPacket tmp_pkt; - - av_init_packet(&tmp_pkt); - - // as long as there is still data in the package - while(audio_pkg_size > 0) + while(packet.size > 0) { - // resize buffer if needed - if(buf_size - buf_pos < AVCODEC_MAX_AUDIO_FRAME_SIZE) - { - buffer.resize(buf_size + AVCODEC_MAX_AUDIO_FRAME_SIZE, true); - buf_size += AVCODEC_MAX_AUDIO_FRAME_SIZE; - } - - // read samples from the packet - data_size = buf_size - buf_pos; - - tmp_pkt.data = audio_pkg_data; - tmp_pkt.size = audio_pkg_size; + got_frame = 0; - read_length = avcodec_decode_audio3( - m_codecCtx, - (int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos), - &data_size, &tmp_pkt); + if(!frame) + frame = avcodec_alloc_frame(); + else + avcodec_get_frame_defaults(frame); - // read error, next packet! + read_length = avcodec_decode_audio4(m_codecCtx, frame, &got_frame, &packet); if(read_length < 0) break; - buf_pos += data_size; + if(got_frame) + { + int data_size = av_samples_get_buffer_size(NULL, m_codecCtx->channels, frame->nb_samples, m_codecCtx->sample_fmt, 1); + + if(buf_size - buf_pos < data_size) + { + buffer.resize(buf_size + data_size, true); + buf_size += data_size; + } + + if(m_tointerleave) + { + int single_size = data_size / m_codecCtx->channels / frame->nb_samples; + for(int channel = 0; channel < m_codecCtx->channels; channel++) + { + for(int i = 0; i < frame->nb_samples; i++) + { + memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size, + frame->data[channel] + i * single_size, single_size); + } + } + } + else + memcpy(((data_t*)buffer.getBuffer()) + buf_pos, frame->data[1], data_size); - // move packet parameters - audio_pkg_data += read_length; - audio_pkg_size -= read_length; + buf_pos += data_size; + } + packet.size -= read_length; + packet.data += read_length; } + packet.data = orig_data; + packet.size = orig_size; + av_free(frame); + return buf_pos; } @@ -133,11 +145,6 @@ void AUD_FFMPEGReader::init() if(!aCodec) AUD_THROW(AUD_ERROR_FFMPEG, nodecoder_error); -#ifdef FFMPEG_SAMPLE_FMT_S16P_SUPPORTED - if(m_codecCtx->sample_fmt == AV_SAMPLE_FMT_S16P) - m_codecCtx->request_sample_fmt = AV_SAMPLE_FMT_S16; -#endif - if(avcodec_open2(m_codecCtx, aCodec, NULL) < 0) AUD_THROW(AUD_ERROR_FFMPEG, codecopen_error); @@ -145,8 +152,9 @@ void AUD_FFMPEGReader::init() //dump_format(m_formatCtx, 0, NULL, 0); m_specs.channels = (AUD_Channels) m_codecCtx->channels; + m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt); - switch(m_codecCtx->sample_fmt) + switch(av_get_packed_sample_fmt(m_codecCtx->sample_fmt)) { case AV_SAMPLE_FMT_U8: m_convert = AUD_convert_u8_float; @@ -320,7 +328,7 @@ void AUD_FFMPEGReader::seek(int position) if(packet.stream_index == m_stream) { // decode the package - m_pkgbuf_left = decode(&packet, m_pkgbuf); + m_pkgbuf_left = decode(packet, m_pkgbuf); search = false; // check position @@ -405,7 +413,7 @@ void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer) if(packet.stream_index == m_stream) { // decode the package - pkgbuf_pos = decode(&packet, m_pkgbuf); + pkgbuf_pos = decode(packet, m_pkgbuf); // copy to output buffer data_size = AUD_MIN(pkgbuf_pos, left * sample_size); diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h index d5d9fb300ff..377086e2625 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h @@ -112,12 +112,17 @@ private: int64_t m_membufferpos; /** + * Whether the audio data has to be interleaved after reading. + */ + bool m_tointerleave; + + /** * Decodes a packet into the given buffer. * \param packet The AVPacket to decode. * \param buffer The target buffer. * \return The count of read bytes. */ - int decode(AVPacket* packet, AUD_Buffer& buffer); + int decode(AVPacket& packet, AUD_Buffer& buffer); /** * Initializes the object. diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 09db010363e..039fd39fc7d 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -416,7 +416,7 @@ class CyclesCameraSettings(bpy.types.PropertyGroup): default=0.0, step=1, precision=4, - subtype = 'DISTANCE' + subtype='DISTANCE', ) cls.aperture_blades = IntProperty( name="Aperture Blades", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index 0d1437e13e4..ee33bf6572a 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -219,7 +219,7 @@ class CyclesRender_PT_performance(CyclesButtonsPanel, Panel): sub.label(text="Final Render:") sub.prop(rd, "use_persistent_data", text="Persistent Images") - + class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel): bl_label = "OpenGL Render" bl_options = {'DEFAULT_CLOSED'} @@ -230,18 +230,18 @@ class CyclesRender_PT_opengl(CyclesButtonsPanel, Panel): rd = context.scene.render split = layout.split() - + col = split.column() col.prop(rd, "use_antialiasing") sub = col.row() sub.active = rd.use_antialiasing sub.prop(rd, "antialiasing_samples", expand=True) - + col = split.column() col.label(text="Alpha:") col.prop(rd, "alpha_mode", text="") - - + + class CyclesRender_PT_layers(CyclesButtonsPanel, Panel): bl_label = "Layers" bl_options = {'HIDE_HEADER'} @@ -902,8 +902,8 @@ class CyclesTexture_PT_context(CyclesButtonsPanel, Panel): split = layout.split(percentage=0.2) split.label(text="Type:") split.prop(tex, "type", text="") - - + + class CyclesTexture_PT_node(CyclesButtonsPanel, Panel): bl_label = "Node" bl_context = "texture" @@ -932,7 +932,7 @@ class CyclesTexture_PT_mapping(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout - + node = context.texture_node mapping = node.texture_mapping @@ -964,7 +964,7 @@ class CyclesTexture_PT_colors(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout - + node = context.texture_node mapping = node.color_mapping diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp index d10fb99450d..acda90f0b83 100644 --- a/intern/cycles/blender/blender_session.cpp +++ b/intern/cycles/blender/blender_session.cpp @@ -576,7 +576,7 @@ void BlenderSession::update_status_progress() timestatus += ", " + b_rlay_name; timestatus += " | "; - BLI_timestr(total_time, time_str); + BLI_timestr(total_time, time_str, sizeof(time_str)); timestatus += "Elapsed: " + string(time_str) + " | "; if(substatus.size() > 0) diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index bd4852d08e1..747008fc7c4 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -30,7 +30,7 @@ * todo: clean this up ... */ extern "C" { -void BLI_timestr(double _time, char *str); +void BLI_timestr(double _time, char *str, size_t maxlen); void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr); void BKE_image_user_file_path(void *iuser, void *ima, char *path); unsigned char *BKE_image_get_pixels_for_frame(void *image, int frame); diff --git a/intern/cycles/render/graph.cpp b/intern/cycles/render/graph.cpp index af27b46771c..50fee15c231 100644 --- a/intern/cycles/render/graph.cpp +++ b/intern/cycles/render/graph.cpp @@ -365,6 +365,45 @@ void ShaderGraph::remove_proxy_nodes(vector<bool>& removed) } } } + + /* remove unused mix closure input when factor is 0.0 or 1.0 */ + if(node->special_type == SHADER_SPECIAL_TYPE_MIX_CLOSURE) { + MixClosureNode *mix = static_cast<MixClosureNode*>(node); + /* Check for closure links and make sure factor link is disconnected */ + if(mix->outputs[0]->links.size() && mix->inputs[1]->link && mix->inputs[2]->link && !mix->inputs[0]->link) { + + /* Factor 0.0 */ + if(mix->inputs[0]->value.x == 0.0f) { + ShaderOutput *output = mix->inputs[1]->link; + vector<ShaderInput*> inputs = mix->outputs[0]->links; + + foreach(ShaderInput *sock, mix->inputs) + if(sock->link) + disconnect(sock); + + foreach(ShaderInput *input, inputs) { + disconnect(input); + if (output) + connect(output, input); + } + } + /* Factor 1.0 */ + else if (mix->inputs[0]->value.x == 1.0f) { + ShaderOutput *output = mix->inputs[2]->link; + vector<ShaderInput*> inputs = mix->outputs[0]->links; + + foreach(ShaderInput *sock, mix->inputs) + if(sock->link) + disconnect(sock); + + foreach(ShaderInput *input, inputs) { + disconnect(input); + if (output) + connect(output, input); + } + } + } + } } } diff --git a/intern/dualcon/intern/octree.h b/intern/dualcon/intern/octree.h index 6cbdc9fb3d8..544048249de 100644 --- a/intern/dualcon/intern/octree.h +++ b/intern/dualcon/intern/octree.h @@ -374,14 +374,14 @@ class Octree /** * Functions to patch rings in a node */ - Node *patch(Node * node, int st[3], int len, PathList * rings); - Node *patchSplit(Node * node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2); - Node *patchSplitSingle(Node * node, int st[3], int len, PathElement * head, int dir, PathList * &nrings1, PathList * &nrings2); - Node *connectFace(Node * node, int st[3], int len, int dir, PathElement * f1, PathElement * f2); - Node *locateCell(InternalNode * node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen); + Node *patch(Node *node, int st[3], int len, PathList * rings); + Node *patchSplit(Node *node, int st[3], int len, PathList * rings, int dir, PathList * &nrings1, PathList * &nrings2); + Node *patchSplitSingle(Node *node, int st[3], int len, PathElement *head, int dir, PathList * &nrings1, PathList * &nrings2); + Node *connectFace(Node *node, int st[3], int len, int dir, PathElement * f1, PathElement * f2); + Node *locateCell(InternalNode *node, int st[3], int len, int ori[3], int dir, int side, Node * &rleaf, int rst[3], int& rlen); void compressRing(PathElement *& ring); void getFacePoint(PathElement *leaf, int dir, int& x, int& y, float& p, float& q); - LeafNode *patchAdjacent(InternalNode * node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha); + LeafNode *patchAdjacent(InternalNode *node, int len, int st1[3], LeafNode * leaf1, int st2[3], LeafNode * leaf2, int walkdir, int inc, int dir, int side, float alpha); int findPair(PathElement *head, int pos, int dir, PathElement *& pre1, PathElement *& pre2); int getSide(PathElement *e, int pos, int dir); int isEqual(PathElement *e1, PathElement *e2); @@ -412,8 +412,8 @@ class Octree /************************************************************************/ void floodFill(); void clearProcessBits(Node *node, int height); - int floodFill(LeafNode * leaf, int st[3], int len, int height, int threshold); - int floodFill(Node * node, int st[3], int len, int height, int threshold); + int floodFill(LeafNode *leaf, int st[3], int len, int height, int threshold); + int floodFill(Node *node, int st[3], int len, int height, int threshold); /** * Write out polygon file @@ -421,9 +421,9 @@ class Octree void writeOut(); void countIntersection(Node *node, int height, int& nedge, int& ncell, int& nface); - void generateMinimizer(Node * node, int st[3], int len, int height, int& offset); + void generateMinimizer(Node *node, int st[3], int len, int height, int& offset); void computeMinimizer(const LeafNode * leaf, int st[3], int len, - float rvalue[3]) const; + float rvalue[3]) const; /** * Traversal functions to generate polygon model * op: 0 for counting, 1 for writing OBJ, 2 for writing OFF, 3 for writing PLY diff --git a/intern/elbeem/intern/solver_init.cpp b/intern/elbeem/intern/solver_init.cpp index 63ce1570eea..4c398ab9cb4 100644 --- a/intern/elbeem/intern/solver_init.cpp +++ b/intern/elbeem/intern/solver_init.cpp @@ -691,7 +691,8 @@ bool LbmFsgrSolver::initializeSolverMemory() calculateMemreqEstimate( mSizex, mSizey, mSizez, mMaxRefine, mFarFieldSize, &memEstFromFunc, &memEstFine, &memreqStr ); - double memLimit; + bool noLimit = false; + double memLimit = 0.; string memLimStr("-"); if(sizeof(void*)==4) { // 32bit system, limit to 2GB @@ -699,8 +700,9 @@ bool LbmFsgrSolver::initializeSolverMemory() memLimStr = string("2GB"); } else { // 64bit, just take 16GB as limit for now... - memLimit = 16.0* 1024.0*1024.0*1024.0; - memLimStr = string("16GB"); + // memLimit = 16.0* 1024.0*1024.0*1024.0; + // memLimStr = string("16GB"); + noLimit = true; } // restrict max. chunk of 1 mem block to 1GB for windos @@ -724,7 +726,7 @@ bool LbmFsgrSolver::initializeSolverMemory() memBlockAllocProblem = true; } - if(memEstFromFunc>memLimit || memBlockAllocProblem) { + if(!noLimit && (memEstFromFunc>memLimit || memBlockAllocProblem)) { sizeReduction *= 0.9; mSizex = (int)(orgSx * sizeReduction); mSizey = (int)(orgSy * sizeReduction); diff --git a/intern/ffmpeg/ffmpeg_compat.h b/intern/ffmpeg/ffmpeg_compat.h index 8663c96a22e..69e2e014761 100644 --- a/intern/ffmpeg/ffmpeg_compat.h +++ b/intern/ffmpeg/ffmpeg_compat.h @@ -110,6 +110,16 @@ int av_opt_set_double(void *obj, const char *name, double val, int search_flags) #define AV_OPT_TYPE_FLOAT FF_OPT_TYPE_FLOAT #endif +#if ((LIBAVUTIL_VERSION_MAJOR < 51) || (LIBAVUTIL_VERSION_MAJOR == 51) && (LIBAVUTIL_VERSION_MINOR < 54)) +static inline +enum AVSampleFormat av_get_packed_sample_fmt(enum AVSampleFormat sample_fmt) +{ + if (sample_fmt < 0 || sample_fmt >= AV_SAMPLE_FMT_NB) + return AV_SAMPLE_FMT_NONE; + return sample_fmt; +} +#endif + #if ((LIBAVFORMAT_VERSION_MAJOR < 53) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24)) || ((LIBAVFORMAT_VERSION_MAJOR == 53) && (LIBAVFORMAT_VERSION_MINOR < 24) && (LIBAVFORMAT_VERSION_MICRO < 2))) #define avformat_close_input(x) av_close_input_file(*(x)) #endif diff --git a/intern/guardedalloc/MEM_sys_types.h b/intern/guardedalloc/MEM_sys_types.h index 3d43733c569..72563fc988d 100644 --- a/intern/guardedalloc/MEM_sys_types.h +++ b/intern/guardedalloc/MEM_sys_types.h @@ -108,10 +108,6 @@ typedef uint64_t u_int64_t; #include <inttypes.h> #elif defined(FREE_WINDOWS) -#ifndef FREE_WINDOWS64 -/* define htoln here, there must be a syntax error in winsock2.h in MinGW */ -unsigned long __attribute__((__stdcall__)) htonl(unsigned long); -#endif #include <stdint.h> #else @@ -144,4 +140,3 @@ unsigned long __attribute__((__stdcall__)) htonl(unsigned long); #endif #endif /* __MEM_SYS_TYPES_H__ */ - diff --git a/intern/opencolorio/CMakeLists.txt b/intern/opencolorio/CMakeLists.txt index c281a6e7bbb..5680ce79762 100644 --- a/intern/opencolorio/CMakeLists.txt +++ b/intern/opencolorio/CMakeLists.txt @@ -48,10 +48,12 @@ if(WITH_OPENCOLORIO) list(APPEND INC_SYS ${OPENCOLORIO_INCLUDE_DIRS} + ${GLEW_INCLUDE_PATH} ) list(APPEND SRC ocio_impl.cc + ocio_impl_glsl.cc ) if(WIN32 AND NOT MINGW) diff --git a/intern/opencolorio/SConscript b/intern/opencolorio/SConscript index 6e7c467f64f..73a8fd7a2e0 100644 --- a/intern/opencolorio/SConscript +++ b/intern/opencolorio/SConscript @@ -35,10 +35,12 @@ defs = [] if env['WITH_BF_OCIO']: defs.append('WITH_OCIO') incs += ' ' + env['BF_OCIO_INC'] + incs += ' ' + '#/extern/glew/include' if env['OURPLATFORM'] in ('win32-vc', 'win64-vc'): incs += ' ' + env['BF_BOOST_INC'] else: sources.remove('ocio_impl.cc') + sources.remove('ocio_impl_glsl.cc') env.BlenderLib( 'bf_intern_opencolorio', sources, Split(incs), defs, libtype=['extern','player'], priority=[10, 185]) diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc index d01d8d4c8f4..47c648e9cba 100644 --- a/intern/opencolorio/fallback_impl.cc +++ b/intern/opencolorio/fallback_impl.cc @@ -380,3 +380,15 @@ void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr *) void FallbackImpl::matrixTransformScale(float * , float * , const float *) { } + +void FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ +} + +void FallbackImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) +{ +} + +void FallbackImpl::freeGLState(struct OCIO_GLSLDrawState *state_r) +{ +} diff --git a/intern/opencolorio/ocio_capi.cc b/intern/opencolorio/ocio_capi.cc index 4f839a61fad..73d8af295f2 100644 --- a/intern/opencolorio/ocio_capi.cc +++ b/intern/opencolorio/ocio_capi.cc @@ -282,3 +282,18 @@ void OCIO_matrixTransformScale(float * m44, float * offset4, const float *scale4 { impl->matrixTransformScale(m44, offset4, scale4f); } + +void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ + impl->setupGLSLDraw(state_r, processor); +} + +void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state) +{ + impl->finishGLSLDraw(state); +} + +void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state) +{ + impl->freeGLState(state); +} diff --git a/intern/opencolorio/ocio_capi.h b/intern/opencolorio/ocio_capi.h index 19fd8fe643b..3c42e0a1a1e 100644 --- a/intern/opencolorio/ocio_capi.h +++ b/intern/opencolorio/ocio_capi.h @@ -32,6 +32,8 @@ extern "C" { #endif +struct OCIO_GLSLDrawState; + #define OCIO_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name #define OCIO_ROLE_SCENE_LINEAR "scene_linear" @@ -119,6 +121,10 @@ void OCIO_matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void OCIO_matrixTransformScale(float * m44, float * offset4, const float * scale4); +void OCIO_setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); +void OCIO_finishGLSLDraw(struct OCIO_GLSLDrawState *state); +void OCIO_freeOGLState(struct OCIO_GLSLDrawState *state); + #ifdef __cplusplus } #endif diff --git a/intern/opencolorio/ocio_impl.cc b/intern/opencolorio/ocio_impl.cc index b073a038f0d..8803814ce3f 100644 --- a/intern/opencolorio/ocio_impl.cc +++ b/intern/opencolorio/ocio_impl.cc @@ -26,8 +26,16 @@ */ #include <iostream> +#include <sstream> #include <string.h> +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/glew.h> +#endif + #include <OpenColorIO/OpenColorIO.h> using namespace OCIO_NAMESPACE; @@ -50,6 +58,8 @@ using namespace OCIO_NAMESPACE; #define MEM_NEW(type) new(MEM_mallocN(sizeof(type), __func__)) type() #define MEM_DELETE(what, type) if(what) { ((type*)(what))->~type(); MEM_freeN(what); } (void)0 +static const int LUT3D_EDGE_SIZE = 32; + static void OCIO_reportError(const char *err) { std::cerr << "OpenColorIO Error: " << err << std::endl; @@ -541,3 +551,228 @@ void OCIOImpl::matrixTransformScale(float * m44, float * offset4, const float *s { MatrixTransform::Scale(m44, offset4, scale4f); } + +/* **** OpenGL drawing routines using GLSL for color space transform ***** */ + +/* Some of the GLSL transform related functions below are adopted from + * ociodisplay utility of OpenColorIO project which are originally + * + * Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. All Rights Reserved. + */ + +typedef struct OCIO_GLSLDrawState { + bool lut3d_texture_allocated; /* boolean flag indicating whether + * lut texture is allocated + */ + + GLuint lut3d_texture; /* OGL texture ID for 3D LUT */ + + float *lut3d; /* 3D LUT table */ + + /* Cache */ + std::string lut3dcacheid; + std::string shadercacheid; + + /* GLSL stuff */ + GLuint fragShader; + GLuint program; + + /* Previous OpenGL state. */ + GLint last_texture, last_texture_unit; +} OCIO_GLSLDrawState; + +static const char * g_fragShaderText = "" +"\n" +"uniform sampler2D tex1;\n" +"uniform sampler3D tex2;\n" +"\n" +"void main()\n" +"{\n" +" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n" +" gl_FragColor = OCIODisplay(col, tex2);\n" +"}\n"; + +static GLuint compileShaderText(GLenum shaderType, const char *text) +{ + GLuint shader; + GLint stat; + + shader = glCreateShader(shaderType); + glShaderSource(shader, 1, (const GLchar **) &text, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); + + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog(shader, 1000, &len, log); + return 0; + } + + return shader; +} + +static GLuint linkShaders(GLuint fragShader) +{ + if (!fragShader) + return 0; + + GLuint program = glCreateProgram(); + + if (fragShader) + glAttachShader(program, fragShader); + + glLinkProgram(program); + + /* check link */ + { + GLint stat; + glGetProgramiv(program, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog(program, 1000, &len, log); + fprintf(stderr, "Shader link error:\n%s\n", log); + return 0; + } + } + + return program; +} + +static OCIO_GLSLDrawState *allocateOpenGLState(void) +{ + OCIO_GLSLDrawState *state; + + /* Allocate memory for state. */ + state = (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState), + "OCIO OpenGL State struct"); + + /* Call constructors on new memory. */ + new (&state->lut3dcacheid) std::string(""); + new (&state->shadercacheid) std::string(""); + + return state; +} + +/* Ensure LUT texture and array are allocated */ +static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state) +{ + int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE; + + if (state->lut3d_texture_allocated) + return; + + glGenTextures(1, &state->lut3d_texture); + + state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT"); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, + LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, + 0, GL_RGB,GL_FLOAT, &state->lut3d); + + state->lut3d_texture_allocated = true; +} + +/** + * Setup OpenGL contexts for a transform defined by processor using GLSL + * All LUT allocating baking and shader compilation happens here. + * + * Once this function is called, callee could start drawing images + * using regular 2D texture. + * + * When all drawing is finished, finishGLSLDraw shall be called to + * restore OpenGL context to it's pre-GLSL draw state. + */ +void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ + ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor; + + /* Create state if needed. */ + OCIO_GLSLDrawState *state; + if (!*state_r) + *state_r = allocateOpenGLState(); + state = *state_r; + + glGetIntegerv(GL_TEXTURE_2D, &state->last_texture); + glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit); + + ensureLUT3DAllocated(state); + + /* Step 1: Create a GPU Shader Description */ + GpuShaderDesc shaderDesc; + shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0); + shaderDesc.setFunctionName("OCIODisplay"); + shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); + + /* Step 2: Compute the 3D LUT */ + std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc); + if (lut3dCacheID != state->lut3dcacheid) { + state->lut3dcacheid = lut3dCacheID; + ocio_processor->getGpuLut3D(state->lut3d, shaderDesc); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, + LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, + GL_RGB, GL_FLOAT, state->lut3d); + } + + /* Step 3: Compute the Shader */ + std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc); + if (state->program == 0 || shaderCacheID != state->shadercacheid) { + state->shadercacheid = shaderCacheID; + + std::ostringstream os; + os << ocio_processor->getGpuShaderText(shaderDesc) << "\n"; + os << g_fragShaderText; + + if (state->fragShader) + glDeleteShader(state->fragShader); + state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str()); + + if (state->program) + glDeleteProgram(state->program); + + state->program = linkShaders(state->fragShader); + } + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + + glActiveTexture(GL_TEXTURE0); + + glUseProgram(state->program); + glUniform1i(glGetUniformLocation(state->program, "tex1"), 0); + glUniform1i(glGetUniformLocation(state->program, "tex2"), 1); +} + +void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) +{ + glActiveTexture(state->last_texture_unit); + glBindTexture(GL_TEXTURE_2D, state->last_texture); + glUseProgram(0); +} + +void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state) +{ + using std::string; + + if (state->lut3d_texture_allocated) + glDeleteTextures(1, &state->lut3d_texture); + + if (state->lut3d) + MEM_freeN(state->lut3d); + + state->lut3dcacheid.~string(); + state->shadercacheid.~string(); + + MEM_freeN(state); +} diff --git a/intern/opencolorio/ocio_impl.h b/intern/opencolorio/ocio_impl.h index b6bbc912e5b..2a1f88be5f4 100644 --- a/intern/opencolorio/ocio_impl.h +++ b/intern/opencolorio/ocio_impl.h @@ -95,6 +95,10 @@ public: virtual void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt) = 0; virtual void matrixTransformScale(float * m44, float * offset4, const float * scale4) = 0; + + virtual void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) = 0; + virtual void finishGLSLDraw(struct OCIO_GLSLDrawState *state) = 0; + virtual void freeGLState(struct OCIO_GLSLDrawState *state_r) = 0; }; class FallbackImpl : public IOCIOImpl { @@ -164,6 +168,10 @@ public: void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void matrixTransformScale(float * m44, float * offset4, const float * scale4); + + void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); + void finishGLSLDraw(struct OCIO_GLSLDrawState *state); + void freeGLState(struct OCIO_GLSLDrawState *state_r); }; #ifdef WITH_OCIO @@ -234,6 +242,10 @@ public: void matrixTransformRelease(OCIO_MatrixTransformRcPtr *mt); void matrixTransformScale(float * m44, float * offset4, const float * scale4); + + void setupGLSLDraw(struct OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor); + void finishGLSLDraw(struct OCIO_GLSLDrawState *state); + void freeGLState(struct OCIO_GLSLDrawState *state_r); }; #endif diff --git a/intern/opencolorio/ocio_impl_glsl.cc b/intern/opencolorio/ocio_impl_glsl.cc new file mode 100644 index 00000000000..c79593779cf --- /dev/null +++ b/intern/opencolorio/ocio_impl_glsl.cc @@ -0,0 +1,274 @@ +/* + * Adapted from OpenColorIO with this license: + * + * Copyright (c) 2003-2010 Sony Pictures Imageworks Inc., et al. + * All Rights Reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Sony Pictures Imageworks nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * Modifications Copyright 2013, Blender Foundation. + * + * Contributor(s): Sergey Sharybin + * + */ + +#include <sstream> +#include <string.h> + +#ifdef __APPLE__ +#include <OpenGL/gl.h> +#include <OpenGL/glu.h> +#else +#include <GL/glew.h> +#endif + +#include <OpenColorIO/OpenColorIO.h> + +using namespace OCIO_NAMESPACE; + +#include "MEM_guardedalloc.h" + +#include "ocio_impl.h" + +static const int LUT3D_EDGE_SIZE = 32; + + +/* **** OpenGL drawing routines using GLSL for color space transform ***** */ + +typedef struct OCIO_GLSLDrawState { + bool lut3d_texture_allocated; /* boolean flag indicating whether + * lut texture is allocated + */ + + GLuint lut3d_texture; /* OGL texture ID for 3D LUT */ + + float *lut3d; /* 3D LUT table */ + + /* Cache */ + std::string lut3dcacheid; + std::string shadercacheid; + + /* GLSL stuff */ + GLuint fragShader; + GLuint program; + + /* Previous OpenGL state. */ + GLint last_texture, last_texture_unit; +} OCIO_GLSLDrawState; + +static const char * g_fragShaderText = "" +"\n" +"uniform sampler2D tex1;\n" +"uniform sampler3D tex2;\n" +"\n" +"void main()\n" +"{\n" +" vec4 col = texture2D(tex1, gl_TexCoord[0].st);\n" +" gl_FragColor = OCIODisplay(col, tex2);\n" +"}\n"; + +static GLuint compileShaderText(GLenum shaderType, const char *text) +{ + GLuint shader; + GLint stat; + + shader = glCreateShader(shaderType); + glShaderSource(shader, 1, (const GLchar **) &text, NULL); + glCompileShader(shader); + glGetShaderiv(shader, GL_COMPILE_STATUS, &stat); + + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetShaderInfoLog(shader, 1000, &len, log); + return 0; + } + + return shader; +} + +static GLuint linkShaders(GLuint fragShader) +{ + if (!fragShader) + return 0; + + GLuint program = glCreateProgram(); + + if (fragShader) + glAttachShader(program, fragShader); + + glLinkProgram(program); + + /* check link */ + { + GLint stat; + glGetProgramiv(program, GL_LINK_STATUS, &stat); + if (!stat) { + GLchar log[1000]; + GLsizei len; + glGetProgramInfoLog(program, 1000, &len, log); + fprintf(stderr, "Shader link error:\n%s\n", log); + return 0; + } + } + + return program; +} + +static OCIO_GLSLDrawState *allocateOpenGLState(void) +{ + OCIO_GLSLDrawState *state; + + /* Allocate memory for state. */ + state = (OCIO_GLSLDrawState *) MEM_callocN(sizeof(OCIO_GLSLDrawState), + "OCIO OpenGL State struct"); + + /* Call constructors on new memory. */ + new (&state->lut3dcacheid) std::string(""); + new (&state->shadercacheid) std::string(""); + + return state; +} + +/* Ensure LUT texture and array are allocated */ +static void ensureLUT3DAllocated(OCIO_GLSLDrawState *state) +{ + int num_3d_entries = 3 * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE * LUT3D_EDGE_SIZE; + + if (state->lut3d_texture_allocated) + return; + + glGenTextures(1, &state->lut3d_texture); + + state->lut3d = (float *) MEM_callocN(sizeof(float) * num_3d_entries, "OCIO GPU 3D LUT"); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB16F_ARB, + LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, + 0, GL_RGB,GL_FLOAT, &state->lut3d); + + state->lut3d_texture_allocated = true; +} + +/** + * Setup OpenGL contexts for a transform defined by processor using GLSL + * All LUT allocating baking and shader compilation happens here. + * + * Once this function is called, callee could start drawing images + * using regular 2D texture. + * + * When all drawing is finished, finishGLSLDraw shall be called to + * restore OpenGL context to it's pre-GLSL draw state. + */ +void OCIOImpl::setupGLSLDraw(OCIO_GLSLDrawState **state_r, OCIO_ConstProcessorRcPtr *processor) +{ + ConstProcessorRcPtr ocio_processor = *(ConstProcessorRcPtr *) processor; + + /* Create state if needed. */ + OCIO_GLSLDrawState *state; + if (!*state_r) + *state_r = allocateOpenGLState(); + state = *state_r; + + glGetIntegerv(GL_TEXTURE_2D, &state->last_texture); + glGetIntegerv(GL_ACTIVE_TEXTURE, &state->last_texture_unit); + + ensureLUT3DAllocated(state); + + /* Step 1: Create a GPU Shader Description */ + GpuShaderDesc shaderDesc; + shaderDesc.setLanguage(GPU_LANGUAGE_GLSL_1_0); + shaderDesc.setFunctionName("OCIODisplay"); + shaderDesc.setLut3DEdgeLen(LUT3D_EDGE_SIZE); + + /* Step 2: Compute the 3D LUT */ + std::string lut3dCacheID = ocio_processor->getGpuLut3DCacheID(shaderDesc); + if (lut3dCacheID != state->lut3dcacheid) { + state->lut3dcacheid = lut3dCacheID; + ocio_processor->getGpuLut3D(state->lut3d, shaderDesc); + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + glTexSubImage3D(GL_TEXTURE_3D, 0, 0, 0, 0, + LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, LUT3D_EDGE_SIZE, + GL_RGB, GL_FLOAT, state->lut3d); + } + + /* Step 3: Compute the Shader */ + std::string shaderCacheID = ocio_processor->getGpuShaderTextCacheID(shaderDesc); + if (state->program == 0 || shaderCacheID != state->shadercacheid) { + state->shadercacheid = shaderCacheID; + + std::ostringstream os; + os << ocio_processor->getGpuShaderText(shaderDesc) << "\n"; + os << g_fragShaderText; + + if (state->fragShader) + glDeleteShader(state->fragShader); + state->fragShader = compileShaderText(GL_FRAGMENT_SHADER, os.str().c_str()); + + if (state->program) + glDeleteProgram(state->program); + + state->program = linkShaders(state->fragShader); + } + + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_3D, state->lut3d_texture); + + glActiveTexture(GL_TEXTURE0); + + glUseProgram(state->program); + glUniform1i(glGetUniformLocation(state->program, "tex1"), 0); + glUniform1i(glGetUniformLocation(state->program, "tex2"), 1); +} + +void OCIOImpl::finishGLSLDraw(OCIO_GLSLDrawState *state) +{ + glActiveTexture(state->last_texture_unit); + glBindTexture(GL_TEXTURE_2D, state->last_texture); + glUseProgram(0); +} + +void OCIOImpl::freeGLState(struct OCIO_GLSLDrawState *state) +{ + using std::string; + + if (state->lut3d_texture_allocated) + glDeleteTextures(1, &state->lut3d_texture); + + if (state->lut3d) + MEM_freeN(state->lut3d); + + state->lut3dcacheid.~string(); + state->shadercacheid.~string(); + + MEM_freeN(state); +} diff --git a/intern/opennl/superlu/superlu_sys_types.h b/intern/opennl/superlu/superlu_sys_types.h index 80d3da4d243..5685b34f1f4 100644 --- a/intern/opennl/superlu/superlu_sys_types.h +++ b/intern/opennl/superlu/superlu_sys_types.h @@ -98,8 +98,6 @@ typedef unsigned long uintptr_t; #include <inttypes.h> #elif defined(FREE_WINDOWS) -/* define htoln here, there must be a syntax error in winsock2.h in MinGW */ -unsigned long __attribute__((__stdcall__)) htonl(unsigned long); #include <stdint.h> #else diff --git a/intern/utfconv/utf_winfunc.c b/intern/utfconv/utf_winfunc.c index 3d7fb11309a..2ae261b44a8 100644 --- a/intern/utfconv/utf_winfunc.c +++ b/intern/utfconv/utf_winfunc.c @@ -28,12 +28,13 @@ #endif #include "utf_winfunc.h" +#include "utfconv.h" #include <io.h> #include <windows.h> #include <wchar.h> -FILE * ufopen(const char * filename, const char * mode) +FILE *ufopen(const char *filename, const char *mode) { FILE *f = NULL; UTF16_ENCODE(filename); @@ -119,7 +120,7 @@ int umkdir(const char *pathname) return r ? 0 : -1; } -char * u_alloc_getenv(const char *varname) +char *u_alloc_getenv(const char *varname) { char * r = 0; wchar_t * str; diff --git a/intern/utfconv/utf_winfunc.h b/intern/utfconv/utf_winfunc.h index 45f6844af5a..8dd77275dcb 100644 --- a/intern/utfconv/utf_winfunc.h +++ b/intern/utfconv/utf_winfunc.h @@ -23,22 +23,26 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef __UTF_WINFUNC_H__ +#define __UTF_WINFUNC_H__ + #ifndef WIN32 # error "This file can only compile on windows" #endif -#include "utfconv.h" #include <stdio.h> -FILE * ufopen(const char * filename, const char * mode); +FILE *ufopen(const char * filename, const char * mode); int uopen(const char *filename, int oflag, int pmode); int uaccess(const char *filename, int mode); -int urename(const char *oldname, const char *newname ); +int urename(const char *oldname, const char *newname); -char * u_alloc_getenv(const char *varname); +char *u_alloc_getenv(const char *varname); void u_free_getenv(char *val); -int uput_getenv(const char *varname, char * value, size_t buffsize); +int uput_getenv(const char *varname, char *value, size_t buffsize); int uputenv(const char *name, const char *value); int umkdir(const char *pathname); + +#endif /* __UTF_WINFUNC_H__ */ diff --git a/intern/utfconv/utfconv.h b/intern/utfconv/utfconv.h index ada85e274e3..f00f4aeef27 100644 --- a/intern/utfconv/utfconv.h +++ b/intern/utfconv/utfconv.h @@ -23,12 +23,13 @@ * ***** END GPL LICENSE BLOCK ***** */ +#ifndef __UTFCONV_H__ +#define __UTFCONV_H__ + #include <wchar.h> #include <stdio.h> #include <stdlib.h> - - #ifdef __cplusplus extern "C" { #endif @@ -100,3 +101,5 @@ wchar_t *alloc_utf16_from_8(const char *in8, size_t add); #ifdef __cplusplus } #endif + +#endif /* __UTFCONV_H__ */ diff --git a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py index ea162557c95..26b6845530d 100644 --- a/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py +++ b/release/scripts/modules/bl_i18n_utils/bl_extract_messages.py @@ -409,6 +409,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings): import ast bpy_struct = bpy.types.ID.__base__ + i18n_contexts = bpy.app.translations.contexts root_paths = tuple(bpy.utils.resource_path(t) for t in ('USER', 'LOCAL', 'SYSTEM')) def make_rel(path): @@ -445,7 +446,7 @@ def dump_py_messages_from_files(msgs, reports, files, settings): nds_ls.extend(nds) ret = _extract_string_merge(estr_ls, nds_ls) return ret - + def extract_strings_split(node): """ Returns a list args as returned by 'extract_strings()', But split into groups based on separate_nodes, this way @@ -468,20 +469,33 @@ def dump_py_messages_from_files(msgs, reports, files, settings): return [_extract_string_merge(estr_ls, nds_ls) for estr_ls, nds_ls in bag] + i18n_ctxt_ids = {v for v in bpy.app.translations.contexts_C_to_py.values()} def _ctxt_to_ctxt(node): - return extract_strings(node)[0] + # We must try, to some extend, to get contexts from vars instead of only literal strings... + ctxt = extract_strings(node)[0] + if ctxt: + return ctxt + # Basically, we search for attributes matching py context names, for now. + # So non-literal contexts should be used that way: + # i18n_ctxt = bpy.app.translations.contexts + # foobar(text="Foo", text_ctxt=i18n_ctxt.id_object) + if type(node) == ast.Attribute: + if node.attr in i18n_ctxt_ids: + #print(node, node.attr, getattr(i18n_contexts, node.attr)) + return getattr(i18n_contexts, node.attr) + return i18n_contexts.default def _op_to_ctxt(node): opname, _ = extract_strings(node) if not opname: - return settings.DEFAULT_CONTEXT + return i18n_contexts.default op = bpy.ops for n in opname.split('.'): op = getattr(op, n) try: return op.get_rna().bl_rna.translation_context except Exception as e: - default_op_context = bpy.app.translations.contexts.operator_default + default_op_context = i18n_contexts.operator_default print("ERROR: ", str(e)) print(" Assuming default operator context '{}'".format(default_op_context)) return default_op_context @@ -492,7 +506,8 @@ def dump_py_messages_from_files(msgs, reports, files, settings): pgettext_variants = ( ("pgettext", ("_",)), ("pgettext_iface", ("iface_",)), - ("pgettext_tip", ("tip_",)) + ("pgettext_tip", ("tip_",)), + ("pgettext_data", ("data_",)), ) pgettext_variants_args = {"msgid": (0, {"msgctxt": 1})} @@ -858,9 +873,8 @@ def dump_addon_messages(module_name, messages_formats, do_checks, settings): # and make the diff! for key in minus_msgs: - if key == settings.PO_HEADER_KEY: - continue - del msgs[key] + if key != settings.PO_HEADER_KEY: + del msgs[key] if check_ctxt: for key in check_ctxt: @@ -873,7 +887,7 @@ def dump_addon_messages(module_name, messages_formats, do_checks, settings): # get strings from UI layout definitions text="..." args reports["check_ctxt"] = check_ctxt - dump_messages_pytext(msgs, reports, addons, settings, addons_only=True) + dump_py_messages(msgs, reports, {addon}, settings, addons_only=True) print_info(reports, pot) diff --git a/release/scripts/modules/bl_i18n_utils/settings.py b/release/scripts/modules/bl_i18n_utils/settings.py index 31e457151bb..832adc80934 100644 --- a/release/scripts/modules/bl_i18n_utils/settings.py +++ b/release/scripts/modules/bl_i18n_utils/settings.py @@ -240,7 +240,7 @@ PYGETTEXT_KEYWORDS = (() + for it in ("IFACE_", "TIP_", "DATA_", "N_")) + tuple((r"{}\(\s*" + _ctxt_re + r"\s*,\s*" + _msg_re + r"\s*\)").format(it) - for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_DATA_", "CTX_N_")) + + for it in ("CTX_IFACE_", "CTX_TIP_", "CTX_DATA_", "CTX_N_")) + tuple(("{}\\((?:[^\"',]+,){{1,2}}\\s*" + _msg_re + r"\s*(?:\)|,)").format(it) for it in ("BKE_report", "BKE_reportf", "BKE_reports_prepend", "BKE_reports_prependf", @@ -252,7 +252,7 @@ PYGETTEXT_KEYWORDS = (() + tuple(("{}\\((?:[^\"',]+,)\\s*" + _msg_re + r"\s*(?:\)|,)").format(it) for it in ("modifier_setError",)) + - tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" + \ + tuple((r"{}\(\s*" + _msg_re + r"\s*,\s*(?:" + r"\s*,\s*)?(?:".join(_ctxt_re_gen(i) for i in range(PYGETTEXT_MAX_MULTI_CTXT)) + r")?\s*\)").format(it) for it in ("BLF_I18N_MSGID_MULTI_CTXT",)) ) @@ -354,7 +354,7 @@ PARSER_PY_ID = "__PY__" PARSER_PY_MARKER_BEGIN = "\n# ##### BEGIN AUTOGENERATED I18N SECTION #####\n" PARSER_PY_MARKER_END = "\n# ##### END AUTOGENERATED I18N SECTION #####\n" -PARSER_MAX_FILE_SIZE = 2**24 # in bytes, i.e. 16 Mb. +PARSER_MAX_FILE_SIZE = 2 ** 24 # in bytes, i.e. 16 Mb. ############################################################################### # PATHS diff --git a/release/scripts/modules/bl_i18n_utils/utils.py b/release/scripts/modules/bl_i18n_utils/utils.py index 4ab92880bde..5e9464b782a 100644 --- a/release/scripts/modules/bl_i18n_utils/utils.py +++ b/release/scripts/modules/bl_i18n_utils/utils.py @@ -173,7 +173,7 @@ class I18nMessage: self.comment_lines.remove(l) lines_src = [] lines_src_custom = [] - for src in sources: + for src in sources: if is_valid_po_path(src): lines_src.append(self.settings.PO_COMMENT_PREFIX_SOURCE + src) else: diff --git a/release/scripts/modules/bpy_extras/anim_utils.py b/release/scripts/modules/bpy_extras/anim_utils.py index 20a9a412f26..de702b53978 100644 --- a/release/scripts/modules/bpy_extras/anim_utils.py +++ b/release/scripts/modules/bpy_extras/anim_utils.py @@ -169,7 +169,7 @@ def bake_action(frame_start, euler_prev = None for (f, matrix) in zip(frame_range, obj_info): - name = "Action Bake" # XXX: placeholder + name = "Action Bake" # XXX: placeholder obj.matrix_basis = matrix obj.keyframe_insert("location", -1, f, name, options) diff --git a/release/scripts/modules/bpy_types.py b/release/scripts/modules/bpy_types.py index f42fd8e3107..85a532e9a27 100644 --- a/release/scripts/modules/bpy_types.py +++ b/release/scripts/modules/bpy_types.py @@ -729,6 +729,7 @@ class Menu(StructRNA, _GenericUI, metaclass=RNAMeta): self.preset_operator, filter_ext=lambda ext: ext.lower() in {".py", ".xml"}) + class Region(StructRNA): __slots__ = () @@ -782,9 +783,11 @@ def gen_valid_identifier(seq): if ch == '_' or ch.isalpha() or ch.isdigit(): yield ch + def sanitize_identifier(name): return ''.join(gen_valid_identifier(name)) + def unique_identifier(name, identifier_list): # First some basic sanitation, to make a usable identifier string from the name base = sanitize_identifier(name) @@ -796,6 +799,7 @@ def unique_identifier(name, identifier_list): identifier = base + str(index) return identifier + class RNAMetaNode(RNAMetaPropGroup): def __new__(cls, name, bases, classdict, **args): # Wrapper for node.init, to add sockets from templates @@ -846,7 +850,7 @@ class Node(StructRNA, metaclass=RNAMetaNode): @classmethod def poll(cls, ntree): - return True + return True class NodeSocket(StructRNA, metaclass=RNAMetaPropGroup): @@ -870,17 +874,18 @@ class CompositorNode(Node): @classmethod def poll(cls, ntree): - return ntree.bl_idname == 'CompositorNodeTree' + return ntree.bl_idname == 'CompositorNodeTree' def update(self): self.tag_need_exec() + class ShaderNode(Node): __slots__ = () @classmethod def poll(cls, ntree): - return ntree.bl_idname == 'ShaderNodeTree' + return ntree.bl_idname == 'ShaderNodeTree' class TextureNode(Node): @@ -888,5 +893,4 @@ class TextureNode(Node): @classmethod def poll(cls, ntree): - return ntree.bl_idname == 'TextureNodeTree' - + return ntree.bl_idname == 'TextureNodeTree' diff --git a/release/scripts/modules/console/complete_import.py b/release/scripts/modules/console/complete_import.py index 9277e04af76..f28f61b303d 100644 --- a/release/scripts/modules/console/complete_import.py +++ b/release/scripts/modules/console/complete_import.py @@ -111,10 +111,11 @@ def module_list(path): else: folder_list = [] #folder_list = glob.glob(os.path.join(path,'*')) - folder_list = [p for p in folder_list \ - if os.path.exists(os.path.join(path, p, '__init__.py')) \ - or p[-3:] in {'.py', '.so'} \ - or p[-4:] in {'.pyc', '.pyo', '.pyd'}] + folder_list = [ + p for p in folder_list + if (os.path.exists(os.path.join(path, p, '__init__.py')) or + p[-3:] in {'.py', '.so'} or + p[-4:] in {'.pyc', '.pyo', '.pyd'})] folder_list = [os.path.basename(p).split('.')[0] for p in folder_list] return folder_list diff --git a/release/scripts/startup/bl_operators/add_mesh_torus.py b/release/scripts/startup/bl_operators/add_mesh_torus.py index 63e796e2b5d..948cb39f5b1 100644 --- a/release/scripts/startup/bl_operators/add_mesh_torus.py +++ b/release/scripts/startup/bl_operators/add_mesh_torus.py @@ -24,6 +24,7 @@ from bpy.props import (FloatProperty, IntProperty, BoolProperty, ) +from bpy.app.translations import pgettext_data as data_ from bpy_extras import object_utils @@ -142,7 +143,7 @@ class AddTorus(Operator, object_utils.AddObjectHelper): self.major_segments, self.minor_segments) - mesh = bpy.data.meshes.new("Torus") + mesh = bpy.data.meshes.new(data_("Torus")) mesh.vertices.add(len(verts_loc) // 3) diff --git a/release/scripts/startup/bl_operators/node.py b/release/scripts/startup/bl_operators/node.py index 5c7f3c3f4b2..c9063436bb3 100644 --- a/release/scripts/startup/bl_operators/node.py +++ b/release/scripts/startup/bl_operators/node.py @@ -127,7 +127,8 @@ def node_class_items_iter(node_class, context): tree_idname = context.space_data.edit_tree.bl_idname for group in bpy.data.node_groups: if group.bl_idname == tree_idname: - yield (group.name, "", {"node_tree":group}) # XXX empty string should be replaced by description from tree + # XXX empty string should be replaced by description from tree + yield (group.name, "", {"node_tree": group}) else: yield (node_class.bl_rna.name, node_class.bl_rna.description, {}) @@ -169,7 +170,7 @@ class NODE_OT_add_search(NodeAddOperator, Operator): for index, item in enumerate(node_items_iter(context)): if str(index) == self.type: node = self.create_node(context, item[0].bl_rna.identifier) - for prop,value in item[3].items(): + for prop, value in item[3].items(): setattr(node, prop, value) break return {'FINISHED'} @@ -257,4 +258,3 @@ class NODE_OT_tree_path_parent(Operator): space.path.pop() return {'FINISHED'} - diff --git a/release/scripts/startup/bl_operators/rigidbody.py b/release/scripts/startup/bl_operators/rigidbody.py index f327c602fb6..80516a85d43 100644 --- a/release/scripts/startup/bl_operators/rigidbody.py +++ b/release/scripts/startup/bl_operators/rigidbody.py @@ -146,7 +146,7 @@ class BakeToKeyframes(Operator): # this is a little roundabout but there's no better way right now aa = mat.to_quaternion().to_axis_angle() obj.rotation_axis_angle = (aa[1], ) + aa[0][:] - else: # euler + else: # euler # make sure euler rotation is compatible to previous frame obj.rotation_euler = mat.to_euler(rot_mode, obj_prev.rotation_euler) @@ -275,10 +275,10 @@ class ConnectRigidBodies(Operator): self._add_constraint(context, objs_sorted[i-1], objs_sorted[i]) change = True - else: # SELECTED_TO_ACTIVE + else: # SELECTED_TO_ACTIVE for obj in objects: self._add_constraint(context, obj_act, obj) - change = True; + change = True if change: # restore selection diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index a7085e51bd3..660faecc564 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -830,7 +830,7 @@ def _wm_doc_get_id(doc_id, do_url=True, url_prefix=""): rna = "bpy.ops.%s.%s" % (class_name, class_prop) else: rna_class = getattr(bpy.types, class_name) - + # an operator setting (selected from a running operator), rare case # note: Py defined operators are subclass of Operator, # C defined operators are subclass of OperatorProperties. @@ -1273,11 +1273,15 @@ class WM_OT_copy_prev_settings(Operator): else: shutil.copytree(path_src, path_dst, symlinks=True) + # reload recent-files.txt + bpy.ops.wm.read_history() + # don't loose users work if they open the splash later. if bpy.data.is_saved is bpy.data.is_dirty is False: bpy.ops.wm.read_homefile() else: self.report({'INFO'}, "Reload Start-Up file to restore settings") + return {'FINISHED'} return {'CANCELLED'} diff --git a/release/scripts/startup/bl_ui/properties_paint_common.py b/release/scripts/startup/bl_ui/properties_paint_common.py index 17dcf267c3b..391874ea3dc 100644 --- a/release/scripts/startup/bl_ui/properties_paint_common.py +++ b/release/scripts/startup/bl_ui/properties_paint_common.py @@ -93,7 +93,7 @@ def brush_texture_settings(layout, brush, sculpt): col.prop(brush, "texture_angle_source_random", text="") else: col.prop(brush, "texture_angle_source_no_random", text="") - + else: col.prop(brush, "texture_angle_source_random", text="") else: diff --git a/release/scripts/startup/bl_ui/properties_physics_common.py b/release/scripts/startup/bl_ui/properties_physics_common.py index 2d9d4649e28..b02a53302e7 100644 --- a/release/scripts/startup/bl_ui/properties_physics_common.py +++ b/release/scripts/startup/bl_ui/properties_physics_common.py @@ -20,8 +20,7 @@ import bpy from bpy.types import Panel - -i18n_default_ctxt = bpy.app.translations.contexts.default +from bpy.app.translations import contexts as i18n_contexts class PhysicButtonsPanel(): @@ -39,20 +38,20 @@ def physics_add(self, layout, md, name, type, typeicon, toggles): sub = layout.row(align=True) if md: sub.context_pointer_set("modifier", md) - sub.operator("object.modifier_remove", text=name, text_ctxt=i18n_default_ctxt, icon='X') + sub.operator("object.modifier_remove", text=name, text_ctxt=i18n_contexts.default, icon='X') if(toggles): sub.prop(md, "show_render", text="") sub.prop(md, "show_viewport", text="") else: - sub.operator("object.modifier_add", text=name, text_ctxt=i18n_default_ctxt, icon=typeicon).type = type + sub.operator("object.modifier_add", text=name, text_ctxt=i18n_contexts.default, icon=typeicon).type = type def physics_add_special(self, layout, data, name, addop, removeop, typeicon): sub = layout.row(align=True) if data: - sub.operator(removeop, text=name, text_ctxt=i18n_default_ctxt, icon='X') + sub.operator(removeop, text=name, text_ctxt=i18n_contexts.default, icon='X') else: - sub.operator(addop, text=name, text_ctxt=i18n_default_ctxt, icon=typeicon) + sub.operator(addop, text=name, text_ctxt=i18n_contexts.default, icon=typeicon) class PHYSICS_PT_add(PhysicButtonsPanel, Panel): diff --git a/release/scripts/startup/bl_ui/properties_render.py b/release/scripts/startup/bl_ui/properties_render.py index 5cf86b8d4b0..c8cc433d3af 100644 --- a/release/scripts/startup/bl_ui/properties_render.py +++ b/release/scripts/startup/bl_ui/properties_render.py @@ -358,12 +358,12 @@ class RENDER_PT_output(RenderButtonsPanel, Panel): layout.prop(rd, "filepath", text="") split = layout.split() - + col = split.column() col.active = not rd.is_movie_format col.prop(rd, "use_overwrite") col.prop(rd, "use_placeholder") - + split.prop(rd, "use_file_extension") layout.template_image_settings(image_settings, color_management=False) diff --git a/release/scripts/startup/bl_ui/space_image.py b/release/scripts/startup/bl_ui/space_image.py index d2bbca358aa..3537ca62d93 100644 --- a/release/scripts/startup/bl_ui/space_image.py +++ b/release/scripts/startup/bl_ui/space_image.py @@ -697,13 +697,6 @@ class IMAGE_PT_paint(Panel, ImagePaintPanel): self.prop_unified_strength(row, context, brush, "use_pressure_strength") row = col.row(align=True) - if(brush.use_relative_jitter): - row.prop(brush, "use_relative_jitter", text="", icon='LOCKED') - row.prop(brush, "jitter", slider=True) - else: - row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED') - row.prop(brush, "jitter_absolute") - row.prop(brush, "use_pressure_jitter", toggle=True, text="") col.prop(brush, "blend", text="Blend") @@ -728,16 +721,24 @@ class IMAGE_PT_tools_brush_texture(BrushButtonsPanel, Panel): brush_texture_settings(col, brush, 0) + # use_texture_overlay and texture_overlay_alpha + col = layout.column(align=True) + col.active = brush.brush_capabilities.has_overlay + col.label(text="Overlay:") + + row = col.row() + if brush.use_texture_overlay: + row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_OFF') + else: + row.prop(brush, "use_texture_overlay", toggle=True, text="", icon='RESTRICT_VIEW_ON') + sub = row.row() + sub.prop(brush, "texture_overlay_alpha", text="Alpha") + class IMAGE_PT_tools_mask_texture(BrushButtonsPanel, Panel): bl_label = "Texture Mask" bl_options = {'DEFAULT_CLOSED'} - def draw_header(self, context): - brush = context.tool_settings.image_paint.brush - tex_slot_alpha = brush.mask_texture_slot - self.layout.prop(brush, 'use_mask', text="") - def draw(self, context): layout = self.layout @@ -778,32 +779,52 @@ class IMAGE_PT_paint_stroke(BrushButtonsPanel, Panel): toolsettings = context.tool_settings.image_paint brush = toolsettings.brush - + col = layout.column() col.prop(toolsettings, "input_samples") - col.prop(brush, "use_airbrush") - row = col.row() - row.active = brush.use_airbrush - row.prop(brush, "rate", slider=True) + col = layout.column() + col.label(text="Stroke Method:") + + col.prop(brush, "stroke_method", text="") + + if brush.use_anchor: + col.separator() + col.prop(brush, "use_edge_to_edge", "Edge To Edge") + + if brush.use_airbrush: + col.separator() + col.prop(brush, "rate", text="Rate", slider=True) + + if brush.use_space: + col.separator() + row = col.row(align=True) + row.active = brush.use_space + row.prop(brush, "spacing", text="Spacing") + row.prop(brush, "use_pressure_spacing", toggle=True, text="") + + + col = layout.column() col.separator() col.prop(brush, "use_smooth_stroke") - col = layout.column() - col.active = brush.use_smooth_stroke - col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True) - col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True) + sub = col.column() + sub.active = brush.use_smooth_stroke + sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True) + sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True) col.separator() - col = layout.column() - col.prop(brush, "use_space") row = col.row(align=True) - row.active = brush.use_space - row.prop(brush, "spacing", text="Distance", slider=True) - row.prop(brush, "use_pressure_spacing", toggle=True, text="") + if brush.use_relative_jitter: + row.prop(brush, "use_relative_jitter", text="", icon='LOCKED') + row.prop(brush, "jitter", slider=True) + else: + row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED') + row.prop(brush, "jitter_absolute") + row.prop(brush, "use_pressure_jitter", toggle=True, text="") col.prop(brush, "use_wrap") diff --git a/release/scripts/startup/bl_ui/space_nla.py b/release/scripts/startup/bl_ui/space_nla.py index 49dedaa83c5..dd3ec33d56b 100644 --- a/release/scripts/startup/bl_ui/space_nla.py +++ b/release/scripts/startup/bl_ui/space_nla.py @@ -167,7 +167,7 @@ class NLA_MT_add(Menu): layout.separator() layout.operator("nla.tracks_add").above_selected = False layout.operator("nla.tracks_add", text="Add Tracks Above Selected").above_selected = True - + layout.separator() layout.operator("nla.selected_objects_add") diff --git a/release/scripts/startup/bl_ui/space_node.py b/release/scripts/startup/bl_ui/space_node.py index 6e92b55f88c..26c76bd6655 100644 --- a/release/scripts/startup/bl_ui/space_node.py +++ b/release/scripts/startup/bl_ui/space_node.py @@ -44,7 +44,7 @@ class NODE_HT_header(Header): row.menu("NODE_MT_node") layout.prop(snode, "tree_type", text="", expand=True) - + if snode.tree_type == 'ShaderNodeTree': if scene.render.use_shading_nodes: layout.prop(snode, "shader_type", text="", expand=True) @@ -84,7 +84,7 @@ class NODE_HT_header(Header): row = layout.row(align=True) row.prop(snode, "backdrop_channels", text="", expand=True) layout.prop(snode, "use_auto_render") - + else: # Custom node tree is edited as independent ID block layout.template_ID(snode, "node_tree", new="node.new_node_tree") @@ -292,7 +292,7 @@ class NODE_UL_interface_sockets(bpy.types.UIList): if self.layout_type in {'DEFAULT', 'COMPACT'}: row = layout.row(align=True) - # inputs get icon on the left + # inputs get icon on the left if socket.in_out == 'IN': row.template_node_socket(color) diff --git a/release/scripts/startup/bl_ui/space_sequencer.py b/release/scripts/startup/bl_ui/space_sequencer.py index ae9e0f72009..90ade0c8ccb 100644 --- a/release/scripts/startup/bl_ui/space_sequencer.py +++ b/release/scripts/startup/bl_ui/space_sequencer.py @@ -514,9 +514,6 @@ class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel): layout.prop(strip, "speed_factor", text="Frame number") layout.prop(strip, "scale_to_length") - #doesn't work currently - #layout.prop(strip, "use_frame_blend") - elif strip.type == 'TRANSFORM': layout = self.layout col = layout.column() diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 2742e6d8155..8755e37c68d 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -20,6 +20,7 @@ import bpy from bpy.types import Header, Menu, Panel from bpy.app.translations import pgettext_iface as iface_ +from bpy.app.translations import contexts as i18n_contexts def ui_style_items(col, context): @@ -528,7 +529,7 @@ class USERPREF_PT_system(Panel): if system.use_international_fonts: column.prop(system, "language") row = column.row() - row.label(text="Translate:", text_ctxt=bpy.app.translations.contexts.id_windowmanager) + row.label(text="Translate:", text_ctxt=i18n_contexts.id_windowmanager) row = column.row(True) row.prop(system, "use_translate_interface", text="Interface", toggle=True) row.prop(system, "use_translate_tooltips", text="Tooltips", toggle=True) diff --git a/release/scripts/startup/bl_ui/space_userpref_keymap.py b/release/scripts/startup/bl_ui/space_userpref_keymap.py index a13d77942eb..8d6eb2c623d 100644 --- a/release/scripts/startup/bl_ui/space_userpref_keymap.py +++ b/release/scripts/startup/bl_ui/space_userpref_keymap.py @@ -20,8 +20,7 @@ import bpy from bpy.types import Menu from bpy.app.translations import pgettext_iface as iface_ - -km_i18n_context = bpy.app.translations.contexts.id_windowmanager +from bpy.app.translations import contexts as i18n_contexts class USERPREF_MT_keyconfigs(Menu): @@ -81,7 +80,7 @@ class InputKeyMapPanel: row = col.row() row.prop(km, "show_expanded_children", text="", emboss=False) - row.label(text=km.name, text_ctxt=km_i18n_context) + row.label(text=km.name, text_ctxt=i18n_contexts.id_windowmanager) row.label() row.label() @@ -112,7 +111,8 @@ class InputKeyMapPanel: # "Add New" at end of keymap item list col = self.indented_layout(col, level + 1) subcol = col.split(percentage=0.2).column() - subcol.operator("wm.keyitem_add", text="Add New", text_ctxt=km_i18n_context, icon='ZOOMIN') + subcol.operator("wm.keyitem_add", text="Add New", text_ctxt=i18n_contexts.id_windowmanager, + icon='ZOOMIN') col.separator() diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py index e474117f0d4..8f65eb5b726 100644 --- a/release/scripts/startup/bl_ui/space_view3d.py +++ b/release/scripts/startup/bl_ui/space_view3d.py @@ -20,6 +20,7 @@ import bpy from bpy.types import Header, Menu, Panel from bl_ui.properties_paint_common import UnifiedPaintPanel +from bpy.app.translations import contexts as i18n_contexts class VIEW3D_HT_header(Header): @@ -994,20 +995,20 @@ class VIEW3D_MT_object_apply(Menu): def draw(self, context): layout = self.layout - props = layout.operator("object.transform_apply", text="Location") + props = layout.operator("object.transform_apply", text="Location", text_ctxt=i18n_contexts.default) props.location, props.rotation, props.scale = True, False, False - props = layout.operator("object.transform_apply", text="Rotation") + props = layout.operator("object.transform_apply", text="Rotation", text_ctxt=i18n_contexts.default) props.location, props.rotation, props.scale = False, True, False - props = layout.operator("object.transform_apply", text="Scale") + props = layout.operator("object.transform_apply", text="Scale", text_ctxt=i18n_contexts.default) props.location, props.rotation, props.scale = False, False, True - props = layout.operator("object.transform_apply", text="Rotation & Scale") + props = layout.operator("object.transform_apply", text="Rotation & Scale", text_ctxt=i18n_contexts.default) props.location, props.rotation, props.scale = False, True, True layout.separator() - layout.operator("object.visual_transform_apply", text="Visual Transform") + layout.operator("object.visual_transform_apply", text="Visual Transform", text_ctxt=i18n_contexts.default) layout.operator("object.duplicates_make_real") @@ -1657,8 +1658,6 @@ class BoneOptions: def draw(self, context): layout = self.layout - default_context = bpy.app.translations.contexts.default - options = [ "show_wire", "use_deform", @@ -1679,7 +1678,7 @@ class BoneOptions: for opt in options: props = layout.operator("wm.context_collection_boolean_set", text=bone_props[opt].name, - text_ctxt=default_context) + text_ctxt=i18n_contexts.default) props.data_path_iter = data_path_iter props.data_path_item = opt_suffix + opt props.type = self.type @@ -2561,7 +2560,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel): col.label() if not with_freestyle: col.prop(mesh, "show_edge_seams", text="Seams") - col.prop(mesh, "show_edge_sharp", text="Sharp") + col.prop(mesh, "show_edge_sharp", text="Sharp", text_ctxt=i18n_contexts.plural) col.prop(mesh, "show_edge_bevel_weight", text="Weights") if with_freestyle: col.prop(mesh, "show_freestyle_edge_marks", text="Edge Marks") @@ -2584,6 +2583,7 @@ class VIEW3D_PT_view3d_meshdisplay(Panel): col.separator() col.label(text="Numerics:") col.prop(mesh, "show_extra_edge_length") + col.prop(mesh, "show_extra_edge_angle") col.prop(mesh, "show_extra_face_angle") col.prop(mesh, "show_extra_face_area") if bpy.app.debug: diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index 54d3b61c665..ff368a682e9 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -681,13 +681,6 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): self.prop_unified_strength(row, context, brush, "use_pressure_strength") row = col.row(align=True) - if(brush.use_relative_jitter): - row.prop(brush, "use_relative_jitter", text="", icon='LOCKED') - row.prop(brush, "jitter", slider=True) - else: - row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED') - row.prop(brush, "jitter_absolute") - row.prop(brush, "use_pressure_jitter", toggle=True, text="") col.prop(brush, "blend", text="Blend") @@ -714,14 +707,7 @@ class VIEW3D_PT_tools_brush(Panel, View3DPaintPanel): self.prop_unified_strength(row, context, brush, "use_pressure_strength") row = col.row(align=True) - if(brush.use_relative_jitter): - row.prop(brush, "use_relative_jitter", text="", icon='LOCKED') - row.prop(brush, "jitter", slider=True) - else: - row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED') - row.prop(brush, "jitter_absolute") - row.prop(brush, "use_pressure_jitter", toggle=True, text="") - + col.prop(brush, "vertex_tool", text="Blend") # Vertex Paint Mode # @@ -793,11 +779,6 @@ class VIEW3D_PT_tools_mask_texture(View3DPanel, Panel): brush = context.tool_settings.image_paint.brush return (context.image_paint_object and brush and brush.image_tool != 'SOFTEN') - def draw_header(self, context): - brush = context.tool_settings.image_paint.brush - tex_slot_alpha = brush.mask_texture_slot - self.layout.prop(brush, 'use_mask', text="") - def draw(self, context): layout = self.layout @@ -830,79 +811,74 @@ class VIEW3D_PT_tools_brush_stroke(Panel, View3DPaintPanel): settings = self.paint_settings(context) brush = settings.brush - image_paint = context.image_paint_object col = layout.column() + col.label(text="Stroke Method:") + if context.sculpt_object: - col.label(text="Stroke Method:") + col.prop(brush, "sculpt_stroke_method", text="") + else: col.prop(brush, "stroke_method", text="") - if brush.use_anchor: - col.separator() - col.prop(brush, "use_edge_to_edge", "Edge To Edge") - - if brush.use_airbrush: - col.separator() - col.prop(brush, "rate", text="Rate", slider=True) - - if brush.use_space: - col.separator() - row = col.row(align=True) - row.active = brush.use_space - row.prop(brush, "spacing", text="Spacing") - row.prop(brush, "use_pressure_spacing", toggle=True, text="") - - if brush.sculpt_capabilities.has_smooth_stroke: - col = layout.column() - col.separator() + if brush.use_anchor: + col.separator() + col.prop(brush, "use_edge_to_edge", "Edge To Edge") - col.prop(brush, "use_smooth_stroke") + if brush.use_airbrush: + col.separator() + col.prop(brush, "rate", text="Rate", slider=True) - sub = col.column() - sub.active = brush.use_smooth_stroke - sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True) - sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True) + if brush.use_space: + col.separator() + row = col.row(align=True) + row.active = brush.use_space + row.prop(brush, "spacing", text="Spacing") + row.prop(brush, "use_pressure_spacing", toggle=True, text="") + if context.sculpt_object: if brush.sculpt_capabilities.has_jitter: col.separator() row = col.row(align=True) - if(brush.use_relative_jitter): + if brush.use_relative_jitter: row.prop(brush, "use_relative_jitter", text="", icon='LOCKED') row.prop(brush, "jitter", slider=True) else: row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED') row.prop(brush, "jitter_absolute") row.prop(brush, "use_pressure_jitter", toggle=True, text="") + if brush.sculpt_capabilities.has_smooth_stroke: + col = layout.column() + col.separator() - else: - col.prop(brush, "use_airbrush") - - row = col.row() - row.active = brush.use_airbrush and (not brush.use_space) and (not brush.use_anchor) - row.prop(brush, "rate", slider=True) + col.prop(brush, "use_smooth_stroke") + sub = col.column() + sub.active = brush.use_smooth_stroke + sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True) + sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True) + else: col.separator() - col.prop(brush, "use_smooth_stroke") + row = col.row(align=True) + if brush.use_relative_jitter: + row.prop(brush, "use_relative_jitter", text="", icon='LOCKED') + row.prop(brush, "jitter", slider=True) + else: + row.prop(brush, "use_relative_jitter", text="", icon='UNLOCKED') + row.prop(brush, "jitter_absolute") + row.prop(brush, "use_pressure_jitter", toggle=True, text="") col = layout.column() - col.active = brush.use_smooth_stroke - col.prop(brush, "smooth_stroke_radius", text="Radius", slider=True) - col.prop(brush, "smooth_stroke_factor", text="Factor", slider=True) - col.separator() - col = layout.column() - col.active = brush.brush_capabilities.has_spacing - col.prop(brush, "use_space") - - row = col.row(align=True) - row.active = brush.use_space - row.prop(brush, "spacing", text="Spacing") - row.prop(brush, "use_pressure_spacing", toggle=True, text="") + col.prop(brush, "use_smooth_stroke") + sub = col.column() + sub.active = brush.use_smooth_stroke + sub.prop(brush, "smooth_stroke_radius", text="Radius", slider=True) + sub.prop(brush, "smooth_stroke_factor", text="Factor", slider=True) class VIEW3D_PT_tools_brush_curve(Panel, View3DPaintPanel): bl_label = "Curve" @@ -1180,7 +1156,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel): row = layout.row() row.prop(ipaint, "use_normal_falloff") - + sub = row.row() sub.active = (ipaint.use_normal_falloff) sub.prop(ipaint, "normal_angle", text="") @@ -1214,7 +1190,7 @@ class VIEW3D_PT_tools_projectpaint(View3DPanel, Panel): col.operator("paint.project_image", text="Apply Camera Image") col.operator("image.save_dirty", text="Save All Edited") - + class VIEW3D_PT_imagepaint_options(View3DPaintPanel): bl_label = "Options" diff --git a/release/windows/contrib/vfapi/vfapi-plugin.c b/release/windows/contrib/vfapi/vfapi-plugin.c index 96a5ada8f14..8fe19da3d72 100644 --- a/release/windows/contrib/vfapi/vfapi-plugin.c +++ b/release/windows/contrib/vfapi/vfapi-plugin.c @@ -111,7 +111,7 @@ __declspec(dllexport) HRESULT vfGetPluginInfo( return VF_OK; } -static unsigned long getipaddress(const char * ipaddr) +static unsigned long getipaddress(const char *ipaddr) { struct hostent *host; unsigned long ip; diff --git a/source/blender/blenfont/BLF_translation.h b/source/blender/blenfont/BLF_translation.h index 2fc179c8d35..127c27f78a8 100644 --- a/source/blender/blenfont/BLF_translation.h +++ b/source/blender/blenfont/BLF_translation.h @@ -138,6 +138,9 @@ const char *BLF_translate_do_new_dataname(const char *msgctxt, const char *msgid /* Default context for operator names/labels. */ #define BLF_I18NCONTEXT_OPERATOR_DEFAULT "Operator" +/* Mark the msgid applies to several elements (needed in some cases, as english adjectives have no plural mark. :( */ +#define BLF_I18NCONTEXT_PLURAL "Plural" + /* ID-types contexts. */ /* WARNING! Keep it in sync with idtypes in blenkernel/intern/idcode.c */ #define BLF_I18NCONTEXT_ID_ACTION "Action" @@ -188,6 +191,7 @@ typedef struct BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT, "default_real"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_DEFAULT_BPYRNA, "default"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_OPERATOR_DEFAULT, "operator_default"), \ + BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_PLURAL, "plural"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ACTION, "id_action"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_ARMATURE, "id_armature"), \ BLF_I18NCONTEXTS_ITEM(BLF_I18NCONTEXT_ID_BRUSH, "id_brush"), \ diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 51c46bcc235..0c988ac45fc 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -235,19 +235,19 @@ struct DerivedMesh { * from the derived mesh (this gives a pointer to the actual data, not * a copy) */ - void *(*getVertData)(DerivedMesh * dm, int index, int type); - void *(*getEdgeData)(DerivedMesh * dm, int index, int type); - void *(*getTessFaceData)(DerivedMesh * dm, int index, int type); - void *(*getPolyData)(DerivedMesh * dm, int index, int type); + void *(*getVertData)(DerivedMesh *dm, int index, int type); + void *(*getEdgeData)(DerivedMesh *dm, int index, int type); + void *(*getTessFaceData)(DerivedMesh *dm, int index, int type); + void *(*getPolyData)(DerivedMesh *dm, int index, int type); /** Return a pointer to the entire array of vert/edge/face custom data * from the derived mesh (this gives a pointer to the actual data, not * a copy) */ - void *(*getVertDataArray)(DerivedMesh * dm, int type); - void *(*getEdgeDataArray)(DerivedMesh * dm, int type); - void *(*getTessFaceDataArray)(DerivedMesh * dm, int type); - void *(*getPolyDataArray)(DerivedMesh * dm, int type); + void *(*getVertDataArray)(DerivedMesh *dm, int type); + void *(*getEdgeDataArray)(DerivedMesh *dm, int type); + void *(*getTessFaceDataArray)(DerivedMesh *dm, int type); + void *(*getPolyDataArray)(DerivedMesh *dm, int type); /** Retrieves the base CustomData structures for * verts/edges/tessfaces/loops/facdes*/ diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h index 2d10b76378a..3e748550e7b 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 266 -#define BLENDER_SUBVERSION 4 +#define BLENDER_SUBVERSION 5 /* 262 was the last editmesh release but it has compatibility code for bmesh data */ #define BLENDER_MINVERSION 262 diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index e234d6c519e..fc1cd6e45d5 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -120,6 +120,7 @@ typedef struct bNodeSocketType { void (*interface_draw_color)(struct bContext *C, struct PointerRNA *ptr, float *r_color); void (*interface_register_properties)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct StructRNA *data_srna); void (*interface_init_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock, const char *data_path); + void (*interface_verify_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock, const char *data_path); void (*interface_from_socket)(struct bNodeTree *ntree, struct bNodeSocket *stemp, struct bNode *node, struct bNodeSocket *sock); /* RNA integration */ diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 2f666bf5922..3fbbbc84ef4 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -121,6 +121,12 @@ static void brush_defaults(Brush *brush) brush->sub_col[0] = 0.39; /* subtract mode color is light blue */ brush->sub_col[1] = 0.39; brush->sub_col[2] = 1.00; + + brush->stencil_pos[0] = 256; + brush->stencil_pos[1] = 256; + + brush->stencil_dimension[0] = 256; + brush->stencil_dimension[1] = 256; } /* Datablock add/copy/free/make_local */ @@ -518,11 +524,45 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, hasrgb = externtex(mtex, point, &intensity, rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); } + else if (mtex->brush_map_mode == MTEX_MAP_MODE_STENCIL) { + float rotation = -mtex->rot; + float point_2d[2] = {point[0], point[1]}; + float x = 0.0f, y = 0.0f; /* Quite warnings */ + float co[3]; + + x = point_2d[0] - br->stencil_pos[0]; + y = point_2d[1] - br->stencil_pos[1]; + + if (rotation > 0.001f || rotation < -0.001f) { + const float angle = atan2f(y, x) + rotation; + const float flen = sqrtf(x * x + y * y); + + x = flen * cosf(angle); + y = flen * sinf(angle); + } + + if (fabs(x) > br->stencil_dimension[0] || fabs(y) > br->stencil_dimension[1]) { + rgba[0] = rgba[1] = rgba[2] = rgba[3] = 0.0; + return 0.0; + } + x /= (br->stencil_dimension[0]); + y /= (br->stencil_dimension[1]); + + x *= br->mtex.size[0]; + y *= br->mtex.size[1]; + + co[0] = x + br->mtex.ofs[0]; + co[1] = y + br->mtex.ofs[1]; + co[2] = 0.0f; + + hasrgb = externtex(mtex, co, &intensity, + rgba, rgba + 1, rgba + 2, rgba + 3, thread, pool); + } else { float rotation = -mtex->rot; float point_2d[2] = {point[0], point[1]}; float x = 0.0f, y = 0.0f; /* Quite warnings */ - float radius = 1.0f; /* Quite warnings */ + float invradius = 1.0f; /* Quite warnings */ float co[3]; if (mtex->brush_map_mode == MTEX_MAP_MODE_VIEW) { @@ -534,13 +574,13 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, y = point_2d[1] - ups->tex_mouse[1]; /* use pressure adjusted size for fixed mode */ - radius = ups->pixel_radius; + invradius = 1.0f / ups->pixel_radius; } else if (mtex->brush_map_mode == MTEX_MAP_MODE_TILED) { /* leave the coordinates relative to the screen */ /* use unadjusted size for tiled mode */ - radius = BKE_brush_size_get(scene, br); + invradius = 1.0f / BKE_brush_size_get(scene, br); x = point_2d[0]; y = point_2d[1]; @@ -551,11 +591,11 @@ float BKE_brush_sample_tex_3D(const Scene *scene, Brush *br, x = point_2d[0] - ups->tex_mouse[0]; y = point_2d[1] - ups->tex_mouse[1]; - radius = ups->pixel_radius; + invradius = 1.0f / ups->pixel_radius; } - x /= radius; - y /= radius; + x *= invradius; + y *= invradius; /* it is probably worth optimizing for those cases where * the texture is not rotated by skipping the calls to diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c index c9034cfe7bb..64bc4928e35 100644 --- a/source/blender/blenkernel/intern/image.c +++ b/source/blender/blenkernel/intern/image.c @@ -1601,7 +1601,7 @@ static void stampdata(Scene *scene, Object *camera, StampData *stamp_data, int d RenderStats *stats = re ? RE_GetStats(re) : NULL; if (stats && (scene->r.stamp & R_STAMP_RENDERTIME)) { - BLI_timestr(stats->lastframetime, text); + BLI_timestr(stats->lastframetime, text, sizeof(text)); BLI_snprintf(stamp_data->rendertime, sizeof(stamp_data->rendertime), do_prefix ? "RenderTime %s" : "%s", text); } @@ -3011,7 +3011,7 @@ static ImBuf *image_acquire_ibuf(Image *ima, ImageUser *iuser, void **lock_r) *lock_r = ima; /* XXX anim play for viewer nodes not yet supported */ - frame = 0; // XXX iuser?iuser->framenr:0; + frame = 0; // XXX iuser ? iuser->framenr : 0; ibuf = image_get_ibuf(ima, 0, frame); if (!ibuf) { diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c index 7fcbc14a593..5cf8758aa1b 100644 --- a/source/blender/blenkernel/intern/node.c +++ b/source/blender/blenkernel/intern/node.c @@ -1668,7 +1668,6 @@ static void node_socket_interface_free(bNodeTree *UNUSED(ntree), bNodeSocket *so MEM_freeN(sock->prop); } - /* can be left over from old files */ if (sock->default_value) MEM_freeN(sock->default_value); } @@ -2006,21 +2005,16 @@ void ntreeLocalMerge(bNodeTree *localtree, bNodeTree *ntree) /* ************ NODE TREE INTERFACE *************** */ -static bNodeSocket *make_socket_template(bNodeTree *ntree, int in_out, +static bNodeSocket *make_socket_interface(bNodeTree *ntree, int in_out, const char *idname, const char *name) { bNodeSocketType *stype = nodeSocketTypeFind(idname); bNodeSocket *sock; int own_index = ntree->cur_index++; - if (stype == NULL) { - printf("Error: node socket type '%s' undefined\n", idname); - return NULL; - } - sock = MEM_callocN(sizeof(bNodeSocket), "socket template"); - sock->typeinfo = stype; BLI_strncpy(sock->idname, stype->idname, sizeof(sock->idname)); + node_socket_set_typeinfo(ntree, sock, stype); sock->in_out = in_out; sock->type = SOCK_CUSTOM; /* int type undefined by default */ @@ -2073,7 +2067,7 @@ bNodeSocket *ntreeAddSocketInterface(bNodeTree *ntree, int in_out, const char *i { bNodeSocket *iosock; - iosock = make_socket_template(ntree, in_out, idname, name); + iosock = make_socket_interface(ntree, in_out, idname, name); if (in_out == SOCK_IN) { BLI_addtail(&ntree->inputs, iosock); ntree->update |= NTREE_UPDATE_GROUP_IN; @@ -2091,7 +2085,7 @@ bNodeSocket *ntreeInsertSocketInterface(bNodeTree *ntree, int in_out, const char { bNodeSocket *iosock; - iosock = make_socket_template(ntree, in_out, idname, name); + iosock = make_socket_interface(ntree, in_out, idname, name); if (in_out == SOCK_IN) { BLI_insertlinkbefore(&ntree->inputs, next_sock, iosock); ntree->update |= NTREE_UPDATE_GROUP_IN; diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c index 3efe25794e1..5124cb1da26 100644 --- a/source/blender/blenkernel/intern/particle_system.c +++ b/source/blender/blenkernel/intern/particle_system.c @@ -1346,7 +1346,7 @@ static int distribute_threads_init_data(ParticleThread *threads, Scene *scene, D ctx->jitoff= jitter_offset; ctx->weight= element_weight; ctx->maxweight= maxweight; - ctx->from= (children)? PART_FROM_CHILD: from; + ctx->from= (children) ? PART_FROM_CHILD : from; ctx->cfrom= cfrom; ctx->distr= distr; ctx->dm= dm; @@ -2039,7 +2039,7 @@ static void set_keyed_keys(ParticleSimulationData *sim) ksim.psys->flag |= keyed_flag; - pt = (pt->next && pt->next->flag & PTARGET_VALID)? pt->next : psys->targets.first; + pt = (pt->next && pt->next->flag & PTARGET_VALID) ? pt->next : psys->targets.first; } psys->flag |= PSYS_KEYED; diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c index 8034c4d1de9..c119eb07779 100644 --- a/source/blender/blenkernel/intern/pointcache.c +++ b/source/blender/blenkernel/intern/pointcache.c @@ -1396,7 +1396,7 @@ void BKE_ptcache_ids_from_object(ListBase *lb, Object *ob, Scene *scene, int dup static int ptcache_path(PTCacheID *pid, char *filename) { - Library *lib= (pid->ob)? pid->ob->id.lib: NULL; + Library *lib = (pid->ob) ? pid->ob->id.lib : NULL; const char *blendfilename= (lib && (pid->cache->flag & PTCACHE_IGNORE_LIBPATH)==0) ? lib->filepath: G.main->name; size_t i; diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c index 6433b73fda0..92f57a54a01 100644 --- a/source/blender/blenkernel/intern/sca.c +++ b/source/blender/blenkernel/intern/sca.c @@ -705,7 +705,7 @@ void sca_move_sensor(bSensor *sens_to_move, Object *ob, int move_up) bSensor *sens, *tmp; int val; - val = move_up ? 1:2; + val = move_up ? 1 : 2; /* make sure this sensor belongs to this object */ sens= ob->sensors.first; @@ -744,7 +744,7 @@ void sca_move_controller(bController *cont_to_move, Object *ob, int move_up) bController *cont, *tmp; int val; - val = move_up ? 1:2; + val = move_up ? 1 : 2; /* make sure this controller belongs to this object */ cont= ob->controllers.first; @@ -787,7 +787,7 @@ void sca_move_actuator(bActuator *act_to_move, Object *ob, int move_up) bActuator *act, *tmp; int val; - val = move_up ? 1:2; + val = move_up ? 1 : 2; /* make sure this actuator belongs to this object */ act= ob->actuators.first; diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c index a1dc19e1ff7..5bae967165c 100644 --- a/source/blender/blenkernel/intern/seqeffects.c +++ b/source/blender/blenkernel/intern/seqeffects.c @@ -965,10 +965,13 @@ static void do_sub_effect_byte(float facf0, float facf1, int x, int y, unsigned straight_uchar_to_premul_float(rt1, cp1); straight_uchar_to_premul_float(rt2, cp2); - tempc[0] = rt1[0] - fac1 * rt2[0]; - tempc[1] = rt1[1] - fac1 * rt2[1]; - tempc[2] = rt1[2] - fac1 * rt2[2]; - tempc[3] = rt1[3] - fac1 * rt2[3]; + tempc[0] = max_ff(rt1[0] - fac1 * rt2[0], 0.0f); + tempc[1] = max_ff(rt1[1] - fac1 * rt2[1], 0.0f); + tempc[2] = max_ff(rt1[2] - fac1 * rt2[2], 0.0f); + tempc[3] = max_ff(rt1[3] - fac1 * rt2[3], 0.0f); + + if (tempc[3] < 1e-6f) + tempc[3] = 0.0f; premul_float_to_straight_uchar(rt, tempc); @@ -984,10 +987,13 @@ static void do_sub_effect_byte(float facf0, float facf1, int x, int y, unsigned straight_uchar_to_premul_float(rt1, cp1); straight_uchar_to_premul_float(rt2, cp2); - tempc[0] = rt1[0] - fac3 * rt2[0]; - tempc[1] = rt1[1] - fac3 * rt2[1]; - tempc[2] = rt1[2] - fac3 * rt2[2]; - tempc[3] = rt1[3] - fac3 * rt2[3]; + tempc[0] = max_ff(rt1[0] - fac3 * rt2[0], 0.0f); + tempc[1] = max_ff(rt1[1] - fac3 * rt2[1], 0.0f); + tempc[2] = max_ff(rt1[2] - fac3 * rt2[2], 0.0f); + tempc[3] = max_ff(rt1[3] - fac3 * rt2[3], 0.0f); + + if (tempc[3] < 1e-6f) + tempc[3] = 0.0f; premul_float_to_straight_uchar(rt, tempc); @@ -1011,22 +1017,34 @@ static void do_sub_effect_float(float facf0, float facf1, int x, int y, float *r fac3 = facf1; while (y--) { - x = xo * 4; + x = xo; while (x--) { - *rt = *rt1 - fac1 * (*rt2); + rt[0] = max_ff(rt1[0] - fac1 * rt2[0], 0.0f); + rt[1] = max_ff(rt1[1] - fac1 * rt2[1], 0.0f); + rt[2] = max_ff(rt1[2] - fac1 * rt2[2], 0.0f); + rt[3] = max_ff(rt1[3] - fac1 * rt2[3], 0.0f); - rt1++; rt2++; rt++; + if (rt[3] < 1e-6f) + rt[3] = 0.0f; + + rt1 += 4; rt2 += 4; rt += 4; } if (y == 0) break; y--; - x = xo * 4; + x = xo; while (x--) { - *rt = *rt1 - fac3 * (*rt2); + rt[0] = max_ff(rt1[0] - fac3 * rt2[0], 0.0f); + rt[1] = max_ff(rt1[1] - fac3 * rt2[1], 0.0f); + rt[2] = max_ff(rt1[2] - fac3 * rt2[2], 0.0f); + rt[3] = max_ff(rt1[3] - fac3 * rt2[3], 0.0f); - rt1++; rt2++; rt++; + if (rt[3] < 1e-6f) + rt[3] = 0.0f; + + rt1 += 4; rt2 += 4; rt += 4; } } } diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h index 54cd687eeac..41968f1ebd6 100644 --- a/source/blender/blenlib/BLI_listbase.h +++ b/source/blender/blenlib/BLI_listbase.h @@ -75,6 +75,37 @@ void BLI_duplicatelist(struct ListBase *dst, const struct ListBase *src); /* create a generic list node containing link to provided data */ struct LinkData *BLI_genericNodeN(void *data); +/** + * Does a full loop on the list, with any value acting as first + * (handy for cycling items) + * + * \code{.c} + * + * LISTBASE_CIRCULAR_FORWARD_BEGIN (listbase, item, item_init) { + * ...operate on marker... + * } + * LISTBASE_CIRCULAR_FORWARD_END (listbase, item, item_init); + * + * \endcode + */ +#define LISTBASE_CIRCULAR_FORWARD_BEGIN(lb, lb_iter, lb_init) \ +if ((lb)->first && (lb_init || (lb_init = (lb)->first))) { \ + lb_iter = lb_init; \ + do { +#define LISTBASE_CIRCULAR_FORWARD_END(lb, lb_iter, lb_init) \ + } while ((lb_iter = (lb_iter)->next ? (lb_iter)->next : (lb)->first), \ + (lb_iter != lb_init)); \ +} + +#define LISTBASE_CIRCULAR_BACKWARD_BEGIN(lb, lb_iter, lb_init) \ +if ((lb)->last && (lb_init || (lb_init = (lb)->last))) { \ + lb_iter = lb_init; \ + do { +#define LISTBASE_CIRCULAR_BACKWARD_END(lb, lb_iter, lb_init) \ + } while ((lb_iter = (lb_iter)->prev ? (lb_iter)->prev : (lb)->last), \ + (lb_iter != lb_init)); \ +} + #ifdef __cplusplus } #endif diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h index c9ad19f74b4..9cf571aa98b 100644 --- a/source/blender/blenlib/BLI_math_vector.h +++ b/source/blender/blenlib/BLI_math_vector.h @@ -92,6 +92,7 @@ MINLINE void add_v3_fl(float r[3], float f); MINLINE void add_v4_fl(float r[4], float f); MINLINE void add_v2_v2(float r[2], const float a[2]); MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]); +MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2]); MINLINE void add_v3_v3(float r[3], const float a[3]); MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3]); MINLINE void add_v4_v4(float r[4], const float a[4]); @@ -99,6 +100,7 @@ MINLINE void add_v4_v4v4(float r[4], const float a[4], const float b[4]); MINLINE void sub_v2_v2(float r[2], const float a[2]); MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2]); +MINLINE void sub_v2_v2v2_int(int r[2], const int a[2], const int b[2]); MINLINE void sub_v3_v3(float r[3], const float a[3]); MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3]); MINLINE void sub_v4_v4(float r[4], const float a[4]); diff --git a/source/blender/blenlib/BLI_string.h b/source/blender/blenlib/BLI_string.h index 3bc9d733254..770a4c0e3ab 100644 --- a/source/blender/blenlib/BLI_string.h +++ b/source/blender/blenlib/BLI_string.h @@ -150,7 +150,7 @@ __attribute__((warn_unused_result)) __attribute__((nonnull)) #endif ; -void BLI_timestr(double _time, char *str) +void BLI_timestr(double _time, char *str, size_t maxlen) #ifdef __GNUC__ __attribute__((nonnull)) #endif diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c index d1c30504153..4c712a2f237 100644 --- a/source/blender/blenlib/intern/BLI_dynstr.c +++ b/source/blender/blenlib/intern/BLI_dynstr.c @@ -30,12 +30,11 @@ * \ingroup bli */ - -#include <stdarg.h> +#include <stdlib.h> /* malloc */ #include <string.h> #include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" +#include "BLI_string.h" #include "BLI_dynstr.h" #ifdef _WIN32 diff --git a/source/blender/blenlib/intern/DLRB_tree.c b/source/blender/blenlib/intern/DLRB_tree.c index 688372b3a28..cb47f07574d 100644 --- a/source/blender/blenlib/intern/DLRB_tree.c +++ b/source/blender/blenlib/intern/DLRB_tree.c @@ -30,7 +30,7 @@ #include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" #include "BLI_dlrbTree.h" /* *********************************************** */ diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c index 8b3cfd07ee9..ae6404153c8 100644 --- a/source/blender/blenlib/intern/fileops.c +++ b/source/blender/blenlib/intern/fileops.c @@ -30,8 +30,8 @@ */ +#include <stdlib.h> /* malloc */ #include <string.h> -#include <stdio.h> #include <sys/types.h> #include <sys/stat.h> @@ -42,10 +42,10 @@ #include "zlib.h" #ifdef WIN32 -#ifdef __MINGW32__ -#include <ctype.h> -#endif -#include <io.h> +# ifdef __MINGW32__ +# include <ctype.h> +# endif +# include <io.h> # include "BLI_winstuff.h" # include "BLI_callbacks.h" # include "utf_winfunc.h" @@ -60,8 +60,11 @@ #include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" #include "BLI_utildefines.h" +#include "BLI_listbase.h" +#include "BLI_string.h" +#include "BLI_path_util.h" +#include "BLI_fileops.h" #include "MEM_sys_types.h" // for intptr_t support @@ -374,7 +377,7 @@ void BLI_dir_create_recursive(const char *dirname) * blah1/blah2 (without slash) */ BLI_strncpy(tmp, dirname, sizeof(tmp)); - lslash = BLI_last_slash(tmp); + lslash = (char *)BLI_last_slash(tmp); if (lslash && (*(lslash + 1) == '\0')) { *lslash = '\0'; @@ -385,7 +388,7 @@ void BLI_dir_create_recursive(const char *dirname) if (BLI_exists(tmp)) return; - lslash = BLI_last_slash(tmp); + lslash = (char *)BLI_last_slash(tmp); if (lslash) { /* Split about the last slash and recurse */ diff --git a/source/blender/blenlib/intern/freetypefont.c b/source/blender/blenlib/intern/freetypefont.c index 24a8edae325..10d574e56b4 100644 --- a/source/blender/blenlib/intern/freetypefont.c +++ b/source/blender/blenlib/intern/freetypefont.c @@ -47,10 +47,11 @@ #include "MEM_guardedalloc.h" +#include "BLI_utildefines.h" #include "BLI_vfontdata.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" +#include "BLI_string.h" #include "BLI_math.h" -#include "BLI_utildefines.h" #include "DNA_vfont_types.h" #include "DNA_packedFile_types.h" diff --git a/source/blender/blenlib/intern/graph.c b/source/blender/blenlib/intern/graph.c index a93bbd97b51..cedec7d07b6 100644 --- a/source/blender/blenlib/intern/graph.c +++ b/source/blender/blenlib/intern/graph.c @@ -25,17 +25,15 @@ * \ingroup bli */ - -#include <float.h> +#include <float.h> #include <math.h> #include "MEM_guardedalloc.h" +#include "BLI_utildefines.h" +#include "BLI_listbase.h" #include "BLI_graph.h" -#include "BLI_blenlib.h" #include "BLI_math.h" -#include "BLI_utildefines.h" - static void testRadialSymmetry(BGraph *graph, BNode *root_node, RadialArc *ring, int total, float axis[3], float limit, int group); diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index 5a9e8244a46..de192d43699 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -215,18 +215,18 @@ BLI_INLINE void bicubic_interpolation(const unsigned char *byte_buffer, const fl } else { if (components == 1) { - byte_output[0] = out[0]; + byte_output[0] = out[0] + 0.5f; } else if (components == 3) { - byte_output[0] = out[0]; - byte_output[1] = out[1]; - byte_output[2] = out[2]; + byte_output[0] = out[0] + 0.5f; + byte_output[1] = out[1] + 0.5f; + byte_output[2] = out[2] + 0.5f; } else { - byte_output[0] = out[0]; - byte_output[1] = out[1]; - byte_output[2] = out[2]; - byte_output[3] = out[3]; + byte_output[0] = out[0] + 0.5f; + byte_output[1] = out[1] + 0.5f; + byte_output[2] = out[2] + 0.5f; + byte_output[3] = out[3] + 0.5f; } } } @@ -322,18 +322,18 @@ BLI_INLINE void bilinear_interpolation(const unsigned char *byte_buffer, const f a_b = a * b; ma_b = (1.0f - a) * b; a_mb = a * (1.0f - b); ma_mb = (1.0f - a) * (1.0f - b); if (components == 1) { - byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0]; + byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f; } else if (components == 3) { - byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0]; - byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1]; - byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2]; + byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f; + byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] + 0.5f; + byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] + 0.5f; } else { - byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0]; - byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1]; - byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2]; - byte_output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3]; + byte_output[0] = ma_mb * row1[0] + a_mb * row3[0] + ma_b * row2[0] + a_b * row4[0] + 0.5f; + byte_output[1] = ma_mb * row1[1] + a_mb * row3[1] + ma_b * row2[1] + a_b * row4[1] + 0.5f; + byte_output[2] = ma_mb * row1[2] + a_mb * row3[2] + ma_b * row2[2] + a_b * row4[2] + 0.5f; + byte_output[3] = ma_mb * row1[3] + a_mb * row3[3] + ma_b * row2[3] + a_b * row4[3] + 0.5f; } } } diff --git a/source/blender/blenlib/intern/math_vector_inline.c b/source/blender/blenlib/intern/math_vector_inline.c index c8e8ff9602b..cce78b5e5d2 100644 --- a/source/blender/blenlib/intern/math_vector_inline.c +++ b/source/blender/blenlib/intern/math_vector_inline.c @@ -271,6 +271,12 @@ MINLINE void add_v2_v2v2(float r[2], const float a[2], const float b[2]) r[1] = a[1] + b[1]; } +MINLINE void add_v2_v2v2_int(int r[2], const int a[2], const int b[2]) +{ + r[0] = a[0] + b[0]; + r[1] = a[1] + b[1]; +} + MINLINE void add_v3_v3(float r[3], const float a[3]) { r[0] += a[0]; @@ -313,6 +319,12 @@ MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2]) r[1] = a[1] - b[1]; } +MINLINE void sub_v2_v2v2_int(int r[2], const int a[2], const int b[2]) +{ + r[0] = a[0] - b[0]; + r[1] = a[1] - b[1]; +} + MINLINE void sub_v3_v3(float r[3], const float a[3]) { r[0] -= a[0]; diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c index 6b9b371a4f3..1f96c10e712 100644 --- a/source/blender/blenlib/intern/path_util.c +++ b/source/blender/blenlib/intern/path_util.c @@ -61,7 +61,8 @@ #endif #ifdef WIN32 -#include "utf_winfunc.h" +# include "utf_winfunc.h" +# include "utfconv.h" # include <io.h> # ifdef _WIN32_IE # undef _WIN32_IE diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c index 906a3095f91..ba914944733 100644 --- a/source/blender/blenlib/intern/string.c +++ b/source/blender/blenlib/intern/string.c @@ -490,22 +490,20 @@ int BLI_natstrcmp(const char *s1, const char *s2) return 0; } -void BLI_timestr(double _time, char *str) +void BLI_timestr(double _time, char *str, size_t maxlen) { /* format 00:00:00.00 (hr:min:sec) string has to be 12 long */ int hr = ( (int) _time) / (60 * 60); int min = (((int) _time) / 60 ) % 60; - int sec = ( (int) (_time)) % 60; + int sec = ( (int) _time) % 60; int hun = ( (int) (_time * 100.0)) % 100; - + if (hr) { - sprintf(str, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun); + BLI_snprintf(str, maxlen, "%.2d:%.2d:%.2d.%.2d", hr, min, sec, hun); } else { - sprintf(str, "%.2d:%.2d.%.2d", min, sec, hun); + BLI_snprintf(str, maxlen, "%.2d:%.2d.%.2d", min, sec, hun); } - - str[11] = 0; } /* determine the length of a fixed-size string */ diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c index fe8f3c20ab4..0b8cc126a86 100644 --- a/source/blender/blenlib/intern/string_utf8.c +++ b/source/blender/blenlib/intern/string_utf8.c @@ -602,7 +602,7 @@ size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf) * * Return value: a pointer to the found character or %NULL. **/ -char * BLI_str_find_prev_char_utf8(const char *str, const char *p) +char *BLI_str_find_prev_char_utf8(const char *str, const char *p) { for (--p; p >= str; --p) { if ((*p & 0xc0) != 0x80) { diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c index a74f82ae965..1d3312fafb1 100644 --- a/source/blender/blenlib/intern/threads.c +++ b/source/blender/blenlib/intern/threads.c @@ -29,14 +29,13 @@ * \ingroup bli */ - +#include <stdlib.h> #include <errno.h> #include <string.h> #include "MEM_guardedalloc.h" - -#include "BLI_blenlib.h" +#include "BLI_listbase.h" #include "BLI_gsqueue.h" #include "BLI_threads.h" diff --git a/source/blender/blenloader/BLO_sys_types.h b/source/blender/blenloader/BLO_sys_types.h index 4e76481c394..73434259432 100644 --- a/source/blender/blenloader/BLO_sys_types.h +++ b/source/blender/blenloader/BLO_sys_types.h @@ -100,10 +100,6 @@ typedef uint64_t u_int64_t; #include <inttypes.h> #elif defined(FREE_WINDOWS) -#ifndef FREE_WINDOWS64 -/* define htoln here, there must be a syntax error in winsock2.h in MinGW */ -unsigned long __attribute__((__stdcall__)) htonl(unsigned long); -#endif #include <stdint.h> #else diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index a6dc4d242e9..b727aae64dd 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -6364,7 +6364,6 @@ static void direct_link_screen(FileData *fd, bScreen *sc) sclip->scopes.track_search = NULL; sclip->scopes.track_preview = NULL; - sclip->draw_context = NULL; sclip->scopes.ok = 0; } } @@ -8127,7 +8126,7 @@ static void do_versions(FileData *fd, Library *lib, Main *main) if (ba->axis==(float) 'x') ba->axis=OB_POSX; else if (ba->axis==(float)'y') ba->axis=OB_POSY; /* don't do an if/else to avoid imediate subversion bump*/ -// ba->axis=((ba->axis == (float) 'x')?OB_POSX_X:OB_POSY); +// ba->axis=((ba->axis == (float)'x') ? OB_POSX_X : OB_POSY); } } } @@ -9269,7 +9268,18 @@ static void do_versions(FileData *fd, Library *lib, Main *main) } if (main->versionfile < 267) { - + //if(!DNA_struct_elem_find(fd->filesdna, "Brush", "int", "stencil_pos")) { + Brush *brush; + + for (brush = main->brush.first; brush; brush = brush->id.next) { + if (brush->stencil_dimension[0] == 0) { + brush->stencil_dimension[0] = 256; + brush->stencil_dimension[1] = 256; + brush->stencil_pos[0] = 256; + brush->stencil_pos[1] = 256; + } + } + /* TIP: to initialize new variables added, use the new function DNA_struct_elem_find(fd->filesdna, "structname", "typename", "varname") example: diff --git a/source/blender/blenloader/intern/versioning_250.c b/source/blender/blenloader/intern/versioning_250.c index c00569e4b51..2445775ad44 100644 --- a/source/blender/blenloader/intern/versioning_250.c +++ b/source/blender/blenloader/intern/versioning_250.c @@ -1070,7 +1070,7 @@ void blo_do_versions_250(FileData *fd, Library *lib, Main *main) sce->gm.dome.warptext = sce->r.dometext; /* Stand Alone */ - sce->gm.playerflag |= (sce->r.fullscreen?GAME_PLAYER_FULLSCREEN:0); + sce->gm.playerflag |= (sce->r.fullscreen ? GAME_PLAYER_FULLSCREEN : 0); sce->gm.xplay = sce->r.xplay; sce->gm.yplay = sce->r.yplay; sce->gm.freqplay = sce->r.freqplay; diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index e8426c58324..011f9df6f8c 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -801,9 +801,9 @@ static void current_screen_compat(Main *mainvar, bScreen **screen) /* find a global current screen in the first open window, to have * a reasonable default for reading in older versions */ - wm= mainvar->wm.first; - window= (wm)? wm->windows.first: NULL; - *screen= (window)? window->screen: NULL; + wm = mainvar->wm.first; + window = (wm) ? wm->windows.first : NULL; + *screen = (window) ? window->screen : NULL; } typedef struct RenderInfo { @@ -3225,7 +3225,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) /* XXX still remap G */ fg.curscreen= screen; - fg.curscene= screen? screen->scene : NULL; + fg.curscene= screen ? screen->scene : NULL; fg.displaymode= G.displaymode; fg.winpos= G.winpos; @@ -3286,7 +3286,11 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil } #endif - sprintf(buf, "BLENDER%c%c%.3d", (sizeof(void*)==8)?'-':'_', (ENDIAN_ORDER==B_ENDIAN)?'V':'v', BLENDER_VERSION); + sprintf(buf, "BLENDER%c%c%.3d", + (sizeof(void *) == 8) ? '-' : '_', + (ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v', + BLENDER_VERSION); + mywrite(wd, buf, 12); write_renderinfo(wd, mainvar); diff --git a/source/blender/bmesh/intern/bmesh_iterators.c b/source/blender/bmesh/intern/bmesh_iterators.c index a1dde035224..89348f23b9d 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.c +++ b/source/blender/bmesh/intern/bmesh_iterators.c @@ -105,6 +105,33 @@ int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, cons return i; } +/** + * \brief Operator Iterator as Array + * + * Sometimes its convenient to get the iterator as an array. + */ +int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask, + void **array, const int len) +{ + int i = 0; + + /* sanity check */ + if (len > 0) { + BMOIter oiter; + void *ele; + + for (ele = BMO_iter_new(&oiter, slot_args, slot_name, restrictmask); ele; ele = BMO_iter_step(&oiter)) { + array[i] = ele; + i++; + if (i == len) { + return len; + } + } + } + + return i; +} + /** * \brief Iterator as Array diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h index 5fb226ae11d..c90fba7898a 100644 --- a/source/blender/bmesh/intern/bmesh_iterators.h +++ b/source/blender/bmesh/intern/bmesh_iterators.h @@ -131,6 +131,9 @@ void *BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len, __attribute__((warn_unused_result)) #endif ; +int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask, + void **array, const int len); + int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value); int BMO_iter_elem_count_flag(BMesh *bm, const char itype, void *data, const short oflag, const bool value); int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value); diff --git a/source/blender/bmesh/operators/bmo_beautify.c b/source/blender/bmesh/operators/bmo_beautify.c index adf8ed4df67..68d0c662b2c 100644 --- a/source/blender/bmesh/operators/bmo_beautify.c +++ b/source/blender/bmesh/operators/bmo_beautify.c @@ -22,9 +22,21 @@ /** \file blender/bmesh/operators/bmo_beautify.c * \ingroup bmesh + * + * Beautify the mesh by rotating edes between triangles + * to more attractive positions until no more rotations can be made. + * + * In princible this is very simple however there is the possability of + * going into an eternal loop where edges keep rotating. + * To avoid this - each edge stores a hash of it previous + * states so as not to rotate back. + * + * TODO + * - Take face normals into account. */ #include "BLI_math.h" +#include "BLI_heap.h" #include "MEM_guardedalloc.h" @@ -112,21 +124,159 @@ static void erot_state_alternate(const BMEdge *e, EdRotState *e_state) } /* -------------------------------------------------------------------- */ -/* Util for setting edge tag once rotated */ +/* Calculate the improvement of rotating the edge */ + +/** + * \return a negative value means the edge can be rotated. + */ +static float bm_edge_calc_rotate_beauty(const BMEdge *e) +{ + /* not a loop (only to be able to break out) */ + do { + float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2]; + + /* first get the 2d values */ + { + const float *v1, *v2, *v3, *v4; + bool is_zero_a, is_zero_b; + float no[3]; + float axis_mat[3][3]; + + v1 = e->l->prev->v->co; /* first face co */ + v2 = e->l->v->co; /* e->v1 or e->v2*/ + v3 = e->l->radial_next->prev->v->co; /* second face co */ + v4 = e->l->next->v->co; /* e->v1 or e->v2*/ + + if (UNLIKELY(v1 == v3)) { + // printf("This should never happen, but does sometimes!\n"); + break; + } + + // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f); + BLI_assert((ELEM3(v1, v2, v3, v4) == false) && + (ELEM3(v2, v1, v3, v4) == false) && + (ELEM3(v3, v1, v2, v4) == false) && + (ELEM3(v4, v1, v2, v3) == false)); + + is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON; + is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON; + + if (LIKELY(is_zero_a == false && is_zero_b == false)) { + float no_a[3], no_b[3]; + normal_tri_v3(no_a, v2, v3, v4); /* a */ + normal_tri_v3(no_b, v2, v4, v1); /* b */ + add_v3_v3v3(no, no_a, no_b); + if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) { + break; + } + } + else if (is_zero_a == false) { + normal_tri_v3(no, v2, v3, v4); /* a */ + } + else if (is_zero_b == false) { + normal_tri_v3(no, v2, v4, v1); /* b */ + } + else { + /* both zero area, no useful normal can be calculated */ + break; + } + + // { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);} + + axis_dominant_v3_to_m3(axis_mat, no); + mul_v2_m3v3(v1_xy, axis_mat, v1); + mul_v2_m3v3(v2_xy, axis_mat, v2); + mul_v2_m3v3(v3_xy, axis_mat, v3); + mul_v2_m3v3(v4_xy, axis_mat, v4); + } + + // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f); + + if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) { + float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2; + /* testing rule: + * the area divided by the total edge lengths + */ + len1 = len_v2v2(v1_xy, v2_xy); + len2 = len_v2v2(v2_xy, v3_xy); + len3 = len_v2v2(v3_xy, v4_xy); + len4 = len_v2v2(v4_xy, v1_xy); + len5 = len_v2v2(v1_xy, v3_xy); + len6 = len_v2v2(v2_xy, v4_xy); + + opp1 = area_tri_v2(v1_xy, v2_xy, v3_xy); + opp2 = area_tri_v2(v1_xy, v3_xy, v4_xy); + + fac1 = opp1 / (len1 + len2 + len5) + opp2 / (len3 + len4 + len5); + + opp1 = area_tri_v2(v2_xy, v3_xy, v4_xy); + opp2 = area_tri_v2(v2_xy, v4_xy, v1_xy); + + fac2 = opp1 / (len2 + len3 + len6) + opp2 / (len4 + len1 + len6); + /* negative number if we're OK */ + return fac2 - fac1; + } + } while (false); + + return FLT_MAX; +} + +/* -------------------------------------------------------------------- */ +/* Update the edge cost of rotation in the heap */ + +/* recalc an edge in the heap (surrounding geometry has changed) */ +static void bm_edge_update_beauty_cost_single(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GHash **edge_state_arr) +{ + if (BM_elem_flag_test(e, BM_ELEM_TAG)) { + const int i = BM_elem_index_get(e); + GHash *e_state_hash = edge_state_arr[i]; + + if (eheap_table[i]) { + BLI_heap_remove(eheap, eheap_table[i]); + eheap_table[i] = NULL; + } + + /* check if we can add it back */ + BLI_assert(BM_edge_is_manifold(e) == true); + //BLI_assert(BMO_elem_flag_test(bm, e->l->f, FACE_MARK) && + // BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK)); + + /* check we're not moving back into a state we have been in before */ + if (e_state_hash != NULL) { + EdRotState e_state_alt; + erot_state_alternate(e, &e_state_alt); + if (BLI_ghash_haskey(e_state_hash, (void *)&e_state_alt)) { + // printf(" skipping, we already have this state\n"); + return; + } + } + + { + /* recalculate edge */ + const float cost = bm_edge_calc_rotate_beauty(e); + if (cost < 0.0f) { + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + } + else { + eheap_table[i] = NULL; + } + } + } +} /* we have rotated an edge, tag other egdes and clear this one */ -static void bm_edge_tag_rotated(BMEdge *e) +static void bm_edge_update_beauty_cost(BMEdge *e, Heap *eheap, HeapNode **eheap_table, GHash **edge_state_arr) { BMLoop *l; BLI_assert(e->l->f->len == 3 && e->l->radial_next->f->len == 3); l = e->l; - BM_elem_flag_enable(l->next->e, BM_ELEM_TAG); - BM_elem_flag_enable(l->prev->e, BM_ELEM_TAG); + bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr); + bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr); l = l->radial_next; - BM_elem_flag_enable(l->next->e, BM_ELEM_TAG); - BM_elem_flag_enable(l->prev->e, BM_ELEM_TAG); + bm_edge_update_beauty_cost_single(l->next->e, eheap, eheap_table, edge_state_arr); + bm_edge_update_beauty_cost_single(l->prev->e, eheap, eheap_table, edge_state_arr); } /* -------------------------------------------------------------------- */ @@ -141,160 +291,71 @@ static void bm_edge_tag_rotated(BMEdge *e) */ static void bm_mesh_beautify_fill(BMesh *bm, BMEdge **edge_array, const int edge_array_len) { + Heap *eheap; /* edge heap */ + HeapNode **eheap_table; /* edge index aligned table pointing to the eheap */ + GHash **edge_state_arr = MEM_callocN(edge_array_len * sizeof(GHash *), __func__); BLI_mempool *edge_state_pool = BLI_mempool_create(sizeof(EdRotState), 512, 512, BLI_MEMPOOL_SYSMALLOC); - bool is_breaked; int i; #ifdef DEBUG_TIME TIMEIT_START(beautify_fill); #endif - do { - is_breaked = true; - - for (i = 0; i < edge_array_len; i++) { - BMEdge *e = edge_array[i]; - GHash *e_state_hash; - - float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2]; - - BLI_assert(BM_edge_is_manifold(e) == true); - BLI_assert(BMO_elem_flag_test(bm, e->l->f, FACE_MARK) && - BMO_elem_flag_test(bm, e->l->radial_next->f, FACE_MARK)); + eheap = BLI_heap_new_ex(edge_array_len); + eheap_table = MEM_mallocN(sizeof(HeapNode *) * edge_array_len, __func__); - if (!BM_elem_flag_test(e, BM_ELEM_TAG)) { - continue; - } - else { - /* don't check this edge again, unless adjaced edges are rotated */ - BM_elem_flag_disable(e, BM_ELEM_TAG); - } + /* build heap */ + for (i = 0; i < edge_array_len; i++) { + BMEdge *e = edge_array[i]; + const float cost = bm_edge_calc_rotate_beauty(e); + if (cost < 0.0f) { + eheap_table[i] = BLI_heap_insert(eheap, cost, e); + } + else { + eheap_table[i] = NULL; + } + } - /* check we're not moving back into a state we have been in before */ - e_state_hash = edge_state_arr[i]; - if (e_state_hash != NULL) { - EdRotState e_state_alt; - erot_state_alternate(e, &e_state_alt); - if (BLI_ghash_haskey(e_state_hash, (void *)&e_state_alt)) { - // printf(" skipping, we already have this state\n"); - continue; - } + while (BLI_heap_is_empty(eheap) == false) { + BMEdge *e = BLI_heap_popmin(eheap); + i = BM_elem_index_get(e); + eheap_table[i] = NULL; + + e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS); + if (LIKELY(e)) { + GHash *e_state_hash = edge_state_arr[i]; + + /* add the new state into the hash so we don't move into this state again + * note: we could add the previous state too but this isn't essential) + * for avoiding eternal loops */ + EdRotState *e_state = BLI_mempool_alloc(edge_state_pool); + erot_state_current(e, e_state); + if (UNLIKELY(e_state_hash == NULL)) { + edge_state_arr[i] = e_state_hash = erot_ghash_new(); /* store previous state */ } + BLI_assert(BLI_ghash_haskey(e_state_hash, (void *)e_state) == false); + BLI_ghash_insert(e_state_hash, e_state, NULL); - { - const float *v1, *v2, *v3, *v4; - bool is_zero_a, is_zero_b; - float no[3]; - float axis_mat[3][3]; - - v1 = e->l->prev->v->co; /* first face co */ - v2 = e->l->v->co; /* e->v1 or e->v2*/ - v3 = e->l->radial_next->prev->v->co; /* second face co */ - v4 = e->l->next->v->co; /* e->v1 or e->v2*/ - - if (UNLIKELY(v1 == v3)) { - // printf("This should never happen, but does sometimes!\n"); - continue; - } - - // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f); - BLI_assert((ELEM3(v1, v2, v3, v4) == false) && - (ELEM3(v2, v1, v3, v4) == false) && - (ELEM3(v3, v1, v2, v4) == false) && - (ELEM3(v4, v1, v2, v3) == false)); - - is_zero_a = area_tri_v3(v2, v3, v4) <= FLT_EPSILON; - is_zero_b = area_tri_v3(v2, v4, v1) <= FLT_EPSILON; - - if (LIKELY(is_zero_a == false && is_zero_b == false)) { - float no_a[3], no_b[3]; - normal_tri_v3(no_a, v2, v3, v4); /* a */ - normal_tri_v3(no_b, v2, v4, v1); /* b */ - add_v3_v3v3(no, no_a, no_b); - if (UNLIKELY(normalize_v3(no) <= FLT_EPSILON)) { - continue; - } - } - else if (is_zero_a == false) { - normal_tri_v3(no, v2, v3, v4); /* a */ - } - else if (is_zero_b == false) { - normal_tri_v3(no, v2, v4, v1); /* b */ - } - else { - /* both zero area, no useful normal can be calculated */ - continue; - } - // { float a = angle_normalized_v3v3(no_a, no_b); printf("~ %.7f\n", a); fflush(stdout);} + // printf(" %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2)); - axis_dominant_v3_to_m3(axis_mat, no); - mul_v2_m3v3(v1_xy, axis_mat, v1); - mul_v2_m3v3(v2_xy, axis_mat, v2); - mul_v2_m3v3(v3_xy, axis_mat, v3); - mul_v2_m3v3(v4_xy, axis_mat, v4); - } + /* maintain the index array */ + edge_array[i] = e; + BM_elem_index_set(e, i); - // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4, e->l->f, e->l->radial_next->f); + /* recalculate faces connected on the heap */ + bm_edge_update_beauty_cost(e, eheap, eheap_table, edge_state_arr); - if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy)) { - float len1, len2, len3, len4, len5, len6, opp1, opp2, fac1, fac2; - /* testing rule: - * the area divided by the total edge lengths - */ - len1 = len_v2v2(v1_xy, v2_xy); - len2 = len_v2v2(v2_xy, v3_xy); - len3 = len_v2v2(v3_xy, v4_xy); - len4 = len_v2v2(v4_xy, v1_xy); - len5 = len_v2v2(v1_xy, v3_xy); - len6 = len_v2v2(v2_xy, v4_xy); - - opp1 = area_tri_v2(v1_xy, v2_xy, v3_xy); - opp2 = area_tri_v2(v1_xy, v3_xy, v4_xy); - - fac1 = opp1 / (len1 + len2 + len5) + opp2 / (len3 + len4 + len5); - - opp1 = area_tri_v2(v2_xy, v3_xy, v4_xy); - opp2 = area_tri_v2(v2_xy, v4_xy, v1_xy); - - fac2 = opp1 / (len2 + len3 + len6) + opp2 / (len4 + len1 + len6); - - if (fac1 > fac2) { - e = BM_edge_rotate(bm, e, false, BM_EDGEROT_CHECK_EXISTS); - if (LIKELY(e)) { - - /* add the new state into the hash so we don't move into this state again - * note: we could add the previous state too but this isn't essential) - * for avoiding eternal loops */ - EdRotState *e_state = BLI_mempool_alloc(edge_state_pool); - erot_state_current(e, e_state); - if (UNLIKELY(e_state_hash == NULL)) { - edge_state_arr[i] = e_state_hash = erot_ghash_new(); /* store previous state */ - } - BLI_assert(BLI_ghash_haskey(e_state_hash, (void *)e_state) == false); - BLI_ghash_insert(e_state_hash, e_state, NULL); - - - // printf(" %d -> %d, %d\n", i, BM_elem_index_get(e->v1), BM_elem_index_get(e->v2)); - - /* maintain the index array */ - edge_array[i] = e; - BM_elem_index_set(e, i); - - /* tag other edges so we know to check them again */ - bm_edge_tag_rotated(e); - - /* update flags */ - BMO_elem_flag_enable(bm, e, ELE_NEW); - BMO_elem_flag_enable(bm, e->l->f, FACE_MARK | ELE_NEW); - BMO_elem_flag_enable(bm, e->l->radial_next->f, FACE_MARK | ELE_NEW); - is_breaked = false; - } - } - } + /* update flags */ + BMO_elem_flag_enable(bm, e, ELE_NEW); + BMO_elem_flag_enable(bm, e->l->f, FACE_MARK | ELE_NEW); + BMO_elem_flag_enable(bm, e->l->radial_next->f, FACE_MARK | ELE_NEW); } - } while (is_breaked == false); + } + + BLI_heap_free(eheap, NULL); + MEM_freeN(eheap_table); for (i = 0; i < edge_array_len; i++) { if (edge_state_arr[i]) { diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c index 052ae9336ab..dc06b0b4f13 100644 --- a/source/blender/bmesh/operators/bmo_bevel.c +++ b/source/blender/bmesh/operators/bmo_bevel.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_bevel.c * \ingroup bmesh + * + * Bevel wrapper around #BM_mesh_bevel */ #include "BLI_utildefines.h" diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c index dc00d020083..2e9cb11569d 100644 --- a/source/blender/bmesh/operators/bmo_connect.c +++ b/source/blender/bmesh/operators/bmo_connect.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_connect.c * \ingroup bmesh + * + * Connect verts across faces (splits faces) and bridge tool. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c index 86904155cd3..ad858c514d2 100644 --- a/source/blender/bmesh/operators/bmo_create.c +++ b/source/blender/bmesh/operators/bmo_create.c @@ -15,13 +15,15 @@ * 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): Joseph Eagar. + * Contributor(s): Joseph Eagar, Campbell Barton. * * ***** END GPL LICENSE BLOCK ***** */ /** \file blender/bmesh/operators/bmo_create.c - * \ingroup bmesh + * \ingroup bmesh + * + * Create faces or edges (Fkey by default). */ #include "MEM_guardedalloc.h" @@ -41,14 +43,9 @@ */ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) { - BMOperator op2; BMOIter oiter; - BMIter iter; BMHeader *h; - BMVert *v, *verts[4]; - BMEdge *e; - BMFace *f; - int totv = 0, tote = 0, totf = 0, amount; + int totv = 0, tote = 0, totf = 0; const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr"); const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth"); @@ -63,6 +60,24 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) BMO_elem_flag_enable(bm, (BMElemF *)h, ELE_NEW); } + /* --- Support Edge Creation --- + * simple case when we only have 2 verts selected. + */ + if (totv == 2 && tote == 0 && totf == 0) { + BMVert *verts[2]; + BMEdge *e; + + BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)verts, 2); + + /* create edge */ + e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE); + BMO_elem_flag_enable(bm, e, ELE_OUT); + tote += 1; + BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT); + return; + } + + /* --- Support for Special Case --- * where there is a contiguous edge ring with one isolated vertex. * @@ -83,29 +98,20 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) /* Here we check for consistency and create 2 edges */ if (totf == 0 && totv >= 4 && totv == tote + 2) { /* find a free standing vertex and 2 endpoint verts */ - BMVert *v_free = NULL, *v_a = NULL, *v_b = NULL; + BMVert *v, *v_free = NULL, *v_a = NULL, *v_b = NULL; bool ok = true; BMO_ITER (v, &oiter, op->slots_in, "geom", BM_VERT) { /* count how many flagged edges this vertex uses */ - int tot_edges = 0; - BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) { - if (BMO_elem_flag_test(bm, e, ELE_NEW)) { - tot_edges++; - if (tot_edges > 2) { - break; - } - } - } - + const int tot_edges = BMO_iter_elem_count_flag(bm, BM_EDGES_OF_VERT, v, ELE_NEW, true); if (tot_edges == 0) { /* only accept 1 free vert */ if (v_free == NULL) v_free = v; else ok = false; /* only ever want one of these */ } else if (tot_edges == 1) { - if (v_a == NULL) v_a = v; + if (v_a == NULL) v_a = v; else if (v_b == NULL) v_b = v; else ok = false; /* only ever want 2 of these */ } @@ -122,6 +128,8 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) } if (ok == true && v_free && v_a && v_b) { + BMEdge *e; + e = BM_edge_create(bm, v_free, v_a, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_NEW); @@ -135,92 +143,81 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) /* -------------------------------------------------------------------- */ /* EdgeNet Create */ + if (tote != 0) { + /* call edgenet prepare op so additional face creation cases work */ + BMOperator op_sub; + BMO_op_initf(bm, &op_sub, op->flag, "edgenet_prepare edges=%fe", ELE_NEW); + BMO_op_exec(bm, &op_sub); + BMO_slot_buffer_flag_enable(bm, op_sub.slots_out, "edges.out", BM_EDGE, ELE_NEW); + BMO_op_finish(bm, &op_sub); + + BMO_op_initf(bm, &op_sub, op->flag, + "edgenet_fill edges=%fe use_fill_check=%b mat_nr=%i use_smooth=%b", + ELE_NEW, true, mat_nr, use_smooth); + + BMO_op_exec(bm, &op_sub); + + /* return if edge net create did something */ + if (BMO_slot_buffer_count(op_sub.slots_out, "faces.out")) { + BMO_slot_copy(&op_sub, slots_out, "faces.out", + op, slots_out, "faces.out"); + BMO_op_finish(bm, &op_sub); + return; + } - /* call edgenet prepare op so additional face creation cases wore */ - BMO_op_initf(bm, &op2, op->flag, "edgenet_prepare edges=%fe", ELE_NEW); - BMO_op_exec(bm, &op2); - BMO_slot_buffer_flag_enable(bm, op2.slots_out, "edges.out", BM_EDGE, ELE_NEW); - BMO_op_finish(bm, &op2); - - BMO_op_initf(bm, &op2, op->flag, - "edgenet_fill edges=%fe use_fill_check=%b mat_nr=%i use_smooth=%b", - ELE_NEW, true, mat_nr, use_smooth); - - BMO_op_exec(bm, &op2); - - /* return if edge net create did something */ - if (BMO_slot_buffer_count(op2.slots_out, "faces.out")) { - BMO_slot_copy(&op2, slots_out, "faces.out", - op, slots_out, "faces.out"); - BMO_op_finish(bm, &op2); - return; + BMO_op_finish(bm, &op_sub); } - BMO_op_finish(bm, &op2); - /* -------------------------------------------------------------------- */ /* Dissolve Face */ - BMO_op_initf(bm, &op2, op->flag, "dissolve_faces faces=%ff", ELE_NEW); - BMO_op_exec(bm, &op2); - - /* if we dissolved anything, then return */ - if (BMO_slot_buffer_count(op2.slots_out, "region.out")) { - BMO_slot_copy(&op2, slots_out, "region.out", - op, slots_out, "faces.out"); - BMO_op_finish(bm, &op2); - return; - } + if (totf != 0) { /* should be (totf > 1)... see below */ + /* note: allow this to run on single faces so running on a single face + * won't go on to create a face, treating them as random */ + BMOperator op_sub; + BMO_op_initf(bm, &op_sub, op->flag, "dissolve_faces faces=%ff", ELE_NEW); + BMO_op_exec(bm, &op_sub); + + /* if we dissolved anything, then return */ + if (BMO_slot_buffer_count(op_sub.slots_out, "region.out")) { + BMO_slot_copy(&op_sub, slots_out, "region.out", + op, slots_out, "faces.out"); + BMO_op_finish(bm, &op_sub); + return; + } - BMO_op_finish(bm, &op2); + BMO_op_finish(bm, &op_sub); + } /* -------------------------------------------------------------------- */ /* Fill EdgeLoop's - fills isolated loops, different from edgenet */ + if (tote > 2) { + BMOperator op_sub; + /* note: in most cases 'edgenet_fill' will handle this case since in common cases + * users fill in empty spaces, however its possible to have an edge selection around + * existing geometry that makes 'edgenet_fill' fail. */ + BMO_op_initf(bm, &op_sub, op->flag, "edgeloop_fill edges=%fe", ELE_NEW); + BMO_op_exec(bm, &op_sub); + + /* return if edge loop fill did something */ + if (BMO_slot_buffer_count(op_sub.slots_out, "faces.out")) { + BMO_slot_copy(&op_sub, slots_out, "faces.out", + op, slots_out, "faces.out"); + BMO_op_finish(bm, &op_sub); + return; + } - /* note: in most cases 'edgenet_fill' will handle this case since in common cases - * users fill in empty spaces, however its possible to have an edge selection around - * existing geometry that makes 'edgenet_fill' fail. */ - BMO_op_initf(bm, &op2, op->flag, "edgeloop_fill edges=%fe", ELE_NEW); - BMO_op_exec(bm, &op2); - - /* return if edge loop fill did something */ - if (BMO_slot_buffer_count(op2.slots_out, "faces.out")) { - BMO_slot_copy(&op2, slots_out, "faces.out", - op, slots_out, "faces.out"); - BMO_op_finish(bm, &op2); - return; + BMO_op_finish(bm, &op_sub); } - BMO_op_finish(bm, &op2); - /* -------------------------------------------------------------------- */ /* Continue with ad-hoc fill methods since operators fail, * edge, vcloud... may add more */ - /* now, count how many verts we have */ - amount = 0; - BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { - if (BMO_elem_flag_test(bm, v, ELE_NEW)) { - verts[amount] = v; - if (amount == 3) { - break; - } - amount++; - - } - } - - if (amount == 2) { - /* create edge */ - e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE); - BMO_elem_flag_enable(bm, e, ELE_OUT); - tote += 1; - BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT); - } - else if (0) { /* nice feature but perhaps it should be a different tool? */ + if (0) { /* nice feature but perhaps it should be a different tool? */ /* tricky feature for making a line/edge from selection history... * @@ -255,9 +252,9 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) for (ese = bm->selected.first; ese; ese = ese->next) { if (ese->htype == BM_VERT) { - v = (BMVert *)ese->ele; + BMVert *v = (BMVert *)ese->ele; if (v_prev) { - e = BM_edge_create(bm, v, v_prev, NULL, BM_CREATE_NO_DOUBLE); + BMEdge *e = BM_edge_create(bm, v, v_prev, NULL, BM_CREATE_NO_DOUBLE); BMO_elem_flag_enable(bm, e, ELE_OUT); } v_prev = v; @@ -266,20 +263,25 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) } BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT); /* done creating edges */ + + return; } - else if (amount > 2) { + + + /* -------------------------------------------------------------------- */ + /* Fill Vertex Cloud + * + * last resort when all else fails. + */ + if (totv > 2) { /* TODO, some of these vertes may be connected by edges, * this connectivity could be used rather then treating * them as a bunch of isolated verts. */ BMVert **vert_arr = MEM_mallocN(sizeof(BMVert **) * totv, __func__); - int i = 0; - - BMO_ITER (v, &oiter, op->slots_in, "geom", BM_VERT) { - vert_arr[i] = v; - i++; - } + BMFace *f; + BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)vert_arr, totv); f = BM_face_create_ngon_vcloud(bm, vert_arr, totv, BM_CREATE_NO_DOUBLE); if (f) { @@ -293,6 +295,4 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op) MEM_freeN(vert_arr); } - - (void)tote; } diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c index 4a241ca645f..13d706d8eed 100644 --- a/source/blender/bmesh/operators/bmo_dissolve.c +++ b/source/blender/bmesh/operators/bmo_dissolve.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_dissolve.c * \ingroup bmesh + * + * Removes isolated geometry regions without creating holes in the mesh. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c index 1448129ccde..9cc96fdca5a 100644 --- a/source/blender/bmesh/operators/bmo_dupe.c +++ b/source/blender/bmesh/operators/bmo_dupe.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_dupe.c * \ingroup bmesh + * + * Duplicate, Split, Spint operators. */ #include "MEM_guardedalloc.h" @@ -124,7 +126,6 @@ static BMEdge *copy_edge(BMOperator *op, * * Copy an existing face from one bmesh to another. */ - static BMFace *copy_face(BMOperator *op, BMOpSlot *slot_facemap_out, BMesh *source_mesh, @@ -183,7 +184,6 @@ static BMFace *copy_face(BMOperator *op, * * Internal Copy function. */ - static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst) { @@ -320,7 +320,6 @@ static void bmo_mesh_copy(BMOperator *op, BMesh *bm_src, BMesh *bm_dst) * BMOP_DUPE_ENEW: Buffer containing pointers to the new mesh edges * BMOP_DUPE_FNEW: Buffer containing pointers to the new mesh faces */ - void bmo_duplicate_exec(BMesh *bm, BMOperator *op) { BMOperator *dupeop = op; @@ -378,11 +377,10 @@ void BMO_dupe_from_flag(BMesh *bm, int htype, const char hflag) * BMOP_DUPE_EOUTPUT: Buffer containing pointers to the split mesh edges * BMOP_DUPE_FOUTPUT: Buffer containing pointers to the split mesh faces */ - -#define SPLIT_INPUT 1 - void bmo_split_exec(BMesh *bm, BMOperator *op) { +#define SPLIT_INPUT 1 + BMOperator *splitop = op; BMOperator dupeop; BMOperator delop; @@ -455,6 +453,8 @@ void bmo_split_exec(BMesh *bm, BMOperator *op) /* cleanup */ BMO_op_finish(bm, &delop); BMO_op_finish(bm, &dupeop); + +#undef SPLIT_INPUT } @@ -478,7 +478,6 @@ void bmo_delete_exec(BMesh *bm, BMOperator *op) * Extrude or duplicate geometry a number of times, * rotating and possibly translating after each step */ - void bmo_spin_exec(BMesh *bm, BMOperator *op) { BMOperator dupop, extop; diff --git a/source/blender/bmesh/operators/bmo_edgeloop_fill.c b/source/blender/bmesh/operators/bmo_edgeloop_fill.c index 3818f449a15..604feeeef5d 100644 --- a/source/blender/bmesh/operators/bmo_edgeloop_fill.c +++ b/source/blender/bmesh/operators/bmo_edgeloop_fill.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_edgeloop_fill.c * \ingroup bmesh + * + * Fill discreet edge loop(s) with faces. */ #include "MEM_guardedalloc.h" @@ -54,6 +56,7 @@ void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op) const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth"); /* 'VERT_USED' will be disabled, so enable and fill the array */ + i = 0; BMO_ITER (e, &oiter, op->slots_in, "edges", BM_EDGE) { BMIter viter; BMO_elem_flag_enable(bm, e, EDGE_MARK); @@ -61,7 +64,7 @@ void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op) if (BMO_elem_flag_test(bm, v, VERT_USED) == false) { BMO_elem_flag_enable(bm, v, VERT_USED); verts[i++] = v; - if (i > tote) { + if (i == tote) { break; } } diff --git a/source/blender/bmesh/operators/bmo_edgenet.c b/source/blender/bmesh/operators/bmo_edgenet.c index cf91dfd0f15..a4af570ded0 100644 --- a/source/blender/bmesh/operators/bmo_edgenet.c +++ b/source/blender/bmesh/operators/bmo_edgenet.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_edgenet.c * \ingroup bmesh + * + * Edge-Net for filling in open edge-loops. */ #include "MEM_guardedalloc.h" @@ -43,7 +45,6 @@ #define FACE_NEW 1 #define ELE_NEW 1 -#define ELE_OUT 2 #define ELE_ORIG 4 #define FACE_IGNORE 16 diff --git a/source/blender/bmesh/operators/bmo_extrude.c b/source/blender/bmesh/operators/bmo_extrude.c index 62220510623..acb1001ca83 100644 --- a/source/blender/bmesh/operators/bmo_extrude.c +++ b/source/blender/bmesh/operators/bmo_extrude.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_extrude.c * \ingroup bmesh + * + * Extrude faces and solidify. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_hull.c b/source/blender/bmesh/operators/bmo_hull.c index 810b608b28e..500e984f4c9 100644 --- a/source/blender/bmesh/operators/bmo_hull.c +++ b/source/blender/bmesh/operators/bmo_hull.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_hull.c * \ingroup bmesh + * + * Create a convex hull using bullet physics library. */ #ifdef WITH_BULLET diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c index ef99dae5ac9..a3656ce5b74 100644 --- a/source/blender/bmesh/operators/bmo_inset.c +++ b/source/blender/bmesh/operators/bmo_inset.c @@ -22,6 +22,11 @@ /** \file blender/bmesh/operators/bmo_inset.c * \ingroup bmesh + * + * Inset face regions. + * + * TODO + * - Inset indervidual faces. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c index e052968a6a0..5e4fa29d953 100644 --- a/source/blender/bmesh/operators/bmo_join_triangles.c +++ b/source/blender/bmesh/operators/bmo_join_triangles.c @@ -22,6 +22,11 @@ /** \file blender/bmesh/operators/bmo_join_triangles.c * \ingroup bmesh + * + * Convert triangle to quads. + * + * TODO + * - convert triangles to any sided faces, not just quads. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_mirror.c b/source/blender/bmesh/operators/bmo_mirror.c index 48b2f76665c..6aff41b47d1 100644 --- a/source/blender/bmesh/operators/bmo_mirror.c +++ b/source/blender/bmesh/operators/bmo_mirror.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_mirror.c * \ingroup bmesh + * + * Basic mirror, optionally with UVs's. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c index 10a48c1b78c..9f17c1dd8e3 100644 --- a/source/blender/bmesh/operators/bmo_primitive.c +++ b/source/blender/bmesh/operators/bmo_primitive.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_primitive.c * \ingroup bmesh + * + * Primitive shapes. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c index 65b3267914f..da70e201976 100644 --- a/source/blender/bmesh/operators/bmo_removedoubles.c +++ b/source/blender/bmesh/operators/bmo_removedoubles.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_removedoubles.c * \ingroup bmesh + * + * Welding and merging functionality. */ #include "MEM_guardedalloc.h" @@ -99,11 +101,11 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) { BMIter iter, liter; BMVert *v, *v2; - BMEdge *e, *e2, **edges = NULL; + BMEdge *e, *e_new, **edges = NULL; BLI_array_declare(edges); - BMLoop *l, *l2, **loops = NULL; + BMLoop *l, *l_new, **loops = NULL; BLI_array_declare(loops); - BMFace *f, *f2; + BMFace *f, *f_new; int a, b; BMOpSlot *slot_targetmap = BMO_slot_get(op->slots_in, "targetmap"); @@ -180,10 +182,10 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) v2 = BMO_slot_map_elem_get(slot_targetmap, v2); } - e2 = v != v2 ? BM_edge_exists(v, v2) : NULL; - if (e2) { + e_new = v != v2 ? BM_edge_exists(v, v2) : NULL; + if (e_new) { for (b = 0; b < a; b++) { - if (edges[b] == e2) { + if (edges[b] == e_new) { break; } } @@ -194,7 +196,7 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) BLI_array_grow_one(edges); BLI_array_grow_one(loops); - edges[a] = e2; + edges[a] = e_new; loops[a] = l; a++; @@ -213,14 +215,14 @@ void bmo_weld_verts_exec(BMesh *bm, BMOperator *op) v2 = BMO_slot_map_elem_get(slot_targetmap, v2); } - f2 = BM_face_create_ngon(bm, v, v2, edges, a, BM_CREATE_NO_DOUBLE); - if (f2 && (f2 != f)) { - BM_elem_attrs_copy(bm, bm, f, f2); + f_new = BM_face_create_ngon(bm, v, v2, edges, a, BM_CREATE_NO_DOUBLE); + if (f_new && (f_new != f)) { + BM_elem_attrs_copy(bm, bm, f, f_new); a = 0; - BM_ITER_ELEM (l, &liter, f2, BM_LOOPS_OF_FACE) { - l2 = loops[a]; - BM_elem_attrs_copy(bm, bm, l2, l); + BM_ITER_ELEM (l, &liter, f_new, BM_LOOPS_OF_FACE) { + l_new = loops[a]; + BM_elem_attrs_copy(bm, bm, l_new, l); a++; } diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c index 0c0a2c308ee..12368d1aeda 100644 --- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c +++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_smooth_laplacian.c * \ingroup bmesh + * + * Advanced smoothing. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_subdivide.c b/source/blender/bmesh/operators/bmo_subdivide.c index 9115ee882dd..32c5385bee6 100644 --- a/source/blender/bmesh/operators/bmo_subdivide.c +++ b/source/blender/bmesh/operators/bmo_subdivide.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_subdivide.c * \ingroup bmesh + * + * Edge based subdivision with various subdivision patterns. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_symmetrize.c b/source/blender/bmesh/operators/bmo_symmetrize.c index 0bfc81f83cf..b684240dc76 100644 --- a/source/blender/bmesh/operators/bmo_symmetrize.c +++ b/source/blender/bmesh/operators/bmo_symmetrize.c @@ -20,6 +20,13 @@ * ***** END GPL LICENSE BLOCK ***** */ +/** \file blender/bmesh/operators/bmo_symmetrize.c + * \ingroup bmesh + * + * Makes the mesh symmetrical by splitting along an axis and duplicating the geometry. + */ + + #include "MEM_guardedalloc.h" #include "BLI_array.h" diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c index 29c3764045e..754709b18c0 100644 --- a/source/blender/bmesh/operators/bmo_triangulate.c +++ b/source/blender/bmesh/operators/bmo_triangulate.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_triangulate.c * \ingroup bmesh + * + * Triangulate faces, also defines triangle fill. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/operators/bmo_unsubdivide.c b/source/blender/bmesh/operators/bmo_unsubdivide.c index 784e695efb0..c1cfb1866f4 100644 --- a/source/blender/bmesh/operators/bmo_unsubdivide.c +++ b/source/blender/bmesh/operators/bmo_unsubdivide.c @@ -22,6 +22,9 @@ /** \file blender/bmesh/operators/bmo_unsubdivide.c * \ingroup bmesh + * + * Pattern based geometry reduction which has the result similar to undoing + * a subdivide operation. */ #include "BLI_math.h" diff --git a/source/blender/bmesh/operators/bmo_wireframe.c b/source/blender/bmesh/operators/bmo_wireframe.c index 00838533104..935a743116e 100644 --- a/source/blender/bmesh/operators/bmo_wireframe.c +++ b/source/blender/bmesh/operators/bmo_wireframe.c @@ -22,6 +22,8 @@ /** \file blender/bmesh/operators/bmo_wireframe.c * \ingroup bmesh + * + * Creates a solid wireframe from conected faces. */ #include "MEM_guardedalloc.h" diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c index 525bf3a2da7..a0fbaaed810 100644 --- a/source/blender/bmesh/tools/bmesh_bevel.c +++ b/source/blender/bmesh/tools/bmesh_bevel.c @@ -675,7 +675,7 @@ static void build_boundary(BevelParams *bp, BevVert *bv) return; } - lastd = bp->vertex_only? bv->offset : e->offset; + lastd = bp->vertex_only ? bv->offset : e->offset; vm->boundstart = NULL; do { if (e->is_bev) { diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c index e94bb9f5417..edbd43a3346 100644 --- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c +++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c @@ -993,7 +993,7 @@ void BM_mesh_decimate_collapse(BMesh *bm, const float factor, float *vweights, c vquadrics = MEM_callocN(sizeof(Quadric) * bm->totvert, __func__); /* since some edges may be degenerate, we might be over allocing a little here */ eheap = BLI_heap_new_ex(bm->totedge); - eheap_table = MEM_callocN(sizeof(HeapNode *) * bm->totedge, __func__); + eheap_table = MEM_mallocN(sizeof(HeapNode *) * bm->totedge, __func__); tot_edge_orig = bm->totedge; diff --git a/source/blender/collada/AnimationImporter.h b/source/blender/collada/AnimationImporter.h index 293b992f219..61c220e4bbe 100644 --- a/source/blender/collada/AnimationImporter.h +++ b/source/blender/collada/AnimationImporter.h @@ -148,20 +148,20 @@ public: #endif void translate_Animations(COLLADAFW::Node * Node, - std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map, - std::multimap<COLLADAFW::UniqueId, Object*>& object_map, - std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map); + std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& root_map, + std::multimap<COLLADAFW::UniqueId, Object*>& object_map, + std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map); AnimMix* get_animation_type( const COLLADAFW::Node * node, std::map<COLLADAFW::UniqueId, const COLLADAFW::Object*> FW_object_map ); - void apply_matrix_curves(Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, + void apply_matrix_curves(Object *ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm ); - void add_bone_animation_sampled(Object * ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm); + void add_bone_animation_sampled(Object *ob, std::vector<FCurve*>& animcurves, COLLADAFW::Node* root, COLLADAFW::Node* node, COLLADAFW::Transformation * tm); void Assign_transform_animations(COLLADAFW::Transformation* transform, - const COLLADAFW::AnimationList::AnimationBinding * binding, - std::vector<FCurve*>* curves, bool is_joint, char * joint_path); + const COLLADAFW::AnimationList::AnimationBinding *binding, + std::vector<FCurve*>* curves, bool is_joint, char *joint_path); void Assign_color_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type); void Assign_float_animations(const COLLADAFW::UniqueId& listid, ListBase *AnimCurves, const char * anim_type); diff --git a/source/blender/collada/ArmatureImporter.h b/source/blender/collada/ArmatureImporter.h index 2a8f1a65e21..bfbf7433d97 100644 --- a/source/blender/collada/ArmatureImporter.h +++ b/source/blender/collada/ArmatureImporter.h @@ -113,7 +113,7 @@ private: void fix_leaf_bones(); - void set_pose ( Object * ob_arm, COLLADAFW::Node * root_node, const char *parentname, float parent_mat[4][4]); + void set_pose( Object *ob_arm, COLLADAFW::Node *root_node, const char *parentname, float parent_mat[4][4]); #if 0 diff --git a/source/blender/collada/ExtraHandler.cpp b/source/blender/collada/ExtraHandler.cpp index 7b8d315b8c5..c72fdd9766b 100644 --- a/source/blender/collada/ExtraHandler.cpp +++ b/source/blender/collada/ExtraHandler.cpp @@ -65,7 +65,8 @@ bool ExtraHandler::textData(const char *text, size_t textLength) bool ExtraHandler::parseElement( const char *profileName, const unsigned long& elementHash, - const COLLADAFW::UniqueId& uniqueId) + const COLLADAFW::UniqueId& uniqueId, + COLLADAFW::Object* object) { if (BLI_strcaseeq(profileName, "blender")) { //printf("In parseElement for supported profile %s for id %s\n", profileName, uniqueId.toAscii().c_str()); diff --git a/source/blender/collada/ExtraHandler.h b/source/blender/collada/ExtraHandler.h index aa1ae52a521..d2da19acb78 100644 --- a/source/blender/collada/ExtraHandler.h +++ b/source/blender/collada/ExtraHandler.h @@ -61,7 +61,8 @@ public: bool parseElement ( const char* profileName, const unsigned long& elementHash, - const COLLADAFW::UniqueId& uniqueId ); + const COLLADAFW::UniqueId& uniqueId, + COLLADAFW::Object* object); private: /** Disable default copy constructor. */ ExtraHandler(const ExtraHandler& pre); diff --git a/source/blender/collada/SConscript b/source/blender/collada/SConscript index e1ab774ffbe..38ffa471070 100644 --- a/source/blender/collada/SConscript +++ b/source/blender/collada/SConscript @@ -47,22 +47,13 @@ incs = [ '../bmesh', '#/intern/guardedalloc', ] -if env['OURPLATFORM']=='darwin': - incs += [ - env['BF_OPENCOLLADA_INC'] + '/COLLADAStreamWriter', - env['BF_OPENCOLLADA_INC'] + '/COLLADABaseUtils', - env['BF_OPENCOLLADA_INC'] + '/COLLADAFramework', - env['BF_OPENCOLLADA_INC'] + '/COLLADASaxFrameworkLoader', - env['BF_OPENCOLLADA_INC'] + '/GeneratedSaxParser', - ] -else: - incs += [ - env['BF_OPENCOLLADA_INC'] + '/COLLADAStreamWriter/include', - env['BF_OPENCOLLADA_INC'] + '/COLLADABaseUtils/include', - env['BF_OPENCOLLADA_INC'] + '/COLLADAFramework/include', - env['BF_OPENCOLLADA_INC'] + '/COLLADASaxFrameworkLoader/include', - env['BF_OPENCOLLADA_INC'] + '/GeneratedSaxParser/include', - ] +incs += [ + env['BF_OPENCOLLADA_INC'] + '/COLLADAStreamWriter', + env['BF_OPENCOLLADA_INC'] + '/COLLADABaseUtils', + env['BF_OPENCOLLADA_INC'] + '/COLLADAFramework', + env['BF_OPENCOLLADA_INC'] + '/COLLADASaxFrameworkLoader', + env['BF_OPENCOLLADA_INC'] + '/GeneratedSaxParser', +] if env['BF_BUILDINFO']: defs.append('WITH_BUILDINFO') diff --git a/source/blender/compositor/intern/COM_ExecutionGroup.cpp b/source/blender/compositor/intern/COM_ExecutionGroup.cpp index 82d1c7883e1..7c454445e4f 100644 --- a/source/blender/compositor/intern/COM_ExecutionGroup.cpp +++ b/source/blender/compositor/intern/COM_ExecutionGroup.cpp @@ -435,7 +435,7 @@ void ExecutionGroup::printBackgroundStats(void) fprintf(stdout, "Mem:%.2fM (%.2fM, Peak %.2fM) ", megs_used_memory, mmap_used_memory, megs_peak_memory); - BLI_timestr(execution_time, timestr); + BLI_timestr(execution_time, timestr, sizeof(timestr)); printf("| Elapsed %s ", timestr); printf("| Tree %s, Tile %d-%d ", this->m_bTree->id.name + 2, this->m_chunksFinished, this->m_numberOfChunks); diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 2dae78ce5eb..4b0a99889b3 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -3368,13 +3368,13 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann break; case ACHANNEL_SETTING_EXPAND: /* expanded triangle */ - //icon = ((enabled)? ICON_TRIA_DOWN : ICON_TRIA_RIGHT); + //icon = ((enabled) ? ICON_TRIA_DOWN : ICON_TRIA_RIGHT); icon = ICON_TRIA_RIGHT; tooltip = TIP_("Make channels grouped under this channel visible"); break; case ACHANNEL_SETTING_SOLO: /* NLA Tracks only */ - //icon = ((enabled)? ICON_LAYER_ACTIVE : ICON_LAYER_USED); + //icon = ((enabled) ? ICON_LAYER_ACTIVE : ICON_LAYER_USED); icon = ICON_LAYER_USED; tooltip = TIP_("NLA Track is the only one evaluated for the AnimData block it belongs to"); break; @@ -3383,13 +3383,13 @@ static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, bAnimChann case ACHANNEL_SETTING_PROTECT: /* protected lock */ // TODO: what about when there's no protect needed? - //icon = ((enabled)? ICON_LOCKED : ICON_UNLOCKED); + //icon = ((enabled) ? ICON_LOCKED : ICON_UNLOCKED); icon = ICON_UNLOCKED; tooltip = TIP_("Editability of keyframes for this channel"); break; case ACHANNEL_SETTING_MUTE: /* muted speaker */ - //icon = ((enabled)? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF); + //icon = ((enabled) ? ICON_MUTE_IPO_ON : ICON_MUTE_IPO_OFF); icon = ICON_MUTE_IPO_OFF; if (ale->type == ALE_FCURVE) diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index 205f67cf96a..b4bbb14245d 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -1017,24 +1017,35 @@ static void MARKER_OT_duplicate(wmOperatorType *ot) /* ************************** selection ************************************/ /* select/deselect TimeMarker at current frame */ -static void select_timeline_marker_frame(ListBase *markers, int frame, unsigned char shift) +static void select_timeline_marker_frame(ListBase *markers, int frame, bool extend) { - TimeMarker *marker; - int select = 0; - + TimeMarker *marker, *marker_first = NULL; + + /* support for selection cycling */ for (marker = markers->first; marker; marker = marker->next) { - /* if Shift is not set, then deselect Markers */ - if (!shift) marker->flag &= ~SELECT; - - /* this way a not-shift select will allways give 1 selected marker */ - if ((marker->frame == frame) && (!select)) { - if (marker->flag & SELECT) - marker->flag &= ~SELECT; - else - marker->flag |= SELECT; - select = 1; + if (marker->frame == frame) { + if (marker->flag & SELECT) { + marker_first = marker->next; + break; + } + } + } + + /* if extend is not set, then deselect markers */ + if (extend == false) { + for (marker = markers->first; marker; marker = marker->next) { + marker->flag &= ~SELECT; + } + } + + LISTBASE_CIRCULAR_FORWARD_BEGIN (markers, marker, marker_first) { + /* this way a not-extend select will allways give 1 selected marker */ + if (marker->frame == frame) { + marker->flag ^= SELECT; + break; } } + LISTBASE_CIRCULAR_FORWARD_END (markers, marker, marker_first); } static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool camera) @@ -1121,6 +1132,8 @@ static int ed_marker_select_invoke_wrapper(bContext *C, wmOperator *op, const wm static void MARKER_OT_select(wmOperatorType *ot) { + PropertyRNA *prop; + /* identifiers */ ot->name = "Select Time Marker"; ot->description = "Select time marker(s)"; @@ -1133,9 +1146,11 @@ static void MARKER_OT_select(wmOperatorType *ot) /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection"); + prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); #ifdef DURIAN_CAMERA_SWITCH - RNA_def_boolean(ot->srna, "camera", 0, "Camera", "Select the camera"); + prop = RNA_def_boolean(ot->srna, "camera", 0, "Camera", "Select the camera"); + RNA_def_property_flag(prop, PROP_SKIP_SAVE); #endif } diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c index d04938fd59b..649ef90f7ba 100644 --- a/source/blender/editors/armature/reeb.c +++ b/source/blender/editors/armature/reeb.c @@ -52,9 +52,11 @@ static ReebGraph *FILTERED_RG = NULL; * SIGGRAPH 2007 * * */ - + +#if 0 #define DEBUG_REEB #define DEBUG_REEB_NODE +#endif /* place-holders! */ typedef struct EditEdge { diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h index b8ad40b2bd9..f698f9b0b11 100644 --- a/source/blender/editors/include/ED_anim_api.h +++ b/source/blender/editors/include/ED_anim_api.h @@ -409,7 +409,7 @@ typedef struct bAnimChannelType { * with type being sizeof(ptr_data) which should be fine for runtime use... * - assume that setting has been checked to be valid for current context */ - void *(*setting_ptr)(bAnimListElem * ale, int setting, short *type); + void *(*setting_ptr)(bAnimListElem *ale, int setting, short *type); } bAnimChannelType; /* ------------------------ Drawing API -------------------------- */ diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h index 28727c913cb..541956136bd 100644 --- a/source/blender/editors/include/ED_clip.h +++ b/source/blender/editors/include/ED_clip.h @@ -39,6 +39,7 @@ struct Main; struct Mask; struct MovieClip; struct SpaceClip; +struct Scene; /* ** clip_editor.c ** */ @@ -81,12 +82,6 @@ void ED_space_clip_set_clip(struct bContext *C, struct bScreen *screen, struct S struct Mask *ED_space_clip_get_mask(struct SpaceClip *sc); void ED_space_clip_set_mask(struct bContext *C, struct SpaceClip *sc, struct Mask *mask); -/* textures buffer */ -int ED_space_clip_texture_buffer_supported(struct SpaceClip *sc); -int ED_space_clip_load_movieclip_buffer(struct SpaceClip *sc, struct ImBuf *ibuf, const unsigned char *display_buffer); -void ED_space_clip_unload_movieclip_buffer(struct SpaceClip *sc); -void ED_space_clip_free_texture_buffer(struct SpaceClip *sc); - /* ** clip_ops.c ** */ void ED_operatormacros_clip(void); diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index f84281a4f08..ab112fde48d 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -278,7 +278,7 @@ void EDBM_redo_state_restore(struct BMBackup, struct BMEditMesh *em, int recalct void EDBM_redo_state_free(struct BMBackup *, struct BMEditMesh *em, int recalctess); -/* meshtools.c */ +/* *** meshtools.c *** */ int join_mesh_exec(struct bContext *C, struct wmOperator *op); int join_mesh_shapes_exec(struct bContext *C, struct wmOperator *op); diff --git a/source/blender/editors/include/ED_types.h b/source/blender/editors/include/ED_types.h index 5908dbf3a1d..fac4c02e8ed 100644 --- a/source/blender/editors/include/ED_types.h +++ b/source/blender/editors/include/ED_types.h @@ -40,7 +40,7 @@ /* proposal = put scene pointers on function calls? */ // #define BASACT (scene->basact) -// #define OBACT (BASACT? BASACT->object: NULL) +// #define OBACT (BASACT ? BASACT->object : NULL) diff --git a/source/blender/editors/include/UI_resources.h b/source/blender/editors/include/UI_resources.h index 050e9c81f2a..63741ee08ba 100644 --- a/source/blender/editors/include/UI_resources.h +++ b/source/blender/editors/include/UI_resources.h @@ -185,6 +185,7 @@ enum { TH_EDGE_CREASE, TH_DRAWEXTRA_EDGELEN, + TH_DRAWEXTRA_EDGEANG, TH_DRAWEXTRA_FACEAREA, TH_DRAWEXTRA_FACEANG, diff --git a/source/blender/editors/interface/interface_draw.c b/source/blender/editors/interface/interface_draw.c index 7fc5c21f052..b9b877c1fb6 100644 --- a/source/blender/editors/interface/interface_draw.c +++ b/source/blender/editors/interface/interface_draw.c @@ -61,6 +61,15 @@ /* own include */ #include "interface_intern.h" +/* only for bug workaround [#34346] */ +#if !defined(WIN32) && !defined(__APPLE__) +# define GPU_OSS_BUG_WOKAROUND +#endif + +#ifdef GPU_OSS_BUG_WOKAROUND +# include "GPU_extensions.h" +#endif + static int roundboxtype = UI_CNR_ALL; void uiSetRoundBox(int type) @@ -1236,6 +1245,7 @@ void ui_draw_but_COLORBAND(uiBut *but, uiWidgetColors *UNUSED(wcol), rcti *rect) void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect) { + static int use_displist = -1; static GLuint displist = 0; int a, old[8]; GLfloat diff[4], diffn[4] = {1.0f, 1.0f, 1.0f, 1.0f}; @@ -1285,20 +1295,30 @@ void ui_draw_but_NORMAL(uiBut *but, uiWidgetColors *wcol, rcti *rect) glScalef(size, size, size); - if (displist == 0) { - GLUquadricObj *qobj; - - displist = glGenLists(1); - glNewList(displist, GL_COMPILE_AND_EXECUTE); +#ifdef GPU_OSS_BUG_WOKAROUND + if (use_displist == -1) { + use_displist = !GPU_type_matches(GPU_DEVICE_ANY, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE); + } +#endif + + if (displist == 0 || use_displist == 0) { + GLUquadricObj *qobj; + + if (use_displist) { + displist = glGenLists(1); + glNewList(displist, GL_COMPILE_AND_EXECUTE); + } qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); + gluQuadricDrawStyle(qobj, GLU_FILL); glShadeModel(GL_SMOOTH); gluSphere(qobj, 100.0, 32, 24); glShadeModel(GL_FLAT); - gluDeleteQuadric(qobj); + gluDeleteQuadric(qobj); - glEndList(); + if (use_displist) { + glEndList(); + } } else { glCallList(displist); diff --git a/source/blender/editors/interface/resources.c b/source/blender/editors/interface/resources.c index 288b8b43e82..b4246fe5b9c 100644 --- a/source/blender/editors/interface/resources.c +++ b/source/blender/editors/interface/resources.c @@ -309,6 +309,8 @@ const unsigned char *UI_ThemeGetColorPtr(bTheme *btheme, int spacetype, int colo cp = &ts->facedot_size; break; case TH_DRAWEXTRA_EDGELEN: cp = ts->extra_edge_len; break; + case TH_DRAWEXTRA_EDGEANG: + cp = ts->extra_edge_angle; break; case TH_DRAWEXTRA_FACEAREA: cp = ts->extra_face_area; break; case TH_DRAWEXTRA_FACEANG: @@ -772,6 +774,7 @@ void ui_theme_init_default(void) btheme->tv3d.facedot_size = 4; rgba_char_args_set(btheme->tv3d.extra_edge_len, 32, 0, 0, 255); + rgba_char_args_set(btheme->tv3d.extra_edge_angle, 32, 32, 0, 255); rgba_char_args_set(btheme->tv3d.extra_face_area, 0, 32, 0, 255); rgba_char_args_set(btheme->tv3d.extra_face_angle, 0, 0, 128, 255); diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index a76872d6e30..1aadac015dd 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -42,7 +42,10 @@ set(INC_SYS set(SRC editface.c editmesh_add.c + editmesh_bevel.c editmesh_bvh.c + editmesh_extrude.c + editmesh_inset.c editmesh_knife.c editmesh_knife_project.c editmesh_loopcut.c diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c index 3117f45156d..34666b363f3 100644 --- a/source/blender/editors/mesh/editmesh_add.c +++ b/source/blender/editors/mesh/editmesh_add.c @@ -30,7 +30,6 @@ */ #include "DNA_object_types.h" -#include "DNA_scene_types.h" #include "BLI_math.h" @@ -50,7 +49,7 @@ #include "ED_screen.h" #include "ED_object.h" -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ /* ********* add primitive operators ************* */ diff --git a/source/blender/editors/mesh/editmesh_bevel.c b/source/blender/editors/mesh/editmesh_bevel.c new file mode 100644 index 00000000000..d79f12551dd --- /dev/null +++ b/source/blender/editors/mesh/editmesh_bevel.c @@ -0,0 +1,368 @@ +/* + * ***** 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): Joseph Eagar, Howard Trickey, Campbell Barton + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mesh/editmesh_bevel.c + * \ingroup edmesh + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_object_types.h" + +#include "BLI_string.h" +#include "BLI_math.h" + +#include "BLF_translation.h" + +#include "BKE_context.h" +#include "BKE_tessmesh.h" + +#include "RNA_define.h" +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_mesh.h" +#include "ED_numinput.h" +#include "ED_screen.h" +#include "ED_transform.h" +#include "ED_view3d.h" + +#include "mesh_intern.h" /* own include */ + + +#define MVAL_PIXEL_MARGIN 5.0f + +typedef struct { + BMEditMesh *em; + BMBackup mesh_backup; + 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. */ +} BevelData; + +#define HEADER_LENGTH 180 + +static void edbm_bevel_update_header(wmOperator *op, bContext *C) +{ + const char *str = IFACE_("Confirm: Enter/LClick, Cancel: (Esc/RMB), Offset: %s, Segments: %d"); + + char msg[HEADER_LENGTH]; + ScrArea *sa = CTX_wm_area(C); + + if (sa) { + char offset_str[NUM_STR_REP_LEN]; + BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset")); + BLI_snprintf(msg, HEADER_LENGTH, str, + offset_str, + RNA_int_get(op->ptr, "segments") + ); + + ED_area_headerprint(sa, msg); + } +} + +static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BevelData *opdata; + + if (em == NULL) { + return 0; + } + + op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator"); + + opdata->em = em; + opdata->is_modal = is_modal; + opdata->shift_factor = -1.0f; + + initNumInput(&opdata->num_input); + opdata->num_input.flag = NUM_NO_NEGATIVE; + + /* avoid the cost of allocating a bm copy */ + if (is_modal) + opdata->mesh_backup = EDBM_redo_state_store(em); + + return 1; +} + +static int edbm_bevel_calc(wmOperator *op) +{ + BevelData *opdata = op->customdata; + BMEditMesh *em = opdata->em; + BMOperator bmop; + const float offset = RNA_float_get(op->ptr, "offset"); + const int segments = RNA_int_get(op->ptr, "segments"); + const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only"); + + /* revert to original mesh */ + if (opdata->is_modal) { + EDBM_redo_state_restore(opdata->mesh_backup, em, false); + } + + if (!EDBM_op_init(em, &bmop, op, + "bevel geom=%hev offset=%f segments=%i vertex_only=%b", + BM_ELEM_SELECT, offset, segments, vertex_only)) + { + return 0; + } + + BMO_op_exec(em->bm, &bmop); + + if (offset != 0.0f) { + /* not essential, but we may have some loose geometry that + * won't get bevel'd and better not leave it selected */ + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); + } + + /* no need to de-select existing geometry */ + if (!EDBM_op_finish(em, &bmop, op, true)) + return 0; + + EDBM_mesh_normals_update(opdata->em); + + EDBM_update_generic(opdata->em, true, true); + + return 1; +} + +static void edbm_bevel_exit(bContext *C, wmOperator *op) +{ + BevelData *opdata = op->customdata; + + ScrArea *sa = CTX_wm_area(C); + + if (sa) { + ED_area_headerprint(sa, NULL); + } + + if (opdata->is_modal) { + EDBM_redo_state_free(&opdata->mesh_backup, NULL, false); + } + MEM_freeN(opdata); + op->customdata = NULL; +} + +static int edbm_bevel_cancel(bContext *C, wmOperator *op) +{ + BevelData *opdata = op->customdata; + if (opdata->is_modal) { + EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, true); + EDBM_update_generic(opdata->em, false, true); + } + + edbm_bevel_exit(C, op); + + /* need to force redisplay or we may still view the modified result */ + ED_region_tag_redraw(CTX_wm_region(C)); + return OPERATOR_CANCELLED; +} + +/* bevel! yay!!*/ +static int edbm_bevel_exec(bContext *C, wmOperator *op) +{ + if (!edbm_bevel_init(C, op, false)) { + edbm_bevel_exit(C, op); + return OPERATOR_CANCELLED; + } + + if (!edbm_bevel_calc(op)) { + edbm_bevel_cancel(C, op); + return OPERATOR_CANCELLED; + } + + edbm_bevel_exit(C, op); + + return OPERATOR_FINISHED; +} + +static int edbm_bevel_invoke(bContext *C, wmOperator *op, const 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; + } + + opdata = op->customdata; + + /* initialize mouse values */ + 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; + } + 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); + + if (!edbm_bevel_calc(op)) { + edbm_bevel_cancel(C, op); + return OPERATOR_CANCELLED; + } + + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + +static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event) +{ + BevelData *opdata = op->customdata; + int use_dist = true; + 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, "offset"); + } + 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, const wmEvent *event) +{ + BevelData *opdata = op->customdata; + int segments = RNA_int_get(op->ptr, "segments"); + + if (event->val == KM_PRESS) { + /* Try to handle numeric inputs... */ + + if (handleNumInput(&opdata->num_input, event)) { + float value = RNA_float_get(op->ptr, "offset"); + applyNumInput(&opdata->num_input, &value); + RNA_float_set(op->ptr, "offset", value); + edbm_bevel_calc(op); + edbm_bevel_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } + } + + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + edbm_bevel_cancel(C, op); + return OPERATOR_CANCELLED; + + case MOUSEMOVE: + if (!hasNumInput(&opdata->num_input)) { + const float factor = edbm_bevel_mval_factor(op, event); + RNA_float_set(op->ptr, "offset", factor); + + edbm_bevel_calc(op); + edbm_bevel_update_header(op, C); + } + break; + + case LEFTMOUSE: + case PADENTER: + case RETKEY: + edbm_bevel_calc(op); + edbm_bevel_exit(C, op); + return OPERATOR_FINISHED; + + case WHEELUPMOUSE: /* change number of segments */ + case PAGEUPKEY: + if (event->val == KM_RELEASE) + break; + + segments++; + RNA_int_set(op->ptr, "segments", segments); + edbm_bevel_calc(op); + edbm_bevel_update_header(op, C); + break; + + case WHEELDOWNMOUSE: /* change number of segments */ + case PAGEDOWNKEY: + if (event->val == KM_RELEASE) + break; + + segments = max_ii(segments - 1, 1); + RNA_int_set(op->ptr, "segments", segments); + edbm_bevel_calc(op); + edbm_bevel_update_header(op, C); + break; + } + + return OPERATOR_RUNNING_MODAL; +} + +void MESH_OT_bevel(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Bevel"; + ot->description = "Edge Bevel"; + ot->idname = "MESH_OT_bevel"; + + /* api callbacks */ + ot->exec = edbm_bevel_exec; + ot->invoke = edbm_bevel_invoke; + ot->modal = edbm_bevel_modal; + ot->cancel = edbm_bevel_cancel; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; + + RNA_def_float(ot->srna, "offset", 0.0f, -FLT_MAX, FLT_MAX, "Offset", "", 0.0f, 1.0f); + RNA_def_int(ot->srna, "segments", 1, 1, 50, "Segments", "Segments for curved edge", 1, 8); + RNA_def_boolean(ot->srna, "vertex_only", false, "Vertex only", "Bevel only vertices"); +} diff --git a/source/blender/editors/mesh/editmesh_bvh.c b/source/blender/editors/mesh/editmesh_bvh.c index 8e397797dd9..4c989a22291 100644 --- a/source/blender/editors/mesh/editmesh_bvh.c +++ b/source/blender/editors/mesh/editmesh_bvh.c @@ -29,9 +29,6 @@ * \ingroup edmesh */ -#define IN_EDITMESHBVH - - #include "MEM_guardedalloc.h" #include "DNA_scene_types.h" @@ -39,18 +36,18 @@ #include "DNA_screen_types.h" #include "DNA_view3d_types.h" - #include "BLI_math.h" #include "BLI_smallhash.h" #include "BKE_DerivedMesh.h" #include "BKE_tessmesh.h" -#include "ED_mesh.h" #include "ED_view3d.h" +#define IN_EDITMESHBVH /* needed for typedef workaround */ #include "editmesh_bvh.h" /* own include */ + typedef struct BMBVHTree { BMEditMesh *em; BMesh *bm; diff --git a/source/blender/editors/mesh/editmesh_extrude.c b/source/blender/editors/mesh/editmesh_extrude.c new file mode 100644 index 00000000000..694053ae2f7 --- /dev/null +++ b/source/blender/editors/mesh/editmesh_extrude.c @@ -0,0 +1,921 @@ +/* + * ***** 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) 2004 by Blender Foundation. + * All rights reserved. + * + * The Original Code is: all of this file. + * + * Contributor(s): Joseph Eagar + * + * ***** END GPL LICENSE BLOCK ***** + */ + +/** \file blender/editors/mesh/editmesh_extrude.c + * \ingroup edmesh + */ + +#include "DNA_modifier_types.h" +#include "DNA_object_types.h" + +#include "BLI_math.h" + +#include "BKE_context.h" +#include "BKE_object.h" +#include "BKE_report.h" +#include "BKE_tessmesh.h" + +#include "RNA_define.h" +#include "RNA_access.h" + +#include "WM_types.h" + +#include "ED_mesh.h" +#include "ED_screen.h" +#include "ED_view3d.h" + +#include "mesh_intern.h" /* own include */ + +/* 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]) +{ + if (dot_v3v3(nor, add) < -0.9999f) { + sub_v3_v3(nor, add); + } + else { + add_v3_v3(nor, add); + } +} + +/* individual face extrude */ +/* will use vertex normals for extrusion directions, so *nor is unaffected */ +static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor)) +{ + BMOIter siter; + BMIter liter; + BMFace *f; + BMLoop *l; + BMOperator bmop; + + EDBM_op_init(em, &bmop, op, "extrude_discrete_faces faces=%hf", hflag); + + /* deselect original verts */ + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + + BMO_op_exec(em->bm, &bmop); + + BMO_ITER (f, &siter, bmop.slots_out, "faces.out", BM_FACE) { + BM_face_select_set(em->bm, f, true); + + /* set face vertex normals to face normal */ + BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { + copy_v3_v3(l->v->no, f->no); + } + } + + if (!EDBM_op_finish(em, &bmop, op, true)) { + return 0; + } + + return 's'; /* s is shrink/fatten */ +} + +/* extrudes individual edges */ +static short edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor)) +{ + BMOperator bmop; + + EDBM_op_init(em, &bmop, op, "extrude_edge_only edges=%he", hflag); + + /* deselect original verts */ + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + + BMO_op_exec(em->bm, &bmop); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true); + + if (!EDBM_op_finish(em, &bmop, op, true)) { + return 0; + } + + return 'n'; /* n is normal grab */ +} + +/* extrudes individual vertices */ +static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor)) +{ + BMOperator bmop; + + EDBM_op_init(em, &bmop, op, "extrude_vert_indiv verts=%hv", hflag); + + /* deselect original verts */ + BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_in, "verts", BM_VERT, BM_ELEM_SELECT, true); + + BMO_op_exec(em->bm, &bmop); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, true); + + if (!EDBM_op_finish(em, &bmop, op, true)) { + return 0; + } + + return 'g'; /* g is grab */ +} + +static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag, float nor[3]) +{ + BMesh *bm = em->bm; + BMIter iter; + BMOIter siter; + BMOperator extop; + BMEdge *edge; + BMFace *f; + ModifierData *md; + BMElem *ele; + BMOpSlot *slot_edges_exclude; + + BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region"); + BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE, hflag); + + slot_edges_exclude = BMO_slot_get(extop.slots_in, "edges_exclude"); + + /* If a mirror modifier with clipping is on, we need to adjust some + * of the cases above to handle edges on the line of symmetry. + */ + md = obedit->modifiers.first; + for (; md; md = md->next) { + if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { + MirrorModifierData *mmd = (MirrorModifierData *) md; + + if (mmd->flag & MOD_MIR_CLIPPING) { + float mtx[4][4]; + if (mmd->mirror_ob) { + float imtx[4][4]; + invert_m4_m4(imtx, mmd->mirror_ob->obmat); + mult_m4_m4m4(mtx, imtx, obedit->obmat); + } + + BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(edge, hflag) && + BM_edge_is_boundary(edge) && + BM_elem_flag_test(edge->l->f, hflag)) + { + float co1[3], co2[3]; + + copy_v3_v3(co1, edge->v1->co); + copy_v3_v3(co2, edge->v2->co); + + if (mmd->mirror_ob) { + mul_v3_m4v3(co1, mtx, co1); + mul_v3_m4v3(co2, mtx, co2); + } + + if (mmd->flag & MOD_MIR_AXIS_X) { + if ((fabsf(co1[0]) < mmd->tolerance) && + (fabsf(co2[0]) < mmd->tolerance)) + { + BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); + } + } + if (mmd->flag & MOD_MIR_AXIS_Y) { + if ((fabsf(co1[1]) < mmd->tolerance) && + (fabsf(co2[1]) < mmd->tolerance)) + { + BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); + } + } + if (mmd->flag & MOD_MIR_AXIS_Z) { + if ((fabsf(co1[2]) < mmd->tolerance) && + (fabsf(co2[2]) < mmd->tolerance)) + { + BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); + } + } + } + } + } + } + } + + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + + BMO_op_exec(bm, &extop); + + zero_v3(nor); + + BMO_ITER (ele, &siter, extop.slots_out, "geom.out", BM_ALL) { + BM_elem_select_set(bm, ele, true); + + if (ele->head.htype == BM_FACE) { + f = (BMFace *)ele; + add_normal_aligned(nor, f->no); + } + } + + normalize_v3(nor); + + BMO_op_finish(bm, &extop); + + /* grab / normal constraint */ + return is_zero_v3(nor) ? 'g' : 'n'; +} + +static short edbm_extrude_vert(Object *obedit, BMEditMesh *em, const char hflag, float nor[3]) +{ + BMIter iter; + BMEdge *eed; + + /* ensure vert flags are consistent for edge selections */ + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { + if (BM_elem_flag_test(eed, hflag)) { + if (hflag & BM_ELEM_SELECT) { + BM_vert_select_set(em->bm, eed->v1, true); + BM_vert_select_set(em->bm, eed->v2, true); + } + + BM_elem_flag_enable(eed->v1, hflag & ~BM_ELEM_SELECT); + BM_elem_flag_enable(eed->v2, hflag & ~BM_ELEM_SELECT); + } + else { + if (BM_elem_flag_test(eed->v1, hflag) && BM_elem_flag_test(eed->v2, hflag)) { + if (hflag & BM_ELEM_SELECT) { + BM_edge_select_set(em->bm, eed, true); + } + + BM_elem_flag_enable(eed, hflag & ~BM_ELEM_SELECT); + } + } + } + + return edbm_extrude_edge(obedit, em, hflag, nor); +} + +static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + RegionView3D *rv3d = CTX_wm_region_view3d(C); + + const int steps = RNA_int_get(op->ptr, "steps"); + + const float offs = RNA_float_get(op->ptr, "offset"); + float dvec[3], tmat[3][3], bmat[3][3], nor[3] = {0.0, 0.0, 0.0}; + short a; + + /* dvec */ + normalize_v3_v3(dvec, rv3d->persinv[2]); + mul_v3_fl(dvec, offs); + + /* base correction */ + copy_m3_m4(bmat, obedit->obmat); + invert_m3_m3(tmat, bmat); + mul_m3_v3(tmat, dvec); + + for (a = 0; a < steps; a++) { + edbm_extrude_edge(obedit, em, BM_ELEM_SELECT, nor); + //BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, "extrude_face_region geom=%hef", BM_ELEM_SELECT); + BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, + "translate vec=%v verts=%hv", + (float *)dvec, BM_ELEM_SELECT); + //extrudeflag(obedit, em, SELECT, nor); + //translateflag(em, SELECT, dvec); + } + + EDBM_mesh_normals_update(em); + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; +} + +void MESH_OT_extrude_repeat(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Extrude Repeat Mesh"; + ot->description = "Extrude selected vertices, edges or faces repeatedly"; + ot->idname = "MESH_OT_extrude_repeat"; + + /* api callbacks */ + ot->exec = edbm_extrude_repeat_exec; + ot->poll = ED_operator_editmesh_view3d; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + 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 */ +static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOperator *op, float *norin) +{ + short nr, transmode = 0; + float stacknor[3] = {0.0f, 0.0f, 0.0f}; + float *nor = norin ? norin : stacknor; + + zero_v3(nor); + + /* XXX If those popup menus were to be enabled again, please get rid of this "menu string" syntax! */ + if (em->selectmode & SCE_SELECT_VERTEX) { + if (em->bm->totvertsel == 0) nr = 0; + else if (em->bm->totvertsel == 1) nr = 4; + else if (em->bm->totedgesel == 0) nr = 4; + else if (em->bm->totfacesel == 0) + nr = 3; /* pupmenu("Extrude %t|Only Edges %x3|Only Vertices %x4"); */ + else if (em->bm->totfacesel == 1) + nr = 1; /* pupmenu("Extrude %t|Region %x1|Only Edges% x3|Only Vertices %x4"); */ + else + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2|Only Edges %x3|Only Vertices %x4"); */ + } + else if (em->selectmode & SCE_SELECT_EDGE) { + if (em->bm->totedgesel == 0) nr = 0; + + nr = 1; +#if 0 + else if (em->totedgesel == 1) nr = 3; + else if (em->totfacesel == 0) nr = 3; + else if (em->totfacesel == 1) + nr = 1; /* pupmenu("Extrude %t|Region %x1|Only Edges %x3"); */ + else + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2|Only Edges %x3"); */ +#endif + } + else { + if (em->bm->totfacesel == 0) nr = 0; + else if (em->bm->totfacesel == 1) nr = 1; + else + nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2"); */ + } + + if (nr < 1) return 'g'; + + if (nr == 1 && (em->selectmode & SCE_SELECT_VERTEX)) + transmode = edbm_extrude_vert(obedit, em, BM_ELEM_SELECT, nor); + else if (nr == 1) transmode = edbm_extrude_edge(obedit, em, BM_ELEM_SELECT, nor); + else if (nr == 4) transmode = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor); + else if (nr == 3) transmode = edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor); + else transmode = edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor); + + if (transmode == 0) { + BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude"); + } + else { + + /* We need to force immediate calculation here because + * transform may use derived objects (which are now stale). + * + * This shouldn't be necessary, derived queries should be + * automatically building this data if invalid. Or something. + */ +// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); + BKE_object_handle_update(scene, obedit); + + /* individual faces? */ +// BIF_TransformSetUndo("Extrude"); + if (nr == 2) { +// initTransform(TFM_SHRINKFATTEN, CTX_NO_PET|CTX_NO_MIRROR); +// Transform(); + } + else { +// initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR); + if (transmode == 'n') { + mul_m4_v3(obedit->obmat, nor); + sub_v3_v3v3(nor, nor, obedit->obmat[3]); +// BIF_setSingleAxisConstraint(nor, "along normal"); + } +// Transform(); + } + } + + return transmode; +} + +/* extrude without transform */ +static int edbm_extrude_region_exec(bContext *C, wmOperator *op) +{ + Scene *scene = CTX_data_scene(C); + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + + edbm_extrude_mesh(scene, obedit, em, op, NULL); + + /* This normally happens when pushing undo but modal operators + * like this one don't push undo data until after modal mode is + * done.*/ + EDBM_mesh_normals_update(em); + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; +} + +void MESH_OT_extrude_region(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Extrude Region"; + ot->idname = "MESH_OT_extrude_region"; + ot->description = "Extrude region of faces"; + + /* api callbacks */ + //ot->invoke = mesh_extrude_region_invoke; + ot->exec = edbm_extrude_region_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); +} + +static int edbm_extrude_verts_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + float nor[3]; + + edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor); + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; +} + +void MESH_OT_extrude_verts_indiv(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Extrude Only Vertices"; + ot->idname = "MESH_OT_extrude_verts_indiv"; + ot->description = "Extrude individual vertices only"; + + /* api callbacks */ + ot->exec = edbm_extrude_verts_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* to give to transform */ + RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); +} + +static int edbm_extrude_edges_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + float nor[3]; + + edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor); + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; +} + +void MESH_OT_extrude_edges_indiv(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Extrude Only Edges"; + ot->idname = "MESH_OT_extrude_edges_indiv"; + ot->description = "Extrude individual edges only"; + + /* api callbacks */ + ot->exec = edbm_extrude_edges_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* to give to transform */ + RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); +} + +static int edbm_extrude_faces_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + float nor[3]; + + edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor); + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; +} + +void MESH_OT_extrude_faces_indiv(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Extrude Individual Faces"; + ot->idname = "MESH_OT_extrude_faces_indiv"; + ot->description = "Extrude individual faces only"; + + /* api callbacks */ + ot->exec = edbm_extrude_faces_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); +} + +/* *************** add-click-mesh (extrude) operator ************** */ +static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + ViewContext vc; + BMVert *v1; + BMIter iter; + float min[3], max[3]; + bool done = false; + bool use_proj; + + em_setup_viewcontext(C, &vc); + + ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); + + + use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && + (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); + + INIT_MINMAX(min, max); + + BM_ITER_MESH (v1, &iter, vc.em->bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v1, BM_ELEM_SELECT)) { + minmax_v3v3_v3(min, max, v1->co); + done = true; + } + } + + /* call extrude? */ + if (done) { + const bool rot_src = RNA_boolean_get(op->ptr, "rotate_source"); + BMEdge *eed; + float vec[3], cent[3], mat[3][3]; + float nor[3] = {0.0, 0.0, 0.0}; + + /* 2D normal calc */ + const float mval_f[2] = {(float)event->mval[0], + (float)event->mval[1]}; + + /* check for edges that are half selected, use for rotation */ + 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[2], co2[2]; + + 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) + * + * accumulate the screenspace normal in 2D, + * with screenspace edge length weighting the result. */ + if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) { + nor[0] += (co1[1] - co2[1]); + nor[1] += -(co1[0] - co2[0]); + } + else { + nor[0] += (co2[1] - co1[1]); + nor[1] += -(co2[0] - co1[0]); + } + done = true; + } + } + } + + if (done) { + float view_vec[3], cross[3]; + + /* convert the 2D nomal into 3D */ + mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* worldspace */ + mul_mat3_m4_v3(vc.obedit->imat, nor); /* local space */ + + /* correct the normal to be aligned on the view plane */ + copy_v3_v3(view_vec, vc.rv3d->viewinv[2]); + mul_mat3_m4_v3(vc.obedit->imat, view_vec); + cross_v3_v3v3(cross, nor, view_vec); + cross_v3_v3v3(nor, view_vec, cross); + normalize_v3(nor); + } + + /* center */ + mid_v3_v3v3(cent, min, max); + copy_v3_v3(min, cent); + + mul_m4_v3(vc.obedit->obmat, min); /* view space */ + ED_view3d_win_to_3d_int(vc.ar, min, event->mval, min); + mul_m4_v3(vc.obedit->imat, min); // back in object space + + sub_v3_v3(min, cent); + + /* calculate rotation */ + unit_m3(mat); + if (done) { + float angle; + + normalize_v3_v3(vec, min); + + angle = angle_normalized_v3v3(vec, nor); + + if (angle != 0.0f) { + float axis[3]; + + cross_v3_v3v3(axis, nor, vec); + + /* halve the rotation if its applied twice */ + if (rot_src) { + angle *= 0.5f; + } + + axis_angle_to_mat3(mat, axis, angle); + } + } + + if (rot_src) { + EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3", + BM_ELEM_SELECT, cent, mat); + + /* also project the source, for retopo workflow */ + if (use_proj) + EMBM_project_snap_verts(C, vc.ar, vc.em); + } + + edbm_extrude_edge(vc.obedit, vc.em, BM_ELEM_SELECT, nor); + EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3", + BM_ELEM_SELECT, cent, mat); + EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v", + BM_ELEM_SELECT, min); + } + else { + const float *curs = give_cursor(vc.scene, vc.v3d); + BMOperator bmop; + BMOIter oiter; + + copy_v3_v3(min, curs); + ED_view3d_win_to_3d_int(vc.ar, min, event->mval, min); + + invert_m4_m4(vc.obedit->imat, vc.obedit->obmat); + mul_m4_v3(vc.obedit->imat, min); // back in object space + + EDBM_op_init(vc.em, &bmop, op, "create_vert co=%v", min); + BMO_op_exec(vc.em->bm, &bmop); + + BMO_ITER (v1, &oiter, bmop.slots_out, "vert.out", BM_VERT) { + BM_vert_select_set(vc.em->bm, v1, true); + } + + if (!EDBM_op_finish(vc.em, &bmop, op, true)) { + return OPERATOR_CANCELLED; + } + } + + if (use_proj) + EMBM_project_snap_verts(C, vc.ar, vc.em); + + /* This normally happens when pushing undo but modal operators + * like this one don't push undo data until after modal mode is + * done. */ + EDBM_mesh_normals_update(vc.em); + + EDBM_update_generic(vc.em, true, true); + + return OPERATOR_FINISHED; +} + +void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Duplicate or Extrude at 3D Cursor"; + ot->idname = "MESH_OT_dupli_extrude_cursor"; + ot->description = "Duplicate and extrude selected vertices, edges or faces towards the mouse cursor"; + + /* api callbacks */ + ot->invoke = edbm_dupli_extrude_cursor_invoke; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "rotate_source", 1, "Rotate Source", "Rotate initial selection giving better shape"); +} + + +static int edbm_spin_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMesh *bm = em->bm; + BMOperator spinop; + float cent[3], axis[3], imat[3][3]; + float d[3] = {0.0f, 0.0f, 0.0f}; + int steps, dupli; + float angle; + + RNA_float_get_array(op->ptr, "center", cent); + RNA_float_get_array(op->ptr, "axis", axis); + steps = RNA_int_get(op->ptr, "steps"); + angle = RNA_float_get(op->ptr, "angle"); + //if (ts->editbutflag & B_CLOCKWISE) + angle = -angle; + dupli = RNA_boolean_get(op->ptr, "dupli"); + + /* undo object transformation */ + copy_m3_m4(imat, obedit->imat); + sub_v3_v3(cent, obedit->obmat[3]); + mul_m3_v3(imat, cent); + mul_m3_v3(imat, axis); + + if (!EDBM_op_init(em, &spinop, op, + "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", + BM_ELEM_SELECT, cent, axis, d, steps, angle, dupli)) + { + return OPERATOR_CANCELLED; + } + BMO_op_exec(bm, &spinop); + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true); + if (!EDBM_op_finish(em, &spinop, op, true)) { + return OPERATOR_CANCELLED; + } + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; +} + +/* get center and axis, in global coords */ +static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = ED_view3d_context_rv3d(C); + + RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d)); + RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[2]); + + return edbm_spin_exec(C, op); +} + +void MESH_OT_spin(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Spin"; + ot->description = "Extrude selected vertices in a circle around the cursor in indicated viewport"; + ot->idname = "MESH_OT_spin"; + + /* api callbacks */ + ot->invoke = edbm_spin_invoke; + ot->exec = edbm_spin_exec; + ot->poll = EDBM_view3d_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, INT_MAX); + RNA_def_boolean(ot->srna, "dupli", 0, "Dupli", "Make Duplicates"); + prop = RNA_def_float(ot->srna, "angle", DEG2RADF(90.0f), -FLT_MAX, FLT_MAX, "Angle", "Angle", DEG2RADF(-360.0f), DEG2RADF(360.0f)); + RNA_def_property_subtype(prop, PROP_ANGLE); + + 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, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); + +} + +static int edbm_screw_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMesh *bm = em->bm; + BMEdge *eed; + BMVert *eve, *v1, *v2; + BMIter iter, eiter; + BMOperator spinop; + float dvec[3], nor[3], cent[3], axis[3]; + float imat[3][3]; + int steps, turns; + int valence; + + + turns = RNA_int_get(op->ptr, "turns"); + steps = RNA_int_get(op->ptr, "steps"); + RNA_float_get_array(op->ptr, "center", cent); + RNA_float_get_array(op->ptr, "axis", axis); + + /* undo object transformation */ + copy_m3_m4(imat, obedit->imat); + sub_v3_v3(cent, obedit->obmat[3]); + mul_m3_v3(imat, cent); + mul_m3_v3(imat, axis); + + + /* find two vertices with valence count == 1, more or less is wrong */ + v1 = NULL; + v2 = NULL; + + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { + valence = 0; + BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) { + if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { + valence++; + } + } + + if (valence == 1) { + if (v1 == NULL) { + v1 = eve; + } + else if (v2 == NULL) { + v2 = eve; + } + else { + v1 = NULL; + break; + } + } + } + + if (v1 == NULL || v2 == NULL) { + BKE_report(op->reports, RPT_ERROR, "You have to select a string of connected vertices too"); + return OPERATOR_CANCELLED; + } + + /* calculate dvec */ + sub_v3_v3v3(dvec, v1->co, v2->co); + mul_v3_fl(dvec, 1.0f / steps); + + if (dot_v3v3(nor, dvec) > 0.000f) + negate_v3(dvec); + + if (!EDBM_op_init(em, &spinop, op, + "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", + BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), false)) + { + return OPERATOR_CANCELLED; + } + BMO_op_exec(bm, &spinop); + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true); + if (!EDBM_op_finish(em, &spinop, op, true)) { + return OPERATOR_CANCELLED; + } + + EDBM_update_generic(em, true, true); + + return OPERATOR_FINISHED; +} + +/* get center and axis, in global coords */ +static int edbm_screw_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + Scene *scene = CTX_data_scene(C); + View3D *v3d = CTX_wm_view3d(C); + RegionView3D *rv3d = ED_view3d_context_rv3d(C); + + RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d)); + RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[1]); + + return edbm_screw_exec(C, op); +} + +void MESH_OT_screw(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Screw"; + ot->description = "Extrude selected vertices in screw-shaped rotation around the cursor in indicated viewport"; + ot->idname = "MESH_OT_screw"; + + /* api callbacks */ + ot->invoke = edbm_screw_invoke; + ot->exec = edbm_screw_exec; + ot->poll = EDBM_view3d_poll; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_int(ot->srna, "steps", 9, 1, INT_MAX, "Steps", "Steps", 3, 256); + RNA_def_int(ot->srna, "turns", 1, 1, INT_MAX, "Turns", "Turns", 1, 256); + + 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, -FLT_MAX, FLT_MAX, + "Axis", "Axis in global view space", -1.0f, 1.0f); +} diff --git a/source/blender/editors/mesh/editmesh_inset.c b/source/blender/editors/mesh/editmesh_inset.c new file mode 100644 index 00000000000..10f384f5b7c --- /dev/null +++ b/source/blender/editors/mesh/editmesh_inset.c @@ -0,0 +1,431 @@ +/* + * ***** 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/editors/mesh/editmesh_inset.c + * \ingroup edmesh + */ + +#include "MEM_guardedalloc.h" + +#include "DNA_object_types.h" + +#include "BLI_string.h" +#include "BLI_math.h" + +#include "BLF_translation.h" + +#include "BKE_context.h" +#include "BKE_tessmesh.h" + +#include "RNA_define.h" +#include "RNA_access.h" + +#include "WM_api.h" +#include "WM_types.h" + +#include "ED_mesh.h" +#include "ED_numinput.h" +#include "ED_screen.h" +#include "ED_transform.h" +#include "ED_view3d.h" + +#include "mesh_intern.h" /* own include */ + + +#define HEADER_LENGTH 180 + +typedef struct { + float old_thickness; + float old_depth; + int mcenter[2]; + int modify_depth; + 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; + BMEditMesh *em; + NumInput num_input; +} InsetData; + + +static void edbm_inset_update_header(wmOperator *op, bContext *C) +{ + InsetData *opdata = op->customdata; + + const char *str = IFACE_("Confirm: Enter/LClick, Cancel: (Esc/RClick), Thickness: %s, " + "Depth (Ctrl to tweak): %s (%s), Outset (O): (%s), Boundary (B): (%s)"); + + char msg[HEADER_LENGTH]; + ScrArea *sa = CTX_wm_area(C); + + if (sa) { + char flts_str[NUM_STR_REP_LEN * 2]; + if (hasNumInput(&opdata->num_input)) + outputNumInput(&opdata->num_input, flts_str); + else { + BLI_snprintf(flts_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "thickness")); + BLI_snprintf(flts_str + NUM_STR_REP_LEN, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "depth")); + } + BLI_snprintf(msg, HEADER_LENGTH, str, + flts_str, + flts_str + NUM_STR_REP_LEN, + opdata->modify_depth ? IFACE_("On") : IFACE_("Off"), + RNA_boolean_get(op->ptr, "use_outset") ? IFACE_("On") : IFACE_("Off"), + RNA_boolean_get(op->ptr, "use_boundary") ? IFACE_("On") : IFACE_("Off") + ); + + ED_area_headerprint(sa, msg); + } +} + + +static int edbm_inset_init(bContext *C, wmOperator *op, int is_modal) +{ + InsetData *opdata; + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + + op->customdata = opdata = MEM_mallocN(sizeof(InsetData), "inset_operator_data"); + + opdata->old_thickness = 0.01; + opdata->old_depth = 0.0; + opdata->modify_depth = false; + opdata->shift = false; + opdata->shift_amount = 0.0f; + opdata->is_modal = is_modal; + opdata->em = em; + + initNumInput(&opdata->num_input); + opdata->num_input.idx_max = 1; /* Two elements. */ + + if (is_modal) + opdata->backup = EDBM_redo_state_store(em); + + return 1; +} + +static void edbm_inset_exit(bContext *C, wmOperator *op) +{ + InsetData *opdata; + ScrArea *sa = CTX_wm_area(C); + + opdata = op->customdata; + + if (opdata->is_modal) + EDBM_redo_state_free(&opdata->backup, NULL, false); + + if (sa) { + ED_area_headerprint(sa, NULL); + } + MEM_freeN(op->customdata); +} + +static int edbm_inset_cancel(bContext *C, wmOperator *op) +{ + InsetData *opdata; + + opdata = op->customdata; + if (opdata->is_modal) { + EDBM_redo_state_free(&opdata->backup, opdata->em, true); + EDBM_update_generic(opdata->em, false, true); + } + + edbm_inset_exit(C, op); + + /* need to force redisplay or we may still view the modified result */ + ED_region_tag_redraw(CTX_wm_region(C)); + return OPERATOR_CANCELLED; +} + +static int edbm_inset_calc(wmOperator *op) +{ + InsetData *opdata; + BMEditMesh *em; + BMOperator bmop; + + const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); + const bool use_even_offset = RNA_boolean_get(op->ptr, "use_even_offset"); + const bool use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset"); + const float thickness = RNA_float_get(op->ptr, "thickness"); + const float depth = RNA_float_get(op->ptr, "depth"); + const bool use_outset = RNA_boolean_get(op->ptr, "use_outset"); + const bool use_select_inset = RNA_boolean_get(op->ptr, "use_select_inset"); /* not passed onto the BMO */ + + opdata = op->customdata; + em = opdata->em; + + if (opdata->is_modal) { + EDBM_redo_state_restore(opdata->backup, em, false); + } + + EDBM_op_init(em, &bmop, op, + "inset faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b " + "thickness=%f depth=%f use_outset=%b", + BM_ELEM_SELECT, use_boundary, use_even_offset, use_relative_offset, + thickness, depth, use_outset); + + BMO_op_exec(em->bm, &bmop); + + if (use_select_inset) { + /* deselect original faces/verts */ + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); + } + else { + BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE, BM_ELEM_SELECT, false); + BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, false); + /* re-select faces so the verts and edges get selected too */ + BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_SELECT); + } + + if (!EDBM_op_finish(em, &bmop, op, true)) { + return 0; + } + else { + EDBM_update_generic(em, true, true); + return 1; + } +} + +static int edbm_inset_exec(bContext *C, wmOperator *op) +{ + edbm_inset_init(C, op, false); + + if (!edbm_inset_calc(op)) { + edbm_inset_exit(C, op); + return OPERATOR_CANCELLED; + } + + edbm_inset_exit(C, op); + return OPERATOR_FINISHED; +} + +static int edbm_inset_invoke(bContext *C, wmOperator *op, const 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, 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; + } + 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(op); + + edbm_inset_update_header(op, C); + + WM_event_add_modal_handler(C, op); + return OPERATOR_RUNNING_MODAL; +} + +static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + InsetData *opdata = op->customdata; + + if (event->val == KM_PRESS) { + /* Try to handle numeric inputs... */ + + if (handleNumInput(&opdata->num_input, event)) { + float amounts[2] = {RNA_float_get(op->ptr, "thickness"), + RNA_float_get(op->ptr, "depth")}; + applyNumInput(&opdata->num_input, amounts); + amounts[0] = max_ff(amounts[0], 0.0f); + RNA_float_set(op->ptr, "thickness", amounts[0]); + RNA_float_set(op->ptr, "depth", amounts[1]); + + if (edbm_inset_calc(op)) { + edbm_inset_update_header(op, C); + return OPERATOR_RUNNING_MODAL; + } + else { + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + } + + switch (event->type) { + case ESCKEY: + case RIGHTMOUSE: + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + + case MOUSEMOVE: + if (!hasNumInput(&opdata->num_input)) { + float mdiff[2]; + float amount; + + mdiff[0] = opdata->mcenter[0] - event->mval[0]; + mdiff[1] = opdata->mcenter[1] - event->mval[1]; + + if (opdata->modify_depth) + amount = opdata->old_depth + ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); + else + amount = opdata->old_thickness - ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); + + /* Fake shift-transform... */ + if (opdata->shift) + amount = (amount - opdata->shift_amount) * 0.1f + opdata->shift_amount; + + if (opdata->modify_depth) + RNA_float_set(op->ptr, "depth", amount); + else { + amount = max_ff(amount, 0.0f); + RNA_float_set(op->ptr, "thickness", amount); + } + + if (edbm_inset_calc(op)) + edbm_inset_update_header(op, C); + else { + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + break; + + case LEFTMOUSE: + case PADENTER: + case RETKEY: + edbm_inset_calc(op); + edbm_inset_exit(C, op); + return OPERATOR_FINISHED; + + case LEFTSHIFTKEY: + case RIGHTSHIFTKEY: + if (event->val == KM_PRESS) { + if (opdata->modify_depth) + opdata->shift_amount = RNA_float_get(op->ptr, "depth"); + else + opdata->shift_amount = RNA_float_get(op->ptr, "thickness"); + opdata->shift = true; + } + else { + opdata->shift_amount = 0.0f; + opdata->shift = false; + } + break; + + case LEFTCTRLKEY: + case RIGHTCTRLKEY: + { + float mlen[2]; + + mlen[0] = opdata->mcenter[0] - event->mval[0]; + mlen[1] = opdata->mcenter[1] - event->mval[1]; + + if (event->val == KM_PRESS) { + opdata->old_thickness = RNA_float_get(op->ptr, "thickness"); + if (opdata->shift) + opdata->shift_amount = opdata->old_thickness; + opdata->modify_depth = true; + } + else { + opdata->old_depth = RNA_float_get(op->ptr, "depth"); + if (opdata->shift) + opdata->shift_amount = opdata->old_depth; + opdata->modify_depth = false; + } + opdata->initial_length = len_v2(mlen); + + edbm_inset_update_header(op, C); + break; + } + + case OKEY: + if (event->val == KM_PRESS) { + const bool use_outset = RNA_boolean_get(op->ptr, "use_outset"); + RNA_boolean_set(op->ptr, "use_outset", !use_outset); + if (edbm_inset_calc(op)) { + edbm_inset_update_header(op, C); + } + else { + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + break; + case BKEY: + if (event->val == KM_PRESS) { + const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); + RNA_boolean_set(op->ptr, "use_boundary", !use_boundary); + if (edbm_inset_calc(op)) { + edbm_inset_update_header(op, C); + } + else { + edbm_inset_cancel(C, op); + return OPERATOR_CANCELLED; + } + } + break; + } + + return OPERATOR_RUNNING_MODAL; +} + + +void MESH_OT_inset(wmOperatorType *ot) +{ + PropertyRNA *prop; + + /* identifiers */ + ot->name = "Inset Faces"; + ot->idname = "MESH_OT_inset"; + ot->description = "Inset new faces into selected faces"; + + /* api callbacks */ + ot->invoke = edbm_inset_invoke; + ot->modal = edbm_inset_modal; + ot->exec = edbm_inset_exec; + ot->cancel = edbm_inset_cancel; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; + + /* properties */ + RNA_def_boolean(ot->srna, "use_boundary", true, "Boundary", "Inset face boundaries"); + RNA_def_boolean(ot->srna, "use_even_offset", true, "Offset Even", "Scale the offset to give more even thickness"); + RNA_def_boolean(ot->srna, "use_relative_offset", false, "Offset Relative", "Scale the offset by surrounding geometry"); + + prop = RNA_def_float(ot->srna, "thickness", 0.01f, 0.0f, FLT_MAX, "Thickness", "", 0.0f, 10.0f); + /* use 1 rather then 10 for max else dragging the button moves too far */ + RNA_def_property_ui_range(prop, 0.0, 1.0, 0.01, 4); + prop = RNA_def_float(ot->srna, "depth", 0.0f, -FLT_MAX, FLT_MAX, "Depth", "", -10.0f, 10.0f); + RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.01, 4); + + RNA_def_boolean(ot->srna, "use_outset", false, "Outset", "Outset rather than inset"); + RNA_def_boolean(ot->srna, "use_select_inset", true, "Select Outer", "Select the new inset faces"); +} diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c index 57d3f7406ca..3f1c8ced5d2 100644 --- a/source/blender/editors/mesh/editmesh_knife.c +++ b/source/blender/editors/mesh/editmesh_knife.c @@ -35,7 +35,8 @@ #include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" +#include "BLI_string.h" #include "BLI_array.h" #include "BLI_linklist.h" #include "BLI_math.h" @@ -58,7 +59,6 @@ #include "WM_api.h" #include "WM_types.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" #include "BKE_tessmesh.h" #include "UI_resources.h" @@ -66,7 +66,7 @@ #include "RNA_access.h" #include "RNA_define.h" -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ /* this code here is kindof messy. . .I might need to eventually rework it - joeedh */ diff --git a/source/blender/editors/mesh/editmesh_knife_project.c b/source/blender/editors/mesh/editmesh_knife_project.c index c8256914884..1dae4aa51c8 100644 --- a/source/blender/editors/mesh/editmesh_knife_project.c +++ b/source/blender/editors/mesh/editmesh_knife_project.c @@ -15,7 +15,7 @@ * 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) 2007 Blender Foundation. + * The Original Code is Copyright (C) 2013 Blender Foundation. * All rights reserved. * * @@ -29,17 +29,12 @@ */ #include "DNA_curve_types.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" -#include "DNA_screen_types.h" -#include "DNA_windowmanager_types.h" -#include "BLI_utildefines.h" #include "BLI_math.h" #include "BLI_linklist.h" #include "BLI_listbase.h" -#include "BKE_library.h" #include "BKE_mesh.h" #include "BKE_context.h" #include "BKE_curve.h" @@ -55,7 +50,7 @@ #include "ED_screen.h" #include "ED_view3d.h" -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ static LinkNode *knifeproject_poly_from_object(ARegion *ar, Scene *scene, Object *ob, LinkNode *polys) diff --git a/source/blender/editors/mesh/editmesh_loopcut.c b/source/blender/editors/mesh/editmesh_loopcut.c index ee1c274b154..62cb1840808 100644 --- a/source/blender/editors/mesh/editmesh_loopcut.c +++ b/source/blender/editors/mesh/editmesh_loopcut.c @@ -29,12 +29,11 @@ */ #include "DNA_object_types.h" -#include "DNA_scene_types.h" #include "MEM_guardedalloc.h" #include "BLI_array.h" -#include "BLI_blenlib.h" +#include "BLI_string.h" #include "BLI_math.h" #include "BLF_translation.h" @@ -58,7 +57,8 @@ #include "WM_api.h" #include "WM_types.h" -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ + /* ringsel operator */ diff --git a/source/blender/editors/mesh/editmesh_rip.c b/source/blender/editors/mesh/editmesh_rip.c index 0ea02f371f0..23920e7424e 100644 --- a/source/blender/editors/mesh/editmesh_rip.c +++ b/source/blender/editors/mesh/editmesh_rip.c @@ -50,7 +50,7 @@ #include "ED_transform.h" #include "ED_view3d.h" -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ /** * helper to find edge for edge_rip, @@ -1049,7 +1049,7 @@ void MESH_OT_rip(wmOperatorType *ot) /* api callbacks */ ot->invoke = edbm_rip_invoke; - ot->poll = EM_view3d_poll; + ot->poll = EDBM_view3d_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c index 9474c051cee..3dfa2fa5c6c 100644 --- a/source/blender/editors/mesh/editmesh_select.c +++ b/source/blender/editors/mesh/editmesh_select.c @@ -31,7 +31,7 @@ #include "MEM_guardedalloc.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" #include "BLI_math.h" #include "BLI_rand.h" #include "BLI_array.h" @@ -42,7 +42,6 @@ #include "BKE_displist.h" #include "BKE_report.h" #include "BKE_paint.h" -#include "BKE_mesh.h" #include "BKE_tessmesh.h" #include "IMB_imbuf_types.h" @@ -61,17 +60,16 @@ #include "BIF_gl.h" -#include "DNA_scene_types.h" #include "DNA_object_types.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "GPU_extensions.h" -#include "mesh_intern.h" - #include "UI_resources.h" +#include "mesh_intern.h" /* own include */ + /* ****************************** MIRROR **************** */ void EDBM_select_mirrored(Object *UNUSED(obedit), BMEditMesh *em, bool extend) @@ -744,7 +742,6 @@ static int similar_face_select_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, false, false); - /* we succeeded */ return OPERATOR_FINISHED; } @@ -786,7 +783,6 @@ static int similar_edge_select_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, false, false); - /* we succeeded */ return OPERATOR_FINISHED; } @@ -831,7 +827,6 @@ static int similar_vert_select_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, false, false); - /* we succeeded */ return OPERATOR_FINISHED; } @@ -1269,6 +1264,82 @@ void MESH_OT_edgering_select(wmOperatorType *ot) RNA_def_boolean(ot->srna, "ring", 1, "Select Ring", "Select ring"); } +/* ******************** (de)select all operator **************** */ +static int edbm_select_all_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + const int action = RNA_enum_get(op->ptr, "action"); + + switch (action) { + case SEL_TOGGLE: + EDBM_select_toggle_all(em); + break; + case SEL_SELECT: + EDBM_flag_enable_all(em, BM_ELEM_SELECT); + break; + case SEL_DESELECT: + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + break; + case SEL_INVERT: + EDBM_select_swap(em); + EDBM_selectmode_flush(em); + break; + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void MESH_OT_select_all(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "(De)select All"; + ot->idname = "MESH_OT_select_all"; + ot->description = "(De)select all vertices, edges or faces"; + + /* api callbacks */ + ot->exec = edbm_select_all_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + WM_operator_properties_select_all(ot); +} + +static int edbm_faces_select_interior_exec(bContext *C, wmOperator *UNUSED(op)) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + + if (EDBM_select_interior_faces(em)) { + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); + + return OPERATOR_FINISHED; + } + else { + return OPERATOR_CANCELLED; + } + +} + +void MESH_OT_select_interior_faces(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Interior Faces"; + ot->idname = "MESH_OT_select_interior_faces"; + ot->description = "Select faces where all edges have more than 2 face users"; + + /* api callbacks */ + ot->exec = edbm_faces_select_interior_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ******************* generic tag_shortest_path and helpers ****************** */ static float step_cost_3_v3(const float v1[3], const float v2[3], const float v3[3]) @@ -2307,6 +2378,9 @@ int EDBM_select_interior_faces(BMEditMesh *em) return change; } + +/************************ Select Linked Operator *************************/ + static void linked_limit_default(bContext *C, wmOperator *op) { if (!RNA_struct_property_is_set(op->ptr, "limit")) { @@ -2319,6 +2393,106 @@ static void linked_limit_default(bContext *C, wmOperator *op) } } +static int edbm_select_linked_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMesh *bm = em->bm; + BMIter iter; + BMVert *v; + BMEdge *e; + BMWalker walker; + + int limit; + + linked_limit_default(C, op); + + limit = RNA_boolean_get(op->ptr, "limit"); + + if (em->selectmode == SCE_SELECT_FACE) { + BMFace *efa; + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + BM_elem_flag_set(efa, BM_ELEM_TAG, (BM_elem_flag_test(efa, BM_ELEM_SELECT) && + !BM_elem_flag_test(efa, BM_ELEM_HIDDEN))); + } + + if (limit) { + /* grr, shouldn't need to alloc BMO flags here */ + BM_mesh_elem_toolflags_ensure(bm); + BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { + /* BMESH_TODO, don't use 'BM_ELEM_SELECT' here, its a HFLAG only! */ + BMO_elem_flag_set(bm, e, BM_ELEM_SELECT, !BM_elem_flag_test(e, BM_ELEM_SEAM)); + } + } + + BMW_init(&walker, bm, BMW_ISLAND, + BMW_MASK_NOP, limit ? BM_ELEM_SELECT : BMW_MASK_NOP, BMW_MASK_NOP, + BMW_FLAG_TEST_HIDDEN, + BMW_NIL_LAY); + + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { + if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { + for (efa = BMW_begin(&walker, efa); efa; efa = BMW_step(&walker)) { + BM_face_select_set(bm, efa, true); + } + } + } + BMW_end(&walker); + + if (limit) { + BM_mesh_elem_toolflags_clear(bm); + } + } + else { + BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { + BM_elem_flag_enable(v, BM_ELEM_TAG); + } + else { + BM_elem_flag_disable(v, BM_ELEM_TAG); + } + } + + BMW_init(&walker, em->bm, BMW_SHELL, + BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP, + BMW_FLAG_TEST_HIDDEN, + BMW_NIL_LAY); + + BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { + if (BM_elem_flag_test(v, BM_ELEM_TAG)) { + for (e = BMW_begin(&walker, v); e; e = BMW_step(&walker)) { + BM_edge_select_set(em->bm, e, true); + } + } + } + BMW_end(&walker); + + EDBM_selectmode_flush(em); + } + + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); + + return OPERATOR_FINISHED; +} + +void MESH_OT_select_linked(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Linked All"; + ot->idname = "MESH_OT_select_linked"; + ot->description = "Select all vertices linked to the active mesh"; + + /* api callbacks */ + ot->exec = edbm_select_linked_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + RNA_def_boolean(ot->srna, "limit", 0, "Limit by Seams", ""); +} + static int edbm_select_linked_pick_invoke(bContext *C, wmOperator *op, const wmEvent *event) { Object *obedit = CTX_data_edit_object(C); @@ -2434,104 +2608,160 @@ void MESH_OT_select_linked_pick(wmOperatorType *ot) } -static int edbm_select_linked_exec(bContext *C, wmOperator *op) +static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BMEdit_FromObject(obedit); - BMesh *bm = em->bm; + BMFace *efa; BMIter iter; - BMVert *v; - BMEdge *e; - BMWalker walker; - - int limit; + const int numverts = RNA_int_get(op->ptr, "number"); + const int type = RNA_enum_get(op->ptr, "type"); - linked_limit_default(C, op); + if (!RNA_boolean_get(op->ptr, "extend")) + EDBM_flag_disable_all(em, BM_ELEM_SELECT); - limit = RNA_boolean_get(op->ptr, "limit"); + BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (em->selectmode == SCE_SELECT_FACE) { - BMFace *efa; + int select; - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - BM_elem_flag_set(efa, BM_ELEM_TAG, (BM_elem_flag_test(efa, BM_ELEM_SELECT) && - !BM_elem_flag_test(efa, BM_ELEM_HIDDEN))); + switch (type) { + case 0: + select = (efa->len < numverts); + break; + case 1: + select = (efa->len == numverts); + break; + case 2: + select = (efa->len > numverts); + break; + case 3: + select = (efa->len != numverts); + break; + default: + BLI_assert(0); + select = false; + break; } - if (limit) { - /* grr, shouldn't need to alloc BMO flags here */ - BM_mesh_elem_toolflags_ensure(bm); - BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { - /* BMESH_TODO, don't use 'BM_ELEM_SELECT' here, its a HFLAG only! */ - BMO_elem_flag_set(bm, e, BM_ELEM_SELECT, !BM_elem_flag_test(e, BM_ELEM_SEAM)); - } + if (select) { + BM_face_select_set(em->bm, efa, true); } + } - BMW_init(&walker, bm, BMW_ISLAND, - BMW_MASK_NOP, limit ? BM_ELEM_SELECT : BMW_MASK_NOP, BMW_MASK_NOP, - BMW_FLAG_TEST_HIDDEN, - BMW_NIL_LAY); + EDBM_selectmode_flush(em); - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - if (BM_elem_flag_test(efa, BM_ELEM_TAG)) { - for (efa = BMW_begin(&walker, efa); efa; efa = BMW_step(&walker)) { - BM_face_select_set(bm, efa, true); - } - } - } - BMW_end(&walker); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + return OPERATOR_FINISHED; +} - if (limit) { - BM_mesh_elem_toolflags_clear(bm); +void MESH_OT_select_face_by_sides(wmOperatorType *ot) +{ + static const EnumPropertyItem type_items[] = { + {0, "LESS", 0, "Less Than", ""}, + {1, "EQUAL", 0, "Equal To", ""}, + {2, "GREATER", 0, "Greater Than", ""}, + {3, "NOTEQUAL", 0, "Not Equal To", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Select Faces by Sides"; + ot->description = "Select vertices or faces by the number of polygon sides"; + ot->idname = "MESH_OT_select_face_by_sides"; + + /* api callbacks */ + ot->exec = edbm_select_face_by_sides_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_int(ot->srna, "number", 4, 3, INT_MAX, "Number of Vertices", "", 3, INT_MAX); + RNA_def_enum(ot->srna, "type", type_items, 1, "Type", "Type of comparison to make"); + RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend the selection"); +} + + +static int edbm_select_loose_verts_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMVert *eve; + BMEdge *eed; + BMIter iter; + + if (!RNA_boolean_get(op->ptr, "extend")) + EDBM_flag_disable_all(em, BM_ELEM_SELECT); + + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { + if (!eve->e) { + BM_vert_select_set(em->bm, eve, true); } } - else { - BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { - BM_elem_flag_enable(v, BM_ELEM_TAG); - } - else { - BM_elem_flag_disable(v, BM_ELEM_TAG); - } + + BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { + if (!eed->l) { + BM_edge_select_set(em->bm, eed, true); } + } - BMW_init(&walker, em->bm, BMW_SHELL, - BMW_MASK_NOP, BMW_MASK_NOP, BMW_MASK_NOP, - BMW_FLAG_TEST_HIDDEN, - BMW_NIL_LAY); + EDBM_selectmode_flush(em); - BM_ITER_MESH (v, &iter, em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v, BM_ELEM_TAG)) { - for (e = BMW_begin(&walker, v); e; e = BMW_step(&walker)) { - BM_edge_select_set(em->bm, e, true); - } - } - } - BMW_end(&walker); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); + return OPERATOR_FINISHED; +} + +void MESH_OT_select_loose_verts(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Select Loose Vertices/Edges"; + ot->description = "Select vertices with no edges nor faces, and edges with no faces"; + ot->idname = "MESH_OT_select_loose_verts"; + + /* api callbacks */ + ot->exec = edbm_select_loose_verts_exec; + ot->poll = ED_operator_editmesh; + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); +} + + +static int edbm_select_mirror_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + bool extend = RNA_boolean_get(op->ptr, "extend"); + + if (em->bm->totvert && em->bm->totvertsel) { + EDBM_select_mirrored(obedit, em, extend); EDBM_selectmode_flush(em); + WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); } - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); - return OPERATOR_FINISHED; } -void MESH_OT_select_linked(wmOperatorType *ot) +void MESH_OT_select_mirror(wmOperatorType *ot) { /* identifiers */ - ot->name = "Select Linked All"; - ot->idname = "MESH_OT_select_linked"; - ot->description = "Select all vertices linked to the active mesh"; - + ot->name = "Select Mirror"; + ot->description = "Select mesh items at mirrored locations"; + ot->idname = "MESH_OT_select_mirror"; + /* api callbacks */ - ot->exec = edbm_select_linked_exec; + ot->exec = edbm_select_mirror_exec; ot->poll = ED_operator_editmesh; - + /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, "limit", 0, "Limit by Seams", ""); + + /* props */ + RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection"); } /* ******************** **************** */ @@ -2796,15 +3026,6 @@ void em_setup_viewcontext(bContext *C, ViewContext *vc) } } -/* poll call for mesh operators requiring a view3d context */ -int EM_view3d_poll(bContext *C) -{ - if (ED_operator_editmesh(C) && ED_operator_view3d_active(C)) - return 1; - - return 0; -} - static int edbm_select_sharp_edges_exec(bContext *C, wmOperator *op) { @@ -3115,6 +3336,91 @@ void MESH_OT_select_ungrouped(wmOperatorType *ot) RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); } + +/* BMESH_TODO - some way to select on an arbitrary axis */ +static int edbm_select_axis_exec(bContext *C, wmOperator *op) +{ + Object *obedit = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(obedit); + BMEditSelection *ese = em->bm->selected.last; + const int axis = RNA_enum_get(op->ptr, "axis"); + const int mode = RNA_enum_get(op->ptr, "mode"); /* -1 == aligned, 0 == neg, 1 == pos */ + + if (ese == NULL || ese->htype != BM_VERT) { + BKE_report(op->reports, RPT_WARNING, "This operator requires an active vertex (last selected)"); + return OPERATOR_CANCELLED; + } + else { + BMVert *ev, *act_vert = (BMVert *)ese->ele; + BMIter iter; + float value = act_vert->co[axis]; + float limit = CTX_data_tool_settings(C)->doublimit; // XXX + + if (mode == 0) + value -= limit; + else if (mode == 1) + value += limit; + + BM_ITER_MESH (ev, &iter, em->bm, BM_VERTS_OF_MESH) { + if (!BM_elem_flag_test(ev, BM_ELEM_HIDDEN)) { + switch (mode) { + case -1: /* aligned */ + if (fabsf(ev->co[axis] - value) < limit) + BM_vert_select_set(em->bm, ev, true); + break; + case 0: /* neg */ + if (ev->co[axis] > value) + BM_vert_select_set(em->bm, ev, true); + break; + case 1: /* pos */ + if (ev->co[axis] < value) + BM_vert_select_set(em->bm, ev, true); + break; + } + } + } + } + + EDBM_selectmode_flush(em); + WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); + + return OPERATOR_FINISHED; +} + +void MESH_OT_select_axis(wmOperatorType *ot) +{ + static EnumPropertyItem axis_mode_items[] = { + {0, "POSITIVE", 0, "Positive Axis", ""}, + {1, "NEGATIVE", 0, "Negative Axis", ""}, + {-1, "ALIGNED", 0, "Aligned Axis", ""}, + {0, NULL, 0, NULL, NULL} + }; + + static EnumPropertyItem axis_items_xyz[] = { + {0, "X_AXIS", 0, "X Axis", ""}, + {1, "Y_AXIS", 0, "Y Axis", ""}, + {2, "Z_AXIS", 0, "Z Axis", ""}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Select Axis"; + ot->description = "Select all data in the mesh on a single axis"; + ot->idname = "MESH_OT_select_axis"; + + /* api callbacks */ + ot->exec = edbm_select_axis_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "mode", axis_mode_items, 0, "Axis Mode", "Axis side to use when selecting"); + RNA_def_enum(ot->srna, "axis", axis_items_xyz, 0, "Axis", "Select the axis to compare each vertex on"); +} + + static int edbm_select_next_loop_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); @@ -3411,3 +3717,118 @@ void MESH_OT_loop_to_region(wmOperatorType *ot) RNA_def_boolean(ot->srna, "select_bigger", 0, "Select Bigger", "Select bigger regions instead of smaller ones"); } + + +/************************ Vertex Path Operator *************************/ + +typedef struct PathNode { + /* int u; */ /* UNUSED */ + /* int visited; */ /* UNUSED */ + ListBase edges; +} PathNode; + +typedef struct PathEdge { + struct PathEdge *next, *prev; + int v; + float w; +} PathEdge; + +static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) +{ + Object *ob = CTX_data_edit_object(C); + BMEditMesh *em = BMEdit_FromObject(ob); + BMOperator bmop; + BMIter iter; + BMVert *eve = NULL, *svert = NULL, *evert = NULL; + BMEditSelection *sv, *ev; + + /* get the type from RNA */ + const int type = RNA_enum_get(op->ptr, "type"); + + /* first try to find vertices in edit selection */ + sv = em->bm->selected.last; + if (sv != NULL) { + ev = sv->prev; + + if (ev && (sv->htype == BM_VERT) && (ev->htype == BM_VERT)) { + svert = (BMVert *)sv->ele; + evert = (BMVert *)ev->ele; + } + } + + /* if those are not found, because vertices where selected by e.g. + * border or circle select, find two selected vertices */ + if (svert == NULL) { + BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { + if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) + continue; + + if (svert == NULL) { + svert = eve; + } + else if (evert == NULL) { + evert = eve; + } + else { + /* more than two vertices are selected, + * show warning message and cancel operator */ + svert = evert = NULL; + break; + } + } + } + + if (svert == NULL || evert == NULL) { + BKE_report(op->reports, RPT_WARNING, "Path selection requires two vertices to be selected"); + return OPERATOR_CANCELLED; + } + + /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */ + EDBM_op_init(em, &bmop, op, + "shortest_path vert_start=%e vert_end=%e type=%i", + svert, evert, type); + + /* execute the operator */ + BMO_op_exec(em->bm, &bmop); + + /* DO NOT clear the existing selection */ + /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */ + + /* select the output */ + BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, true); + + /* finish the operator */ + if (!EDBM_op_finish(em, &bmop, op, true)) { + return OPERATOR_CANCELLED; + } + + EDBM_selectmode_flush(em); + + EDBM_update_generic(em, false, false); + + return OPERATOR_FINISHED; +} + +void MESH_OT_select_vertex_path(wmOperatorType *ot) +{ + static const EnumPropertyItem type_items[] = { + {VPATH_SELECT_EDGE_LENGTH, "EDGE_LENGTH", 0, "Edge Length", NULL}, + {VPATH_SELECT_TOPOLOGICAL, "TOPOLOGICAL", 0, "Topological", NULL}, + {0, NULL, 0, NULL, NULL} + }; + + /* identifiers */ + ot->name = "Select Vertex Path"; + ot->idname = "MESH_OT_select_vertex_path"; + ot->description = "Selected vertex path between two vertices"; + + /* api callbacks */ + ot->exec = edbm_select_vertex_path_exec; + ot->poll = ED_operator_editmesh; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* properties */ + RNA_def_enum(ot->srna, "type", type_items, VPATH_SELECT_EDGE_LENGTH, "Type", "Method to compute distance"); +} diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c index f05df06ffa2..5befcd7b5f2 100644 --- a/source/blender/editors/mesh/editmesh_tools.c +++ b/source/blender/editors/mesh/editmesh_tools.c @@ -37,19 +37,15 @@ #include "DNA_meshdata_types.h" #include "DNA_modifier_types.h" #include "DNA_object_types.h" -#include "DNA_scene_types.h" -#include "BLI_blenlib.h" +#include "BLI_listbase.h" #include "BLI_noise.h" #include "BLI_math.h" #include "BLI_rand.h" -#include "BLF_translation.h" - #include "BKE_material.h" #include "BKE_context.h" #include "BKE_depsgraph.h" -#include "BKE_object.h" #include "BKE_report.h" #include "BKE_texture.h" #include "BKE_main.h" @@ -63,7 +59,6 @@ #include "WM_types.h" #include "ED_mesh.h" -#include "ED_numinput.h" #include "ED_object.h" #include "ED_screen.h" #include "ED_transform.h" @@ -75,24 +70,10 @@ #include "UI_interface.h" #include "UI_resources.h" -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ #define USE_FACE_CREATE_SEL_EXTEND -#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]) -{ - if (dot_v3v3(nor, add) < -0.9999f) { - sub_v3_v3(nor, add); - } - else { - add_v3_v3(nor, add); - } -} - static int edbm_subdivide_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -229,735 +210,6 @@ void EMBM_project_snap_verts(bContext *C, ARegion *ar, BMEditMesh *em) } -/* individual face extrude */ -/* will use vertex normals for extrusion directions, so *nor is unaffected */ -static short edbm_extrude_discrete_faces(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor)) -{ - BMOIter siter; - BMIter liter; - BMFace *f; - BMLoop *l; - BMOperator bmop; - - EDBM_op_init(em, &bmop, op, "extrude_discrete_faces faces=%hf", hflag); - - /* deselect original verts */ - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - - BMO_op_exec(em->bm, &bmop); - - BMO_ITER (f, &siter, bmop.slots_out, "faces.out", BM_FACE) { - BM_face_select_set(em->bm, f, true); - - /* set face vertex normals to face normal */ - BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) { - copy_v3_v3(l->v->no, f->no); - } - } - - if (!EDBM_op_finish(em, &bmop, op, true)) { - return 0; - } - - return 's'; /* s is shrink/fatten */ -} - -/* extrudes individual edges */ -static short edbm_extrude_edges_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor)) -{ - BMOperator bmop; - - EDBM_op_init(em, &bmop, op, "extrude_edge_only edges=%he", hflag); - - /* deselect original verts */ - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - - BMO_op_exec(em->bm, &bmop); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "geom.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true); - - if (!EDBM_op_finish(em, &bmop, op, true)) { - return 0; - } - - return 'n'; /* n is normal grab */ -} - -/* extrudes individual vertices */ -static short edbm_extrude_verts_indiv(BMEditMesh *em, wmOperator *op, const char hflag, float *UNUSED(nor)) -{ - BMOperator bmop; - - EDBM_op_init(em, &bmop, op, "extrude_vert_indiv verts=%hv", hflag); - - /* deselect original verts */ - BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_in, "verts", BM_VERT, BM_ELEM_SELECT, true); - - BMO_op_exec(em->bm, &bmop); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, true); - - if (!EDBM_op_finish(em, &bmop, op, true)) { - return 0; - } - - return 'g'; /* g is grab */ -} - -static short edbm_extrude_edge(Object *obedit, BMEditMesh *em, const char hflag, float nor[3]) -{ - BMesh *bm = em->bm; - BMIter iter; - BMOIter siter; - BMOperator extop; - BMEdge *edge; - BMFace *f; - ModifierData *md; - BMElem *ele; - BMOpSlot *slot_edges_exclude; - - BMO_op_init(bm, &extop, BMO_FLAG_DEFAULTS, "extrude_face_region"); - BMO_slot_buffer_from_enabled_hflag(bm, &extop, extop.slots_in, "geom", BM_VERT | BM_EDGE | BM_FACE, hflag); - - slot_edges_exclude = BMO_slot_get(extop.slots_in, "edges_exclude"); - - /* If a mirror modifier with clipping is on, we need to adjust some - * of the cases above to handle edges on the line of symmetry. - */ - md = obedit->modifiers.first; - for (; md; md = md->next) { - if ((md->type == eModifierType_Mirror) && (md->mode & eModifierMode_Realtime)) { - MirrorModifierData *mmd = (MirrorModifierData *) md; - - if (mmd->flag & MOD_MIR_CLIPPING) { - float mtx[4][4]; - if (mmd->mirror_ob) { - float imtx[4][4]; - invert_m4_m4(imtx, mmd->mirror_ob->obmat); - mult_m4_m4m4(mtx, imtx, obedit->obmat); - } - - BM_ITER_MESH (edge, &iter, bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(edge, hflag) && - BM_edge_is_boundary(edge) && - BM_elem_flag_test(edge->l->f, hflag)) - { - float co1[3], co2[3]; - - copy_v3_v3(co1, edge->v1->co); - copy_v3_v3(co2, edge->v2->co); - - if (mmd->mirror_ob) { - mul_v3_m4v3(co1, mtx, co1); - mul_v3_m4v3(co2, mtx, co2); - } - - if (mmd->flag & MOD_MIR_AXIS_X) { - if ((fabsf(co1[0]) < mmd->tolerance) && - (fabsf(co2[0]) < mmd->tolerance)) - { - BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); - } - } - if (mmd->flag & MOD_MIR_AXIS_Y) { - if ((fabsf(co1[1]) < mmd->tolerance) && - (fabsf(co2[1]) < mmd->tolerance)) - { - BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); - } - } - if (mmd->flag & MOD_MIR_AXIS_Z) { - if ((fabsf(co1[2]) < mmd->tolerance) && - (fabsf(co2[2]) < mmd->tolerance)) - { - BMO_slot_map_empty_insert(&extop, slot_edges_exclude, edge); - } - } - } - } - } - } - } - - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - - BMO_op_exec(bm, &extop); - - zero_v3(nor); - - BMO_ITER (ele, &siter, extop.slots_out, "geom.out", BM_ALL) { - BM_elem_select_set(bm, ele, true); - - if (ele->head.htype == BM_FACE) { - f = (BMFace *)ele; - add_normal_aligned(nor, f->no); - } - } - - normalize_v3(nor); - - BMO_op_finish(bm, &extop); - - /* grab / normal constraint */ - return is_zero_v3(nor) ? 'g' : 'n'; -} - -static short edbm_extrude_vert(Object *obedit, BMEditMesh *em, const char hflag, float nor[3]) -{ - BMIter iter; - BMEdge *eed; - - /* ensure vert flags are consistent for edge selections */ - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - if (BM_elem_flag_test(eed, hflag)) { - if (hflag & BM_ELEM_SELECT) { - BM_vert_select_set(em->bm, eed->v1, true); - BM_vert_select_set(em->bm, eed->v2, true); - } - - BM_elem_flag_enable(eed->v1, hflag & ~BM_ELEM_SELECT); - BM_elem_flag_enable(eed->v2, hflag & ~BM_ELEM_SELECT); - } - else { - if (BM_elem_flag_test(eed->v1, hflag) && BM_elem_flag_test(eed->v2, hflag)) { - if (hflag & BM_ELEM_SELECT) { - BM_edge_select_set(em->bm, eed, true); - } - - BM_elem_flag_enable(eed, hflag & ~BM_ELEM_SELECT); - } - } - } - - return edbm_extrude_edge(obedit, em, hflag, nor); -} - -static int edbm_extrude_repeat_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - RegionView3D *rv3d = CTX_wm_region_view3d(C); - - const int steps = RNA_int_get(op->ptr, "steps"); - - const float offs = RNA_float_get(op->ptr, "offset"); - float dvec[3], tmat[3][3], bmat[3][3], nor[3] = {0.0, 0.0, 0.0}; - short a; - - /* dvec */ - normalize_v3_v3(dvec, rv3d->persinv[2]); - mul_v3_fl(dvec, offs); - - /* base correction */ - copy_m3_m4(bmat, obedit->obmat); - invert_m3_m3(tmat, bmat); - mul_m3_v3(tmat, dvec); - - for (a = 0; a < steps; a++) { - edbm_extrude_edge(obedit, em, BM_ELEM_SELECT, nor); - //BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, "extrude_face_region geom=%hef", BM_ELEM_SELECT); - BMO_op_callf(em->bm, BMO_FLAG_DEFAULTS, - "translate vec=%v verts=%hv", - (float *)dvec, BM_ELEM_SELECT); - //extrudeflag(obedit, em, SELECT, nor); - //translateflag(em, SELECT, dvec); - } - - EDBM_mesh_normals_update(em); - - EDBM_update_generic(em, true, true); - - return OPERATOR_FINISHED; -} - -void MESH_OT_extrude_repeat(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Extrude Repeat Mesh"; - ot->description = "Extrude selected vertices, edges or faces repeatedly"; - ot->idname = "MESH_OT_extrude_repeat"; - - /* api callbacks */ - ot->exec = edbm_extrude_repeat_exec; - ot->poll = ED_operator_editmesh_view3d; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* props */ - 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 */ -static int edbm_extrude_mesh(Scene *scene, Object *obedit, BMEditMesh *em, wmOperator *op, float *norin) -{ - short nr, transmode = 0; - float stacknor[3] = {0.0f, 0.0f, 0.0f}; - float *nor = norin ? norin : stacknor; - - zero_v3(nor); - - /* XXX If those popup menus were to be enabled again, please get rid of this "menu string" syntax! */ - if (em->selectmode & SCE_SELECT_VERTEX) { - if (em->bm->totvertsel == 0) nr = 0; - else if (em->bm->totvertsel == 1) nr = 4; - else if (em->bm->totedgesel == 0) nr = 4; - else if (em->bm->totfacesel == 0) - nr = 3; /* pupmenu("Extrude %t|Only Edges %x3|Only Vertices %x4"); */ - else if (em->bm->totfacesel == 1) - nr = 1; /* pupmenu("Extrude %t|Region %x1|Only Edges% x3|Only Vertices %x4"); */ - else - nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2|Only Edges %x3|Only Vertices %x4"); */ - } - else if (em->selectmode & SCE_SELECT_EDGE) { - if (em->bm->totedgesel == 0) nr = 0; - - nr = 1; -#if 0 - else if (em->totedgesel == 1) nr = 3; - else if (em->totfacesel == 0) nr = 3; - else if (em->totfacesel == 1) - nr = 1; /* pupmenu("Extrude %t|Region %x1|Only Edges %x3"); */ - else - nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2|Only Edges %x3"); */ -#endif - } - else { - if (em->bm->totfacesel == 0) nr = 0; - else if (em->bm->totfacesel == 1) nr = 1; - else - nr = 1; /* pupmenu("Extrude %t|Region %x1|Individual Faces %x2"); */ - } - - if (nr < 1) return 'g'; - - if (nr == 1 && (em->selectmode & SCE_SELECT_VERTEX)) - transmode = edbm_extrude_vert(obedit, em, BM_ELEM_SELECT, nor); - else if (nr == 1) transmode = edbm_extrude_edge(obedit, em, BM_ELEM_SELECT, nor); - else if (nr == 4) transmode = edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor); - else if (nr == 3) transmode = edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor); - else transmode = edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor); - - if (transmode == 0) { - BKE_report(op->reports, RPT_ERROR, "Not a valid selection for extrude"); - } - else { - - /* We need to force immediate calculation here because - * transform may use derived objects (which are now stale). - * - * This shouldn't be necessary, derived queries should be - * automatically building this data if invalid. Or something. - */ -// DAG_object_flush_update(scene, obedit, OB_RECALC_DATA); - BKE_object_handle_update(scene, obedit); - - /* individual faces? */ -// BIF_TransformSetUndo("Extrude"); - if (nr == 2) { -// initTransform(TFM_SHRINKFATTEN, CTX_NO_PET|CTX_NO_MIRROR); -// Transform(); - } - else { -// initTransform(TFM_TRANSLATION, CTX_NO_PET|CTX_NO_MIRROR); - if (transmode == 'n') { - mul_m4_v3(obedit->obmat, nor); - sub_v3_v3v3(nor, nor, obedit->obmat[3]); -// BIF_setSingleAxisConstraint(nor, "along normal"); - } -// Transform(); - } - } - - return transmode; -} - -/* extrude without transform */ -static int edbm_extrude_region_exec(bContext *C, wmOperator *op) -{ - Scene *scene = CTX_data_scene(C); - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - - edbm_extrude_mesh(scene, obedit, em, op, NULL); - - /* This normally happens when pushing undo but modal operators - * like this one don't push undo data until after modal mode is - * done.*/ - EDBM_mesh_normals_update(em); - - EDBM_update_generic(em, true, true); - - return OPERATOR_FINISHED; -} - -void MESH_OT_extrude_region(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Extrude Region"; - ot->idname = "MESH_OT_extrude_region"; - ot->description = "Extrude region of faces"; - - /* api callbacks */ - //ot->invoke = mesh_extrude_region_invoke; - ot->exec = edbm_extrude_region_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); -} - -static int edbm_extrude_verts_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - float nor[3]; - - edbm_extrude_verts_indiv(em, op, BM_ELEM_SELECT, nor); - - EDBM_update_generic(em, true, true); - - return OPERATOR_FINISHED; -} - -void MESH_OT_extrude_verts_indiv(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Extrude Only Vertices"; - ot->idname = "MESH_OT_extrude_verts_indiv"; - ot->description = "Extrude individual vertices only"; - - /* api callbacks */ - ot->exec = edbm_extrude_verts_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* to give to transform */ - RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); -} - -static int edbm_extrude_edges_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - float nor[3]; - - edbm_extrude_edges_indiv(em, op, BM_ELEM_SELECT, nor); - - EDBM_update_generic(em, true, true); - - return OPERATOR_FINISHED; -} - -void MESH_OT_extrude_edges_indiv(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Extrude Only Edges"; - ot->idname = "MESH_OT_extrude_edges_indiv"; - ot->description = "Extrude individual edges only"; - - /* api callbacks */ - ot->exec = edbm_extrude_edges_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* to give to transform */ - RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); -} - -static int edbm_extrude_faces_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - float nor[3]; - - edbm_extrude_discrete_faces(em, op, BM_ELEM_SELECT, nor); - - EDBM_update_generic(em, true, true); - - return OPERATOR_FINISHED; -} - -void MESH_OT_extrude_faces_indiv(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Extrude Individual Faces"; - ot->idname = "MESH_OT_extrude_faces_indiv"; - ot->description = "Extrude individual faces only"; - - /* api callbacks */ - ot->exec = edbm_extrude_faces_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", ""); -} - -/* ******************** (de)select all operator **************** */ - -static int edbm_select_all_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - const int action = RNA_enum_get(op->ptr, "action"); - - switch (action) { - case SEL_TOGGLE: - EDBM_select_toggle_all(em); - break; - case SEL_SELECT: - EDBM_flag_enable_all(em, BM_ELEM_SELECT); - break; - case SEL_DESELECT: - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - break; - case SEL_INVERT: - EDBM_select_swap(em); - EDBM_selectmode_flush(em); - break; - } - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); - - return OPERATOR_FINISHED; -} - -void MESH_OT_select_all(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "(De)select All"; - ot->idname = "MESH_OT_select_all"; - ot->description = "(De)select all vertices, edges or faces"; - - /* api callbacks */ - ot->exec = edbm_select_all_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - WM_operator_properties_select_all(ot); -} - -static int edbm_faces_select_interior_exec(bContext *C, wmOperator *UNUSED(op)) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - - if (EDBM_select_interior_faces(em)) { - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit); - - return OPERATOR_FINISHED; - } - else { - return OPERATOR_CANCELLED; - } - -} - -void MESH_OT_select_interior_faces(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Interior Faces"; - ot->idname = "MESH_OT_select_interior_faces"; - ot->description = "Select faces where all edges have more than 2 face users"; - - /* api callbacks */ - ot->exec = edbm_faces_select_interior_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; -} - -/* *************** add-click-mesh (extrude) operator ************** */ -static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const wmEvent *event) -{ - ViewContext vc; - BMVert *v1; - BMIter iter; - float min[3], max[3]; - bool done = false; - bool use_proj; - - em_setup_viewcontext(C, &vc); - - ED_view3d_init_mats_rv3d(vc.obedit, vc.rv3d); - - - use_proj = ((vc.scene->toolsettings->snap_flag & SCE_SNAP) && - (vc.scene->toolsettings->snap_mode == SCE_SNAP_MODE_FACE)); - - INIT_MINMAX(min, max); - - BM_ITER_MESH (v1, &iter, vc.em->bm, BM_VERTS_OF_MESH) { - if (BM_elem_flag_test(v1, BM_ELEM_SELECT)) { - minmax_v3v3_v3(min, max, v1->co); - done = true; - } - } - - /* call extrude? */ - if (done) { - const bool rot_src = RNA_boolean_get(op->ptr, "rotate_source"); - BMEdge *eed; - float vec[3], cent[3], mat[3][3]; - float nor[3] = {0.0, 0.0, 0.0}; - - /* 2D normal calc */ - const float mval_f[2] = {(float)event->mval[0], - (float)event->mval[1]}; - - /* check for edges that are half selected, use for rotation */ - 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[2], co2[2]; - - 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) - * - * accumulate the screenspace normal in 2D, - * with screenspace edge length weighting the result. */ - if (line_point_side_v2(co1, co2, mval_f) >= 0.0f) { - nor[0] += (co1[1] - co2[1]); - nor[1] += -(co1[0] - co2[0]); - } - else { - nor[0] += (co2[1] - co1[1]); - nor[1] += -(co2[0] - co1[0]); - } - done = true; - } - } - } - - if (done) { - float view_vec[3], cross[3]; - - /* convert the 2D nomal into 3D */ - mul_mat3_m4_v3(vc.rv3d->viewinv, nor); /* worldspace */ - mul_mat3_m4_v3(vc.obedit->imat, nor); /* local space */ - - /* correct the normal to be aligned on the view plane */ - copy_v3_v3(view_vec, vc.rv3d->viewinv[2]); - mul_mat3_m4_v3(vc.obedit->imat, view_vec); - cross_v3_v3v3(cross, nor, view_vec); - cross_v3_v3v3(nor, view_vec, cross); - normalize_v3(nor); - } - - /* center */ - mid_v3_v3v3(cent, min, max); - copy_v3_v3(min, cent); - - mul_m4_v3(vc.obedit->obmat, min); /* view space */ - ED_view3d_win_to_3d_int(vc.ar, min, event->mval, min); - mul_m4_v3(vc.obedit->imat, min); // back in object space - - sub_v3_v3(min, cent); - - /* calculate rotation */ - unit_m3(mat); - if (done) { - float angle; - - normalize_v3_v3(vec, min); - - angle = angle_normalized_v3v3(vec, nor); - - if (angle != 0.0f) { - float axis[3]; - - cross_v3_v3v3(axis, nor, vec); - - /* halve the rotation if its applied twice */ - if (rot_src) { - angle *= 0.5f; - } - - axis_angle_to_mat3(mat, axis, angle); - } - } - - if (rot_src) { - EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3", - BM_ELEM_SELECT, cent, mat); - - /* also project the source, for retopo workflow */ - if (use_proj) - EMBM_project_snap_verts(C, vc.ar, vc.em); - } - - edbm_extrude_edge(vc.obedit, vc.em, BM_ELEM_SELECT, nor); - EDBM_op_callf(vc.em, op, "rotate verts=%hv cent=%v matrix=%m3", - BM_ELEM_SELECT, cent, mat); - EDBM_op_callf(vc.em, op, "translate verts=%hv vec=%v", - BM_ELEM_SELECT, min); - } - else { - const float *curs = give_cursor(vc.scene, vc.v3d); - BMOperator bmop; - BMOIter oiter; - - copy_v3_v3(min, curs); - ED_view3d_win_to_3d_int(vc.ar, min, event->mval, min); - - invert_m4_m4(vc.obedit->imat, vc.obedit->obmat); - mul_m4_v3(vc.obedit->imat, min); // back in object space - - EDBM_op_init(vc.em, &bmop, op, "create_vert co=%v", min); - BMO_op_exec(vc.em->bm, &bmop); - - BMO_ITER (v1, &oiter, bmop.slots_out, "vert.out", BM_VERT) { - BM_vert_select_set(vc.em->bm, v1, true); - } - - if (!EDBM_op_finish(vc.em, &bmop, op, true)) { - return OPERATOR_CANCELLED; - } - } - - if (use_proj) - EMBM_project_snap_verts(C, vc.ar, vc.em); - - /* This normally happens when pushing undo but modal operators - * like this one don't push undo data until after modal mode is - * done. */ - EDBM_mesh_normals_update(vc.em); - - EDBM_update_generic(vc.em, true, true); - - return OPERATOR_FINISHED; -} - -void MESH_OT_dupli_extrude_cursor(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Duplicate or Extrude at 3D Cursor"; - ot->idname = "MESH_OT_dupli_extrude_cursor"; - ot->description = "Duplicate and extrude selected vertices, edges or faces towards the mouse cursor"; - - /* api callbacks */ - ot->invoke = edbm_dupli_extrude_cursor_invoke; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - RNA_def_boolean(ot->srna, "rotate_source", 1, "Rotate Source", "Rotate initial selection giving better shape"); -} - /* Note, these values must match delete_mesh() event values */ static EnumPropertyItem prop_mesh_delete_types[] = { {0, "VERT", 0, "Vertices", ""}, @@ -2014,7 +1266,6 @@ static int edbm_rotate_uvs_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, false, false); - /* we succeeded */ return OPERATOR_FINISHED; } @@ -2037,7 +1288,6 @@ static int edbm_reverse_uvs_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, false, false); - /* we succeeded */ return OPERATOR_FINISHED; } @@ -2064,7 +1314,6 @@ static int edbm_rotate_colors_exec(bContext *C, wmOperator *op) /* dependencies graph and notification stuff */ EDBM_update_generic(em, false, false); - /* we succeeded */ return OPERATOR_FINISHED; } @@ -2088,7 +1337,6 @@ static int edbm_reverse_colors_exec(bContext *C, wmOperator *op) EDBM_update_generic(em, false, false); - /* we succeeded */ return OPERATOR_FINISHED; } @@ -2110,7 +1358,6 @@ void MESH_OT_uvs_rotate(wmOperatorType *ot) RNA_def_boolean(ot->srna, "use_ccw", false, "Counter Clockwise", ""); } -//void MESH_OT_uvs_mirror(wmOperatorType *ot) void MESH_OT_uvs_reverse(wmOperatorType *ot) { /* identifiers */ @@ -2428,123 +1675,6 @@ void MESH_OT_remove_doubles(wmOperatorType *ot) RNA_def_boolean(ot->srna, "use_unselected", 0, "Unselected", "Merge selected to other unselected vertices"); } -/************************ Vertex Path Operator *************************/ - -typedef struct PathNode { - /* int u; */ /* UNUSED */ - /* int visited; */ /* UNUSED */ - ListBase edges; -} PathNode; - -typedef struct PathEdge { - struct PathEdge *next, *prev; - int v; - float w; -} PathEdge; - - - -static int edbm_select_vertex_path_exec(bContext *C, wmOperator *op) -{ - Object *ob = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(ob); - BMOperator bmop; - BMIter iter; - BMVert *eve = NULL, *svert = NULL, *evert = NULL; - BMEditSelection *sv, *ev; - - /* get the type from RNA */ - const int type = RNA_enum_get(op->ptr, "type"); - - /* first try to find vertices in edit selection */ - sv = em->bm->selected.last; - if (sv != NULL) { - ev = sv->prev; - - if (ev && (sv->htype == BM_VERT) && (ev->htype == BM_VERT)) { - svert = (BMVert *)sv->ele; - evert = (BMVert *)ev->ele; - } - } - - /* if those are not found, because vertices where selected by e.g. - * border or circle select, find two selected vertices */ - if (svert == NULL) { - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - if (!BM_elem_flag_test(eve, BM_ELEM_SELECT) || BM_elem_flag_test(eve, BM_ELEM_HIDDEN)) - continue; - - if (svert == NULL) { - svert = eve; - } - else if (evert == NULL) { - evert = eve; - } - else { - /* more than two vertices are selected, - * show warning message and cancel operator */ - svert = evert = NULL; - break; - } - } - } - - if (svert == NULL || evert == NULL) { - BKE_report(op->reports, RPT_WARNING, "Path selection requires two vertices to be selected"); - return OPERATOR_CANCELLED; - } - - /* initialize the bmop using EDBM api, which does various ui error reporting and other stuff */ - EDBM_op_init(em, &bmop, op, - "shortest_path vert_start=%e vert_end=%e type=%i", - svert, evert, type); - - /* execute the operator */ - BMO_op_exec(em->bm, &bmop); - - /* DO NOT clear the existing selection */ - /* EDBM_flag_disable_all(em, BM_ELEM_SELECT); */ - - /* select the output */ - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "verts.out", BM_VERT, BM_ELEM_SELECT, true); - - /* finish the operator */ - if (!EDBM_op_finish(em, &bmop, op, true)) { - return OPERATOR_CANCELLED; - } - - EDBM_selectmode_flush(em); - - EDBM_update_generic(em, false, false); - - /* we succeeded */ - return OPERATOR_FINISHED; -} - -void MESH_OT_select_vertex_path(wmOperatorType *ot) -{ - static const EnumPropertyItem type_items[] = { - {VPATH_SELECT_EDGE_LENGTH, "EDGE_LENGTH", 0, "Edge Length", NULL}, - {VPATH_SELECT_TOPOLOGICAL, "TOPOLOGICAL", 0, "Topological", NULL}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name = "Select Vertex Path"; - ot->idname = "MESH_OT_select_vertex_path"; - ot->description = "Selected vertex path between two vertices"; - - /* api callbacks */ - ot->exec = edbm_select_vertex_path_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "type", type_items, VPATH_SELECT_EDGE_LENGTH, "Type", "Method to compute distance"); -} -/********************** Rip Operator *************************/ /************************ Shape Operators *************************/ @@ -2740,89 +1870,6 @@ void MESH_OT_blend_from_shape(wmOperatorType *ot) RNA_def_boolean(ot->srna, "add", 1, "Add", "Add rather than blend between shapes"); } -/* BMESH_TODO - some way to select on an arbitrary axis */ -static int edbm_select_axis_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - BMEditSelection *ese = em->bm->selected.last; - const int axis = RNA_enum_get(op->ptr, "axis"); - const int mode = RNA_enum_get(op->ptr, "mode"); /* -1 == aligned, 0 == neg, 1 == pos */ - - if (ese == NULL || ese->htype != BM_VERT) { - BKE_report(op->reports, RPT_WARNING, "This operator requires an active vertex (last selected)"); - return OPERATOR_CANCELLED; - } - else { - BMVert *ev, *act_vert = (BMVert *)ese->ele; - BMIter iter; - float value = act_vert->co[axis]; - float limit = CTX_data_tool_settings(C)->doublimit; // XXX - - if (mode == 0) - value -= limit; - else if (mode == 1) - value += limit; - - BM_ITER_MESH (ev, &iter, em->bm, BM_VERTS_OF_MESH) { - if (!BM_elem_flag_test(ev, BM_ELEM_HIDDEN)) { - switch (mode) { - case -1: /* aligned */ - if (fabsf(ev->co[axis] - value) < limit) - BM_vert_select_set(em->bm, ev, true); - break; - case 0: /* neg */ - if (ev->co[axis] > value) - BM_vert_select_set(em->bm, ev, true); - break; - case 1: /* pos */ - if (ev->co[axis] < value) - BM_vert_select_set(em->bm, ev, true); - break; - } - } - } - } - - EDBM_selectmode_flush(em); - WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data); - - return OPERATOR_FINISHED; -} - -void MESH_OT_select_axis(wmOperatorType *ot) -{ - static EnumPropertyItem axis_mode_items[] = { - {0, "POSITIVE", 0, "Positive Axis", ""}, - {1, "NEGATIVE", 0, "Negative Axis", ""}, - {-1, "ALIGNED", 0, "Aligned Axis", ""}, - {0, NULL, 0, NULL, NULL} - }; - - static EnumPropertyItem axis_items_xyz[] = { - {0, "X_AXIS", 0, "X Axis", ""}, - {1, "Y_AXIS", 0, "Y Axis", ""}, - {2, "Z_AXIS", 0, "Z Axis", ""}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name = "Select Axis"; - ot->description = "Select all data in the mesh on a single axis"; - ot->idname = "MESH_OT_select_axis"; - - /* api callbacks */ - ot->exec = edbm_select_axis_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_enum(ot->srna, "mode", axis_mode_items, 0, "Axis Mode", "Axis side to use when selecting"); - RNA_def_enum(ot->srna, "axis", axis_items_xyz, 0, "Axis", "Select the axis to compare each vertex on"); -} - static int edbm_solidify_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); @@ -3197,7 +2244,7 @@ void MESH_OT_knife_cut(wmOperatorType *ot) ot->modal = WM_gesture_lines_modal; ot->exec = edbm_knife_cut_exec; - ot->poll = EM_view3d_poll; + ot->poll = EDBM_view3d_poll; /* flags */ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; @@ -3842,366 +2889,6 @@ void MESH_OT_split(wmOperatorType *ot) ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; } - -static int edbm_spin_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - BMesh *bm = em->bm; - BMOperator spinop; - float cent[3], axis[3], imat[3][3]; - float d[3] = {0.0f, 0.0f, 0.0f}; - int steps, dupli; - float angle; - - RNA_float_get_array(op->ptr, "center", cent); - RNA_float_get_array(op->ptr, "axis", axis); - steps = RNA_int_get(op->ptr, "steps"); - angle = RNA_float_get(op->ptr, "angle"); - //if (ts->editbutflag & B_CLOCKWISE) - angle = -angle; - dupli = RNA_boolean_get(op->ptr, "dupli"); - - /* undo object transformation */ - copy_m3_m4(imat, obedit->imat); - sub_v3_v3(cent, obedit->obmat[3]); - mul_m3_v3(imat, cent); - mul_m3_v3(imat, axis); - - if (!EDBM_op_init(em, &spinop, op, - "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, d, steps, angle, dupli)) - { - return OPERATOR_CANCELLED; - } - BMO_op_exec(bm, &spinop); - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true); - if (!EDBM_op_finish(em, &spinop, op, true)) { - return OPERATOR_CANCELLED; - } - - EDBM_update_generic(em, true, true); - - return OPERATOR_FINISHED; -} - -/* get center and axis, in global coords */ -static int edbm_spin_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = ED_view3d_context_rv3d(C); - - RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d)); - RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[2]); - - return edbm_spin_exec(C, op); -} - -void MESH_OT_spin(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name = "Spin"; - ot->description = "Extrude selected vertices in a circle around the cursor in indicated viewport"; - ot->idname = "MESH_OT_spin"; - - /* api callbacks */ - ot->invoke = edbm_spin_invoke; - ot->exec = edbm_spin_exec; - ot->poll = EM_view3d_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* props */ - RNA_def_int(ot->srna, "steps", 9, 0, INT_MAX, "Steps", "Steps", 0, INT_MAX); - RNA_def_boolean(ot->srna, "dupli", 0, "Dupli", "Make Duplicates"); - prop = RNA_def_float(ot->srna, "angle", DEG2RADF(90.0f), -FLT_MAX, FLT_MAX, "Angle", "Angle", DEG2RADF(-360.0f), DEG2RADF(360.0f)); - RNA_def_property_subtype(prop, PROP_ANGLE); - - 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, -FLT_MAX, FLT_MAX, "Axis", "Axis in global view space", -1.0f, 1.0f); - -} - -static int edbm_screw_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - BMesh *bm = em->bm; - BMEdge *eed; - BMVert *eve, *v1, *v2; - BMIter iter, eiter; - BMOperator spinop; - float dvec[3], nor[3], cent[3], axis[3]; - float imat[3][3]; - int steps, turns; - int valence; - - - turns = RNA_int_get(op->ptr, "turns"); - steps = RNA_int_get(op->ptr, "steps"); - RNA_float_get_array(op->ptr, "center", cent); - RNA_float_get_array(op->ptr, "axis", axis); - - /* undo object transformation */ - copy_m3_m4(imat, obedit->imat); - sub_v3_v3(cent, obedit->obmat[3]); - mul_m3_v3(imat, cent); - mul_m3_v3(imat, axis); - - - /* find two vertices with valence count == 1, more or less is wrong */ - v1 = NULL; - v2 = NULL; - - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - valence = 0; - BM_ITER_ELEM (eed, &eiter, eve, BM_EDGES_OF_VERT) { - if (BM_elem_flag_test(eed, BM_ELEM_SELECT)) { - valence++; - } - } - - if (valence == 1) { - if (v1 == NULL) { - v1 = eve; - } - else if (v2 == NULL) { - v2 = eve; - } - else { - v1 = NULL; - break; - } - } - } - - if (v1 == NULL || v2 == NULL) { - BKE_report(op->reports, RPT_ERROR, "You have to select a string of connected vertices too"); - return OPERATOR_CANCELLED; - } - - /* calculate dvec */ - sub_v3_v3v3(dvec, v1->co, v2->co); - mul_v3_fl(dvec, 1.0f / steps); - - if (dot_v3v3(nor, dvec) > 0.000f) - negate_v3(dvec); - - if (!EDBM_op_init(em, &spinop, op, - "spin geom=%hvef cent=%v axis=%v dvec=%v steps=%i angle=%f use_duplicate=%b", - BM_ELEM_SELECT, cent, axis, dvec, turns * steps, DEG2RADF(360.0f * turns), false)) - { - return OPERATOR_CANCELLED; - } - BMO_op_exec(bm, &spinop); - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BMO_slot_buffer_hflag_enable(bm, spinop.slots_out, "geom_last.out", BM_ALL_NOLOOP, BM_ELEM_SELECT, true); - if (!EDBM_op_finish(em, &spinop, op, true)) { - return OPERATOR_CANCELLED; - } - - EDBM_update_generic(em, true, true); - - return OPERATOR_FINISHED; -} - -/* get center and axis, in global coords */ -static int edbm_screw_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) -{ - Scene *scene = CTX_data_scene(C); - View3D *v3d = CTX_wm_view3d(C); - RegionView3D *rv3d = ED_view3d_context_rv3d(C); - - RNA_float_set_array(op->ptr, "center", give_cursor(scene, v3d)); - RNA_float_set_array(op->ptr, "axis", rv3d->viewinv[1]); - - return edbm_screw_exec(C, op); -} - -void MESH_OT_screw(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Screw"; - ot->description = "Extrude selected vertices in screw-shaped rotation around the cursor in indicated viewport"; - ot->idname = "MESH_OT_screw"; - - /* api callbacks */ - ot->invoke = edbm_screw_invoke; - ot->exec = edbm_screw_exec; - ot->poll = EM_view3d_poll; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* props */ - RNA_def_int(ot->srna, "steps", 9, 1, INT_MAX, "Steps", "Steps", 3, 256); - RNA_def_int(ot->srna, "turns", 1, 1, INT_MAX, "Turns", "Turns", 1, 256); - - 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, -FLT_MAX, FLT_MAX, - "Axis", "Axis in global view space", -1.0f, 1.0f); -} - -static int edbm_select_face_by_sides_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - BMFace *efa; - BMIter iter; - const int numverts = RNA_int_get(op->ptr, "number"); - const int type = RNA_enum_get(op->ptr, "type"); - - if (!RNA_boolean_get(op->ptr, "extend")) - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - - BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) { - - int select; - - switch (type) { - case 0: - select = (efa->len < numverts); - break; - case 1: - select = (efa->len == numverts); - break; - case 2: - select = (efa->len > numverts); - break; - case 3: - select = (efa->len != numverts); - break; - default: - BLI_assert(0); - select = false; - break; - } - - if (select) { - BM_face_select_set(em->bm, efa, true); - } - } - - EDBM_selectmode_flush(em); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - return OPERATOR_FINISHED; -} - -void MESH_OT_select_face_by_sides(wmOperatorType *ot) -{ - static const EnumPropertyItem type_items[] = { - {0, "LESS", 0, "Less Than", ""}, - {1, "EQUAL", 0, "Equal To", ""}, - {2, "GREATER", 0, "Greater Than", ""}, - {3, "NOTEQUAL", 0, "Not Equal To", ""}, - {0, NULL, 0, NULL, NULL} - }; - - /* identifiers */ - ot->name = "Select Faces by Sides"; - ot->description = "Select vertices or faces by the number of polygon sides"; - ot->idname = "MESH_OT_select_face_by_sides"; - - /* api callbacks */ - ot->exec = edbm_select_face_by_sides_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* properties */ - RNA_def_int(ot->srna, "number", 4, 3, INT_MAX, "Number of Vertices", "", 3, INT_MAX); - RNA_def_enum(ot->srna, "type", type_items, 1, "Type", "Type of comparison to make"); - RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend the selection"); -} - -static int edbm_select_loose_verts_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - BMVert *eve; - BMEdge *eed; - BMIter iter; - - if (!RNA_boolean_get(op->ptr, "extend")) - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - - BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) { - if (!eve->e) { - BM_vert_select_set(em->bm, eve, true); - } - } - - BM_ITER_MESH (eed, &iter, em->bm, BM_EDGES_OF_MESH) { - if (!eed->l) { - BM_edge_select_set(em->bm, eed, true); - } - } - - EDBM_selectmode_flush(em); - - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - return OPERATOR_FINISHED; -} - -void MESH_OT_select_loose_verts(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Loose Vertices/Edges"; - ot->description = "Select vertices with no edges nor faces, and edges with no faces"; - ot->idname = "MESH_OT_select_loose_verts"; - - /* api callbacks */ - ot->exec = edbm_select_loose_verts_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* props */ - RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend the selection"); -} - -static int edbm_select_mirror_exec(bContext *C, wmOperator *op) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - bool extend = RNA_boolean_get(op->ptr, "extend"); - - if (em->bm->totvert && em->bm->totvertsel) { - EDBM_select_mirrored(obedit, em, extend); - EDBM_selectmode_flush(em); - WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); - } - - return OPERATOR_FINISHED; -} - -void MESH_OT_select_mirror(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Select Mirror"; - ot->description = "Select mesh items at mirrored locations"; - ot->idname = "MESH_OT_select_mirror"; - - /* api callbacks */ - ot->exec = edbm_select_mirror_exec; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; - - /* props */ - RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the existing selection"); -} - /****************************************************************************** * qsort routines. * Now unified, for vertices/edges/faces. */ @@ -4854,320 +3541,6 @@ void MESH_OT_noise(wmOperatorType *ot) RNA_def_float(ot->srna, "factor", 0.1f, -FLT_MAX, FLT_MAX, "Factor", "", 0.0f, 1.0f); } -typedef struct { - BMEditMesh *em; - BMBackup mesh_backup; - 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. */ -} BevelData; - -#define HEADER_LENGTH 180 - -static void edbm_bevel_update_header(wmOperator *op, bContext *C) -{ - const char *str = IFACE_("Confirm: Enter/LClick, Cancel: (Esc/RMB), Offset: %s, Segments: %d"); - - char msg[HEADER_LENGTH]; - ScrArea *sa = CTX_wm_area(C); - - if (sa) { - char offset_str[NUM_STR_REP_LEN]; - BLI_snprintf(offset_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "offset")); - BLI_snprintf(msg, HEADER_LENGTH, str, - offset_str, - RNA_int_get(op->ptr, "segments") - ); - - ED_area_headerprint(sa, msg); - } -} - -static int edbm_bevel_init(bContext *C, wmOperator *op, int is_modal) -{ - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - BevelData *opdata; - - if (em == NULL) { - return 0; - } - - op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator"); - - opdata->em = em; - opdata->is_modal = is_modal; - opdata->shift_factor = -1.0f; - - initNumInput(&opdata->num_input); - opdata->num_input.flag = NUM_NO_NEGATIVE; - - /* avoid the cost of allocating a bm copy */ - if (is_modal) - opdata->mesh_backup = EDBM_redo_state_store(em); - - return 1; -} - -static int edbm_bevel_calc(wmOperator *op) -{ - BevelData *opdata = op->customdata; - BMEditMesh *em = opdata->em; - BMOperator bmop; - const float offset = RNA_float_get(op->ptr, "offset"); - const int segments = RNA_int_get(op->ptr, "segments"); - const bool vertex_only = RNA_boolean_get(op->ptr, "vertex_only"); - - /* revert to original mesh */ - if (opdata->is_modal) { - EDBM_redo_state_restore(opdata->mesh_backup, em, false); - } - - if (!EDBM_op_init(em, &bmop, op, - "bevel geom=%hev offset=%f segments=%i vertex_only=%b", - BM_ELEM_SELECT, offset, segments, vertex_only)) - { - return 0; - } - - BMO_op_exec(em->bm, &bmop); - - if (offset != 0.0f) { - /* not essential, but we may have some loose geometry that - * won't get bevel'd and better not leave it selected */ - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); - } - - /* no need to de-select existing geometry */ - if (!EDBM_op_finish(em, &bmop, op, true)) - return 0; - - EDBM_mesh_normals_update(opdata->em); - - EDBM_update_generic(opdata->em, true, true); - - return 1; -} - -static void edbm_bevel_exit(bContext *C, wmOperator *op) -{ - BevelData *opdata = op->customdata; - - ScrArea *sa = CTX_wm_area(C); - - if (sa) { - ED_area_headerprint(sa, NULL); - } - - if (opdata->is_modal) { - EDBM_redo_state_free(&opdata->mesh_backup, NULL, false); - } - MEM_freeN(opdata); - op->customdata = NULL; -} - -static int edbm_bevel_cancel(bContext *C, wmOperator *op) -{ - BevelData *opdata = op->customdata; - if (opdata->is_modal) { - EDBM_redo_state_free(&opdata->mesh_backup, opdata->em, true); - EDBM_update_generic(opdata->em, false, true); - } - - edbm_bevel_exit(C, op); - - /* need to force redisplay or we may still view the modified result */ - ED_region_tag_redraw(CTX_wm_region(C)); - return OPERATOR_CANCELLED; -} - -/* bevel! yay!!*/ -static int edbm_bevel_exec(bContext *C, wmOperator *op) -{ - if (!edbm_bevel_init(C, op, false)) { - edbm_bevel_exit(C, op); - return OPERATOR_CANCELLED; - } - - if (!edbm_bevel_calc(op)) { - edbm_bevel_cancel(C, op); - return OPERATOR_CANCELLED; - } - - edbm_bevel_exit(C, op); - - return OPERATOR_FINISHED; -} - -static int edbm_bevel_invoke(bContext *C, wmOperator *op, const 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; - } - - opdata = op->customdata; - - /* initialize mouse values */ - 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; - } - 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); - - if (!edbm_bevel_calc(op)) { - edbm_bevel_cancel(C, op); - return OPERATOR_CANCELLED; - } - - WM_event_add_modal_handler(C, op); - - return OPERATOR_RUNNING_MODAL; -} - -static float edbm_bevel_mval_factor(wmOperator *op, const wmEvent *event) -{ - BevelData *opdata = op->customdata; - int use_dist = true; - 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, "offset"); - } - 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, const wmEvent *event) -{ - BevelData *opdata = op->customdata; - int segments = RNA_int_get(op->ptr, "segments"); - - if (event->val == KM_PRESS) { - /* Try to handle numeric inputs... */ - - if (handleNumInput(&opdata->num_input, event)) { - float value = RNA_float_get(op->ptr, "offset"); - applyNumInput(&opdata->num_input, &value); - RNA_float_set(op->ptr, "offset", value); - edbm_bevel_calc(op); - edbm_bevel_update_header(op, C); - return OPERATOR_RUNNING_MODAL; - } - } - - switch (event->type) { - case ESCKEY: - case RIGHTMOUSE: - edbm_bevel_cancel(C, op); - return OPERATOR_CANCELLED; - - case MOUSEMOVE: - if (!hasNumInput(&opdata->num_input)) { - const float factor = edbm_bevel_mval_factor(op, event); - RNA_float_set(op->ptr, "offset", factor); - - edbm_bevel_calc(op); - edbm_bevel_update_header(op, C); - } - break; - - case LEFTMOUSE: - case PADENTER: - case RETKEY: - edbm_bevel_calc(op); - edbm_bevel_exit(C, op); - return OPERATOR_FINISHED; - - case WHEELUPMOUSE: /* change number of segments */ - case PAGEUPKEY: - if (event->val == KM_RELEASE) - break; - - segments++; - RNA_int_set(op->ptr, "segments", segments); - edbm_bevel_calc(op); - edbm_bevel_update_header(op, C); - break; - - case WHEELDOWNMOUSE: /* change number of segments */ - case PAGEDOWNKEY: - if (event->val == KM_RELEASE) - break; - - segments = max_ii(segments - 1, 1); - RNA_int_set(op->ptr, "segments", segments); - edbm_bevel_calc(op); - edbm_bevel_update_header(op, C); - break; - } - - return OPERATOR_RUNNING_MODAL; -} - -void MESH_OT_bevel(wmOperatorType *ot) -{ - /* identifiers */ - ot->name = "Bevel"; - ot->description = "Edge Bevel"; - ot->idname = "MESH_OT_bevel"; - - /* api callbacks */ - ot->exec = edbm_bevel_exec; - ot->invoke = edbm_bevel_invoke; - ot->modal = edbm_bevel_modal; - ot->cancel = edbm_bevel_cancel; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; - - RNA_def_float(ot->srna, "offset", 0.0f, -FLT_MAX, FLT_MAX, "Offset", "", 0.0f, 1.0f); - RNA_def_int(ot->srna, "segments", 1, 1, 50, "Segments", "Segments for curved edge", 1, 8); - RNA_def_boolean(ot->srna, "vertex_only", false, "Vertex only", "Bevel only vertices"); -} - static int edbm_bridge_edge_loops_exec(bContext *C, wmOperator *op) { BMOperator bmop; @@ -5218,382 +3591,6 @@ void MESH_OT_bridge_edge_loops(wmOperatorType *ot) RNA_def_float(ot->srna, "merge_factor", 0.5f, 0.0f, 1.0f, "Merge Factor", "", 0.0f, 1.0f); } -typedef struct { - float old_thickness; - float old_depth; - int mcenter[2]; - int modify_depth; - 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; - BMEditMesh *em; - NumInput num_input; -} InsetData; - -static void edbm_inset_update_header(wmOperator *op, bContext *C) -{ - InsetData *opdata = op->customdata; - - const char *str = IFACE_("Confirm: Enter/LClick, Cancel: (Esc/RClick), Thickness: %s, " - "Depth (Ctrl to tweak): %s (%s), Outset (O): (%s), Boundary (B): (%s)"); - - char msg[HEADER_LENGTH]; - ScrArea *sa = CTX_wm_area(C); - - if (sa) { - char flts_str[NUM_STR_REP_LEN * 2]; - if (hasNumInput(&opdata->num_input)) - outputNumInput(&opdata->num_input, flts_str); - else { - BLI_snprintf(flts_str, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "thickness")); - BLI_snprintf(flts_str + NUM_STR_REP_LEN, NUM_STR_REP_LEN, "%f", RNA_float_get(op->ptr, "depth")); - } - BLI_snprintf(msg, HEADER_LENGTH, str, - flts_str, - flts_str + NUM_STR_REP_LEN, - opdata->modify_depth ? IFACE_("On") : IFACE_("Off"), - RNA_boolean_get(op->ptr, "use_outset") ? IFACE_("On") : IFACE_("Off"), - RNA_boolean_get(op->ptr, "use_boundary") ? IFACE_("On") : IFACE_("Off") - ); - - ED_area_headerprint(sa, msg); - } -} - - -static int edbm_inset_init(bContext *C, wmOperator *op, int is_modal) -{ - InsetData *opdata; - Object *obedit = CTX_data_edit_object(C); - BMEditMesh *em = BMEdit_FromObject(obedit); - - op->customdata = opdata = MEM_mallocN(sizeof(InsetData), "inset_operator_data"); - - opdata->old_thickness = 0.01; - opdata->old_depth = 0.0; - opdata->modify_depth = false; - opdata->shift = false; - opdata->shift_amount = 0.0f; - opdata->is_modal = is_modal; - opdata->em = em; - - initNumInput(&opdata->num_input); - opdata->num_input.idx_max = 1; /* Two elements. */ - - if (is_modal) - opdata->backup = EDBM_redo_state_store(em); - - return 1; -} - -static void edbm_inset_exit(bContext *C, wmOperator *op) -{ - InsetData *opdata; - ScrArea *sa = CTX_wm_area(C); - - opdata = op->customdata; - - if (opdata->is_modal) - EDBM_redo_state_free(&opdata->backup, NULL, false); - - if (sa) { - ED_area_headerprint(sa, NULL); - } - MEM_freeN(op->customdata); -} - -static int edbm_inset_cancel(bContext *C, wmOperator *op) -{ - InsetData *opdata; - - opdata = op->customdata; - if (opdata->is_modal) { - EDBM_redo_state_free(&opdata->backup, opdata->em, true); - EDBM_update_generic(opdata->em, false, true); - } - - edbm_inset_exit(C, op); - - /* need to force redisplay or we may still view the modified result */ - ED_region_tag_redraw(CTX_wm_region(C)); - return OPERATOR_CANCELLED; -} - -static int edbm_inset_calc(wmOperator *op) -{ - InsetData *opdata; - BMEditMesh *em; - BMOperator bmop; - - const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); - const bool use_even_offset = RNA_boolean_get(op->ptr, "use_even_offset"); - const bool use_relative_offset = RNA_boolean_get(op->ptr, "use_relative_offset"); - const float thickness = RNA_float_get(op->ptr, "thickness"); - const float depth = RNA_float_get(op->ptr, "depth"); - const bool use_outset = RNA_boolean_get(op->ptr, "use_outset"); - const bool use_select_inset = RNA_boolean_get(op->ptr, "use_select_inset"); /* not passed onto the BMO */ - - opdata = op->customdata; - em = opdata->em; - - if (opdata->is_modal) { - EDBM_redo_state_restore(opdata->backup, em, false); - } - - EDBM_op_init(em, &bmop, op, - "inset faces=%hf use_boundary=%b use_even_offset=%b use_relative_offset=%b " - "thickness=%f depth=%f use_outset=%b", - BM_ELEM_SELECT, use_boundary, use_even_offset, use_relative_offset, - thickness, depth, use_outset); - - BMO_op_exec(em->bm, &bmop); - - if (use_select_inset) { - /* deselect original faces/verts */ - EDBM_flag_disable_all(em, BM_ELEM_SELECT); - BMO_slot_buffer_hflag_enable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, true); - } - else { - BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE, BM_ELEM_SELECT, false); - BMO_slot_buffer_hflag_disable(em->bm, bmop.slots_out, "faces.out", BM_FACE, BM_ELEM_SELECT, false); - /* re-select faces so the verts and edges get selected too */ - BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, BM_ELEM_SELECT); - } - - if (!EDBM_op_finish(em, &bmop, op, true)) { - return 0; - } - else { - EDBM_update_generic(em, true, true); - return 1; - } -} - -static int edbm_inset_exec(bContext *C, wmOperator *op) -{ - edbm_inset_init(C, op, false); - - if (!edbm_inset_calc(op)) { - edbm_inset_exit(C, op); - return OPERATOR_CANCELLED; - } - - edbm_inset_exit(C, op); - return OPERATOR_FINISHED; -} - -static int edbm_inset_invoke(bContext *C, wmOperator *op, const 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, 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; - } - 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(op); - - edbm_inset_update_header(op, C); - - WM_event_add_modal_handler(C, op); - return OPERATOR_RUNNING_MODAL; -} - -static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event) -{ - InsetData *opdata = op->customdata; - - if (event->val == KM_PRESS) { - /* Try to handle numeric inputs... */ - - if (handleNumInput(&opdata->num_input, event)) { - float amounts[2] = {RNA_float_get(op->ptr, "thickness"), - RNA_float_get(op->ptr, "depth")}; - applyNumInput(&opdata->num_input, amounts); - amounts[0] = max_ff(amounts[0], 0.0f); - RNA_float_set(op->ptr, "thickness", amounts[0]); - RNA_float_set(op->ptr, "depth", amounts[1]); - - if (edbm_inset_calc(op)) { - edbm_inset_update_header(op, C); - return OPERATOR_RUNNING_MODAL; - } - else { - edbm_inset_cancel(C, op); - return OPERATOR_CANCELLED; - } - } - } - - switch (event->type) { - case ESCKEY: - case RIGHTMOUSE: - edbm_inset_cancel(C, op); - return OPERATOR_CANCELLED; - - case MOUSEMOVE: - if (!hasNumInput(&opdata->num_input)) { - float mdiff[2]; - float amount; - - mdiff[0] = opdata->mcenter[0] - event->mval[0]; - mdiff[1] = opdata->mcenter[1] - event->mval[1]; - - if (opdata->modify_depth) - amount = opdata->old_depth + ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); - else - amount = opdata->old_thickness - ((len_v2(mdiff) - opdata->initial_length) * opdata->pixel_size); - - /* Fake shift-transform... */ - if (opdata->shift) - amount = (amount - opdata->shift_amount) * 0.1f + opdata->shift_amount; - - if (opdata->modify_depth) - RNA_float_set(op->ptr, "depth", amount); - else { - amount = max_ff(amount, 0.0f); - RNA_float_set(op->ptr, "thickness", amount); - } - - if (edbm_inset_calc(op)) - edbm_inset_update_header(op, C); - else { - edbm_inset_cancel(C, op); - return OPERATOR_CANCELLED; - } - } - break; - - case LEFTMOUSE: - case PADENTER: - case RETKEY: - edbm_inset_calc(op); - edbm_inset_exit(C, op); - return OPERATOR_FINISHED; - - case LEFTSHIFTKEY: - case RIGHTSHIFTKEY: - if (event->val == KM_PRESS) { - if (opdata->modify_depth) - opdata->shift_amount = RNA_float_get(op->ptr, "depth"); - else - opdata->shift_amount = RNA_float_get(op->ptr, "thickness"); - opdata->shift = true; - } - else { - opdata->shift_amount = 0.0f; - opdata->shift = false; - } - break; - - case LEFTCTRLKEY: - case RIGHTCTRLKEY: - { - float mlen[2]; - - mlen[0] = opdata->mcenter[0] - event->mval[0]; - mlen[1] = opdata->mcenter[1] - event->mval[1]; - - if (event->val == KM_PRESS) { - opdata->old_thickness = RNA_float_get(op->ptr, "thickness"); - if (opdata->shift) - opdata->shift_amount = opdata->old_thickness; - opdata->modify_depth = true; - } - else { - opdata->old_depth = RNA_float_get(op->ptr, "depth"); - if (opdata->shift) - opdata->shift_amount = opdata->old_depth; - opdata->modify_depth = false; - } - opdata->initial_length = len_v2(mlen); - - edbm_inset_update_header(op, C); - break; - } - - case OKEY: - if (event->val == KM_PRESS) { - const bool use_outset = RNA_boolean_get(op->ptr, "use_outset"); - RNA_boolean_set(op->ptr, "use_outset", !use_outset); - if (edbm_inset_calc(op)) { - edbm_inset_update_header(op, C); - } - else { - edbm_inset_cancel(C, op); - return OPERATOR_CANCELLED; - } - } - break; - case BKEY: - if (event->val == KM_PRESS) { - const bool use_boundary = RNA_boolean_get(op->ptr, "use_boundary"); - RNA_boolean_set(op->ptr, "use_boundary", !use_boundary); - if (edbm_inset_calc(op)) { - edbm_inset_update_header(op, C); - } - else { - edbm_inset_cancel(C, op); - return OPERATOR_CANCELLED; - } - } - break; - } - - return OPERATOR_RUNNING_MODAL; -} - - -void MESH_OT_inset(wmOperatorType *ot) -{ - PropertyRNA *prop; - - /* identifiers */ - ot->name = "Inset Faces"; - ot->idname = "MESH_OT_inset"; - ot->description = "Inset new faces into selected faces"; - - /* api callbacks */ - ot->invoke = edbm_inset_invoke; - ot->modal = edbm_inset_modal; - ot->exec = edbm_inset_exec; - ot->cancel = edbm_inset_cancel; - ot->poll = ED_operator_editmesh; - - /* flags */ - ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_GRAB_POINTER | OPTYPE_BLOCKING; - - /* properties */ - RNA_def_boolean(ot->srna, "use_boundary", true, "Boundary", "Inset face boundaries"); - RNA_def_boolean(ot->srna, "use_even_offset", true, "Offset Even", "Scale the offset to give more even thickness"); - RNA_def_boolean(ot->srna, "use_relative_offset", false, "Offset Relative", "Scale the offset by surrounding geometry"); - - prop = RNA_def_float(ot->srna, "thickness", 0.01f, 0.0f, FLT_MAX, "Thickness", "", 0.0f, 10.0f); - /* use 1 rather then 10 for max else dragging the button moves too far */ - RNA_def_property_ui_range(prop, 0.0, 1.0, 0.01, 4); - prop = RNA_def_float(ot->srna, "depth", 0.0f, -FLT_MAX, FLT_MAX, "Depth", "", -10.0f, 10.0f); - RNA_def_property_ui_range(prop, -10.0f, 10.0f, 0.01, 4); - - RNA_def_boolean(ot->srna, "use_outset", false, "Outset", "Outset rather than inset"); - RNA_def_boolean(ot->srna, "use_select_inset", true, "Select Outer", "Select the new inset faces"); -} - static int edbm_wireframe_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); diff --git a/source/blender/editors/mesh/editmesh_utils.c b/source/blender/editors/mesh/editmesh_utils.c index cb15fdef880..9020e133b33 100644 --- a/source/blender/editors/mesh/editmesh_utils.c +++ b/source/blender/editors/mesh/editmesh_utils.c @@ -33,7 +33,6 @@ #include "DNA_mesh_types.h" #include "DNA_object_types.h" -#include "DNA_scene_types.h" #include "BLI_math.h" @@ -51,10 +50,10 @@ #include "WM_types.h" #include "ED_mesh.h" +#include "ED_screen.h" #include "ED_util.h" - -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ /* mesh backup implementation. This would greatly benefit from some sort of binary diffing * just as the undo stack would. So leaving this as an interface for further work */ @@ -1367,3 +1366,12 @@ void EDBM_update_generic(BMEditMesh *em, const bool do_tessface, const bool is_d BLI_assert(EDBM_index_arrays_check(em) == true); } } + +/* poll call for mesh operators requiring a view3d context */ +int EDBM_view3d_poll(bContext *C) +{ + if (ED_operator_editmesh(C) && ED_operator_view3d_active(C)) + return 1; + + return 0; +} diff --git a/source/blender/editors/mesh/mesh_data.c b/source/blender/editors/mesh/mesh_data.c index 20633aa0c87..cbaa80718ee 100644 --- a/source/blender/editors/mesh/mesh_data.c +++ b/source/blender/editors/mesh/mesh_data.c @@ -61,7 +61,7 @@ #include "ED_uvedit.h" #include "ED_view3d.h" -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ static CustomData *mesh_customdata_get_type(Mesh *me, const char htype, int *r_tot) diff --git a/source/blender/editors/mesh/mesh_intern.h b/source/blender/editors/mesh/mesh_intern.h index 89a320ca928..4a0bbbb8dbf 100644 --- a/source/blender/editors/mesh/mesh_intern.h +++ b/source/blender/editors/mesh/mesh_intern.h @@ -29,7 +29,6 @@ * \ingroup edmesh */ - /* Internal for editmesh_xxxx.c functions */ #ifndef __MESH_INTERN_H__ @@ -50,21 +49,18 @@ struct wmOperator; struct wmOperatorType; struct LinkNode; -/* ******************** editmesh_utils.c */ +/* *** editmesh_utils.c *** */ /* * ok: the EDBM module is for editmode bmesh stuff. in contrast, the * BMEdit module is for code shared with blenkernel that concerns - * the BMEditMesh structure. - */ + * the BMEditMesh structure. */ -/*calls a bmesh op, reporting errors to the user, etc*/ +/* Calls a bmesh op, reporting errors to the user, etc */ bool EDBM_op_callf(struct BMEditMesh *em, struct wmOperator *op, const char *fmt, ...); - bool EDBM_op_call_and_selectf(struct BMEditMesh *em, struct wmOperator *op, const char *selectslot, const char *fmt, ...); - -/* same as above, but doesn't report errors.*/ +/* Same as above, but doesn't report errors.*/ bool EDBM_op_call_silentf(struct BMEditMesh *em, const char *fmt, ...); /* these next two functions are the split version of EDBM_op_callf, so you can @@ -74,17 +70,16 @@ bool EDBM_op_call_silentf(struct BMEditMesh *em, const char *fmt, ...); * execute the operator with BM_Exec_Op */ bool EDBM_op_init(struct BMEditMesh *em, struct BMOperator *bmop, struct wmOperator *op, const char *fmt, ...); -/*cleans up after a bmesh operator*/ +/* Cleans up after a bmesh operator */ bool EDBM_op_finish(struct BMEditMesh *em, struct BMOperator *bmop, struct wmOperator *op, const bool do_report); void EDBM_stats_update(struct BMEditMesh *em); -/* ******************** editface.c */ +int EDBM_view3d_poll(struct bContext *C); -void MESH_OT_separate(struct wmOperatorType *ot); -/* ******************* editmesh_add.c */ +/* *** editmesh_add.c *** */ void MESH_OT_primitive_plane_add(struct wmOperatorType *ot); void MESH_OT_primitive_cube_add(struct wmOperatorType *ot); void MESH_OT_primitive_circle_add(struct wmOperatorType *ot); @@ -95,101 +90,125 @@ void MESH_OT_primitive_monkey_add(struct wmOperatorType *ot); void MESH_OT_primitive_uv_sphere_add(struct wmOperatorType *ot); void MESH_OT_primitive_ico_sphere_add(struct wmOperatorType *ot); -void MESH_OT_edge_face_add(struct wmOperatorType *ot); + +/* *** editmesh_bevel.c *** */ +void MESH_OT_bevel(struct wmOperatorType *ot); + + +/* *** editmesh_extrude.c *** */ +void MESH_OT_extrude_repeat(struct wmOperatorType *ot); +void MESH_OT_extrude_region(struct wmOperatorType *ot); +void MESH_OT_extrude_verts_indiv(struct wmOperatorType *ot); +void MESH_OT_extrude_edges_indiv(struct wmOperatorType *ot); +void MESH_OT_extrude_faces_indiv(struct wmOperatorType *ot); void MESH_OT_dupli_extrude_cursor(struct wmOperatorType *ot); -void MESH_OT_duplicate(struct wmOperatorType *ot); +void MESH_OT_spin(struct wmOperatorType *ot); +void MESH_OT_screw(struct wmOperatorType *ot); -extern int EM_view3d_poll(struct bContext *C); + +/* *** editmesh_inset.c *** */ +void MESH_OT_inset(struct wmOperatorType *ot); + + +/* *** editmesh_knife.c *** */ +void MESH_OT_knife_tool(struct wmOperatorType *ot); +void MESH_OT_knife_project(wmOperatorType *ot); +void EDBM_mesh_knife(struct bContext *C, struct LinkNode *polys, bool use_tag); struct wmKeyMap *knifetool_modal_keymap(struct wmKeyConfig *keyconf); -/* ******************* knifetool.c */ -void MESH_OT_knife_cut(struct wmOperatorType *ot); +/* *** editmesh_loopcut.c *** */ +void MESH_OT_loopcut(struct wmOperatorType *ot); + + +/* *** editmesh_rip.c *** */ +void MESH_OT_rip(struct wmOperatorType *ot); -/* ******************* bmesh_select.c */ + +/* *** editmesh_select.c *** */ +void MESH_OT_select_similar(struct wmOperatorType *ot); +void MESH_OT_select_mode(struct wmOperatorType *ot); +void MESH_OT_loop_multi_select(struct wmOperatorType *ot); void MESH_OT_loop_select(struct wmOperatorType *ot); +void MESH_OT_edgering_select(struct wmOperatorType *ot); void MESH_OT_select_all(struct wmOperatorType *ot); void MESH_OT_select_interior_faces(struct wmOperatorType *ot); -void MESH_OT_select_more(struct wmOperatorType *ot); -void MESH_OT_select_less(struct wmOperatorType *ot); -void MESH_OT_select_non_manifold(struct wmOperatorType *ot); +void MESH_OT_select_shortest_path(struct wmOperatorType *ot); void MESH_OT_select_linked(struct wmOperatorType *ot); void MESH_OT_select_linked_pick(struct wmOperatorType *ot); -void MESH_OT_hide(struct wmOperatorType *ot); -void MESH_OT_reveal(struct wmOperatorType *ot); void MESH_OT_select_face_by_sides(struct wmOperatorType *ot); void MESH_OT_select_loose_verts(struct wmOperatorType *ot); void MESH_OT_select_mirror(struct wmOperatorType *ot); -void MESH_OT_normals_make_consistent(struct wmOperatorType *ot); -void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot); +void MESH_OT_select_more(struct wmOperatorType *ot); +void MESH_OT_select_less(struct wmOperatorType *ot); +void MESH_OT_select_nth(struct wmOperatorType *ot); void MESH_OT_edges_select_sharp(struct wmOperatorType *ot); -void MESH_OT_select_shortest_path(struct wmOperatorType *ot); -void MESH_OT_select_similar(struct wmOperatorType *ot); -void MESH_OT_select_mode(struct wmOperatorType *ot); +void MESH_OT_faces_select_linked_flat(struct wmOperatorType *ot); +void MESH_OT_select_non_manifold(struct wmOperatorType *ot); void MESH_OT_select_random(struct wmOperatorType *ot); void MESH_OT_select_ungrouped(struct wmOperatorType *ot); -void MESH_OT_loop_multi_select(struct wmOperatorType *ot); -void MESH_OT_mark_seam(struct wmOperatorType *ot); -void MESH_OT_mark_sharp(struct wmOperatorType *ot); -#ifdef WITH_FREESTYLE -void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot); -#endif -void MESH_OT_vertices_smooth(struct wmOperatorType *ot); -void MESH_OT_vertices_smooth_laplacian(struct wmOperatorType *ot); -void MESH_OT_noise(struct wmOperatorType *ot); -void MESH_OT_flip_normals(struct wmOperatorType *ot); -void MESH_OT_solidify(struct wmOperatorType *ot); -void MESH_OT_select_nth(struct wmOperatorType *ot); +void MESH_OT_select_axis(struct wmOperatorType *ot); void MESH_OT_select_next_loop(struct wmOperatorType *ot); +void MESH_OT_region_to_loop(struct wmOperatorType *ot); +void MESH_OT_loop_to_region(struct wmOperatorType *ot); +void MESH_OT_select_vertex_path(struct wmOperatorType *ot); extern struct EnumPropertyItem *corner_type_items; -void MESH_OT_merge(struct wmOperatorType *ot); + +/* *** editmesh_tools.c *** */ 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); - -void MESH_OT_fill(struct wmOperatorType *ot); -void MESH_OT_beautify_fill(struct wmOperatorType *ot); -void MESH_OT_quads_convert_to_tris(struct wmOperatorType *ot); -void MESH_OT_tris_convert_to_quads(struct wmOperatorType *ot); -void MESH_OT_dissolve(struct wmOperatorType *ot); -void MESH_OT_dissolve_limited(struct wmOperatorType *ot); -void MESH_OT_faces_shade_smooth(struct wmOperatorType *ot); -void MESH_OT_faces_shade_flat(struct wmOperatorType *ot); -void MESH_OT_split(struct wmOperatorType *ot); -void MESH_OT_extrude_repeat(struct wmOperatorType *ot); -void MESH_OT_edge_rotate(struct wmOperatorType *ot); -void MESH_OT_select_vertex_path(struct wmOperatorType *ot); -void MESH_OT_loop_to_region(struct wmOperatorType *ot); -void MESH_OT_region_to_loop(struct wmOperatorType *ot); -void MESH_OT_select_axis(struct wmOperatorType *ot); - +void MESH_OT_normals_make_consistent(struct wmOperatorType *ot); +void MESH_OT_vertices_smooth(struct wmOperatorType *ot); +void MESH_OT_vertices_smooth_laplacian(struct wmOperatorType *ot); +void MESH_OT_vert_connect(struct wmOperatorType *ot); +void MESH_OT_edge_split(struct wmOperatorType *ot); +void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot); +void MESH_OT_wireframe(struct wmOperatorType *ot); +void MESH_OT_convex_hull(struct wmOperatorType *ot); +void MESH_OT_symmetrize(struct wmOperatorType *ot); +void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot); +void MESH_OT_blend_from_shape(struct wmOperatorType *ot); +void MESH_OT_sort_elements(struct wmOperatorType *ot); void MESH_OT_uvs_rotate(struct wmOperatorType *ot); -//void MESH_OT_uvs_mirror(struct wmOperatorType *ot); void MESH_OT_uvs_reverse(struct wmOperatorType *ot); void MESH_OT_colors_rotate(struct wmOperatorType *ot); -//void MESH_OT_colors_mirror(struct wmOperatorType *ot); - void MESH_OT_colors_reverse(struct wmOperatorType *ot); - void MESH_OT_delete(struct wmOperatorType *ot); void MESH_OT_edge_collapse(struct wmOperatorType *ot); void MESH_OT_edge_collapse_loop(struct wmOperatorType *ot); -void MESH_OT_rip(struct wmOperatorType *ot); +void MESH_OT_faces_shade_smooth(struct wmOperatorType *ot); +void MESH_OT_faces_shade_flat(struct wmOperatorType *ot); +void MESH_OT_split(struct wmOperatorType *ot); +void MESH_OT_edge_rotate(struct wmOperatorType *ot); +void MESH_OT_hide(struct wmOperatorType *ot); +void MESH_OT_reveal(struct wmOperatorType *ot); +void MESH_OT_mark_seam(struct wmOperatorType *ot); +void MESH_OT_mark_sharp(struct wmOperatorType *ot); +void MESH_OT_noise(struct wmOperatorType *ot); +void MESH_OT_flip_normals(struct wmOperatorType *ot); +void MESH_OT_solidify(struct wmOperatorType *ot); +void MESH_OT_knife_cut(struct wmOperatorType *ot); +void MESH_OT_separate(struct wmOperatorType *ot); +void MESH_OT_fill(struct wmOperatorType *ot); +void MESH_OT_beautify_fill(struct wmOperatorType *ot); +void MESH_OT_quads_convert_to_tris(struct wmOperatorType *ot); +void MESH_OT_tris_convert_to_quads(struct wmOperatorType *ot); +void MESH_OT_dissolve(struct wmOperatorType *ot); +void MESH_OT_dissolve_limited(struct wmOperatorType *ot); +void MESH_OT_edge_face_add(struct wmOperatorType *ot); +void MESH_OT_duplicate(struct wmOperatorType *ot); +void MESH_OT_merge(struct wmOperatorType *ot); +void MESH_OT_remove_doubles(struct wmOperatorType *ot); -void MESH_OT_shape_propagate_to_all(struct wmOperatorType *ot); -void MESH_OT_blend_from_shape(struct wmOperatorType *ot); -void MESH_OT_sort_elements(struct wmOperatorType *ot); #ifdef WITH_FREESTYLE +void MESH_OT_mark_freestyle_edge(struct wmOperatorType *ot); void MESH_OT_mark_freestyle_face(struct wmOperatorType *ot); #endif -/* ******************* mesh_data.c */ - +/* *** mesh_data.c *** */ void MESH_OT_uv_texture_add(struct wmOperatorType *ot); void MESH_OT_uv_texture_remove(struct wmOperatorType *ot); void MESH_OT_vertex_color_add(struct wmOperatorType *ot); @@ -197,40 +216,15 @@ void MESH_OT_vertex_color_remove(struct wmOperatorType *ot); /* no create_mask yet */ void MESH_OT_customdata_clear_mask(struct wmOperatorType *ot); void MESH_OT_customdata_clear_skin(struct wmOperatorType *ot); - void MESH_OT_drop_named_image(struct wmOperatorType *ot); -/* ************* bmesh_tools.c ***********/ -void MESH_OT_vert_connect(struct wmOperatorType *ot); -void MESH_OT_edge_split(struct wmOperatorType *ot); -void MESH_OT_extrude_region(struct wmOperatorType *ot); -void MESH_OT_extrude_verts_indiv(struct wmOperatorType *ot); -void MESH_OT_extrude_edges_indiv(struct wmOperatorType *ot); -void MESH_OT_extrude_faces_indiv(struct wmOperatorType *ot); - -void MESH_OT_edgering_select(struct wmOperatorType *ot); -void MESH_OT_loopcut(struct wmOperatorType *ot); - -void MESH_OT_knife_tool(struct wmOperatorType *ot); -void MESH_OT_knife_project(wmOperatorType *ot); - -void MESH_OT_bevel(struct wmOperatorType *ot); -void MESH_OT_bridge_edge_loops(struct wmOperatorType *ot); -void MESH_OT_inset(struct wmOperatorType *ot); -void MESH_OT_wireframe(struct wmOperatorType *ot); - -void MESH_OT_convex_hull(struct wmOperatorType *ot); - -void MESH_OT_symmetrize(struct wmOperatorType *ot); - -/* ******************* mesh_navmesh.c */ +/* *** mesh_navmesh.c *** */ void MESH_OT_navmesh_make(struct wmOperatorType *ot); void MESH_OT_navmesh_face_copy(struct wmOperatorType *ot); 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); -void EDBM_mesh_knife(struct bContext *C, struct LinkNode *polys, bool use_tag); #endif /* __MESH_INTERN_H__ */ diff --git a/source/blender/editors/mesh/mesh_navmesh.c b/source/blender/editors/mesh/mesh_navmesh.c index 2111b6f3409..e6c36274687 100644 --- a/source/blender/editors/mesh/mesh_navmesh.c +++ b/source/blender/editors/mesh/mesh_navmesh.c @@ -52,9 +52,10 @@ #include "WM_api.h" #include "WM_types.h" -#include "mesh_intern.h" #include "recast-capi.h" +#include "mesh_intern.h" /* own include */ + static void createVertsTrisData(bContext *C, LinkNode *obs, int *nverts_r, float **verts_r, int *ntris_r, int **tris_r, unsigned int *r_lay) diff --git a/source/blender/editors/mesh/mesh_ops.c b/source/blender/editors/mesh/mesh_ops.c index 42a139d7961..a17b0f5551b 100644 --- a/source/blender/editors/mesh/mesh_ops.c +++ b/source/blender/editors/mesh/mesh_ops.c @@ -28,13 +28,8 @@ * \ingroup edmesh */ - - - - #include "BLI_math.h" - #include "RNA_access.h" #include "WM_api.h" @@ -44,8 +39,7 @@ #include "ED_mesh.h" #include "ED_screen.h" - -#include "mesh_intern.h" +#include "mesh_intern.h" /* own include */ /**************************** registration **********************************/ diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 562bc4a8e02..b34f43cd082 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -60,7 +60,6 @@ #include "BKE_tessmesh.h" #include "BKE_multires.h" - #include "ED_mesh.h" #include "ED_object.h" #include "ED_view3d.h" diff --git a/source/blender/editors/object/object_constraint.c b/source/blender/editors/object/object_constraint.c index 9b61fa44955..3e66c4ca110 100644 --- a/source/blender/editors/object/object_constraint.c +++ b/source/blender/editors/object/object_constraint.c @@ -604,7 +604,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int list = &pchan->constraints; else { //if (G.debug & G_DEBUG) - //printf("edit_constraint_property_get: No active bone for object '%s'\n", (ob)? ob->id.name + 2 : "<None>"); + //printf("edit_constraint_property_get: No active bone for object '%s'\n", (ob) ? ob->id.name + 2 : "<None>"); return NULL; } } @@ -616,7 +616,7 @@ static bConstraint *edit_constraint_property_get(wmOperator *op, Object *ob, int con = BKE_constraints_findByName(list, constraint_name); //if (G.debug & G_DEBUG) - //printf("constraint found = %p, %s\n", (void *)con, (con)?con->name:"<Not found>"); + //printf("constraint found = %p, %s\n", (void *)con, (con) ? con->name : "<Not found>"); if (con && (type != 0) && (con->type != type)) con = NULL; diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c index 05c3af40a29..9634acd701a 100644 --- a/source/blender/editors/physics/dynamicpaint_ops.c +++ b/source/blender/editors/physics/dynamicpaint_ops.c @@ -394,7 +394,7 @@ static int dynamicPaint_initBake(struct bContext *C, struct wmOperator *op) /* Format time string */ char time_str[30]; double time = PIL_check_seconds_timer() - timer; - BLI_timestr(time, time_str); + BLI_timestr(time, time_str, sizeof(time_str)); /* Show bake info */ BKE_reportf(op->reports, RPT_INFO, "Bake complete! (%s)", time_str); diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c index e972b7d6620..f00295a9033 100644 --- a/source/blender/editors/physics/particle_edit.c +++ b/source/blender/editors/physics/particle_edit.c @@ -2287,13 +2287,13 @@ static void subdivide_particle(PEData *data, int pa_index) nekey++; if (ekey->flag & PEK_SELECT && (ekey+1)->flag & PEK_SELECT) { - nkey->time= (key->time + (key+1)->time)*0.5f; - state.time= (endtime != 0.0f)? nkey->time/endtime: 0.0f; + nkey->time = (key->time + (key + 1)->time) * 0.5f; + state.time = (endtime != 0.0f) ? nkey->time / endtime: 0.0f; psys_get_particle_on_path(&sim, pa_index, &state, 0); copy_v3_v3(nkey->co, state.co); nekey->co= nkey->co; - nekey->time= &nkey->time; + nekey->time = &nkey->time; nekey->flag |= PEK_SELECT; if (!(psys->flag & PSYS_GLOBAL_HAIR)) nekey->flag |= PEK_USE_WCO; diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c index df723b06259..8fe3eb66c67 100644 --- a/source/blender/editors/physics/physics_fluid.c +++ b/source/blender/editors/physics/physics_fluid.c @@ -528,7 +528,7 @@ static void export_fluid_objects(ListBase *fobjects, Scene *scene, int length) if ( ELEM(fsmesh.type, OB_FLUIDSIM_FLUID, OB_FLUIDSIM_INFLOW)) { fsmesh.channelInitialVel = fobj->InitialVelocity; - fsmesh.localInivelCoords = ((fluidmd->fss->typeFlags & OB_FSINFLOW_LOCALCOORD)?1:0); + fsmesh.localInivelCoords = ((fluidmd->fss->typeFlags & OB_FSINFLOW_LOCALCOORD) ? 1 : 0); } if (fluidmd->fss->typeFlags & OB_FSBND_NOSLIP) diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c index 1268d577f44..365ac02d15b 100644 --- a/source/blender/editors/render/render_internal.c +++ b/source/blender/editors/render/render_internal.c @@ -311,7 +311,7 @@ static void make_renderinfo_string(RenderStats *rs, Scene *scene, char *str) spos += sprintf(spos, IFACE_("Blur %d "), rs->curblur); } - BLI_timestr(rs->lastframetime, info_time_str); + BLI_timestr(rs->lastframetime, info_time_str, sizeof(info_time_str)); spos += sprintf(spos, IFACE_("Time:%s "), info_time_str); if (rs->curfsa) diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c index 8501b53afae..89315e041de 100644 --- a/source/blender/editors/screen/glutil.c +++ b/source/blender/editors/screen/glutil.c @@ -519,6 +519,15 @@ void glaDrawPixelsTexScaled(float x, float y, int img_w, int img_h, int format, nsubparts_x = (img_w + (offset_x - 1)) / (offset_x); nsubparts_y = (img_h + (offset_y - 1)) / (offset_y); + if (format == GL_FLOAT) { + /* need to set internal format to higher range float */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA16F, tex_w, tex_h, 0, GL_RGBA, GL_FLOAT, NULL); + } + else { + /* switch to 8bit RGBA for byte buffer */ + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, tex_w, tex_h, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL); + } + for (subpart_y = 0; subpart_y < nsubparts_y; subpart_y++) { for (subpart_x = 0; subpart_x < nsubparts_x; subpart_x++) { int remainder_x = img_w - subpart_x * offset_x; diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c index 8d9cbbbcf11..a27ef91df24 100644 --- a/source/blender/editors/sculpt_paint/paint_cursor.c +++ b/source/blender/editors/sculpt_paint/paint_cursor.c @@ -85,7 +85,8 @@ static int same_snap(Snapshot *snap, Brush *brush, ViewContext *vc) return (((mtex->tex) && equals_v3v3(mtex->ofs, snap->ofs) && equals_v3v3(mtex->size, snap->size) && - mtex->rot == snap->rot) && + (brush->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL || + mtex->rot == snap->rot)) && /* make brush smaller shouldn't cause a resample */ ((mtex->brush_map_mode == MTEX_MAP_MODE_VIEW && @@ -117,7 +118,7 @@ static void make_snap(Snapshot *snap, Brush *brush, ViewContext *vc) snap->winy = vc->ar->winy; } -static int load_tex(Brush *br, ViewContext *vc) +static int load_tex(Brush *br, ViewContext *vc, float zoom, bool col) { static GLuint overlay_texture = 0; static int init = 0; @@ -125,12 +126,15 @@ static int load_tex(Brush *br, ViewContext *vc) static int curve_changed_timestamp = -1; static Snapshot snap; static int old_size = -1; + static int old_zoom = -1; + static bool old_col = -1; GLubyte *buffer = NULL; int size; int j; int refresh; + GLenum format = col ? GL_RGBA : GL_ALPHA; if (br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED && !br->mtex.tex) return 0; @@ -141,10 +145,17 @@ static int load_tex(Brush *br, ViewContext *vc) br->mtex.tex->preview->changed_timestamp[0] != tex_changed_timestamp)) || !br->curve || br->curve->changed_timestamp != curve_changed_timestamp || + old_zoom != zoom || + old_col != col || !same_snap(&snap, br, vc); if (refresh) { struct ImagePool *pool = NULL; + /* stencil is rotated later */ + const float rotation = (br->mtex.brush_map_mode != MTEX_MAP_MODE_STENCIL) ? + -br->mtex.rot : 0; + + float radius = BKE_brush_size_get(vc->scene, br) * zoom; if (br->mtex.tex && br->mtex.tex->preview) tex_changed_timestamp = br->mtex.tex->preview->changed_timestamp[0]; @@ -152,6 +163,7 @@ static int load_tex(Brush *br, ViewContext *vc) if (br->curve) curve_changed_timestamp = br->curve->changed_timestamp; + old_zoom = zoom; make_snap(&snap, br, vc); if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) { @@ -182,8 +194,10 @@ static int load_tex(Brush *br, ViewContext *vc) old_size = size; } - - buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex"); + if (col) + buffer = MEM_mallocN(sizeof(GLubyte) * size * size * 4, "load_tex"); + else + buffer = MEM_mallocN(sizeof(GLubyte) * size * size, "load_tex"); if (br->mtex.tex) pool = BKE_image_pool_new(); @@ -198,11 +212,8 @@ static int load_tex(Brush *br, ViewContext *vc) // largely duplicated from tex_strength - const float rotation = -br->mtex.rot; - float radius = BKE_brush_size_get(vc->scene, br); int index = j * size + i; float x; - float avg; x = (float)i / size; y = (float)j / size; @@ -221,7 +232,7 @@ static int load_tex(Brush *br, ViewContext *vc) len = sqrtf(x * x + y * y); - if ((br->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) || len <= 1) { + if (ELEM(br->mtex.brush_map_mode, MTEX_MAP_MODE_TILED, MTEX_MAP_MODE_STENCIL) || len <= 1) { /* it is probably worth optimizing for those cases where * the texture is not rotated by skipping the calls to * atan2, sqrtf, sin, and cos. */ @@ -238,17 +249,41 @@ static int load_tex(Brush *br, ViewContext *vc) x += br->mtex.ofs[0]; y += br->mtex.ofs[1]; - avg = br->mtex.tex ? paint_get_tex_pixel(br, x, y, pool) : 1; + if (col) { + float rgba[4]; - avg += br->texture_sample_bias; + if (br->mtex.tex) + paint_get_tex_pixel_col(&br->mtex, x, y, rgba, pool); - if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) - avg *= BKE_brush_curve_strength(br, len, 1); /* Falloff curve */ + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) + mul_v4_fl(rgba, BKE_brush_curve_strength(br, len, 1)); /* Falloff curve */ + + buffer[index * 4] = rgba[0] * 255; + buffer[index * 4 + 1] = rgba[1] * 255; + buffer[index * 4 + 2] = rgba[2] * 255; + buffer[index * 4 + 3] = rgba[3] * 255; + } + else { + float avg = br->mtex.tex ? paint_get_tex_pixel(&br->mtex, x, y, pool) : 1; - buffer[index] = 255 - (GLubyte)(255 * avg); + avg += br->texture_sample_bias; + + if (br->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) + avg *= BKE_brush_curve_strength(br, len, 1); /* Falloff curve */ + + buffer[index] = 255 - (GLubyte)(255 * avg); + } } else { - buffer[index] = 0; + if (col) { + buffer[index * 4] = 0; + buffer[index * 4 + 1] = 0; + buffer[index * 4 + 2] = 0; + buffer[index * 4 + 3] = 0; + } + else { + buffer[index] = 0; + } } } } @@ -266,16 +301,18 @@ static int load_tex(Brush *br, ViewContext *vc) glBindTexture(GL_TEXTURE_2D, overlay_texture); if (refresh) { - if (!init) { - glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, size, size, 0, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + if (!init || (old_col != col)) { + glTexImage2D(GL_TEXTURE_2D, 0, format, size, size, 0, format, GL_UNSIGNED_BYTE, buffer); init = 1; } else { - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, GL_ALPHA, GL_UNSIGNED_BYTE, buffer); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, size, size, format, GL_UNSIGNED_BYTE, buffer); } if (buffer) MEM_freeN(buffer); + + old_col = col; } glEnable(GL_TEXTURE_2D); @@ -382,17 +419,20 @@ static int sculpt_get_brush_geometry(bContext *C, ViewContext *vc, * have on brush strength */ /* TODO: sculpt only for now */ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, - ViewContext *vc, int x, int y) + ViewContext *vc, int x, int y, float zoom, PaintMode mode) { rctf quad; - + bool col; /* check for overlay mode */ - if (!(brush->flag & BRUSH_TEXTURE_OVERLAY) || - !(ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED))) + + if (!((brush->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL && brush->mtex.tex) || + ((brush->flag & BRUSH_TEXTURE_OVERLAY) && + ELEM(brush->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_TILED)))) { return; } + col = ELEM3(mode, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D, PAINT_VERTEX) ? true: false; /* save lots of GL state * TODO: check on whether all of these are needed? */ glPushAttrib(GL_COLOR_BUFFER_BIT | @@ -406,7 +446,7 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, GL_VIEWPORT_BIT | GL_TEXTURE_BIT); - if (load_tex(brush, vc)) { + if (load_tex(brush, vc, zoom, col)) { glEnable(GL_BLEND); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); @@ -439,25 +479,43 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, quad.ymax = aim[1] + ups->anchored_size; } else { - const int radius = BKE_brush_size_get(vc->scene, brush); + const int radius = BKE_brush_size_get(vc->scene, brush) * zoom; quad.xmin = x - radius; quad.ymin = y - radius; quad.xmax = x + radius; quad.ymax = y + radius; } } - else { + else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_TILED) { quad.xmin = 0; quad.ymin = 0; quad.xmax = BLI_rcti_size_x(&vc->ar->winrct); quad.ymax = BLI_rcti_size_y(&vc->ar->winrct); } + else if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL) { + quad.xmin = -brush->stencil_dimension[0]; + quad.ymin = -brush->stencil_dimension[1]; + quad.xmax = brush->stencil_dimension[0]; + quad.ymax = brush->stencil_dimension[1]; + + glMatrixMode(GL_MODELVIEW); + glPushMatrix(); + glTranslatef(brush->stencil_pos[0], brush->stencil_pos[1], 0); + glRotatef(RAD2DEGF(brush->mtex.rot), 0, 0, 1); + glMatrixMode(GL_TEXTURE); + } - /* set quad color */ - glColor4f(U.sculpt_paint_overlay_col[0], - U.sculpt_paint_overlay_col[1], - U.sculpt_paint_overlay_col[2], - brush->texture_overlay_alpha / 100.0f); + /* set quad color. Colored overlay does not get blending */ + if (col) + glColor4f(1.0, + 1.0, + 1.0, + brush->texture_overlay_alpha / 100.0f); + else + glColor4f(U.sculpt_paint_overlay_col[0], + U.sculpt_paint_overlay_col[1], + U.sculpt_paint_overlay_col[2], + brush->texture_overlay_alpha / 100.0f); /* draw textured quad */ glBegin(GL_QUADS); @@ -472,6 +530,11 @@ static void paint_draw_alpha_overlay(UnifiedPaintSettings *ups, Brush *brush, glEnd(); glPopMatrix(); + + if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL) { + glMatrixMode(GL_MODELVIEW); + glPopMatrix(); + } } glPopAttrib(); @@ -516,17 +579,12 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) Paint *paint = paint_get_active_from_context(C); Brush *brush = paint_brush(paint); ViewContext vc; + PaintMode mode; float final_radius; float translation[2]; float outline_alpha, *outline_col; + float zoomx, zoomy; - /* set various defaults */ - translation[0] = x; - translation[1] = y; - outline_alpha = 0.5; - outline_col = brush->add_col; - final_radius = BKE_brush_size_get(scene, brush); - /* check that brush drawing is enabled */ if (!(paint->flags & PAINT_SHOW_BRUSH)) return; @@ -535,12 +593,25 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused)) * mouse over too, not just during a stroke */ view3d_set_viewcontext(C, &vc); + get_imapaint_zoom(C, &zoomx, &zoomy); + zoomx = max_ff(zoomx, zoomy); + mode = paintmode_get_active_from_context(C); + + /* set various defaults */ + translation[0] = x; + translation[1] = y; + outline_alpha = 0.5; + outline_col = brush->add_col; + final_radius = BKE_brush_size_get(scene, brush) * zoomx; + if (brush->flag & BRUSH_RAKE) /* here, translation contains the mouse coordinates. */ paint_calculate_rake_rotation(ups, translation); + else if (!(brush->flag & BRUSH_ANCHORED)) + ups->brush_rotation = 0.0; /* draw overlay */ - paint_draw_alpha_overlay(ups, brush, &vc, x, y); + paint_draw_alpha_overlay(ups, brush, &vc, x, y, zoomx, mode); /* TODO: as sculpt and other paint modes are unified, this * special mode of drawing will go away */ @@ -611,3 +682,9 @@ void paint_cursor_start(bContext *C, int (*poll)(bContext *C)) if (p && !p->paint_cursor) p->paint_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), poll, paint_draw_cursor, NULL); } + +void paint_cursor_start_explicit(Paint *p, wmWindowManager *wm, int (*poll)(bContext *C)) +{ + if (p && !p->paint_cursor) + p->paint_cursor = WM_paint_cursor_activate(wm, poll, paint_draw_cursor, NULL); +} diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c index 4478d68d3be..a47f364ac67 100644 --- a/source/blender/editors/sculpt_paint/paint_image.c +++ b/source/blender/editors/sculpt_paint/paint_image.c @@ -442,7 +442,7 @@ static void paint_redraw(const bContext *C, PaintOperation *pop, int final) } } -static PaintOperation * texture_paint_init(bContext *C, wmOperator *op, const wmEvent *event) +static PaintOperation *texture_paint_init(bContext *C, wmOperator *op, const wmEvent *event) { Scene *scene = CTX_data_scene(C); ToolSettings *settings = scene->toolsettings; @@ -721,8 +721,7 @@ static void toggle_paint_cursor(bContext *C, int enable) settings->imapaint.paintcursor = NULL; } else if (enable) - settings->imapaint.paintcursor = - WM_paint_cursor_activate(wm, image_paint_poll, brush_drawcursor_texpaint_uvsculpt, NULL); + paint_cursor_start(C, image_paint_poll); } /* enable the paint cursor if it isn't already. @@ -746,11 +745,7 @@ void ED_space_image_paint_update(wmWindowManager *wm, ToolSettings *settings) if (enabled) { BKE_paint_init(&imapaint->paint, PAINT_CURSOR_TEXTURE_PAINT); - if (!imapaint->paintcursor) { - imapaint->paintcursor = - WM_paint_cursor_activate(wm, image_paint_poll, - brush_drawcursor_texpaint_uvsculpt, NULL); - } + paint_cursor_start_explicit(&imapaint->paint, wm, image_paint_poll); } } @@ -882,8 +877,7 @@ static int sample_color_invoke(bContext *C, wmOperator *op, const wmEvent *event static int sample_color_modal(bContext *C, wmOperator *op, const wmEvent *event) { switch (event->type) { - case LEFTMOUSE: - case RIGHTMOUSE: // XXX hardcoded + case SKEY: // XXX hardcoded return OPERATOR_FINISHED; case MOUSEMOVE: RNA_int_set_array(op->ptr, "location", event->mval); diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c index a45209de643..6032a7a4c22 100644 --- a/source/blender/editors/sculpt_paint/paint_image_2d.c +++ b/source/blender/editors/sculpt_paint/paint_image_2d.c @@ -87,11 +87,8 @@ BLI_INLINE unsigned char f_to_char(const float val) #define IMAPAINT_FLOAT_RGB_COPY(a, b) copy_v3_v3(a, b) typedef struct BrushPainterCache { - short enabled; - int size; /* size override, if 0 uses 2*BKE_brush_size_get(brush) */ short flt; /* need float imbuf? */ - short texonly; /* no alpha, color or fallof, only texture in imbuf */ int lastsize; float lastalpha; @@ -157,11 +154,9 @@ static BrushPainter *brush_painter_2d_new(Scene *scene, Brush *brush) } -static void brush_painter_2d_require_imbuf(BrushPainter *painter, short flt, short texonly, int size) +static void brush_painter_2d_require_imbuf(BrushPainter *painter, short flt, int size) { - if ((painter->cache.flt != flt) || (painter->cache.size != size) || - ((painter->cache.texonly != texonly) && texonly)) - { + if ((painter->cache.flt != flt) || (painter->cache.size != size)) { if (painter->cache.ibuf) IMB_freeImBuf(painter->cache.ibuf); if (painter->cache.maskibuf) IMB_freeImBuf(painter->cache.maskibuf); painter->cache.ibuf = painter->cache.maskibuf = NULL; @@ -176,8 +171,6 @@ static void brush_painter_2d_require_imbuf(BrushPainter *painter, short flt, sho painter->cache.size = size; painter->cache.flt = flt; - painter->cache.texonly = texonly; - painter->cache.enabled = 1; } static void brush_painter_2d_free(BrushPainter *painter) @@ -738,10 +731,9 @@ int paint_2d_stroke(void *ps, const int prev_mval[2], const int mval[2], int era /* OCIO_TODO: float buffers are now always linear, so always use color correction * this should probably be changed when texture painting color space is supported */ - brush_painter_2d_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0, 0); + brush_painter_2d_require_imbuf(painter, ((ibuf->rect_float) ? 1 : 0), 0); - if (painter->cache.enabled) - brush_painter_2d_refresh_cache(painter, newuv, is_data == false); + brush_painter_2d_refresh_cache(painter, newuv, is_data == false); if (paint_2d_op(s, painter->cache.ibuf, olduv, newuv)) { imapaint_image_update(s->sima, s->image, ibuf, false); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 5dcfa181fa2..a2101305b4b 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -4160,7 +4160,7 @@ static void project_state_init(bContext *C, Object *ob, ProjPaintState *ps, int /* disable for 3d mapping also because painting on mirrored mesh can create "stripes" */ ps->do_masking = (brush->flag & BRUSH_AIRBRUSH || brush->mtex.brush_map_mode != MTEX_MAP_MODE_TILED) ? false : true; ps->is_texbrush = (brush->mtex.tex && brush->imagepaint_tool == PAINT_TOOL_DRAW) ? true : false; - ps->is_maskbrush = (brush->flag & BRUSH_USE_MASK && brush->mask_mtex.tex) ? true : false; + ps->is_maskbrush = (brush->mask_mtex.tex) ? true : false; } else { /* brush may be NULL*/ diff --git a/source/blender/editors/sculpt_paint/paint_intern.h b/source/blender/editors/sculpt_paint/paint_intern.h index 88c18602c89..8b1de32f1ea 100644 --- a/source/blender/editors/sculpt_paint/paint_intern.h +++ b/source/blender/editors/sculpt_paint/paint_intern.h @@ -39,8 +39,10 @@ struct Brush; struct ImagePool; struct ListBase; struct Mesh; +struct MTex; struct Object; struct PaintStroke; +struct Paint; struct PointerRNA; struct rcti; struct Scene; @@ -51,6 +53,7 @@ struct wmEvent; struct wmOperator; struct wmOperatorType; struct ImagePaintState; +struct wmWindowManager; enum PaintMode; /* paint_stroke.c */ @@ -79,6 +82,7 @@ void *paint_stroke_mode_data(struct PaintStroke *stroke); void paint_stroke_set_mode_data(struct PaintStroke *stroke, void *mode_data); int paint_poll(struct bContext *C); void paint_cursor_start(struct bContext *C, int (*poll)(struct bContext *C)); +void paint_cursor_start_explicit(struct Paint *p, struct wmWindowManager *wm, int (*poll)(struct bContext *C)); /* paint_vertex.c */ int weight_paint_poll(struct bContext *C); @@ -176,7 +180,8 @@ void paint_calc_redraw_planes(float planes[4][4], void projectf(struct bglMats *mats, const float v[3], float p[2]); float paint_calc_object_space_radius(struct ViewContext *vc, const float center[3], float pixel_radius); -float paint_get_tex_pixel(struct Brush *br, float u, float v, struct ImagePool *pool); +float paint_get_tex_pixel(struct MTex *mtex, float u, float v, struct ImagePool *pool); +void paint_get_tex_pixel_col(struct MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool); int imapaint_pick_face(struct ViewContext *vc, const int mval[2], unsigned int *index, unsigned int totface); void imapaint_pick_uv(struct Scene *scene, struct Object *ob, unsigned int faceindex, const int xy[2], float uv[2]); void brush_drawcursor_texpaint_uvsculpt(struct bContext *C, int x, int y, void *customdata); @@ -201,7 +206,7 @@ int facemask_paint_poll(struct bContext *C); typedef enum BrushStrokeMode { BRUSH_STROKE_NORMAL, BRUSH_STROKE_INVERT, - BRUSH_STROKE_SMOOTH, + BRUSH_STROKE_SMOOTH } BrushStrokeMode; /* paint_undo.c */ diff --git a/source/blender/editors/sculpt_paint/paint_ops.c b/source/blender/editors/sculpt_paint/paint_ops.c index 120d0a3b10a..cd9523f8ff6 100644 --- a/source/blender/editors/sculpt_paint/paint_ops.c +++ b/source/blender/editors/sculpt_paint/paint_ops.c @@ -28,6 +28,7 @@ #include "BLI_listbase.h" #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLI_math_vector.h" #include "DNA_object_types.h" #include "DNA_scene_types.h" @@ -307,11 +308,7 @@ static int brush_select_exec(bContext *C, wmOperator *op) Object *ob = CTX_data_active_object(C); if (ob) { /* select current paint mode */ - paint_mode = ob->mode & - (OB_MODE_SCULPT | - OB_MODE_VERTEX_PAINT | - OB_MODE_WEIGHT_PAINT | - OB_MODE_TEXTURE_PAINT); + paint_mode = ob->mode & OB_MODE_ALL_PAINT; } else { return OPERATOR_CANCELLED; @@ -448,6 +445,171 @@ static void BRUSH_OT_uv_sculpt_tool_set(wmOperatorType *ot) ot->prop = RNA_def_enum(ot->srna, "tool", uv_sculpt_tool_items, 0, "Tool", ""); } +/***** Stencil Control *****/ + +enum { +STENCIL_TRANSLATE, +STENCIL_SCALE, +STENCIL_ROTATE +} StencilControlMode; + +typedef struct { + int init_mouse[2]; + int init_spos[2]; + int init_sdim[2]; + float init_rot; + float init_angle; + float lenorig; + int mode; + Brush *br; +} StencilControlData; + +static int stencil_control_invoke(bContext *C, wmOperator *op, const wmEvent *event) +{ + Paint *paint = paint_get_active_from_context(C); + Brush *br = paint->brush; + int mdiff[2]; + + StencilControlData *scd = MEM_mallocN(sizeof(StencilControlData), "stencil_control"); + + copy_v2_v2_int(scd->init_mouse, event->mval); + copy_v2_v2_int(scd->init_sdim, br->stencil_dimension); + copy_v2_v2_int(scd->init_spos, br->stencil_pos); + sub_v2_v2v2_int(mdiff, event->mval, br->stencil_pos); + scd->lenorig = sqrtf(mdiff[0] * mdiff[0] + mdiff[1] * mdiff[1]); + scd->br = br; + scd->init_rot = br->mtex.rot; + scd->init_angle = atan2(mdiff[1], mdiff[0]); + scd->mode = RNA_enum_get(op->ptr, "mode"); + + op->customdata = scd; + WM_event_add_modal_handler(C, op); + + return OPERATOR_RUNNING_MODAL; +} + + +static int stencil_control_cancel(bContext *UNUSED(C), wmOperator *op) +{ + StencilControlData *scd = op->customdata; + Brush *br = scd->br; + + copy_v2_v2_int(br->stencil_dimension, scd->init_sdim); + copy_v2_v2_int(br->stencil_pos, scd->init_spos); + br->mtex.rot = scd->init_rot; + MEM_freeN(op->customdata); + return OPERATOR_CANCELLED; +} + +static int stencil_control_modal(bContext *C, wmOperator *op, const wmEvent *event) +{ + StencilControlData *scd = op->customdata; + + switch (event->type) { + case MOUSEMOVE: + { + int mdiff[2]; + switch (scd->mode) { + case STENCIL_TRANSLATE: + sub_v2_v2v2_int(mdiff, event->mval, scd->init_mouse); + add_v2_v2v2_int(scd->br->stencil_pos, scd->init_spos, + mdiff); + break; + case STENCIL_SCALE: + { + float len, factor; + sub_v2_v2v2_int(mdiff, event->mval, scd->br->stencil_pos); + len = sqrtf(mdiff[0] * mdiff[0] + mdiff[1] * mdiff[1]); + factor = len/scd->lenorig; + mdiff[0] = factor * scd->init_sdim[0]; + mdiff[1] = factor * scd->init_sdim[1]; + copy_v2_v2_int(scd->br->stencil_dimension, mdiff); + break; + } + case STENCIL_ROTATE: + { + float angle; + sub_v2_v2v2_int(mdiff, event->mval, scd->br->stencil_pos); + angle = atan2(mdiff[1], mdiff[0]); + angle = scd->init_rot + angle - scd->init_angle; + if (angle < 0.0f) + angle += (float)(2 * M_PI); + if (angle > (float)(2 * M_PI)) + angle -= (float)(2 * M_PI); + scd->br->mtex.rot = angle; + break; + } + } + } + break; + /* XXX hardcoded! */ + case RIGHTMOUSE: + if (event->val == KM_RELEASE) { + MEM_freeN(op->customdata); + WM_event_add_notifier(C, NC_WINDOW, NULL); + return OPERATOR_FINISHED; + } + case ESCKEY: + if (event->val == KM_PRESS) { + stencil_control_cancel(C, op); + WM_event_add_notifier(C, NC_WINDOW, NULL); + return OPERATOR_CANCELLED; + } + default: + break; + } + + ED_region_tag_redraw(CTX_wm_region(C)); + + return OPERATOR_RUNNING_MODAL; +} + +static int stencil_control_poll(bContext *C) +{ + Paint *paint = paint_get_active_from_context(C); + Brush *br = paint->brush; + + return br->mtex.brush_map_mode == MTEX_MAP_MODE_STENCIL; +} + +static void BRUSH_OT_stencil_control(wmOperatorType *ot) +{ + static EnumPropertyItem stencil_control_items[] = { + {STENCIL_TRANSLATE, "TRANSLATION", 0, "Transation", ""}, + {STENCIL_SCALE, "SCALE", 0, "Scale", ""}, + {STENCIL_ROTATE, "ROTATION", 0, "Rotation", ""}, + {0, NULL, 0, NULL, NULL} + }; + /* identifiers */ + ot->name = "Stencil Brush Control"; + ot->description = "Control the stencil brush"; + ot->idname = "BRUSH_OT_stencil_control"; + + /* api callbacks */ + ot->invoke = stencil_control_invoke; + ot->modal = stencil_control_modal; + ot->cancel = stencil_control_cancel; + ot->poll = stencil_control_poll; + + /* flags */ + ot->flag = 0; + + RNA_def_enum(ot->srna, "mode", stencil_control_items, 0, "Tool", ""); +} + +static void ed_keymap_stencil(wmKeyMap *keymap) +{ + wmKeyMapItem *kmi; + + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", RIGHTMOUSE, KM_PRESS, 0, 0); + RNA_enum_set(kmi->ptr, "mode", STENCIL_TRANSLATE); + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", RIGHTMOUSE, KM_PRESS, KM_SHIFT, 0); + RNA_enum_set(kmi->ptr, "mode", STENCIL_SCALE); + kmi = WM_keymap_add_item(keymap, "BRUSH_OT_stencil_control", RIGHTMOUSE, KM_PRESS, KM_CTRL, 0); + RNA_enum_set(kmi->ptr, "mode", STENCIL_ROTATE); + +} + /**************************** registration **********************************/ void ED_operatortypes_paint(void) @@ -457,6 +619,7 @@ void ED_operatortypes_paint(void) WM_operatortype_append(BRUSH_OT_scale_size); WM_operatortype_append(BRUSH_OT_curve_preset); WM_operatortype_append(BRUSH_OT_reset); + WM_operatortype_append(BRUSH_OT_stencil_control); /* note, particle uses a different system, can be added with existing operators in wm.py */ WM_operatortype_append(PAINT_OT_brush_select); @@ -671,6 +834,8 @@ void ED_keymap_paint(wmKeyConfig *keyconf) ed_keymap_paint_brush_size(keymap, "tool_settings.sculpt.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "sculpt", RC_ROTATION); + ed_keymap_stencil(keymap); + keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_DRAW, DKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_SMOOTH, SKEY, 0); keymap_brush_select(keymap, OB_MODE_SCULPT, SCULPT_TOOL_PINCH, PKEY, 0); @@ -687,7 +852,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf) /* */ kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0); - RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.stroke_method"); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.sculpt_stroke_method"); kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_SHIFT, 0); RNA_string_set(kmi->ptr, "data_path", "tool_settings.sculpt.brush.use_smooth_stroke"); @@ -700,7 +865,7 @@ void ED_keymap_paint(wmKeyConfig *keyconf) keymap->poll = vertex_paint_mode_poll; WM_keymap_verify_item(keymap, "PAINT_OT_vertex_paint", LEFTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_sample_color", SKEY, KM_PRESS, 0, 0); WM_keymap_add_item(keymap, "PAINT_OT_vertex_color_set", KKEY, KM_PRESS, KM_SHIFT, 0); @@ -709,6 +874,8 @@ void ED_keymap_paint(wmKeyConfig *keyconf) ed_keymap_paint_brush_size(keymap, "tool_settings.vertex_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "vertex_paint", RC_COLOR | RC_ROTATION); + ed_keymap_stencil(keymap); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */ RNA_string_set(kmi->ptr, "data_path", "vertex_paint_object.data.use_paint_mask"); @@ -718,6 +885,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.texture_angle_source_random"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.stroke_method"); + /* Weight Paint mode */ keymap = WM_keymap_find(keyconf, "Weight Paint", 0, 0); keymap->poll = weight_paint_mode_poll; @@ -738,6 +908,11 @@ void ED_keymap_paint(wmKeyConfig *keyconf) ed_keymap_paint_brush_size(keymap, "tool_settings.weight_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "weight_paint", 0); + ed_keymap_stencil(keymap); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.vertex_paint.brush.stroke_method"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* face mask toggle */ RNA_string_set(kmi->ptr, "data_path", "weight_paint_object.data.use_paint_mask"); @@ -770,12 +945,14 @@ void ED_keymap_paint(wmKeyConfig *keyconf) RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, 0, 0)->ptr, "mode", BRUSH_STROKE_NORMAL); RNA_enum_set(WM_keymap_add_item(keymap, "PAINT_OT_image_paint", LEFTMOUSE, KM_PRESS, KM_CTRL, 0)->ptr, "mode", BRUSH_STROKE_INVERT); WM_keymap_add_item(keymap, "PAINT_OT_grab_clone", RIGHTMOUSE, KM_PRESS, 0, 0); - WM_keymap_add_item(keymap, "PAINT_OT_sample_color", RIGHTMOUSE, KM_PRESS, 0, 0); + WM_keymap_add_item(keymap, "PAINT_OT_sample_color", SKEY, KM_PRESS, 0, 0); ed_keymap_paint_brush_switch(keymap, "image_paint"); ed_keymap_paint_brush_size(keymap, "tool_settings.image_paint.brush.size"); ed_keymap_paint_brush_radial_control(keymap, "image_paint", RC_COLOR | RC_ZOOM | RC_ROTATION); + ed_keymap_stencil(keymap); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0); /* mask toggle */ RNA_string_set(kmi->ptr, "data_path", "image_paint_object.data.use_paint_mask"); @@ -785,6 +962,9 @@ void ED_keymap_paint(wmKeyConfig *keyconf) kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", RKEY, KM_PRESS, 0, 0); RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.texture_angle_source_random"); + kmi = WM_keymap_add_item(keymap, "WM_OT_context_menu_enum", AKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "tool_settings.image_paint.brush.stroke_method"); + /* face-mask mode */ keymap = WM_keymap_find(keyconf, "Face Mask", 0, 0); keymap->poll = facemask_paint_poll; diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c index ca48524096a..1c0830a8158 100644 --- a/source/blender/editors/sculpt_paint/paint_stroke.c +++ b/source/blender/editors/sculpt_paint/paint_stroke.c @@ -174,10 +174,7 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode, ups->pixel_radius *= stroke->cached_pressure; } - if (!(brush->flag & BRUSH_ANCHORED || - ELEM4(brush->sculpt_tool, SCULPT_TOOL_GRAB, SCULPT_TOOL_SNAKE_HOOK, - SCULPT_TOOL_THUMB, SCULPT_TOOL_ROTATE))) - { + if (paint_supports_dynamic_tex_coords(brush, mode)) { if (((brush->mtex.brush_map_mode == MTEX_MAP_MODE_VIEW) || (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)) && !(brush->flag & BRUSH_RAKE)) @@ -188,7 +185,7 @@ static void paint_brush_update(bContext *C, Brush *brush, PaintMode mode, ups->brush_rotation = 0.0f; } - if ((brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM)) + if (brush->mtex.brush_map_mode == MTEX_MAP_MODE_RANDOM) BKE_brush_randomize_texture_coordinates(ups); else copy_v2_v2(ups->tex_mouse, mouse); @@ -281,9 +278,7 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const wmEve paint_brush_update(C, brush, mode, stroke, mouse_in, pressure); - /* TODO: as sculpt and other paint modes are unified, this - * separation will go away */ - if (paint_supports_jitter(mode)) { + { float delta[2]; float factor = stroke->zoom_2d; @@ -301,9 +296,6 @@ static void paint_brush_stroke_add_step(bContext *C, wmOperator *op, const wmEve add_v2_v2v2(mouse_out, mouse_in, delta); } } - else { - copy_v2_v2(mouse_out, mouse_in); - } /* TODO: can remove the if statement once all modes have this */ if (stroke->get_location) @@ -528,11 +520,6 @@ bool paint_supports_dynamic_tex_coords(Brush *br, PaintMode mode) return true; } -bool paint_supports_jitter(PaintMode mode) -{ - return ELEM3(mode, PAINT_SCULPT, PAINT_TEXTURE_PROJECTIVE, PAINT_TEXTURE_2D); -} - #define PAINT_STROKE_MODAL_CANCEL 1 /* called in paint_ops.c, on each regeneration of keymaps */ diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c index 5e88c7b5730..47e20bcc5fb 100644 --- a/source/blender/editors/sculpt_paint/paint_utils.c +++ b/source/blender/editors/sculpt_paint/paint_utils.c @@ -43,6 +43,8 @@ #include "BLI_utildefines.h" #include "BLI_rect.h" +#include "BLF_translation.h" + #include "BKE_brush.h" #include "BKE_context.h" #include "BKE_DerivedMesh.h" @@ -57,6 +59,7 @@ #include "BIF_glutil.h" #include "RE_shader_ext.h" +#include "RE_render_ext.h" #include "ED_view3d.h" #include "ED_screen.h" @@ -174,13 +177,13 @@ float paint_calc_object_space_radius(ViewContext *vc, const float center[3], return len_v3(delta) / scale; } -float paint_get_tex_pixel(Brush *br, float u, float v, struct ImagePool *pool) +float paint_get_tex_pixel(MTex *mtex, float u, float v, struct ImagePool *pool) { TexResult texres = {0}; float co[3] = {u, v, 0.0f}; int hasrgb; - hasrgb = multitex_ext(br->mtex.tex, co, NULL, NULL, 0, &texres, pool); + hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 0, &texres, pool); if (hasrgb & TEX_RGB) texres.tin = rgb_to_grayscale(&texres.tr) * texres.ta; @@ -188,6 +191,23 @@ float paint_get_tex_pixel(Brush *br, float u, float v, struct ImagePool *pool) return texres.tin; } +void paint_get_tex_pixel_col(MTex *mtex, float u, float v, float rgba[4], struct ImagePool *pool) +{ + float co[3] = {u, v, 0.0f}; + int hasrgb; + float intensity; + + hasrgb = externtex(mtex, co, &intensity, + rgba, rgba + 1, rgba + 2, rgba + 3, 0, pool); + + if (!hasrgb) { + rgba[0] = intensity; + rgba[1] = intensity; + rgba[2] = intensity; + rgba[3] = 1.0f; + } +} + /* 3D Paint */ static void imapaint_project(Object *ob, float model[4][4], float proj[4][4], const float co[3], float pco[4]) @@ -375,6 +395,7 @@ static int brush_curve_preset_poll(bContext *C) void BRUSH_OT_curve_preset(wmOperatorType *ot) { + PropertyRNA *prop; static EnumPropertyItem prop_shape_items[] = { {CURVE_PRESET_SHARP, "SHARP", 0, "Sharp", ""}, {CURVE_PRESET_SMOOTH, "SMOOTH", 0, "Smooth", ""}, @@ -391,7 +412,8 @@ void BRUSH_OT_curve_preset(wmOperatorType *ot) ot->exec = brush_curve_preset_exec; ot->poll = brush_curve_preset_poll; - RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", ""); + prop = RNA_def_enum(ot->srna, "shape", prop_shape_items, CURVE_PRESET_SMOOTH, "Mode", ""); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ } diff --git a/source/blender/editors/sculpt_paint/paint_vertex.c b/source/blender/editors/sculpt_paint/paint_vertex.c index 197231124fc..2eca3f94e95 100644 --- a/source/blender/editors/sculpt_paint/paint_vertex.c +++ b/source/blender/editors/sculpt_paint/paint_vertex.c @@ -866,6 +866,7 @@ static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co { float delta[2]; float dist_squared; + float factor = 1.0; sub_v2_v2v2(delta, mval, co_ss); dist_squared = dot_v2v2(delta, delta); /* len squared */ @@ -880,8 +881,9 @@ static float calc_vp_strength_col_dl(VPaint *vp, ViewContext *vc, const float co const float co_ss_3d[3] = {co_ss[0], co_ss[1], 0.0f}; /* we need a 3rd empty value */ BKE_brush_sample_tex_3D(vc->scene, brush, co_ss_3d, rgba, 0, NULL); } + factor = rgba[3]; } - return BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); + return factor * BKE_brush_curve_strength_clamp(brush, dist, brush_size_pressure); } } if (rgba) diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index 20b8f90df8b..5edd14cd8e3 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -968,7 +968,7 @@ static float tex_strength(SculptSession *ss, Brush *br, x += br->mtex.ofs[0]; y += br->mtex.ofs[1]; - avg = paint_get_tex_pixel(br, x, y, ss->tex_pool); + avg = paint_get_tex_pixel(&br->mtex, x, y, ss->tex_pool); avg += br->texture_sample_bias; } @@ -3220,8 +3220,15 @@ static void sculpt_flush_stroke_deform(Sculpt *sd, Object *ob) PBVHNode **nodes; float (*vertCos)[3] = NULL; - if (ss->kb) - vertCos = MEM_callocN(sizeof(*vertCos) * me->totvert, "flushStrokeDeofrm keyVerts"); + if (ss->kb) { + vertCos = MEM_mallocN(sizeof(*vertCos) * me->totvert, "flushStrokeDeofrm keyVerts"); + + /* mesh could have isolated verts which wouldn't be in BVH, + * to deal with this we copy old coordinates over new ones + * and then update coordinates for all vertices from BVH + */ + memcpy(vertCos, ss->orig_cos, 3 * sizeof(float) * me->totvert); + } BKE_pbvh_search_gather(ss->pbvh, NULL, NULL, &nodes, &totnode); diff --git a/source/blender/editors/space_buttons/buttons_ops.c b/source/blender/editors/space_buttons/buttons_ops.c index dcc61cfa544..cf277957e70 100644 --- a/source/blender/editors/space_buttons/buttons_ops.c +++ b/source/blender/editors/space_buttons/buttons_ops.c @@ -120,6 +120,8 @@ static int file_browse_exec(bContext *C, wmOperator *op) BLI_path_abs(path, id ? ID_BLEND_PATH(G.main, id) : G.main->name); if (BLI_is_dir(path)) { + /* do this first so '//' isnt converted to '//\' on windows */ + BLI_add_slash(path); if (is_relative) { BLI_strncpy(path, str, FILE_MAX); BLI_path_rel(path, G.main->name); @@ -129,7 +131,6 @@ static int file_browse_exec(bContext *C, wmOperator *op) else { str = MEM_reallocN(str, strlen(str) + 2); } - BLI_add_slash(str); } else { char * const lslash = (char *)BLI_last_slash(str); diff --git a/source/blender/editors/space_clip/clip_draw.c b/source/blender/editors/space_clip/clip_draw.c index 2d3dc9127c3..cbca2f0c46e 100644 --- a/source/blender/editors/space_clip/clip_draw.c +++ b/source/blender/editors/space_clip/clip_draw.c @@ -248,6 +248,53 @@ static void draw_movieclip_notes(SpaceClip *sc, ARegion *ar) ED_region_info_draw(ar, str, block, 0.6f); } +static void draw_movieclip_buffer_glsl(SpaceClip *sc, ImBuf *ibuf, int x, int y, + float zoomx, float zoomy) +{ + MovieClip *clip = ED_space_clip_get_clip(sc); + int filter = GL_LINEAR; + + glPushMatrix(); + glTranslatef(x, y, 0.0f); + glScalef(zoomx, zoomy, 1.0f); + + glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glColor4f(1.0, 1.0, 1.0, 1.0); + + /* non-scaled proxy shouldn;t use diltering */ + if ((clip->flag & MCLIP_USE_PROXY) == 0 || + ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100)) + { + filter = GL_NEAREST; + } + + glaDrawPixelsTex(0, 0, ibuf->x, ibuf->y, GL_FLOAT, filter, ibuf->rect_float); + + glPopMatrix(); +} + +static void draw_movieclip_buffer_fallback(const bContext *C, ImBuf *ibuf, int x, int y, + int width, int height, float zoomx, float zoomy) +{ + unsigned char *display_buffer; + void *cache_handle; + + display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); + + if (display_buffer) { + /* set zoom */ + glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y); + + glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer); + + /* reset zoom */ + glPixelZoom(1.0f, 1.0f); + } + + IMB_display_buffer_release(cache_handle); +} + static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, ImBuf *ibuf, int width, int height, float zoomx, float zoomy) { @@ -261,62 +308,32 @@ static void draw_movieclip_buffer(const bContext *C, SpaceClip *sc, ARegion *ar, glRectf(x, y, x + zoomx * width, y + zoomy * height); } else { - unsigned char *display_buffer; - void *cache_handle; - - display_buffer = IMB_display_buffer_acquire_ctx(C, ibuf, &cache_handle); - - if (display_buffer) { - int need_fallback = 1; - - /* checkerboard for case alpha */ - if (ibuf->planes == 32) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y); - } + bool need_fallback = true; - if (ED_space_clip_texture_buffer_supported(sc)) { - if (ED_space_clip_load_movieclip_buffer(sc, ibuf, display_buffer)) { - glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + /* checkerboard for case alpha */ + if (ibuf->planes == 32) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glPushMatrix(); - glTranslatef(x, y, 0.0f); - glScalef(zoomx, zoomy, 1.0f); - - glBegin(GL_QUADS); - glTexCoord2f(0.0f, 0.0f); glVertex2f(0.0f, 0.0f); - glTexCoord2f(1.0f, 0.0f); glVertex2f(width, 0.0f); - glTexCoord2f(1.0f, 1.0f); glVertex2f(width, height); - glTexCoord2f(0.0f, 1.0f); glVertex2f(0.0f, height); - glEnd(); - - glPopMatrix(); - - ED_space_clip_unload_movieclip_buffer(sc); - - need_fallback = 0; - } - } + fdrawcheckerboard(x, y, x + zoomx * ibuf->x, y + zoomy * ibuf->y); + } - /* if texture buffers aren't efficiently supported or texture is too large to - * be binder fallback to simple draw pixels solution */ - if (need_fallback) { - /* set zoom */ - glPixelZoom(zoomx * width / ibuf->x, zoomy * height / ibuf->y); + /* GLSL display transform for byte buffers is not supported yet */ + if (ibuf->rect_float && IMB_coloemanagement_setup_glsl_draw_from_ctx(C)) { + draw_movieclip_buffer_glsl(sc, ibuf, x, y, zoomx, zoomy); - glaDrawPixelsAuto(x, y, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, display_buffer); + IMB_coloemanagement_finish_glsl_draw(); - /* reset zoom */ - glPixelZoom(1.0f, 1.0f); - } + need_fallback = false; + } - if (ibuf->planes == 32) - glDisable(GL_BLEND); + /* if GLSL display failed, fallback to regular glaDrawPixelsAuto method */ + if (need_fallback) { + draw_movieclip_buffer_fallback(C, ibuf, x, y, width, height, zoomx, zoomy); } - IMB_display_buffer_release(cache_handle); + if (ibuf->planes == 32) + glDisable(GL_BLEND); } } diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index b00cc564a99..d297d0485e3 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -62,15 +62,13 @@ #include "GPU_extensions.h" +#include "IMB_colormanagement.h" #include "IMB_imbuf_types.h" #include "IMB_imbuf.h" #include "ED_screen.h" #include "ED_clip.h" -#include "BIF_gl.h" -#include "BIF_glutil.h" - #include "WM_api.h" #include "WM_types.h" @@ -580,163 +578,6 @@ void ED_space_clip_set_mask(bContext *C, SpaceClip *sc, Mask *mask) } } -/* OpenGL draw context */ - -typedef struct SpaceClipDrawContext { - int support_checked, buffers_supported; - - GLuint texture; /* OGL texture ID */ - short texture_allocated; /* flag if texture was allocated by glGenTextures */ - struct ImBuf *texture_ibuf; /* image buffer for which texture was created */ - const unsigned char *display_buffer; /* display buffer for which texture was created */ - int image_width, image_height; /* image width and height for which texture was created */ - unsigned last_texture; /* ID of previously used texture, so it'll be restored after clip drawing */ - - /* fields to check if cache is still valid */ - int framenr, start_frame, frame_offset; - short render_size, render_flag; - - char colorspace[64]; -} SpaceClipDrawContext; - -int ED_space_clip_texture_buffer_supported(SpaceClip *sc) -{ - SpaceClipDrawContext *context = sc->draw_context; - - if (!context) { - context = MEM_callocN(sizeof(SpaceClipDrawContext), "SpaceClipDrawContext"); - sc->draw_context = context; - } - - if (!context->support_checked) { - context->support_checked = TRUE; - if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) { - context->buffers_supported = FALSE; - } - else { - context->buffers_supported = GPU_non_power_of_two_support(); - } - } - - return context->buffers_supported; -} - -int ED_space_clip_load_movieclip_buffer(SpaceClip *sc, ImBuf *ibuf, const unsigned char *display_buffer) -{ - SpaceClipDrawContext *context = sc->draw_context; - MovieClip *clip = ED_space_clip_get_clip(sc); - int need_rebind = 0; - - context->last_texture = glaGetOneInteger(GL_TEXTURE_2D); - - glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); - - /* image texture need to be rebinded if displaying another image buffer - * assuming displaying happens of footage frames only on which painting doesn't happen. - * so not changed image buffer pointer means unchanged image content */ - need_rebind |= context->texture_ibuf != ibuf; - need_rebind |= context->display_buffer != display_buffer; - need_rebind |= context->framenr != sc->user.framenr; - need_rebind |= context->render_size != sc->user.render_size; - need_rebind |= context->render_flag != sc->user.render_flag; - need_rebind |= context->start_frame != clip->start_frame; - need_rebind |= context->frame_offset != clip->frame_offset; - - if (!need_rebind) { - /* OCIO_TODO: not entirely nice, but currently it seems to be easiest way - * to deal with changing input color space settings - * pointer-based check could fail due to new buffers could be - * be allocated on on old memory - */ - need_rebind = strcmp(context->colorspace, clip->colorspace_settings.name) != 0; - } - - if (need_rebind) { - int width = ibuf->x, height = ibuf->y; - int need_recreate = 0; - - if (width > GL_MAX_TEXTURE_SIZE || height > GL_MAX_TEXTURE_SIZE) - return 0; - - /* if image resolution changed (e.g. switched to proxy display) texture need to be recreated */ - need_recreate = context->image_width != ibuf->x || context->image_height != ibuf->y; - - if (context->texture_ibuf && need_recreate) { - glDeleteTextures(1, &context->texture); - context->texture_allocated = 0; - } - - if (need_recreate || !context->texture_allocated) { - /* texture doesn't exist yet or need to be re-allocated because of changed dimensions */ - int filter = GL_LINEAR; - - /* non-scaled proxy shouldn;t use diltering */ - if ((clip->flag & MCLIP_USE_PROXY) == 0 || - ELEM(sc->user.render_size, MCLIP_PROXY_RENDER_SIZE_FULL, MCLIP_PROXY_RENDER_SIZE_100)) - { - filter = GL_NEAREST; - } - - glGenTextures(1, &context->texture); - glBindTexture(GL_TEXTURE_2D, context->texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - } - else { - /* if texture doesn't need to be reallocated itself, just bind it so - * loading of image will happen to a proper texture */ - glBindTexture(GL_TEXTURE_2D, context->texture); - } - - if (display_buffer) - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); - - /* store settings */ - context->texture_allocated = 1; - context->display_buffer = display_buffer; - context->texture_ibuf = ibuf; - context->image_width = ibuf->x; - context->image_height = ibuf->y; - context->framenr = sc->user.framenr; - context->render_size = sc->user.render_size; - context->render_flag = sc->user.render_flag; - context->start_frame = clip->start_frame; - context->frame_offset = clip->frame_offset; - - BLI_strncpy(context->colorspace, clip->colorspace_settings.name, sizeof(context->colorspace)); - } - else { - /* displaying exactly the same image which was loaded t oa texture, - * just bint texture in this case */ - glBindTexture(GL_TEXTURE_2D, context->texture); - } - - glEnable(GL_TEXTURE_2D); - - return TRUE; -} - -void ED_space_clip_unload_movieclip_buffer(SpaceClip *sc) -{ - SpaceClipDrawContext *context = sc->draw_context; - - glBindTexture(GL_TEXTURE_2D, context->last_texture); - glDisable(GL_TEXTURE_2D); -} - -void ED_space_clip_free_texture_buffer(SpaceClip *sc) -{ - SpaceClipDrawContext *context = sc->draw_context; - - if (context) { - glDeleteTextures(1, &context->texture); - - MEM_freeN(context); - } -} - /* ******** pre-fetching functions ******** */ typedef struct PrefetchJob { diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c index ced19020034..64b643f8a58 100644 --- a/source/blender/editors/space_clip/space_clip.c +++ b/source/blender/editors/space_clip/space_clip.c @@ -327,8 +327,6 @@ static void clip_free(SpaceLink *sl) if (sc->scopes.track_search) IMB_freeImBuf(sc->scopes.track_search); - - ED_space_clip_free_texture_buffer(sc); } /* spacetype; init callback */ @@ -348,7 +346,6 @@ static SpaceLink *clip_duplicate(SpaceLink *sl) scn->scopes.track_search = NULL; scn->scopes.track_preview = NULL; scn->scopes.ok = FALSE; - scn->draw_context = NULL; return (SpaceLink *)scn; } diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c index a413eb47140..5e5b2ece8c9 100644 --- a/source/blender/editors/space_node/drawnode.c +++ b/source/blender/editors/space_node/drawnode.c @@ -2872,10 +2872,57 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr, } } +static void std_node_socket_interface_draw(bContext *UNUSED(C), uiLayout *layout, PointerRNA *ptr) +{ + bNodeSocket *sock = ptr->data; + int type = sock->typeinfo->type; + /*int subtype = sock->typeinfo->subtype;*/ + + switch (type) { + case SOCK_FLOAT: { + uiLayout *row; + uiItemR(layout, ptr, "default_value", 0, NULL, 0); + row = uiLayoutRow(layout, true); + uiItemR(row, ptr, "min_value", 0, "min", 0); + uiItemR(row, ptr, "max_value", 0, "max", 0); + break; + } + case SOCK_INT: { + uiLayout *row; + uiItemR(layout, ptr, "default_value", 0, NULL, 0); + row = uiLayoutRow(layout, true); + uiItemR(row, ptr, "min_value", 0, "min", 0); + uiItemR(row, ptr, "max_value", 0, "max", 0); + break; + } + case SOCK_BOOLEAN: { + uiItemR(layout, ptr, "default_value", 0, NULL, 0); + break; + } + case SOCK_VECTOR: { + uiLayout *row; + uiItemR(layout, ptr, "default_value", UI_ITEM_R_EXPAND, NULL, 0); + row = uiLayoutRow(layout, true); + uiItemR(row, ptr, "min_value", 0, "min", 0); + uiItemR(row, ptr, "max_value", 0, "max", 0); + break; + } + case SOCK_RGBA: { + uiItemR(layout, ptr, "default_value", 0, NULL, 0); + break; + } + case SOCK_STRING: { + uiItemR(layout, ptr, "default_value", 0, NULL, 0); + break; + } + } +} + void ED_init_standard_node_socket_type(bNodeSocketType *stype) { stype->draw = std_node_socket_draw; stype->draw_color = std_node_socket_draw_color; + stype->interface_draw = std_node_socket_interface_draw; stype->interface_draw_color = std_node_socket_interface_draw_color; } diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c index c74c160080c..cba807a436f 100644 --- a/source/blender/editors/space_node/node_edit.c +++ b/source/blender/editors/space_node/node_edit.c @@ -115,7 +115,7 @@ static void compo_tag_output_nodes(bNodeTree *nodetree, int recalc_flags) if (recalc_flags & COM_RECALC_COMPOSITE) node->flag |= NODE_DO_OUTPUT_RECALC; } - else if (node->type == CMP_NODE_VIEWER) { + else if (node->type == CMP_NODE_VIEWER || node->type == CMP_NODE_SPLITVIEWER) { if (recalc_flags & COM_RECALC_VIEWER) node->flag |= NODE_DO_OUTPUT_RECALC; } @@ -2364,7 +2364,7 @@ static int node_shader_script_update_exec(bContext *C, wmOperator *op) RE_engine_free(engine); - return (found)? OPERATOR_FINISHED: OPERATOR_CANCELLED; + return (found) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } void NODE_OT_shader_script_update(wmOperatorType *ot) diff --git a/source/blender/editors/space_node/node_select.c b/source/blender/editors/space_node/node_select.c index cdb89a66867..62537fb713f 100644 --- a/source/blender/editors/space_node/node_select.c +++ b/source/blender/editors/space_node/node_select.c @@ -823,9 +823,10 @@ static int node_select_same_type_step_exec(bContext *C, wmOperator *op) /* is note outside view? */ if (active->totr.xmax < ar->v2d.cur.xmin || active->totr.xmin > ar->v2d.cur.xmax || - active->totr.ymax < ar->v2d.cur.ymin || active->totr.ymin > ar->v2d.cur.ymax) - space_node_view_flag(C, snode, CTX_wm_region(C), NODE_SELECT); - + active->totr.ymax < ar->v2d.cur.ymin || active->totr.ymin > ar->v2d.cur.ymax) + { + space_node_view_flag(C, snode, CTX_wm_region(C), NODE_SELECT); + } } if (node_array) diff --git a/source/blender/editors/space_sequencer/sequencer_draw.c b/source/blender/editors/space_sequencer/sequencer_draw.c index 1a4d461c3c1..3c2c715efc2 100644 --- a/source/blender/editors/space_sequencer/sequencer_draw.c +++ b/source/blender/editors/space_sequencer/sequencer_draw.c @@ -1050,6 +1050,17 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq /* setting up the view - actual drawing starts here */ UI_view2d_view_ortho(v2d); + /* only draw alpha for main buffer */ + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { + if (sseq->flag & SEQ_USE_ALPHA) { + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + + fdrawcheckerboard(v2d->tot.xmin, v2d->tot.ymin, v2d->tot.xmax, v2d->tot.ymax); + glColor4f(1.0, 1.0, 1.0, 1.0); + } + } + last_texid = glaGetOneInteger(GL_TEXTURE_2D); glEnable(GL_TEXTURE_2D); glGenTextures(1, (GLuint *)&texid); @@ -1061,14 +1072,6 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, ibuf->x, ibuf->y, 0, GL_RGBA, GL_UNSIGNED_BYTE, display_buffer); - /* only draw alpha for main buffer */ - if (sseq->mainb == SEQ_DRAW_IMG_IMBUF) { - if (sseq->flag & SEQ_USE_ALPHA) { - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - } - } - glBegin(GL_QUADS); if (draw_overlay) { @@ -1100,7 +1103,7 @@ void draw_image_seq(const bContext *C, Scene *scene, ARegion *ar, SpaceSeq *sseq glEnd(); glBindTexture(GL_TEXTURE_2D, last_texid); glDisable(GL_TEXTURE_2D); - if (sseq->flag & SEQ_USE_ALPHA) + if (sseq->mainb == SEQ_DRAW_IMG_IMBUF && sseq->flag & SEQ_USE_ALPHA) glDisable(GL_BLEND); glDeleteTextures(1, &texid); diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 8eae1571933..265fef0f59b 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -37,6 +37,7 @@ #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_meta_types.h" +#include "DNA_rigidbody_types.h" #include "DNA_scene_types.h" #include "DNA_smoke_types.h" #include "DNA_world_types.h" @@ -2660,9 +2661,9 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS unsigned char col[4] = {0, 0, 0, 255}; /* color of the text to draw */ float area; /* area of the face */ float grid = unit->system ? unit->scale_length : v3d->grid; - const int do_split = unit->flag & USER_UNIT_OPT_SPLIT; - const int do_global = v3d->flag & V3D_GLOBAL_STATS; - const int do_moving = G.moving; + const bool do_split = (unit->flag & USER_UNIT_OPT_SPLIT) != 0; + const bool do_global = (v3d->flag & V3D_GLOBAL_STATS) != 0; + const bool do_moving = G.moving; BMIter iter; int i; @@ -2703,7 +2704,7 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS unit->system, B_UNIT_LENGTH, do_split, false); } else { - sprintf(numstr, conv_float, len_v3v3(v1, v2)); + BLI_snprintf(numstr, sizeof(numstr), conv_float, len_v3v3(v1, v2)); } view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); @@ -2711,6 +2712,57 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS } } + if (me->drawflag & ME_DRAWEXTRA_EDGEANG) { + const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS); + BMEdge *eed; + + UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGEANG, col); + + // invert_m4_m4(ob->imat, ob->obmat); // this is already called + + eed = BM_iter_new(&iter, em->bm, BM_EDGES_OF_MESH, NULL); + for (; eed; eed = BM_iter_step(&iter)) { + BMLoop *l_a, *l_b; + if (BM_edge_loop_pair(eed, &l_a, &l_b)) { + /* draw selected edges, or edges next to selected verts while draging */ + if (BM_elem_flag_test(eed, BM_ELEM_SELECT) || + (do_moving && (BM_elem_flag_test(eed->v1, BM_ELEM_SELECT) || + BM_elem_flag_test(eed->v2, BM_ELEM_SELECT) || + /* special case, this is useful to show when vertes connected to this edge via a + * face are being transformed */ + BM_elem_flag_test(l_a->next->next->v, BM_ELEM_SELECT) || + BM_elem_flag_test(l_a->prev->v, BM_ELEM_SELECT) || + BM_elem_flag_test(l_b->next->next->v, BM_ELEM_SELECT) || + BM_elem_flag_test(l_b->prev->v, BM_ELEM_SELECT) + ))) + { + float angle; + copy_v3_v3(v1, eed->v1->co); + copy_v3_v3(v2, eed->v2->co); + + mid_v3_v3v3(vmid, v1, v2); + + if (do_global) { + float no_a[3]; + float no_b[3]; + copy_v3_v3(no_a, l_a->f->no); + copy_v3_v3(no_b, l_b->f->no); + mul_mat3_m4_v3(ob->imat, no_a); + mul_mat3_m4_v3(ob->imat, no_b); + angle = angle_v3v3(no_a, no_b); + } + else { + angle = angle_normalized_v3v3(l_a->f->no, l_b->f->no); + } + + BLI_snprintf(numstr, sizeof(numstr), "%.3f", is_rad ? angle : RAD2DEGF(angle)); + + view3d_cached_text_draw_add(vmid, numstr, 0, txt_flag, col); + } + } + } + } + if (me->drawflag & ME_DRAWEXTRA_FACEAREA) { /* would be nice to use BM_face_calc_area, but that is for 2d faces * so instead add up tessellation triangle areas */ @@ -2773,7 +2825,7 @@ static void draw_em_measure_stats(View3D *v3d, Object *ob, BMEditMesh *em, UnitS if (me->drawflag & ME_DRAWEXTRA_FACEANG) { BMFace *efa; - int is_rad = unit->system_rotation == USER_UNIT_ROT_RADIANS; + const bool is_rad = (unit->system_rotation == USER_UNIT_ROT_RADIANS); UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); @@ -2846,7 +2898,7 @@ static void draw_em_indices(BMEditMesh *em) UI_GetThemeColor3ubv(TH_DRAWEXTRA_FACEANG, col); BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) { if (BM_elem_flag_test(v, BM_ELEM_SELECT)) { - sprintf(numstr, "%d", i); + BLI_snprintf(numstr, sizeof(numstr), "%d", i); view3d_cached_text_draw_add(v->co, numstr, 0, txt_flag, col); } i++; @@ -2858,7 +2910,7 @@ static void draw_em_indices(BMEditMesh *em) UI_GetThemeColor3ubv(TH_DRAWEXTRA_EDGELEN, col); BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) { if (BM_elem_flag_test(e, BM_ELEM_SELECT)) { - sprintf(numstr, "%d", i); + BLI_snprintf(numstr, sizeof(numstr), "%d", i); mid_v3_v3v3(pos, e->v1->co, e->v2->co); view3d_cached_text_draw_add(pos, numstr, 0, txt_flag, col); } @@ -2872,7 +2924,7 @@ static void draw_em_indices(BMEditMesh *em) BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) { if (BM_elem_flag_test(f, BM_ELEM_SELECT)) { BM_face_calc_center_mean(f, pos); - sprintf(numstr, "%d", i); + BLI_snprintf(numstr, sizeof(numstr), "%d", i); view3d_cached_text_draw_add(pos, numstr, 0, txt_flag, col); } i++; @@ -3091,7 +3143,10 @@ static void draw_em_fancy(Scene *scene, View3D *v3d, RegionView3D *rv3d, draw_dm_vert_normals(em, scene, ob, cageDM); } - if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN | ME_DRAWEXTRA_FACEAREA | ME_DRAWEXTRA_FACEANG)) && + if ((me->drawflag & (ME_DRAWEXTRA_EDGELEN | + ME_DRAWEXTRA_FACEAREA | + ME_DRAWEXTRA_FACEANG | + ME_DRAWEXTRA_EDGEANG)) && !(v3d->flag2 & V3D_RENDER_OVERRIDE)) { draw_em_measure_stats(v3d, ob, em, &scene->unit); @@ -3148,7 +3203,7 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D eWireDrawMode draw_wire = OBDRAW_WIRE_OFF; int /* totvert,*/ totedge, totface; DerivedMesh *dm = mesh_get_derived_final(scene, ob, scene->customdata_mask); - const short is_obact = (ob == OBACT); + const bool is_obact = (ob == OBACT); int draw_flags = (is_obact && paint_facesel_test(ob)) ? DRAW_FACE_SELECT : 0; if (!dm) @@ -4485,15 +4540,15 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv if (part->draw & PART_DRAW_NUM) { if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { - sprintf(val_pos, "%d:%.2f", a, pa_health); + BLI_snprintf(val_pos, sizeof(numstr), "%d:%.2f", a, pa_health); } else { - sprintf(val_pos, "%d", a); + BLI_snprintf(val_pos, sizeof(numstr), "%d", a); } } else { if (a < totpart && (part->draw & PART_DRAW_HEALTH) && (part->phystype == PART_PHYS_BOIDS)) { - sprintf(val_pos, "%.2f", pa_health); + BLI_snprintf(val_pos, sizeof(numstr), "%.2f", pa_health); } } @@ -6368,7 +6423,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short short dtx; char dt; short zbufoff = 0; - const short is_obact = (ob == OBACT); + const bool is_obact = (ob == OBACT); /* only once set now, will be removed too, should become a global standard */ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -6992,6 +7047,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short /* not for sets, duplicators or picking */ if (dflag == 0 && (v3d->flag & V3D_HIDE_HELPLINES) == 0 && (v3d->flag2 & V3D_RENDER_OVERRIDE) == 0) { ListBase *list; + RigidBodyCon *rbc = ob ? ob->rigidbody_constraint : NULL; /* draw hook center and offset line */ if (ob != scene->obedit) draw_hooks(ob); @@ -7077,6 +7133,22 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short BKE_constraints_clear_evalob(cob); } + /* draw rigid body constraint lines */ + if (rbc) { + UI_ThemeColor(TH_WIRE); + setlinestyle(3); + glBegin(GL_LINES); + if (rbc->ob1) { + glVertex3fv(ob->obmat[3]); + glVertex3fv(rbc->ob1->obmat[3]); + } + if (rbc->ob2) { + glVertex3fv(ob->obmat[3]); + glVertex3fv(rbc->ob2->obmat[3]); + } + glEnd(); + setlinestyle(0); + } } free_old_images(); diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index 66047b6e8f4..b6d46f82e6a 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1831,7 +1831,7 @@ static void view3d_draw_bgpic(Scene *scene, ARegion *ar, View3D *v3d, * glaDrawPixelsSafe in some cases, which will end up in misssing * alpha transparency for the background image (sergey) */ - glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_NEAREST, ibuf->rect); + glaDrawPixelsTex(x1, y1, ibuf->x, ibuf->y, GL_UNSIGNED_BYTE, GL_LINEAR, ibuf->rect); glPixelZoom(1.0, 1.0); glPixelTransferf(GL_ALPHA_SCALE, 1.0f); diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c index bea1f9da057..41a3418ada9 100644 --- a/source/blender/editors/transform/transform_manipulator.c +++ b/source/blender/editors/transform/transform_manipulator.c @@ -948,7 +948,6 @@ static void postOrtho(int ortho) static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, int drawflags, int combo) { - GLUquadricObj *qobj; double plane[4]; float matt[4][4]; float size, unitmat[4][4]; @@ -968,9 +967,6 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, glDisable(GL_DEPTH_TEST); unit_m4(unitmat); - qobj = gluNewQuadric(); - gluQuadricDrawStyle(qobj, GLU_FILL); - /* prepare for screen aligned draw */ size = len_v3(rv3d->twmat[0]); glPushMatrix(); @@ -1195,7 +1191,6 @@ static void draw_manipulator_rotate(View3D *v3d, RegionView3D *rv3d, int moving, /* restore */ glLoadMatrixf(rv3d->viewmat); - gluDeleteQuadric(qobj); if (v3d->zbuf) glEnable(GL_DEPTH_TEST); } diff --git a/source/blender/editors/transform/transform_ops.c b/source/blender/editors/transform/transform_ops.c index 60b0c655691..bdfd9df6246 100644 --- a/source/blender/editors/transform/transform_ops.c +++ b/source/blender/editors/transform/transform_ops.c @@ -446,7 +446,9 @@ void Transform_Properties(struct wmOperatorType *ot, int flags) if (flags & P_PROPORTIONAL) { RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", ""); - RNA_def_enum(ot->srna, "proportional_edit_falloff", proportional_falloff_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode"); + prop = RNA_def_enum(ot->srna, "proportional_edit_falloff", proportional_falloff_items, 0, + "Proportional Editing Falloff", "Falloff type for proportional editing mode"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ RNA_def_float(ot->srna, "proportional_size", 1, 0.00001f, FLT_MAX, "Proportional Size", "", 0.001, 100); } diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 840b16a4567..ae1eb62bc18 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -475,7 +475,7 @@ static void codegen_print_uniforms_functions(DynStr *ds, ListBase *nodes) /* create exactly one sampler for each texture */ if (codegen_input_has_texture(input) && input->bindtex) BLI_dynstr_appendf(ds, "uniform %s samp%d;\n", - (input->textype == GPU_TEX2D)? "sampler2D": "sampler2DShadow", + (input->textype == GPU_TEX2D) ? "sampler2D" : "sampler2DShadow", input->texid); } else if (input->source == GPU_SOURCE_BUILTIN) { diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c index 33402426b62..b772507e0cc 100644 --- a/source/blender/gpu/intern/gpu_draw.c +++ b/source/blender/gpu/intern/gpu_draw.c @@ -1295,7 +1295,7 @@ void GPU_begin_object_materials(View3D *v3d, RegionView3D *rv3d, Scene *scene, O GMS.gob = ob; GMS.gscene = scene; - GMS.totmat= use_matcap? 1 : ob->totcol+1; /* materials start from 1, default material is 0 */ + GMS.totmat = use_matcap ? 1 : ob->totcol + 1; /* materials start from 1, default material is 0 */ GMS.glay= (v3d->localvd)? v3d->localvd->lay: v3d->lay; /* keep lamps visible in local view */ GMS.gviewmat= rv3d->viewmat; GMS.gviewinv= rv3d->viewinv; diff --git a/source/blender/gpu/intern/gpu_extensions.c b/source/blender/gpu/intern/gpu_extensions.c index c455e8f7642..e8d28877043 100644 --- a/source/blender/gpu/intern/gpu_extensions.c +++ b/source/blender/gpu/intern/gpu_extensions.c @@ -393,7 +393,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in if (fpixels) { glTexSubImage1D(tex->target, 0, 0, w, format, type, - pixels? pixels: fpixels); + pixels ? pixels : fpixels); if (tex->w > w) GPU_glTexSubImageEmpty(tex->target, format, w, 0, @@ -406,7 +406,7 @@ static GPUTexture *GPU_texture_create_nD(int w, int h, int n, float *fpixels, in if (fpixels) { glTexSubImage2D(tex->target, 0, 0, 0, w, h, - format, type, pixels? pixels: fpixels); + format, type, pixels ? pixels : fpixels); if (tex->w > w) GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w-w, tex->h); diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 4fc04175bba..147d002475b 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -93,7 +93,7 @@ void hsv_to_rgb(vec4 hsv, out vec4 outcol) float srgb_to_linearrgb(float c) { if(c < 0.04045) - return (c < 0.0)? 0.0: c * (1.0/12.92); + return (c < 0.0) ? 0.0: c * (1.0 / 12.92); else return pow((c + 0.055)*(1.0/1.055), 2.4); } @@ -101,7 +101,7 @@ float srgb_to_linearrgb(float c) float linearrgb_to_srgb(float c) { if(c < 0.0031308) - return (c < 0.0)? 0.0: c * 12.92; + return (c < 0.0) ? 0.0: c * 12.92; else return 1.055 * pow(c, 1.0/2.4) - 0.055; } @@ -2098,7 +2098,7 @@ void node_add_shader(vec4 shader1, vec4 shader2, out vec4 shader) void node_fresnel(float ior, vec3 N, vec3 I, out float result) { float eta = max(ior, 0.00001); - result = fresnel_dielectric(I, N, eta); //backfacing()? 1.0/eta: eta); + result = fresnel_dielectric(I, N, eta); //backfacing() ? 1.0/eta: eta); } /* geometry */ diff --git a/source/blender/gpu/shaders/gpu_shader_simple_frag.glsl b/source/blender/gpu/shaders/gpu_shader_simple_frag.glsl index 9610e0cf5aa..94c73d9e248 100644 --- a/source/blender/gpu/shaders/gpu_shader_simple_frag.glsl +++ b/source/blender/gpu/shaders/gpu_shader_simple_frag.glsl @@ -70,7 +70,7 @@ void main() #ifndef NO_SPECULAR /* view vector computation, depends on orthographics or perspective */ - vec3 V = (gl_ProjectionMatrix[3][3] == 0.0)? normalize(varying_position): vec3(0.0, 0.0, -1.0); + vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? normalize(varying_position): vec3(0.0, 0.0, -1.0); #endif for (int i = 0; i < NUM_SCENE_LIGHTS; i++) { diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h index b981390582e..473bd7d0c7a 100644 --- a/source/blender/imbuf/IMB_colormanagement.h +++ b/source/blender/imbuf/IMB_colormanagement.h @@ -148,6 +148,14 @@ void IMB_colormanagement_processor_apply(struct ColormanageProcessor *cm_process int channels, int predivide); void IMB_colormanagement_processor_free(struct ColormanageProcessor *cm_processor); +/* ** OpenGL drawing routines using GLSL for color space transform ** */ + +int IMB_coloemanagement_setup_glsl_draw(const struct ColorManagedViewSettings *view_settings, + const struct ColorManagedDisplaySettings *display_settings); + +int IMB_coloemanagement_setup_glsl_draw_from_ctx(const struct bContext *C); +void IMB_coloemanagement_finish_glsl_draw(void); + /* Roles */ enum { COLOR_ROLE_SCENE_LINEAR = 0, diff --git a/source/blender/imbuf/intern/IMB_indexer.h b/source/blender/imbuf/intern/IMB_indexer.h index 64ec658f0db..96f7a68d669 100644 --- a/source/blender/imbuf/intern/IMB_indexer.h +++ b/source/blender/imbuf/intern/IMB_indexer.h @@ -81,7 +81,7 @@ typedef struct anim_index_builder { struct anim_index_entry *entry); } anim_index_builder; -anim_index_builder * IMB_index_builder_create(const char *name); +anim_index_builder *IMB_index_builder_create(const char *name); void IMB_index_builder_add_entry( anim_index_builder * fp, int frameno, unsigned long long seek_pos, @@ -118,7 +118,7 @@ void IMB_free_indices(struct anim *anim); struct anim *IMB_anim_open_proxy( struct anim *anim, IMB_Proxy_Size preview_size); -struct anim_index * IMB_anim_open_index( +struct anim_index *IMB_anim_open_index( struct anim *anim, IMB_Timecode_Type tc); int IMB_proxy_size_to_array_index(IMB_Proxy_Size pr_size); diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c index 65a3db839a9..95f67b9b21d 100644 --- a/source/blender/imbuf/intern/colormanagement.c +++ b/source/blender/imbuf/intern/colormanagement.c @@ -102,6 +102,19 @@ typedef struct ColormanageProcessor { int is_data_result; } ColormanageProcessor; +static struct global_glsl_state { + /* Actual processor used for GLSL baked LUTs. */ + OCIO_ConstProcessorRcPtr *processor; + + /* Settings of processor for comparison. */ + char view[MAX_COLORSPACE_NAME]; + char display[MAX_COLORSPACE_NAME]; + float exposure, gamma; + + /* Container for GLSL state needed for OCIO module. */ + struct OCIO_GLSLDrawState *ocio_glsl_state; +} global_glsl_state; + /*********************** Color managed cache *************************/ /* Cache Implementation Notes @@ -607,6 +620,12 @@ void colormanagement_init(void) void colormanagement_exit(void) { + if (global_glsl_state.processor) + OCIO_processorRelease(global_glsl_state.processor); + + if (global_glsl_state.ocio_glsl_state) + OCIO_freeOGLState(global_glsl_state.ocio_glsl_state); + colormanage_free_config(); } @@ -1876,7 +1895,7 @@ unsigned char *IMB_display_buffer_acquire(ImBuf *ibuf, const ColorManagedViewSet /* early out: no float buffer and byte buffer is already in display space, * let's just use if */ - if (ibuf->rect_float == NULL && ibuf->rect_colorspace) { + if (ibuf->rect_float == NULL && ibuf->rect_colorspace && ibuf->channels == 4) { if (is_ibuf_rect_in_display_space(ibuf, applied_view_settings, display_settings)) return (unsigned char *) ibuf->rect; } @@ -2691,3 +2710,87 @@ void IMB_colormanagement_processor_free(ColormanageProcessor *cm_processor) MEM_freeN(cm_processor); } + +/* **** OpenGL drawing routines using GLSL for color space transform ***** */ + +static bool check_glsl_display_processor_changed(const ColorManagedViewSettings *view_settings, + const ColorManagedDisplaySettings *display_settings) +{ + return !(global_glsl_state.exposure == view_settings->exposure && + global_glsl_state.gamma == view_settings->gamma && + STREQ(global_glsl_state.view, view_settings->view_transform) && + STREQ(global_glsl_state.display, display_settings->display_device)); +} + +static void update_glsl_display_processor(const ColorManagedViewSettings *view_settings, + const ColorManagedDisplaySettings *display_settings) +{ + /* Update state if there's no processor yet or + * processor settings has been changed. + */ + if (global_glsl_state.processor == NULL || + check_glsl_display_processor_changed(view_settings, display_settings)) + { + /* Store settings of processor for further comparison. */ + strcpy(global_glsl_state.view, view_settings->view_transform); + strcpy(global_glsl_state.display, display_settings->display_device); + global_glsl_state.exposure = view_settings->exposure; + global_glsl_state.gamma = view_settings->gamma; + + /* Free old processor, if any. */ + if (global_glsl_state.processor) + OCIO_processorRelease(global_glsl_state.processor); + + /* We're using display OCIO processor, no RGB curves yet. */ + global_glsl_state.processor = + create_display_buffer_processor(global_glsl_state.view, + global_glsl_state.display, + global_glsl_state.exposure, + global_glsl_state.gamma); + } +} + +int IMB_coloemanagement_setup_glsl_draw(const ColorManagedViewSettings *view_settings, + const ColorManagedDisplaySettings *display_settings) +{ + ColorManagedViewSettings default_view_settings; + const ColorManagedViewSettings *applied_view_settings; + + if (view_settings) { + applied_view_settings = view_settings; + } + else { + /* if no view settings were specified, use default display transformation + * this happens for images which don't want to be displayed with render settings + */ + + init_default_view_settings(display_settings, &default_view_settings); + applied_view_settings = &default_view_settings; + } + + /* RGB curves mapping is not supported on GPU yet. */ + if (applied_view_settings->flag & COLORMANAGE_VIEW_USE_CURVES) + return FALSE; + + /* Make sure OCIO processor is up-to-date. */ + update_glsl_display_processor(applied_view_settings, display_settings); + + OCIO_setupGLSLDraw(&global_glsl_state.ocio_glsl_state, global_glsl_state.processor); + + return TRUE; +} + +int IMB_coloemanagement_setup_glsl_draw_from_ctx(const bContext *C) +{ + ColorManagedViewSettings *view_settings; + ColorManagedDisplaySettings *display_settings; + + display_transform_get_from_ctx(C, &view_settings, &display_settings); + + return IMB_coloemanagement_setup_glsl_draw(view_settings, display_settings); +} + +void IMB_coloemanagement_finish_glsl_draw(void) +{ + OCIO_finishGLSLDraw(global_glsl_state.ocio_glsl_state); +} diff --git a/source/blender/imbuf/intern/dds/DirectDrawSurface.h b/source/blender/imbuf/intern/dds/DirectDrawSurface.h index 11e6d4a5708..3d308ba1ff1 100644 --- a/source/blender/imbuf/intern/dds/DirectDrawSurface.h +++ b/source/blender/imbuf/intern/dds/DirectDrawSurface.h @@ -171,9 +171,9 @@ public: void setHasAlphaFlag(bool b); void setUserVersion(int version); - void mipmap(Image * img, uint f, uint m); + void mipmap(Image *img, uint f, uint m); void *readData(uint &size); - // void mipmap(FloatImage * img, uint f, uint m); + // void mipmap(FloatImage *img, uint f, uint m); void printInfo() const; diff --git a/source/blender/imbuf/intern/dds/Image.h b/source/blender/imbuf/intern/dds/Image.h index 81074fba6b7..658f01deaec 100644 --- a/source/blender/imbuf/intern/dds/Image.h +++ b/source/blender/imbuf/intern/dds/Image.h @@ -56,9 +56,9 @@ public: void allocate(uint w, uint h); #if 0 - bool load(const char * name); + bool load(const char *name); - void wrap(void * data, uint w, uint h); + void wrap(void *data, uint w, uint h); void unwrap(); #endif diff --git a/source/blender/imbuf/intern/dds/PixelFormat.h b/source/blender/imbuf/intern/dds/PixelFormat.h index 2bb1864e49d..e841e696833 100644 --- a/source/blender/imbuf/intern/dds/PixelFormat.h +++ b/source/blender/imbuf/intern/dds/PixelFormat.h @@ -80,7 +80,7 @@ } // Get pixel component shift and size given its mask. - inline void maskShiftAndSize(uint mask, uint * shift, uint * size) + inline void maskShiftAndSize(uint mask, uint *shift, uint *size) { if (!mask) { *shift = 0; diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c index 958070c1479..79bf9eba1cc 100644 --- a/source/blender/imbuf/intern/rectop.c +++ b/source/blender/imbuf/intern/rectop.c @@ -138,7 +138,7 @@ static void blend_color_add_alpha(char cp[4], const char cp1[4], const char cp2[ cp[0] = cp1[0]; cp[1] = cp1[1]; cp[2] = cp1[2]; - cp[3] = (temp > 255)? 255 : ((temp < 0) ? 0 : temp); + cp[3] = (temp > 255) ? 255 : ((temp < 0) ? 0 : temp); } diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h index 9103914c3e7..875e01f8037 100644 --- a/source/blender/makesdna/DNA_ID.h +++ b/source/blender/makesdna/DNA_ID.h @@ -225,7 +225,7 @@ typedef struct PreviewImage { /* fluidsim Ipo */ #define ID_FLUIDSIM MAKE_ID2('F', 'S') -#define ID_REAL_USERS(id) (((ID *)id)->us - ((((ID *)id)->flag & LIB_FAKEUSER) ? 1:0)) +#define ID_REAL_USERS(id) (((ID *)id)->us - ((((ID *)id)->flag & LIB_FAKEUSER) ? 1 : 0)) #define ID_CHECK_UNDO(id) ((GS((id)->name) != ID_SCR) && (GS((id)->name) != ID_WM)) diff --git a/source/blender/makesdna/DNA_brush_types.h b/source/blender/makesdna/DNA_brush_types.h index 0c38adb3c83..11dd68bb11b 100644 --- a/source/blender/makesdna/DNA_brush_types.h +++ b/source/blender/makesdna/DNA_brush_types.h @@ -105,6 +105,9 @@ typedef struct Brush { float add_col[3]; float sub_col[3]; + + int stencil_pos[2]; + int stencil_dimension[2]; } Brush; /* Brush.flag */ @@ -141,8 +144,7 @@ typedef enum BrushFlags { /* temporary flag which sets up automatically for correct brush * drawing when inverted modal operator is running */ BRUSH_INVERTED = (1 << 29), - BRUSH_ABSOLUTE_JITTER = (1 << 30), - BRUSH_USE_MASK = (1 << 31) + BRUSH_ABSOLUTE_JITTER = (1 << 30) } BrushFlags; /* Brush.sculpt_tool */ diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index df8b423fcad..85bb58a2017 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -199,9 +199,10 @@ typedef struct TFace { #define ME_DRAWEXTRA_EDGELEN (1 << 10) #define ME_DRAWEXTRA_FACEAREA (1 << 11) #define ME_DRAWEXTRA_FACEANG (1 << 12) +#define ME_DRAWEXTRA_EDGEANG (1 << 13) /* debug only option */ -#define ME_DRAWEXTRA_INDICES (1 << 13) +#define ME_DRAWEXTRA_INDICES (1 << 14) #define ME_DRAW_FREESTYLE_EDGE (1 << 14) #define ME_DRAW_FREESTYLE_FACE (1 << 15) diff --git a/source/blender/makesdna/DNA_sequence_types.h b/source/blender/makesdna/DNA_sequence_types.h index 455350d8310..d9057c45380 100644 --- a/source/blender/makesdna/DNA_sequence_types.h +++ b/source/blender/makesdna/DNA_sequence_types.h @@ -314,7 +314,7 @@ typedef struct SequencerScopes { /* SpeedControlVars->flags */ #define SEQ_SPEED_INTEGRATE 1 -#define SEQ_SPEED_BLEND 2 +/* #define SEQ_SPEED_BLEND 2 */ /* DEPRECATED */ #define SEQ_SPEED_COMPRESS_IPO_Y 4 /* ***************** SEQUENCE ****************** */ diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h index 1bc858f59f4..02316461d95 100644 --- a/source/blender/makesdna/DNA_space_types.h +++ b/source/blender/makesdna/DNA_space_types.h @@ -1073,8 +1073,6 @@ typedef struct SpaceClip { /* grease pencil */ short gpencil_src, pad2; - void *draw_context; - int around, pad4; /* pivot point for transforms */ MaskSpaceInfo mask_info; diff --git a/source/blender/makesdna/DNA_texture_types.h b/source/blender/makesdna/DNA_texture_types.h index afb2ac74d99..0b6e5f9c7bb 100644 --- a/source/blender/makesdna/DNA_texture_types.h +++ b/source/blender/makesdna/DNA_texture_types.h @@ -500,6 +500,7 @@ typedef struct ColorMapping { #define MTEX_MAP_MODE_3D 2 #define MTEX_MAP_MODE_AREA 3 #define MTEX_MAP_MODE_RANDOM 4 +#define MTEX_MAP_MODE_STENCIL 5 /* **************** EnvMap ********************* */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 1d7658d974e..a68d702594f 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -234,7 +234,7 @@ typedef struct ThemeSpace { 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 extra_edge_len[4], extra_face_angle[4], extra_face_area[4], pad3[4]; + char extra_edge_len[4], extra_edge_angle[4], extra_face_angle[4], extra_face_area[4]; char normal[4]; char vertex_normal[4]; char bone_solid[4], bone_pose[4], bone_pose_active[4]; diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c index 6fc4ab33ad1..bcab2b6a58a 100644 --- a/source/blender/makesrna/intern/makesrna.c +++ b/source/blender/makesrna/intern/makesrna.c @@ -47,18 +47,6 @@ # endif #endif -/* so we can use __func__ everywhere */ -#if defined(_MSC_VER) -# define __func__ __FUNCTION__ -#endif - -/* copied from BLI_utildefines.h ugh */ -#ifdef __GNUC__ -# define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) -#else -# define UNUSED(x) x -#endif - /* Replace if different */ #define TMP_EXT ".tmp" diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c index b9ee9b6ad1c..68a5ac5f639 100644 --- a/source/blender/makesrna/intern/rna_access.c +++ b/source/blender/makesrna/intern/rna_access.c @@ -6194,8 +6194,8 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) int *array_a, *array_b; int equals; - array_a = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_a; - array_b = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_b; + array_a = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals") : fixed_a; + array_b = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals") : fixed_b; RNA_property_boolean_get_array(a, prop, array_a); RNA_property_boolean_get_array(b, prop, array_b); @@ -6220,8 +6220,8 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) int *array_a, *array_b; int equals; - array_a = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_a; - array_b = (len > 16)? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_b; + array_a = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_a; + array_b = (len > 16) ? MEM_callocN(sizeof(int) * len, "RNA equals"): fixed_b; RNA_property_int_get_array(a, prop, array_a); RNA_property_int_get_array(b, prop, array_b); @@ -6246,8 +6246,8 @@ int RNA_property_equals(PointerRNA *a, PointerRNA *b, PropertyRNA *prop) float *array_a, *array_b; int equals; - array_a = (len > 16)? MEM_callocN(sizeof(float) * len, "RNA equals"): fixed_a; - array_b = (len > 16)? MEM_callocN(sizeof(float) * len, "RNA equals"): fixed_b; + array_a = (len > 16) ? MEM_callocN(sizeof(float) * len, "RNA equals") : fixed_a; + array_b = (len > 16) ? MEM_callocN(sizeof(float) * len, "RNA equals") : fixed_b; RNA_property_float_get_array(a, prop, array_a); RNA_property_float_get_array(b, prop, array_b); diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index de68c4d19d9..8946274fc38 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -145,9 +145,10 @@ static int rna_SculptToolCapabilities_has_normal_weight_get(PointerRNA *ptr) static int rna_BrushCapabilities_has_overlay_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; - return ELEM(br->mtex.brush_map_mode, + return ELEM3(br->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, - MTEX_MAP_MODE_TILED); + MTEX_MAP_MODE_TILED, + MTEX_MAP_MODE_STENCIL); } static int rna_SculptToolCapabilities_has_persistence_get(PointerRNA *ptr) @@ -237,10 +238,11 @@ static int rna_SculptToolCapabilities_has_strength_get(PointerRNA *ptr) static int rna_BrushCapabilities_has_texture_angle_get(PointerRNA *ptr) { Brush *br = (Brush *)ptr->data; - return ELEM3(br->mtex.brush_map_mode, + return ELEM4(br->mtex.brush_map_mode, MTEX_MAP_MODE_VIEW, MTEX_MAP_MODE_AREA, - MTEX_MAP_MODE_TILED); + MTEX_MAP_MODE_TILED, + MTEX_MAP_MODE_STENCIL); } static int rna_BrushCapabilities_has_texture_angle_source_get(PointerRNA *ptr) @@ -433,6 +435,7 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna) {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""}, {MTEX_MAP_MODE_RANDOM, "RANDOM", 0, "Random", ""}, + {MTEX_MAP_MODE_STENCIL, "STENCIL", 0, "Stencil", ""}, {0, NULL, 0, NULL, NULL} }; @@ -441,6 +444,7 @@ static void rna_def_brush_texture_slot(BlenderRNA *brna) {MTEX_MAP_MODE_TILED, "TILED", 0, "Tiled", ""}, {MTEX_MAP_MODE_3D, "3D", 0, "3D", ""}, {MTEX_MAP_MODE_RANDOM, "RANDOM", 0, "Random", ""}, + {MTEX_MAP_MODE_STENCIL, "STENCIL", 0, "Stencil", ""}, {0, NULL, 0, NULL, NULL} }; @@ -551,7 +555,7 @@ static void rna_def_brush(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static EnumPropertyItem brush_stroke_method_items[] = { + static EnumPropertyItem sculpt_stroke_method_items[] = { {0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"}, {BRUSH_RESTORE_MESH, "DRAG_DOT", 0, "Drag Dot", "Allows a single dot to be carefully positioned"}, {BRUSH_SPACE, "SPACE", 0, "Space", "Limit brush application to the distance specified by spacing"}, @@ -560,6 +564,13 @@ static void rna_def_brush(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; + static EnumPropertyItem brush_stroke_method_items[] = { + {0, "DOTS", 0, "Dots", "Apply paint on each mouse move step"}, + {BRUSH_SPACE, "SPACE", 0, "Space", "Limit brush application to the distance specified by spacing"}, + {BRUSH_AIRBRUSH, "AIRBRUSH", 0, "Airbrush", "Keep applying paint effect while holding mouse (spray)"}, + {0, NULL, 0, NULL, NULL} + }; + static EnumPropertyItem texture_angle_source_items[] = { {0, "USER", 0, "User", "Rotate the brush texture by given angle"}, {BRUSH_RAKE, "RAKE", 0, "Rake", "Rotate the brush texture to match the stroke direction"}, @@ -628,6 +639,12 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Stroke Method", ""); RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "sculpt_stroke_method", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); + RNA_def_property_enum_items(prop, sculpt_stroke_method_items); + RNA_def_property_ui_text(prop, "Stroke Method", ""); + RNA_def_property_update(prop, 0, "rna_Brush_update"); + prop = RNA_def_property(srna, "texture_angle_source_random", PROP_ENUM, PROP_NONE); RNA_def_property_enum_bitflag_sdna(prop, NULL, "flag"); RNA_def_property_enum_items(prop, texture_angle_source_items); @@ -914,11 +931,6 @@ static void rna_def_brush(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Restore Mesh", "Allow a single dot to be carefully positioned"); RNA_def_property_update(prop, 0, "rna_Brush_update"); - prop = RNA_def_property(srna, "use_mask", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_USE_MASK); - RNA_def_property_ui_text(prop, "Mask Texture", "Use a texture as mask for the brush"); - RNA_def_property_update(prop, 0, "rna_Brush_update"); - /* only for projection paint, TODO, other paint modes */ prop = RNA_def_property(srna, "use_alpha", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", BRUSH_LOCK_ALPHA); diff --git a/source/blender/makesrna/intern/rna_mask.c b/source/blender/makesrna/intern/rna_mask.c index 72b0030ee23..c47b81ec9ca 100644 --- a/source/blender/makesrna/intern/rna_mask.c +++ b/source/blender/makesrna/intern/rna_mask.c @@ -35,6 +35,8 @@ #include "DNA_object_types.h" /* SELECT */ #include "DNA_scene_types.h" +#include "BLF_translation.h" + #include "BKE_movieclip.h" #include "BKE_tracking.h" @@ -680,6 +682,7 @@ static void rna_def_mask_layer(BlenderRNA *brna) RNA_def_property_enum_sdna(prop, NULL, "falloff"); RNA_def_property_enum_items(prop, proportional_falloff_curve_only_items); RNA_def_property_ui_text(prop, "Falloff", "Falloff type the feather"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ RNA_def_property_update(prop, NC_MASK | NA_EDITED, NULL); } diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index 13ce4a77153..17519b5baf5 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -734,13 +734,13 @@ static void rna_MeshLoopColorLayer_data_begin(CollectionPropertyIterator *iter, { Mesh *me = rna_mesh(ptr); CustomDataLayer *layer = (CustomDataLayer *)ptr->data; - rna_iterator_array_begin(iter, layer->data, sizeof(MLoopCol), me->totloop, 0, NULL); + rna_iterator_array_begin(iter, layer->data, sizeof(MLoopCol), (me->edit_btmesh) ? 0 : me->totloop, 0, NULL); } static int rna_MeshLoopColorLayer_data_length(PointerRNA *ptr) { Mesh *me = rna_mesh(ptr); - return me->totloop; + return (me->edit_btmesh) ? 0 : me->totloop; } static int rna_MeshLoopColorLayer_active_render_get(PointerRNA *ptr) @@ -2974,6 +2974,12 @@ static void rna_def_mesh(BlenderRNA *brna) "Display selected edge lengths, using global values when set in the transform panel"); RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + prop = RNA_def_property(srna, "show_extra_edge_angle", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWEXTRA_EDGEANG); + RNA_def_property_ui_text(prop, "Edge Angle", + "Display selected edge angle, using global values when set in the transform panel"); + RNA_def_property_update(prop, 0, "rna_Mesh_update_draw"); + prop = RNA_def_property(srna, "show_extra_face_angle", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "drawflag", ME_DRAWEXTRA_FACEANG); RNA_def_property_ui_text(prop, "Face Angles", diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c index 185968ded79..9fcb05a3dc2 100644 --- a/source/blender/makesrna/intern/rna_modifier.c +++ b/source/blender/makesrna/intern/rna_modifier.c @@ -889,6 +889,7 @@ static void rna_def_modifier_warp(BlenderRNA *brna) prop = RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_falloff_items); RNA_def_property_ui_text(prop, "Falloff Type", ""); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "falloff_radius", PROP_FLOAT, PROP_UNSIGNED | PROP_DISTANCE); @@ -2984,6 +2985,7 @@ static void rna_def_modifier_weightvgedit(BlenderRNA *brna) prop = RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, weightvg_edit_falloff_type_items); RNA_def_property_ui_text(prop, "Falloff Type", "How weights are mapped to their new values"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ RNA_def_property_update(prop, 0, "rna_Modifier_update"); prop = RNA_def_property(srna, "use_add", PROP_BOOLEAN, PROP_NONE); @@ -3187,6 +3189,7 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna) prop = RNA_def_property(srna, "falloff_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, weightvg_proximity_falloff_type_items); RNA_def_property_ui_text(prop, "Falloff Type", "How weights are mapped to their new values"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ RNA_def_property_update(prop, 0, "rna_Modifier_update"); /* Common masking properties. */ diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index d8dd9ff3c33..16f63e31353 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -33,6 +33,8 @@ #include "BLI_string.h" #include "BLI_utildefines.h" +#include "BLF_translation.h" + #include "DNA_material_types.h" #include "DNA_mesh_types.h" #include "DNA_node_types.h" @@ -2734,7 +2736,7 @@ static void rna_ShaderNodeScript_bytecode_get(PointerRNA *ptr, char *value) bNode *node = (bNode *)ptr->data; NodeShaderScript *nss = node->storage; - strcpy(value, (nss->bytecode)? nss->bytecode: ""); + strcpy(value, (nss->bytecode) ? nss->bytecode : ""); } static int rna_ShaderNodeScript_bytecode_length(PointerRNA *ptr) @@ -4028,6 +4030,7 @@ static void def_cmp_dilate_erode(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "falloff"); RNA_def_property_enum_items(prop, proportional_falloff_curve_only_items); RNA_def_property_ui_text(prop, "Falloff", "Falloff type the feather"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); } @@ -5662,6 +5665,7 @@ static void def_cmp_keying(StructRNA *srna) RNA_def_property_enum_sdna(prop, NULL, "feather_falloff"); RNA_def_property_enum_items(prop, proportional_falloff_curve_only_items); RNA_def_property_ui_text(prop, "Feather Falloff", "Falloff type the feather"); + RNA_def_property_translation_context(prop, BLF_I18NCONTEXT_ID_CURVE); /* Abusing id_curve :/ */ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); prop = RNA_def_property(srna, "feather_distance", PROP_INT, PROP_NONE); @@ -6058,13 +6062,32 @@ static void rna_def_node_socket_float(BlenderRNA *brna, const char *idname, cons RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); /* socket interface */ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); RNA_def_struct_ui_text(srna, "Float Node Socket Interface", "Floating point number socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueFloat", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype); + RNA_def_property_float_sdna(prop, NULL, "value"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_float_range"); + RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + prop = RNA_def_property(srna, "min_value", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "min"); + RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + prop = RNA_def_property(srna, "max_value", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "max"); + RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); } static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, const char *interface_idname, PropertySubType subtype) @@ -6085,13 +6108,32 @@ static void rna_def_node_socket_int(BlenderRNA *brna, const char *identifier, co RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); /* socket interface */ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); RNA_def_struct_ui_text(srna, "Integer Node Socket Interface", "Integer number socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueInt", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_INT, subtype); + RNA_def_property_int_sdna(prop, NULL, "value"); + RNA_def_property_int_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_int_range"); + RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + prop = RNA_def_property(srna, "min_value", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "min"); + RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + prop = RNA_def_property(srna, "max_value", PROP_INT, PROP_NONE); + RNA_def_property_int_sdna(prop, NULL, "max"); + RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); } static void rna_def_node_socket_bool(BlenderRNA *brna, const char *identifier, const char *interface_idname) @@ -6111,13 +6153,21 @@ static void rna_def_node_socket_bool(BlenderRNA *brna, const char *identifier, c RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); /* socket interface */ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); RNA_def_struct_ui_text(srna, "Boolean Node Socket Interface", "Boolean value socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueBoolean", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "value", 1); + RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); } static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier, const char *interface_idname, PropertySubType subtype) @@ -6138,13 +6188,32 @@ static void rna_def_node_socket_vector(BlenderRNA *brna, const char *identifier, RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); /* socket interface */ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); RNA_def_struct_ui_text(srna, "Vector Node Socket Interface", "3D vector socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueVector", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_FLOAT, subtype); + RNA_def_property_float_sdna(prop, NULL, "value"); + RNA_def_property_float_funcs(prop, NULL, NULL, "rna_NodeSocketStandard_vector_range"); + RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + prop = RNA_def_property(srna, "min_value", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "min"); + RNA_def_property_ui_text(prop, "Minimum Value", "Minimum value"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + prop = RNA_def_property(srna, "max_value", PROP_FLOAT, PROP_NONE); + RNA_def_property_float_sdna(prop, NULL, "max"); + RNA_def_property_ui_text(prop, "Maximum Value", "Maximum value"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); } static void rna_def_node_socket_color(BlenderRNA *brna, const char *identifier, const char *interface_idname) @@ -6164,13 +6233,21 @@ static void rna_def_node_socket_color(BlenderRNA *brna, const char *identifier, RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); /* socket interface */ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); RNA_def_struct_ui_text(srna, "Color Node Socket Interface", "RGBA color socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueRGBA", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_FLOAT, PROP_COLOR); + RNA_def_property_float_sdna(prop, NULL, "value"); + RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); } static void rna_def_node_socket_string(BlenderRNA *brna, const char *identifier, const char *interface_idname) @@ -6190,13 +6267,21 @@ static void rna_def_node_socket_string(BlenderRNA *brna, const char *identifier, RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketStandard_value_update"); RNA_def_property_flag(prop, PROP_CONTEXT_UPDATE); - /* XXX need to reset the from-type here, so subtype subclasses cast correctly! (RNA bug) */ RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); /* socket interface */ srna = RNA_def_struct(brna, interface_idname, "NodeSocketInterfaceStandard"); RNA_def_struct_ui_text(srna, "String Node Socket Interface", "String socket of a node"); RNA_def_struct_sdna(srna, "bNodeSocket"); + + RNA_def_struct_sdna_from(srna, "bNodeSocketValueString", "default_value"); + + prop = RNA_def_property(srna, "default_value", PROP_STRING, PROP_NONE); + RNA_def_property_string_sdna(prop, NULL, "value"); + RNA_def_property_ui_text(prop, "Default Value", "Input value used for unconnected socket"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_NodeSocketInterface_update"); + + RNA_def_struct_sdna_from(srna, "bNodeSocket", NULL); } static void rna_def_node_socket_shader(BlenderRNA *brna, const char *identifier, const char *interface_idname) diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c index 475b3e614c1..ad87bd74292 100644 --- a/source/blender/makesrna/intern/rna_sequencer.c +++ b/source/blender/makesrna/intern/rna_sequencer.c @@ -2144,11 +2144,6 @@ static void rna_def_speed_control(StructRNA *srna) RNA_def_property_ui_text(prop, "Use as speed", "Interpret the value as speed instead of a frame number"); RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); - prop = RNA_def_property(srna, "use_frame_blend", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_sdna(prop, NULL, "flags", SEQ_SPEED_BLEND); - RNA_def_property_ui_text(prop, "Frame Blending", "Blend two frames into the target for a smoother result"); - RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update"); - prop = RNA_def_property(srna, "scale_to_length", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flags", SEQ_SPEED_COMPRESS_IPO_Y); RNA_def_property_ui_text(prop, "Scale to length", "Scale values from 0.0 to 1.0 to target sequence length"); diff --git a/source/blender/makesrna/intern/rna_test.c b/source/blender/makesrna/intern/rna_test.c index 1f5a4ff7f92..22b6f323647 100644 --- a/source/blender/makesrna/intern/rna_test.c +++ b/source/blender/makesrna/intern/rna_test.c @@ -57,12 +57,12 @@ (void)0 #define DEF_GET_SET(type, arr) \ - void rna_Test_ ## arr ## _get(PointerRNA * ptr, type * values) \ + void rna_Test_ ## arr ## _get(PointerRNA *ptr, type * values) \ { \ memcpy(values, arr, sizeof(arr)); \ } \ - \ - void rna_Test_ ## arr ## _set(PointerRNA * ptr, const type * values) \ + \ + void rna_Test_ ## arr ## _set(PointerRNA *ptr, const type * values) \ { \ memcpy(arr, values, sizeof(arr)); \ } \ @@ -73,14 +73,14 @@ { \ return arr ## _len; \ } \ - \ - static int rna_Test_ ## arr ## _set_length(PointerRNA * ptr, int length) \ + \ + static int rna_Test_ ## arr ## _set_length(PointerRNA *ptr, int length) \ { \ if (length > max) \ return 0; \ - \ + \ arr ## _len = length; \ - \ + \ return 1; \ } \ (void)0 diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index b118f5bc970..ebda8b7d33f 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -1475,6 +1475,11 @@ static void rna_def_userdef_theme_space_view3d(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Edge Length Text", ""); RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "extra_edge_angle", PROP_FLOAT, PROP_COLOR_GAMMA); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Edge Angle Text", ""); + RNA_def_property_update(prop, 0, "rna_userdef_update"); + prop = RNA_def_property(srna, "extra_face_angle", PROP_FLOAT, PROP_COLOR_GAMMA); RNA_def_property_array(prop, 3); RNA_def_property_ui_text(prop, "Face Angle Text", ""); diff --git a/source/blender/nodes/NOD_socket.h b/source/blender/nodes/NOD_socket.h index 5f7da1c3f4d..81230456193 100644 --- a/source/blender/nodes/NOD_socket.h +++ b/source/blender/nodes/NOD_socket.h @@ -50,6 +50,7 @@ struct bNodeSocket *node_add_socket_from_template(struct bNodeTree *ntree, struc void node_verify_socket_templates(struct bNodeTree *ntree, struct bNode *node); void node_socket_init_default_value(struct bNodeSocket *sock); +void node_socket_copy_default_value(struct bNodeSocket *to, struct bNodeSocket *from); void register_standard_node_socket_types(void); #endif diff --git a/source/blender/nodes/intern/node_common.c b/source/blender/nodes/intern/node_common.c index 54ffd3cd01c..4e4443f7c3f 100644 --- a/source/blender/nodes/intern/node_common.c +++ b/source/blender/nodes/intern/node_common.c @@ -84,7 +84,7 @@ bNodeSocket *node_group_find_output_socket(bNode *groupnode, const char *identif /* groups display their internal tree name as label */ const char *node_group_label(bNode *node) { - return (node->id)? node->id->name + 2: IFACE_("Missing Datablock"); + return (node->id) ? node->id->name + 2 : IFACE_("Missing Datablock"); } int node_group_poll_instance(bNode *node, bNodeTree *nodetree) @@ -124,6 +124,9 @@ static bNodeSocket *group_verify_socket(bNodeTree *ntree, bNode *gnode, bNodeSoc } if (sock) { strcpy(sock->name, iosock->name); + + if (iosock->typeinfo->interface_verify_socket) + iosock->typeinfo->interface_verify_socket(ntree, iosock, gnode, sock, "interface"); } else { sock = nodeAddSocket(ntree, gnode, in_out, iosock->idname, iosock->identifier, iosock->name); diff --git a/source/blender/nodes/intern/node_socket.c b/source/blender/nodes/intern/node_socket.c index 86a8331e5dd..74d44fe5f53 100644 --- a/source/blender/nodes/intern/node_socket.c +++ b/source/blender/nodes/intern/node_socket.c @@ -260,11 +260,107 @@ void node_socket_init_default_value(bNodeSocket *sock) } } +void node_socket_copy_default_value(bNodeSocket *to, bNodeSocket *from) +{ + /* sanity check */ + if (!STREQ(to->idname, from->idname)) + return; + + /* make sure both exist */ + if (!from->default_value) + return; + node_socket_init_default_value(to); + + switch (from->typeinfo->type) { + case SOCK_FLOAT: { + bNodeSocketValueFloat *toval = to->default_value; + bNodeSocketValueFloat *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *toval = to->default_value; + bNodeSocketValueInt *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_BOOLEAN: { + bNodeSocketValueBoolean *toval = to->default_value; + bNodeSocketValueBoolean *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_VECTOR: { + bNodeSocketValueVector *toval = to->default_value; + bNodeSocketValueVector *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_RGBA: { + bNodeSocketValueRGBA *toval = to->default_value; + bNodeSocketValueRGBA *fromval = from->default_value; + *toval = *fromval; + break; + } + case SOCK_STRING: { + bNodeSocketValueString *toval = to->default_value; + bNodeSocketValueString *fromval = from->default_value; + *toval = *fromval; + break; + } + } +} -static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree), bNodeSocket *UNUSED(stemp), bNode *UNUSED(node), bNodeSocket *sock, const char *UNUSED(data_path)) +static void standard_node_socket_interface_init_socket(bNodeTree *UNUSED(ntree), bNodeSocket *stemp, bNode *UNUSED(node), bNodeSocket *sock, const char *UNUSED(data_path)) { /* initialize the type value */ sock->type = sock->typeinfo->type; + + /* copy default_value settings */ + node_socket_copy_default_value(sock, stemp); +} + +/* copies settings that are not changed for each socket instance */ +static void standard_node_socket_interface_verify_socket(bNodeTree *UNUSED(ntree), bNodeSocket *stemp, bNode *UNUSED(node), bNodeSocket *sock, const char *UNUSED(data_path)) +{ + /* sanity check */ + if (!STREQ(sock->idname, stemp->idname)) + return; + + /* make sure both exist */ + if (!stemp->default_value) + return; + node_socket_init_default_value(sock); + + switch (stemp->typeinfo->type) { + case SOCK_FLOAT: { + bNodeSocketValueFloat *toval = sock->default_value; + bNodeSocketValueFloat *fromval = stemp->default_value; + toval->min = fromval->min; + toval->max = fromval->max; + break; + } + case SOCK_INT: { + bNodeSocketValueInt *toval = sock->default_value; + bNodeSocketValueInt *fromval = stemp->default_value; + toval->min = fromval->min; + toval->max = fromval->max; + break; + } + case SOCK_VECTOR: { + bNodeSocketValueVector *toval = sock->default_value; + bNodeSocketValueVector *fromval = stemp->default_value; + toval->min = fromval->min; + toval->max = fromval->max; + break; + } + } +} + +static void standard_node_socket_interface_from_socket(bNodeTree *UNUSED(ntree), bNodeSocket *stemp, bNode *UNUSED(node), bNodeSocket *sock) +{ + /* initialize settings */ + node_socket_copy_default_value(stemp, sock); } static bNodeSocketType *make_standard_socket_type(int type, int subtype) @@ -300,6 +396,8 @@ static bNodeSocketType *make_standard_socket_type(int type, int subtype) ED_init_standard_node_socket_type(stype); stype->interface_init_socket = standard_node_socket_interface_init_socket; + stype->interface_from_socket = standard_node_socket_interface_from_socket; + stype->interface_verify_socket = standard_node_socket_interface_verify_socket; return stype; } diff --git a/source/blender/nodes/shader/nodes/node_shader_geom.c b/source/blender/nodes/shader/nodes/node_shader_geom.c index 40ba2cca4e5..a99d9b0cf56 100644 --- a/source/blender/nodes/shader/nodes/node_shader_geom.c +++ b/source/blender/nodes/shader/nodes/node_shader_geom.c @@ -116,7 +116,7 @@ static void node_shader_exec_geom(void *data, int UNUSED(thread), bNode *node, b } /* front/back, normal flipping was stored */ - out[GEOM_OUT_FRONTBACK]->vec[0] = (shi->flippednor)? 0.0f: 1.0f; + out[GEOM_OUT_FRONTBACK]->vec[0] = (shi->flippednor) ? 0.0f : 1.0f; } } diff --git a/source/blender/nodes/shader/nodes/node_shader_math.c b/source/blender/nodes/shader/nodes/node_shader_math.c index 31a1501bc3f..c3e2fc54c78 100644 --- a/source/blender/nodes/shader/nodes/node_shader_math.c +++ b/source/blender/nodes/shader/nodes/node_shader_math.c @@ -94,14 +94,14 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode { if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */ /* Can't do the impossible... */ - if ( in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1 ) + if (in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1) out[0]->vec[0] = asin(in[0]->vec[0]); else out[0]->vec[0] = 0.0; } else { /* Can't do the impossible... */ - if ( in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1 ) + if (in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1) out[0]->vec[0] = asin(in[1]->vec[0]); else out[0]->vec[0] = 0.0; @@ -112,14 +112,14 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode { if (in[0]->hasinput || !in[1]->hasinput) { /* This one only takes one input, so we've got to choose. */ /* Can't do the impossible... */ - if ( in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1 ) + if (in[0]->vec[0] <= 1 && in[0]->vec[0] >= -1) out[0]->vec[0] = acos(in[0]->vec[0]); else out[0]->vec[0] = 0.0; } else { /* Can't do the impossible... */ - if ( in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1 ) + if (in[1]->vec[0] <= 1 && in[1]->vec[0] >= -1) out[0]->vec[0] = acos(in[1]->vec[0]); else out[0]->vec[0] = 0.0; @@ -137,7 +137,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode case 10: /* Power */ { /* Only raise negative numbers by full integers */ - if ( in[0]->vec[0] >= 0 ) { + if (in[0]->vec[0] >= 0) { out[0]->vec[0] = pow(in[0]->vec[0], in[1]->vec[0]); } else { @@ -157,7 +157,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode case 11: /* Logarithm */ { /* Don't want any imaginary numbers... */ - if ( in[0]->vec[0] > 0 && in[1]->vec[0] > 0 ) + if (in[0]->vec[0] > 0 && in[1]->vec[0] > 0) out[0]->vec[0] = log(in[0]->vec[0]) / log(in[1]->vec[0]); else out[0]->vec[0] = 0.0; @@ -165,7 +165,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode break; case 12: /* Minimum */ { - if ( in[0]->vec[0] < in[1]->vec[0] ) + if (in[0]->vec[0] < in[1]->vec[0]) out[0]->vec[0] = in[0]->vec[0]; else out[0]->vec[0] = in[1]->vec[0]; @@ -173,7 +173,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode break; case 13: /* Maximum */ { - if ( in[0]->vec[0] > in[1]->vec[0] ) + if (in[0]->vec[0] > in[1]->vec[0]) out[0]->vec[0] = in[0]->vec[0]; else out[0]->vec[0] = in[1]->vec[0]; @@ -182,14 +182,14 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode case 14: /* Round */ { if (in[0]->hasinput || !in[1]->hasinput) /* This one only takes one input, so we've got to choose. */ - out[0]->vec[0] = (in[0]->vec[0]<0)?(int)(in[0]->vec[0] - 0.5f):(int)(in[0]->vec[0] + 0.5f); + out[0]->vec[0] = (in[0]->vec[0] < 0) ? (int)(in[0]->vec[0] - 0.5f) : (int)(in[0]->vec[0] + 0.5f); else - out[0]->vec[0] = (in[1]->vec[0]<0)?(int)(in[1]->vec[0] - 0.5f):(int)(in[1]->vec[0] + 0.5f); + out[0]->vec[0] = (in[1]->vec[0] < 0) ? (int)(in[1]->vec[0] - 0.5f) : (int)(in[1]->vec[0] + 0.5f); } break; case 15: /* Less Than */ { - if ( in[0]->vec[0] < in[1]->vec[0] ) + if (in[0]->vec[0] < in[1]->vec[0]) out[0]->vec[0] = 1.0f; else out[0]->vec[0] = 0.0f; @@ -197,7 +197,7 @@ static void node_shader_exec_math(void *UNUSED(data), int UNUSED(thread), bNode break; case 16: /* Greater Than */ { - if ( in[0]->vec[0] > in[1]->vec[0] ) + if (in[0]->vec[0] > in[1]->vec[0]) out[0]->vec[0] = 1.0f; else out[0]->vec[0] = 0.0f; diff --git a/source/blender/nodes/texture/nodes/node_texture_math.c b/source/blender/nodes/texture/nodes/node_texture_math.c index 499412e750d..03349a57832 100644 --- a/source/blender/nodes/texture/nodes/node_texture_math.c +++ b/source/blender/nodes/texture/nodes/node_texture_math.c @@ -88,7 +88,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor case 7: /* Arc-Sine */ { /* Can't do the impossible... */ - if ( in0 <= 1 && in0 >= -1 ) + if (in0 <= 1 && in0 >= -1) *out= asin(in0); else *out= 0.0; @@ -97,7 +97,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor case 8: /* Arc-Cosine */ { /* Can't do the impossible... */ - if ( in0 <= 1 && in0 >= -1 ) + if (in0 <= 1 && in0 >= -1) *out= acos(in0); else *out= 0.0; @@ -111,7 +111,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor case 10: /* Power */ { /* Only raise negative numbers by full integers */ - if ( in0 >= 0 ) { + if (in0 >= 0) { out[0] = pow(in0, in1); } else { @@ -128,7 +128,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor case 11: /* Logarithm */ { /* Don't want any imaginary numbers... */ - if ( in0 > 0 && in1 > 0 ) + if (in0 > 0 && in1 > 0) *out= log(in0) / log(in1); else *out= 0.0; @@ -136,7 +136,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; case 12: /* Minimum */ { - if ( in0 < in1 ) + if (in0 < in1) *out= in0; else *out= in1; @@ -144,7 +144,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; case 13: /* Maximum */ { - if ( in0 > in1 ) + if (in0 > in1) *out= in0; else *out= in1; @@ -152,13 +152,13 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor break; case 14: /* Round */ { - *out= (in0<0)?(int)(in0 - 0.5f):(int)(in0 + 0.5f); + *out= (in0 < 0) ? (int)(in0 - 0.5f) : (int)(in0 + 0.5f); } break; case 15: /* Less Than */ { - if ( in0 < in1 ) + if (in0 < in1) *out= 1.0f; else *out= 0.0f; @@ -167,7 +167,7 @@ static void valuefn(float *out, TexParams *p, bNode *node, bNodeStack **in, shor case 16: /* Greater Than */ { - if ( in0 > in1 ) + if (in0 > in1) *out= 1.0f; else *out= 0.0f; diff --git a/source/blender/render/intern/source/imagetexture.c b/source/blender/render/intern/source/imagetexture.c index 756fb098882..d822439ed16 100644 --- a/source/blender/render/intern/source/imagetexture.c +++ b/source/blender/render/intern/source/imagetexture.c @@ -119,7 +119,7 @@ int imagewrap(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], TexResul texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f; /* we need to set retval OK, otherwise texture code generates normals itself... */ - retval= texres->nor?3:1; + retval= texres->nor ? 3 : 1; /* quick tests */ if (ibuf==NULL && ima==NULL) @@ -1500,7 +1500,7 @@ int imagewraposa(Tex *tex, Image *ima, ImBuf *ibuf, const float texvec[3], const texres->tin= texres->ta= texres->tr= texres->tg= texres->tb= 0.0f; /* we need to set retval OK, otherwise texture code generates normals itself... */ - retval= texres->nor?3:1; + retval = texres->nor ? 3 : 1; /* quick tests */ if (ibuf==NULL && ima==NULL) diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c index 1450af4ff83..44f91aaafe7 100644 --- a/source/blender/render/intern/source/pipeline.c +++ b/source/blender/render/intern/source/pipeline.c @@ -2460,12 +2460,12 @@ static int do_write_image_or_movie(Render *re, Main *bmain, Scene *scene, bMovie render_time = re->i.lastframetime; re->i.lastframetime = PIL_check_seconds_timer() - re->i.starttime; - BLI_timestr(re->i.lastframetime, name); + BLI_timestr(re->i.lastframetime, name, sizeof(name)); printf(" Time: %s", name); BLI_callback_exec(G.main, NULL, BLI_CB_EVT_RENDER_STATS); - BLI_timestr(re->i.lastframetime - render_time, name); + BLI_timestr(re->i.lastframetime - render_time, name, sizeof(name)); printf(" (Saving: %s)\n", name); fputc('\n', stdout); diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 7152adb4a11..f8cd154df35 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -602,6 +602,13 @@ int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory return TRUE; } +int wm_history_read_exec(bContext *UNUSED(C), wmOperator *UNUSED(op)) +{ + /* TODO, read bookmarks */ + wm_read_history(); + return OPERATOR_FINISHED; +} + int wm_homefile_read_exec(bContext *C, wmOperator *op) { int from_memory = strcmp(op->type->idname, "WM_OT_read_factory_settings") == 0; @@ -637,7 +644,6 @@ void wm_read_history(void) } BLI_file_free_lines(lines); - } static void write_history(void) @@ -950,7 +956,7 @@ void wm_autosave_location(char *filepath) { char pidstr[32]; #ifdef WIN32 - char *savedir; + const char *savedir; #endif BLI_snprintf(pidstr, sizeof(pidstr), "%d.blend", abs(getpid())); diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 532404cf218..193af2f92c6 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -47,6 +47,7 @@ #include "DNA_userdef_types.h" #include "DNA_windowmanager_types.h" +#include "BLI_callbacks.h" #include "BLI_listbase.h" #include "BLI_path_util.h" #include "BLI_string.h" @@ -220,8 +221,17 @@ void WM_init(bContext *C, int argc, const char **argv) #endif /* load last session, uses regular file reading so it has to be in end (after init py etc) */ - if (U.uiflag2 & USER_KEEP_SESSION) + if (U.uiflag2 & USER_KEEP_SESSION) { wm_recover_last_session(C, NULL); + } + else { + /* normally 'wm_homefile_read' will do this, + * however python is not initialized when called from this function. + * + * unlikey any handlers are set but its possible, + * note that recovering the last session does its own callbacks. */ + BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_POST); + } } void WM_init_splash(bContext *C) diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index b27f014ccb3..b4a4e4612e3 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -1906,6 +1906,19 @@ static void WM_OT_save_userpref(wmOperatorType *ot) ot->poll = WM_operator_winactive; } +static void WM_OT_read_history(wmOperatorType *ot) +{ + ot->name = "Reload History File"; + ot->idname = "WM_OT_read_history"; + ot->description = "Reloads history and bookmarks"; + + ot->invoke = WM_operator_confirm; + ot->exec = wm_history_read_exec; + + /* this operator is only used for loading settings from a previous blender install */ + ot->flag = OPTYPE_INTERNAL; +} + static void WM_OT_read_homefile(wmOperatorType *ot) { ot->name = "Reload Start-Up File"; @@ -4043,6 +4056,7 @@ void wm_operatortype_init(void) global_ops_hash = BLI_ghash_str_new("wm_operatortype_init gh"); WM_operatortype_append(WM_OT_window_duplicate); + WM_operatortype_append(WM_OT_read_history); WM_operatortype_append(WM_OT_read_homefile); WM_operatortype_append(WM_OT_read_factory_settings); WM_operatortype_append(WM_OT_save_homefile); diff --git a/source/blender/windowmanager/wm_files.h b/source/blender/windowmanager/wm_files.h index fe007e7f52f..9fda6801925 100644 --- a/source/blender/windowmanager/wm_files.h +++ b/source/blender/windowmanager/wm_files.h @@ -33,6 +33,7 @@ void wm_read_history(void); int wm_file_write(struct bContext *C, const char *target, int fileflags, struct ReportList *reports); +int wm_history_read_exec(bContext *C, wmOperator *op); int wm_homefile_read_exec(struct bContext *C, struct wmOperator *op); int wm_homefile_read(struct bContext *C, struct ReportList *reports, short from_memory); int wm_homefile_write_exec(struct bContext *C, struct wmOperator *op); diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt index 141eb04727a..6455f9165ce 100644 --- a/source/creator/CMakeLists.txt +++ b/source/creator/CMakeLists.txt @@ -989,7 +989,7 @@ endif() list_insert_after(BLENDER_SORTED_LIBS "bf_blenkernel" "bf_intern_rigidbody") endif() - if(WITH_BULLET AND NOT WITH_BULLET_SYSTEM) + if(WITH_BULLET AND NOT WITH_SYSTEM_BULLET) list_insert_after(BLENDER_SORTED_LIBS "ge_logic_ngnetwork" "extern_bullet") endif() diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 580691d88c4..e9bb6b1ba3c 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -222,7 +222,7 @@ public: virtual CValue *ConvertPythonToValue(PyObject *pyobj, const char *error_prefix); - static PyObject *pyattr_get_name(void * self, const KX_PYATTRIBUTE_DEF * attrdef); + static PyObject *pyattr_get_name(void *self, const KX_PYATTRIBUTE_DEF *attrdef); virtual PyObject *ConvertKeysToPython( void ); #endif /* WITH_PYTHON */ diff --git a/source/gameengine/Expressions/VoidValue.h b/source/gameengine/Expressions/VoidValue.h index e97278b3142..832f75c9c9f 100644 --- a/source/gameengine/Expressions/VoidValue.h +++ b/source/gameengine/Expressions/VoidValue.h @@ -46,7 +46,7 @@ class CVoidValue : public CPropValue public: /// Construction/destruction CVoidValue() : m_bDeleteOnDestruct(false), m_pAnything(NULL) { } - CVoidValue(void * voidptr, bool bDeleteOnDestruct, AllocationTYPE alloctype) : + CVoidValue(void *voidptr, bool bDeleteOnDestruct, AllocationTYPE alloctype) : m_bDeleteOnDestruct(bDeleteOnDestruct), m_pAnything(voidptr) { diff --git a/source/gameengine/Ketsji/KX_MeshProxy.h b/source/gameengine/Ketsji/KX_MeshProxy.h index 5366634ef98..4a4358bff3a 100644 --- a/source/gameengine/Ketsji/KX_MeshProxy.h +++ b/source/gameengine/Ketsji/KX_MeshProxy.h @@ -74,9 +74,9 @@ public: KX_PYMETHOD(KX_MeshProxy,Transform); KX_PYMETHOD(KX_MeshProxy,TransformUV); - static PyObject *pyattr_get_materials(void* self_v, const KX_PYATTRIBUTE_DEF *attrdef); - static PyObject *pyattr_get_numMaterials(void * self, const KX_PYATTRIBUTE_DEF * attrdef); - static PyObject *pyattr_get_numPolygons(void * self, const KX_PYATTRIBUTE_DEF * attrdef); + static PyObject *pyattr_get_materials(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef); + static PyObject *pyattr_get_numMaterials(void *self, const KX_PYATTRIBUTE_DEF * attrdef); + static PyObject *pyattr_get_numPolygons(void *self, const KX_PYATTRIBUTE_DEF * attrdef); }; #endif /* WITH_PYTHON */ diff --git a/source/gameengine/Ketsji/KX_PythonSeq.cpp b/source/gameengine/Ketsji/KX_PythonSeq.cpp index 4c491654d1f..edbb0537559 100644 --- a/source/gameengine/Ketsji/KX_PythonSeq.cpp +++ b/source/gameengine/Ketsji/KX_PythonSeq.cpp @@ -189,7 +189,7 @@ static PyObject *KX_PythonSeq_getIndex(PyObject *self, Py_ssize_t index) return NULL; } -static PyObjectPlus * KX_PythonSeq_subscript__internal(PyObject *self, const char *key) +static PyObjectPlus *KX_PythonSeq_subscript__internal(PyObject *self, const char *key) { PyObjectPlus *self_plus= BGE_PROXY_REF(((KX_PythonSeq *)self)->base); diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp index b2b766b65e8..af8c855f3b0 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp +++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp @@ -254,7 +254,7 @@ void RAS_BucketManager::Renderbuckets( rendertools->SetClientObject(rasty, NULL); } -RAS_MaterialBucket* RAS_BucketManager::FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated) +RAS_MaterialBucket *RAS_BucketManager::FindBucket(RAS_IPolyMaterial *material, bool &bucketCreated) { BucketList::iterator it; diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h index 78125a7bbb3..bf88da6f1ba 100644 --- a/source/gameengine/Rasterizer/RAS_BucketManager.h +++ b/source/gameengine/Rasterizer/RAS_BucketManager.h @@ -54,13 +54,13 @@ public: void Renderbuckets(const MT_Transform & cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools); - RAS_MaterialBucket* FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated); + RAS_MaterialBucket* FindBucket(RAS_IPolyMaterial *material, bool &bucketCreated); void OptimizeBuckets(MT_Scalar distance); - void ReleaseDisplayLists(RAS_IPolyMaterial * material = NULL); - void ReleaseMaterials(RAS_IPolyMaterial * material = NULL); + void ReleaseDisplayLists(RAS_IPolyMaterial *material = NULL); + void ReleaseMaterials(RAS_IPolyMaterial *material = NULL); - void RemoveMaterial(RAS_IPolyMaterial * mat); // freeing scenes only + void RemoveMaterial(RAS_IPolyMaterial *mat); // freeing scenes only /* for merging */ void MergeBucketManager(RAS_BucketManager *other, SCA_IScene *scene); diff --git a/source/gameengine/VideoTexture/Exception.h b/source/gameengine/VideoTexture/Exception.h index e0c1fdd568d..4410ec1aa8b 100644 --- a/source/gameengine/VideoTexture/Exception.h +++ b/source/gameengine/VideoTexture/Exception.h @@ -105,7 +105,7 @@ public: // returns 0, if exception identification don't match at all // returns 1, if only exception identification is matching // returns 2, if both exception identification and result are matching - int isExp (ExceptionID * exp, RESULT hres = S_OK) throw() + int isExp (ExceptionID *exp, RESULT hres = S_OK) throw() { // check exception identification if (&m_expID == exp) diff --git a/source/gameengine/VideoTexture/FilterBase.cpp b/source/gameengine/VideoTexture/FilterBase.cpp index 77d12ddc9e6..97abe36bb81 100644 --- a/source/gameengine/VideoTexture/FilterBase.cpp +++ b/source/gameengine/VideoTexture/FilterBase.cpp @@ -58,7 +58,7 @@ void FilterBase::release (void) // set new previous filter -void FilterBase::setPrevious (PyFilter * filt, bool useRefCnt) +void FilterBase::setPrevious(PyFilter *filt, bool useRefCnt) { // if reference counting has to be used if (useRefCnt) diff --git a/source/gameengine/VideoTexture/FilterBase.h b/source/gameengine/VideoTexture/FilterBase.h index f8fe2c772f0..a1d199b1851 100644 --- a/source/gameengine/VideoTexture/FilterBase.h +++ b/source/gameengine/VideoTexture/FilterBase.h @@ -79,7 +79,7 @@ public: /// get previous filter PyFilter * getPrevious (void) { return m_previous; } /// set previous filter - void setPrevious (PyFilter * filt, bool useRefCnt = true); + void setPrevious (PyFilter *filt, bool useRefCnt = true); /// find first filter in chain FilterBase * findFirst (void); @@ -92,20 +92,20 @@ protected: PyFilter * m_previous; /// filter pixel, source byte buffer - virtual unsigned int filter (unsigned char * src, short x, short y, - short * size, unsigned int pixSize, unsigned int val = 0) + virtual unsigned int filter(unsigned char *src, short x, short y, + short *size, unsigned int pixSize, unsigned int val = 0) { return val; } /// filter pixel, source int buffer - virtual unsigned int filter (unsigned int * src, short x, short y, - short * size, unsigned int pixSize, unsigned int val = 0) + virtual unsigned int filter(unsigned int *src, short x, short y, + short *size, unsigned int pixSize, unsigned int val = 0) { return val; } /// filter pixel, source float buffer - virtual unsigned int filter (float * src, short x, short y, - short * size, unsigned int pixSize, unsigned int val = 0) + virtual unsigned int filter(float *src, short x, short y, + short *size, unsigned int pixSize, unsigned int val = 0) { return val; } /// get source pixel size - virtual unsigned int getPixelSize (void) { return 1; } + virtual unsigned int getPixelSize(void) { return 1; } /// get converted pixel from previous filters template <class SRC> unsigned int convertPrevious (SRC src, short x, short y, diff --git a/source/gameengine/VideoTexture/FilterBlueScreen.h b/source/gameengine/VideoTexture/FilterBlueScreen.h index 5a90590a39d..cf74a6705b7 100644 --- a/source/gameengine/VideoTexture/FilterBlueScreen.h +++ b/source/gameengine/VideoTexture/FilterBlueScreen.h @@ -92,12 +92,12 @@ protected: } /// virtual filtering function for byte source - virtual unsigned int filter (unsigned char * src, short x, short y, - short * size, unsigned int pixSize, unsigned int val = 0) + virtual unsigned int filter (unsigned char *src, short x, short y, + short * size, unsigned int pixSize, unsigned int val = 0) { return tFilter(src, x, y, size, pixSize, val); } /// virtual filtering function for unsigned int source - virtual unsigned int filter (unsigned int * src, short x, short y, - short * size, unsigned int pixSize, unsigned int val = 0) + virtual unsigned int filter (unsigned int *src, short x, short y, + short * size, unsigned int pixSize, unsigned int val = 0) { return tFilter(src, x, y, size, pixSize, val); } }; diff --git a/source/gameengine/VideoTexture/FilterNormal.h b/source/gameengine/VideoTexture/FilterNormal.h index b21afb3ec26..951ecb84d9d 100644 --- a/source/gameengine/VideoTexture/FilterNormal.h +++ b/source/gameengine/VideoTexture/FilterNormal.h @@ -70,8 +70,8 @@ protected: unsigned short m_colIdx; /// filter pixel, source int buffer - template <class SRC> unsigned int tFilter (SRC * src, short x, short y, - short * size, unsigned int pixSize, unsigned int val = 0) + template <class SRC> unsigned int tFilter (SRC *src, short x, short y, + short * size, unsigned int pixSize, unsigned int val = 0) { // get value of required color int actPix = int(VT_C(val,m_colIdx)); diff --git a/source/gameengine/VideoTexture/FilterSource.h b/source/gameengine/VideoTexture/FilterSource.h index f1d2615ee32..0289c88f056 100644 --- a/source/gameengine/VideoTexture/FilterSource.h +++ b/source/gameengine/VideoTexture/FilterSource.h @@ -49,7 +49,7 @@ public: protected: /// filter pixel, source byte buffer - virtual unsigned int filter (unsigned char * src, short x, short y, + virtual unsigned int filter (unsigned char *src, short x, short y, short * size, unsigned int pixSize, unsigned int val) { VT_RGBA(val,src[0],src[1],src[2],0xFF); return val; } }; @@ -68,7 +68,7 @@ public: protected: /// filter pixel, source byte buffer - virtual unsigned int filter (unsigned char * src, short x, short y, + virtual unsigned int filter (unsigned char *src, short x, short y, short * size, unsigned int pixSize, unsigned int val) { if ((intptr_t(src)&0x3) == 0) @@ -95,8 +95,8 @@ public: protected: /// filter pixel, source byte buffer - virtual unsigned int filter (unsigned char * src, short x, short y, - short * size, unsigned int pixSize, unsigned int val) + virtual unsigned int filter (unsigned char *src, short x, short y, + short * size, unsigned int pixSize, unsigned int val) { VT_RGBA(val,src[2],src[1],src[0],0xFF); return val; } }; @@ -114,11 +114,11 @@ public: protected: /// filter pixel, source float buffer - virtual unsigned int filter (float * src, short x, short y, + virtual unsigned int filter (float *src, short x, short y, short * size, unsigned int pixSize, unsigned int val) { // calculate gray value - // convert float to unsigned char + // convert float to unsigned char unsigned int depth = int(src[0] * 255); // return depth scale value VT_R(val) = depth; @@ -145,8 +145,8 @@ public: protected: /// filter pixel, source float buffer - virtual unsigned int filter (float * src, short x, short y, - short * size, unsigned int pixSize, unsigned int val) + virtual unsigned int filter (float *src, short x, short y, + short *size, unsigned int pixSize, unsigned int val) { /* Copy the float value straight away * The user can retrieve the original float value by using @@ -193,59 +193,59 @@ protected: { return (9 * (b + c) - a - d + 8) >> 4; } /// common horizontal interpolation - int interpolH (unsigned char * src) + int interpolH (unsigned char *src) { return interpol(*(src-1), *src, *(src+1), *(src+2)); } /// common vertical interpolation - int interpolV (unsigned char * src) + int interpolV (unsigned char *src) { return interpol(*(src-m_pitchUV), *src, *(src+m_pitchUV), *(src+2*m_pitchUV)); } /// common joined vertical and horizontal interpolation - int interpolVH (unsigned char * src) + int interpolVH (unsigned char *src) { return interpol(interpolV(src-1), interpolV(src), interpolV(src+1), - interpolV(src+2)); + interpolV(src+2)); } /// is pixel on edge - bool isEdge (short x, short y, short * size) + bool isEdge (short x, short y, const short size[2]) { return x <= 1 || x >= size[0] - 4 || y <= 1 || y >= size[1] - 4; } /// get the first parameter on the low edge - unsigned char * interParA (unsigned char * src, short x, short size, short shift) + unsigned char * interParA (unsigned char *src, short x, short size, short shift) { return x > 1 ? src - shift : src; } /// get the third parameter on the high edge - unsigned char * interParC (unsigned char * src, short x, short size, short shift) + unsigned char * interParC (unsigned char *src, short x, short size, short shift) { return x < size - 2 ? src + shift : src; } /// get the fourth parameter on the high edge - unsigned char * interParD (unsigned char * src, short x, short size, short shift) + unsigned char * interParD (unsigned char *src, short x, short size, short shift) { return x < size - 4 ? src + 2 * shift : x < size - 2 ? src + shift : src; } /// horizontal interpolation on edges - int interpolEH (unsigned char * src, short x, short size) - { + int interpolEH (unsigned char *src, short x, short size) + { return interpol(*interParA(src, x, size, 1), *src, - *interParC(src, x, size, 1), *interParD(src, x, size, 1)); + *interParC(src, x, size, 1), *interParD(src, x, size, 1)); } /// vertical interpolation on edges - int interpolEV (unsigned char * src, short y, short size) - { + int interpolEV (unsigned char *src, short y, short size) + { return interpol(*interParA(src, y, size, m_pitchUV), *src, - *interParC(src, y, size, m_pitchUV), *interParD(src, y, size, m_pitchUV)); + *interParC(src, y, size, m_pitchUV), *interParD(src, y, size, m_pitchUV)); } /// joined vertical and horizontal interpolation on edges - int interpolEVH (unsigned char * src, short x, short y, short * size) + int interpolEVH (unsigned char *src, short x, short y, short * size) { return interpol(interpolEV(interParA(src, x, size[0], 1), y, size[1]), - interpolEV(src, y, size[1]), interpolEV(interParC(src, x, size[0], 1), y, size[1]), - interpolEV(interParD(src, x, size[0], 1), y, size[1])); + interpolEV(src, y, size[1]), interpolEV(interParC(src, x, size[0], 1), y, size[1]), + interpolEV(interParD(src, x, size[0], 1), y, size[1])); } /// filter pixel, source byte buffer - virtual unsigned int filter (unsigned char * src, short x, short y, + virtual unsigned int filter (unsigned char *src, short x, short y, short * size, unsigned int pixSize, unsigned int val) { // V & U offset @@ -325,5 +325,4 @@ protected: } }; - -#endif +#endif /* __FILTERSOURCE_H__ */ diff --git a/source/gameengine/VideoTexture/ImageBase.cpp b/source/gameengine/VideoTexture/ImageBase.cpp index 5a11cd24bcf..4109981a98c 100644 --- a/source/gameengine/VideoTexture/ImageBase.cpp +++ b/source/gameengine/VideoTexture/ImageBase.cpp @@ -124,7 +124,7 @@ void ImageBase::refresh (void) // get source object -PyImage * ImageBase::getSource (const char * id) +PyImage * ImageBase::getSource (const char *id) { // find source ImageSourceList::iterator src = findSource(id); @@ -134,7 +134,7 @@ PyImage * ImageBase::getSource (const char * id) // set source object -bool ImageBase::setSource (const char * id, PyImage *source) +bool ImageBase::setSource (const char *id, PyImage *source) { // find source ImageSourceList::iterator src = findSource(id); @@ -223,7 +223,7 @@ void ImageBase::init (short width, short height) // find source -ImageSourceList::iterator ImageBase::findSource (const char * id) +ImageSourceList::iterator ImageBase::findSource (const char *id) { // iterate sources ImageSourceList::iterator it; @@ -294,7 +294,7 @@ bool ImageBase::loopDetect (ImageBase * img) // ImageSource class implementation // constructor -ImageSource::ImageSource (const char * id) : m_source(NULL), m_image(NULL) +ImageSource::ImageSource (const char *id) : m_source(NULL), m_image(NULL) { // copy id int idx; @@ -312,9 +312,9 @@ ImageSource::~ImageSource (void) // compare id -bool ImageSource::is (const char * id) +bool ImageSource::is (const char *id) { - for (char * myId = m_id; *myId != '\0'; ++myId, ++id) + for (char *myId = m_id; *myId != '\0'; ++myId, ++id) if (*myId != *id) return false; return *id == '\0'; } @@ -551,7 +551,7 @@ int Image_setFlip(PyImage *self, PyObject *value, void *closure) } // get zbuff -PyObject *Image_getZbuff(PyImage * self, void *closure) +PyObject *Image_getZbuff(PyImage *self, void *closure) { if (self->m_image != NULL && self->m_image->getZbuff()) Py_RETURN_TRUE; else Py_RETURN_FALSE; @@ -573,7 +573,7 @@ int Image_setZbuff(PyImage *self, PyObject *value, void *closure) } // get depth -PyObject *Image_getDepth(PyImage * self, void *closure) +PyObject *Image_getDepth(PyImage *self, void *closure) { if (self->m_image != NULL && self->m_image->getDepth()) Py_RETURN_TRUE; else Py_RETURN_FALSE; @@ -601,7 +601,7 @@ int Image_setDepth(PyImage *self, PyObject *value, void *closure) PyObject *Image_getSource(PyImage *self, PyObject *args) { // get arguments - char * id; + char *id; if (!PyArg_ParseTuple(args, "s:getSource", &id)) return NULL; if (self->m_image != NULL) @@ -625,7 +625,7 @@ PyObject *Image_getSource(PyImage *self, PyObject *args) PyObject *Image_setSource(PyImage *self, PyObject *args) { // get arguments - char * id; + char *id; PyObject *obj; if (!PyArg_ParseTuple(args, "sO:setSource", &id, &obj)) return NULL; diff --git a/source/gameengine/VideoTexture/ImageBase.h b/source/gameengine/VideoTexture/ImageBase.h index 718191fd049..50dc8c10ec6 100644 --- a/source/gameengine/VideoTexture/ImageBase.h +++ b/source/gameengine/VideoTexture/ImageBase.h @@ -92,9 +92,9 @@ public: void setDepth(bool depth) { m_depth = depth; } /// get source object - PyImage * getSource(const char * id); + PyImage * getSource(const char *id); /// set source object, return true, if source was set - bool setSource(const char * id, PyImage *source); + bool setSource(const char *id, PyImage *source); /// get pixel filter PyFilter * getFilter(void) { return m_pyfilter; } @@ -236,7 +236,7 @@ protected: } // template for specific filter preprocessing - template <class F, class SRC> void filterImage (F & filt, SRC srcBuff, short * srcSize) + template <class F, class SRC> void filterImage (F & filt, SRC srcBuff, short *srcSize) { // find first filter in chain FilterBase * firstFilter = NULL; @@ -280,14 +280,14 @@ class ImageSource { public: /// constructor - ImageSource (const char * id); + ImageSource (const char *id); /// destructor virtual ~ImageSource (void); /// get id const char * getId (void) { return m_id; } /// compare id to argument - bool is (const char * id); + bool is (const char *id); /// get source object PyImage * getSource (void) { return m_source; } @@ -330,7 +330,7 @@ extern PyTypeList pyImageTypes; // object initialization template <class T> static int Image_init(PyObject *pySelf, PyObject *args, PyObject *kwds) { - PyImage *self = reinterpret_cast<PyImage*>(pySelf); + PyImage *self = reinterpret_cast<PyImage *>(pySelf); // create source object if (self->m_image != NULL) delete self->m_image; self->m_image = new T(); @@ -344,7 +344,7 @@ PyObject *Image_allocNew(PyTypeObject *type, PyObject *args, PyObject *kwds); void Image_dealloc(PyImage *self); // get image data -PyObject *Image_getImage(PyImage *self, char * mode); +PyObject *Image_getImage(PyImage *self, char *mode); // get image size PyObject *Image_getSize(PyImage *self, void *closure); // refresh image - invalidate current content @@ -364,13 +364,13 @@ PyObject *Image_getSource(PyImage *self, PyObject *args); // set filter source object PyObject *Image_setSource(PyImage *self, PyObject *args); // get Z buffer -PyObject *Image_getZbuff(PyImage * self, void *closure); +PyObject *Image_getZbuff(PyImage *self, void *closure); // set Z buffer -int Image_setZbuff(PyImage * self, PyObject *value, void *closure); +int Image_setZbuff(PyImage *self, PyObject *value, void *closure); // get depth -PyObject *Image_getDepth(PyImage * self, void *closure); +PyObject *Image_getDepth(PyImage *self, void *closure); // set depth -int Image_setDepth(PyImage * self, PyObject *value, void *closure); +int Image_setDepth(PyImage *self, PyObject *value, void *closure); // get pixel filter object PyObject *Image_getFilter(PyImage *self, void *closure); diff --git a/source/gameengine/VideoTexture/ImageBuff.cpp b/source/gameengine/VideoTexture/ImageBuff.cpp index 80ad9b40c24..8f547aa8b57 100644 --- a/source/gameengine/VideoTexture/ImageBuff.cpp +++ b/source/gameengine/VideoTexture/ImageBuff.cpp @@ -94,7 +94,7 @@ ImageBuff::~ImageBuff (void) // load image from buffer -void ImageBuff::load (unsigned char * img, short width, short height) +void ImageBuff::load(unsigned char *img, short width, short height) { // loading a new buffer implies to reset the imbuf if any, because the size may change if (m_imbuf) @@ -117,7 +117,7 @@ void ImageBuff::load (unsigned char * img, short width, short height) m_avail = true; } -void ImageBuff::clear (short width, short height, unsigned char color) +void ImageBuff::clear(short width, short height, unsigned char color) { unsigned char *p; int size; @@ -146,7 +146,7 @@ void ImageBuff::clear (short width, short height, unsigned char color) } // img must point to a array of RGBA data of size width*height -void ImageBuff::plot (unsigned char * img, short width, short height, short x, short y, short mode) +void ImageBuff::plot(unsigned char *img, short width, short height, short x, short y, short mode) { struct ImBuf *tmpbuf; @@ -170,7 +170,7 @@ void ImageBuff::plot (unsigned char * img, short width, short height, short x, s IMB_freeImBuf(tmpbuf); } -void ImageBuff::plot (ImageBuff* img, short x, short y, short mode) +void ImageBuff::plot(ImageBuff *img, short x, short y, short mode) { if (m_size[0] == 0 || m_size[1] == 0 || img->m_size[0] == 0 || img->m_size[1] == 0) return; @@ -194,13 +194,13 @@ void ImageBuff::plot (ImageBuff* img, short x, short y, short mode) // cast Image pointer to ImageBuff -inline ImageBuff * getImageBuff (PyImage *self) -{ return static_cast<ImageBuff*>(self->m_image); } +inline ImageBuff *getImageBuff(PyImage *self) +{ return static_cast<ImageBuff *>(self->m_image); } // python methods -static bool testPyBuffer(Py_buffer* buffer, int width, int height, unsigned int pixsize) +static bool testPyBuffer(Py_buffer *buffer, int width, int height, unsigned int pixsize) { if (buffer->itemsize != 1) { @@ -232,7 +232,7 @@ static bool testPyBuffer(Py_buffer* buffer, int width, int height, unsigned int return true; } -static bool testBGLBuffer(Buffer* buffer, int width, int height, unsigned int pixsize) +static bool testBGLBuffer(Buffer *buffer, int width, int height, unsigned int pixsize) { unsigned int size = BGL_typeSize(buffer->type); for (int i=0; i<buffer->ndimensions; i++) @@ -313,7 +313,7 @@ static PyObject *load(PyImage *self, PyObject *args) Py_RETURN_NONE; } -static PyObject *plot (PyImage *self, PyObject *args) +static PyObject *plot(PyImage *self, PyObject *args) { PyImage * other; Buffer* bglBuffer; @@ -362,15 +362,14 @@ static PyObject *plot (PyImage *self, PyObject *args) } // methods structure -static PyMethodDef imageBuffMethods[] = -{ +static PyMethodDef imageBuffMethods[] = { {"load", (PyCFunction)load, METH_VARARGS, "Load image from buffer"}, {"plot", (PyCFunction)plot, METH_VARARGS, "update image buffer"}, {NULL} }; // attributes structure -static PyGetSetDef imageBuffGetSets[] = -{ // attributes from ImageBase class +static PyGetSetDef imageBuffGetSets[] = { + // attributes from ImageBase class {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL}, {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, @@ -382,8 +381,7 @@ static PyGetSetDef imageBuffGetSets[] = // define python type -PyTypeObject ImageBuffType = -{ +PyTypeObject ImageBuffType = { PyVarObject_HEAD_INIT(NULL, 0) "VideoTexture.ImageBuff", /*tp_name*/ sizeof(PyImage), /*tp_basicsize*/ diff --git a/source/gameengine/VideoTexture/ImageMix.cpp b/source/gameengine/VideoTexture/ImageMix.cpp index ee6e16d0a86..dc93bf03423 100644 --- a/source/gameengine/VideoTexture/ImageMix.cpp +++ b/source/gameengine/VideoTexture/ImageMix.cpp @@ -42,12 +42,12 @@ // cast ImageSource pointer to ImageSourceMix -inline ImageSourceMix * getImageSourceMix (ImageSource * src) +inline ImageSourceMix *getImageSourceMix(ImageSource *src) { return static_cast<ImageSourceMix*>(src); } // get weight -short ImageMix::getWeight (const char * id) +short ImageMix::getWeight(const char *id) { // find source ImageSourceList::iterator src = findSource(id); @@ -56,7 +56,7 @@ short ImageMix::getWeight (const char * id) } // set weight -bool ImageMix::setWeight (const char * id, short weight) +bool ImageMix::setWeight(const char *id, short weight) { // find source ImageSourceList::iterator src = findSource(id); @@ -72,7 +72,7 @@ ExceptionID ImageSizesNotMatch; ExpDesc ImageSizesNotMatchDesc(ImageSizesNotMatch, "Image sizes of sources are different"); // calculate image from sources and set its availability -void ImageMix::calcImage (unsigned int texId, double ts) +void ImageMix::calcImage(unsigned int texId, double ts) { // check source sizes if (!checkSourceSizes()) THRWEXCP(ImageSizesNotMatch, S_OK); @@ -105,19 +105,19 @@ void ImageMix::calcImage (unsigned int texId, double ts) // cast Image pointer to ImageMix -inline ImageMix * getImageMix (PyImage *self) +inline ImageMix * getImageMix(PyImage *self) { return static_cast<ImageMix*>(self->m_image); } // python methods // get source weight -static PyObject *getWeight (PyImage *self, PyObject *args) +static PyObject *getWeight(PyImage *self, PyObject *args) { // weight short weight = 0; // get arguments - char * id; + char *id; if (!PyArg_ParseTuple(args, "s:getWeight", &id)) return NULL; if (self->m_image != NULL) @@ -129,10 +129,10 @@ static PyObject *getWeight (PyImage *self, PyObject *args) // set source weight -static PyObject *setWeight (PyImage *self, PyObject *args) +static PyObject *setWeight(PyImage *self, PyObject *args) { // get arguments - char * id; + char *id; short weight = 0; if (!PyArg_ParseTuple(args, "sh:setWeight", &id, &weight)) return NULL; @@ -150,8 +150,7 @@ static PyObject *setWeight (PyImage *self, PyObject *args) // methods structure -static PyMethodDef imageMixMethods[] = -{ +static PyMethodDef imageMixMethods[] = { {"getSource", (PyCFunction)Image_getSource, METH_VARARGS, "get image source"}, {"setSource", (PyCFunction)Image_setSource, METH_VARARGS, "set image source"}, {"getWeight", (PyCFunction)getWeight, METH_VARARGS, "get image source weight"}, @@ -161,8 +160,8 @@ static PyMethodDef imageMixMethods[] = {NULL} }; // attributes structure -static PyGetSetDef imageMixGetSets[] = -{ // attributes from ImageBase class +static PyGetSetDef imageMixGetSets[] = { + // attributes from ImageBase class {(char*)"valid", (getter)Image_valid, NULL, (char*)"bool to tell if an image is available", NULL}, {(char*)"image", (getter)Image_getImage, NULL, (char*)"image data", NULL}, {(char*)"size", (getter)Image_getSize, NULL, (char*)"image size", NULL}, @@ -174,11 +173,10 @@ static PyGetSetDef imageMixGetSets[] = // define python type -PyTypeObject ImageMixType = -{ +PyTypeObject ImageMixType = { PyVarObject_HEAD_INIT(NULL, 0) "VideoTexture.ImageMix", /*tp_name*/ - sizeof(PyImage), /*tp_basicsize*/ + sizeof(PyImage), /*tp_basicsize*/ 0, /*tp_itemsize*/ (destructor)Image_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ @@ -196,16 +194,16 @@ PyTypeObject ImageMixType = 0, /*tp_setattro*/ &imageBufferProcs, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ - "Image mixer", /* tp_doc */ - 0, /* tp_traverse */ - 0, /* tp_clear */ - 0, /* tp_richcompare */ - 0, /* tp_weaklistoffset */ - 0, /* tp_iter */ - 0, /* tp_iternext */ - imageMixMethods, /* tp_methods */ - 0, /* tp_members */ - imageMixGetSets, /* tp_getset */ + "Image mixer", /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + imageMixMethods, /* tp_methods */ + 0, /* tp_members */ + imageMixGetSets, /* tp_getset */ 0, /* tp_base */ 0, /* tp_dict */ 0, /* tp_descr_get */ @@ -213,6 +211,6 @@ PyTypeObject ImageMixType = 0, /* tp_dictoffset */ (initproc)Image_init<ImageMix>, /* tp_init */ 0, /* tp_alloc */ - Image_allocNew, /* tp_new */ + Image_allocNew, /* tp_new */ }; diff --git a/source/gameengine/VideoTexture/ImageMix.h b/source/gameengine/VideoTexture/ImageMix.h index 712efde7dd4..e55b95834fa 100644 --- a/source/gameengine/VideoTexture/ImageMix.h +++ b/source/gameengine/VideoTexture/ImageMix.h @@ -43,7 +43,7 @@ class ImageSourceMix : public ImageSource { public: /// constructor - ImageSourceMix (const char * id) : ImageSource(id), m_weight(0x100) {} + ImageSourceMix (const char *id) : ImageSource(id), m_weight(0x100) {} /// destructor virtual ~ImageSourceMix (void) {} @@ -76,14 +76,14 @@ public: virtual ~ImageMix (void) {} /// get weight - short getWeight (const char * id); + short getWeight(const char *id); /// set weight - bool setWeight (const char * id, short weight); + bool setWeight(const char *id, short weight); protected: /// create new source - virtual ImageSource * newSource (const char * id) { return new ImageSourceMix(id); } + virtual ImageSource *newSource(const char *id) { return new ImageSourceMix(id); } /// calculate image from sources and set its availability virtual void calcImage (unsigned int texId, double ts); diff --git a/source/gameengine/VideoTexture/ImageRender.cpp b/source/gameengine/VideoTexture/ImageRender.cpp index 11ddec681c5..016020048e9 100644 --- a/source/gameengine/VideoTexture/ImageRender.cpp +++ b/source/gameengine/VideoTexture/ImageRender.cpp @@ -62,7 +62,7 @@ ExpDesc MirrorHorizontalDesc(MirrorHorizontal, "Mirror is horizontal in local sp ExpDesc MirrorTooSmallDesc(MirrorTooSmall, "Mirror is too small"); // constructor -ImageRender::ImageRender (KX_Scene * scene, KX_Camera * camera) : +ImageRender::ImageRender (KX_Scene *scene, KX_Camera * camera) : ImageViewport(), m_render(true), m_scene(scene), @@ -562,7 +562,7 @@ static PyGetSetDef imageMirrorGetSets[] = // constructor -ImageRender::ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat) : +ImageRender::ImageRender (KX_Scene *scene, KX_GameObject *observer, KX_GameObject *mirror, RAS_IPolyMaterial *mat) : ImageViewport(), m_render(false), m_scene(scene), diff --git a/source/gameengine/VideoTexture/ImageRender.h b/source/gameengine/VideoTexture/ImageRender.h index 27882a9d117..680e1cc1d89 100644 --- a/source/gameengine/VideoTexture/ImageRender.h +++ b/source/gameengine/VideoTexture/ImageRender.h @@ -49,8 +49,8 @@ class ImageRender : public ImageViewport { public: /// constructor - ImageRender (KX_Scene * scene, KX_Camera * camera); - ImageRender (KX_Scene * scene, KX_GameObject * observer, KX_GameObject * mirror, RAS_IPolyMaterial * mat); + ImageRender(KX_Scene *scene, KX_Camera *camera); + ImageRender(KX_Scene *scene, KX_GameObject *observer, KX_GameObject *mirror, RAS_IPolyMaterial * mat); /// destructor virtual ~ImageRender (void); diff --git a/source/gameengine/VideoTexture/PyTypeList.cpp b/source/gameengine/VideoTexture/PyTypeList.cpp index 99e9ae13e64..588a1257d6a 100644 --- a/source/gameengine/VideoTexture/PyTypeList.cpp +++ b/source/gameengine/VideoTexture/PyTypeList.cpp @@ -58,7 +58,7 @@ bool PyTypeList::in (PyTypeObject *type) } /// add type to list -void PyTypeList::add (PyTypeObject *type, const char * name) +void PyTypeList::add (PyTypeObject *type, const char *name) { // if list doesn't exist, create it if (m_list.get() == NULL) diff --git a/source/gameengine/VideoTexture/VideoBase.cpp b/source/gameengine/VideoTexture/VideoBase.cpp index edf03dea484..9c8df0ca8c4 100644 --- a/source/gameengine/VideoTexture/VideoBase.cpp +++ b/source/gameengine/VideoTexture/VideoBase.cpp @@ -52,7 +52,7 @@ void VideoBase::init(short width, short height) // process video frame -void VideoBase::process (BYTE * sample) +void VideoBase::process (BYTE *sample) { // if scale was changed if (m_scaleChange) @@ -106,7 +106,7 @@ ExpDesc SourceVideoEmptyDesc(SourceVideoEmpty, "Source Video is empty"); ExpDesc SourceVideoCreationDesc(SourceVideoCreation, "SourceVideo object was not created"); // open video source -void Video_open(VideoBase * self, char * file, short captureID) +void Video_open(VideoBase *self, char *file, short captureID) { // if file is empty, throw exception if (file == NULL) THRWEXCP(SourceVideoEmpty, S_OK); diff --git a/source/gameengine/VideoTexture/VideoBase.h b/source/gameengine/VideoTexture/VideoBase.h index 9880165c198..8d64980c9c2 100644 --- a/source/gameengine/VideoTexture/VideoBase.h +++ b/source/gameengine/VideoTexture/VideoBase.h @@ -66,13 +66,13 @@ public: virtual ~VideoBase (void) {} /// open video file - virtual void openFile (char * file) + virtual void openFile(char *file) { m_isFile = true; m_status = SourceReady; } /// open video capture device - virtual void openCam (char * file, short camIdx) + virtual void openCam(char *file, short camIdx) { m_isFile = false; m_status = SourceReady; @@ -186,7 +186,7 @@ template <class T> void Video_init(PyImage *self) // video functions -void Video_open(VideoBase * self, char * file, short captureID); +void Video_open(VideoBase *self, char *file, short captureID); PyObject *Video_play(PyImage *self); PyObject *Video_pause(PyImage *self); PyObject *Video_stop(PyImage *self); diff --git a/source/gameengine/VideoTexture/VideoFFmpeg.h b/source/gameengine/VideoTexture/VideoFFmpeg.h index 2f466eb5eeb..4a948fe61de 100644 --- a/source/gameengine/VideoTexture/VideoFFmpeg.h +++ b/source/gameengine/VideoTexture/VideoFFmpeg.h @@ -79,9 +79,9 @@ public: /// set initial parameters void initParams (short width, short height, float rate, bool image=false); /// open video/image file - virtual void openFile (char * file); + virtual void openFile(char *file); /// open video capture device - virtual void openCam (char * driver, short camIdx); + virtual void openCam(char *driver, short camIdx); /// release video source virtual bool release (void); |